mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-12 08:31:27 +00:00
Compare commits
547 Commits
stdlib/add
...
beta5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
994eceabc0 | ||
|
|
e46544cc5e | ||
|
|
c0668334b4 | ||
|
|
1ad2c6e4a7 | ||
|
|
26b3c06963 | ||
|
|
362f1641b8 | ||
|
|
889126cc25 | ||
|
|
000b14d86e | ||
|
|
258ae08a6e | ||
|
|
a0d9271e00 | ||
|
|
3ceba38a78 | ||
|
|
c28e9b0f3c | ||
|
|
5b23a86f6e | ||
|
|
8c1cd3a1ed | ||
|
|
ab7c2cb82a | ||
|
|
b707da415c | ||
|
|
ddfdff0b30 | ||
|
|
e7c81388b7 | ||
|
|
b00d05ecad | ||
|
|
f5ead3507a | ||
|
|
a4b9c32933 | ||
|
|
8839e9f707 | ||
|
|
4f9b441a66 | ||
|
|
e4116624c3 | ||
|
|
4dd91c0a81 | ||
|
|
47ad2370e3 | ||
|
|
39598530d5 | ||
|
|
fa98553461 | ||
|
|
94369a24d5 | ||
|
|
036828b923 | ||
|
|
5f27032bae | ||
|
|
cee7724d9f | ||
|
|
a86fcf1141 | ||
|
|
02262534db | ||
|
|
2706dd1d8e | ||
|
|
2b1b54bc28 | ||
|
|
0cd0f54b21 | ||
|
|
24522175e5 | ||
|
|
74d7d109b9 | ||
|
|
fe5df28123 | ||
|
|
62f92f2453 | ||
|
|
839c1d29d3 | ||
|
|
ecddf5ee20 | ||
|
|
b7b099e795 | ||
|
|
292055276d | ||
|
|
90491cf683 | ||
|
|
d4c55159bd | ||
|
|
b7451c6e2b | ||
|
|
3941ac308d | ||
|
|
28f7ed010b | ||
|
|
9a19322bac | ||
|
|
cca091991f | ||
|
|
3933b8a48f | ||
|
|
a69bd11a77 | ||
|
|
e3d45d22ac | ||
|
|
d6b04166c0 | ||
|
|
dbcb91a118 | ||
|
|
58b1cf42ae | ||
|
|
6221c76578 | ||
|
|
7ffda5d985 | ||
|
|
c40227d93f | ||
|
|
6b411b900e | ||
|
|
95cad01d97 | ||
|
|
0893dafab3 | ||
|
|
118b619da3 | ||
|
|
195bbfe1ba | ||
|
|
8dd3f438d8 | ||
|
|
741cdbe0a3 | ||
|
|
94b39326de | ||
|
|
c3432df3c8 | ||
|
|
c5a84077f0 | ||
|
|
7f36a3ea3a | ||
|
|
edf7200e5d | ||
|
|
8bf0f32b18 | ||
|
|
9d08d51377 | ||
|
|
fb09160d87 | ||
|
|
30796c5dd2 | ||
|
|
69ba93fa16 | ||
|
|
bc06c0b264 | ||
|
|
009794dfd2 | ||
|
|
cbaf84754c | ||
|
|
14d3208b7a | ||
|
|
9cfc11d0df | ||
|
|
499ddeec82 | ||
|
|
63508c8e66 | ||
|
|
0e5b1ed884 | ||
|
|
8469003416 | ||
|
|
fb0e6c758d | ||
|
|
7166b69c5f | ||
|
|
53f92f35d4 | ||
|
|
b4840bddc5 | ||
|
|
3b253d10f3 | ||
|
|
19c3382a19 | ||
|
|
65a1c7b040 | ||
|
|
0cffd955ea | ||
|
|
3847dd9794 | ||
|
|
bc5911e64b | ||
|
|
6f96192e2f | ||
|
|
9f378345fc | ||
|
|
760052b917 | ||
|
|
035fe187c1 | ||
|
|
e1a0caa27b | ||
|
|
e0061f5f37 | ||
|
|
128ddd5237 | ||
|
|
b8094b2073 | ||
|
|
e3924564ed | ||
|
|
3bb8d69760 | ||
|
|
c926c135ca | ||
|
|
8714672ced | ||
|
|
bbc8941d76 | ||
|
|
2a18ab2d76 | ||
|
|
280c41a64d | ||
|
|
9e986db840 | ||
|
|
bcaa755c4e | ||
|
|
1574dc78df | ||
|
|
e8a697cb6d | ||
|
|
fe9cbd982d | ||
|
|
3b08e5e547 | ||
|
|
a97e623d04 | ||
|
|
f21b6a4777 | ||
|
|
fe4f51617c | ||
|
|
790524e391 | ||
|
|
f1783530ac | ||
|
|
e25d31618c | ||
|
|
b57d2ff702 | ||
|
|
7aae2bd452 | ||
|
|
a5b098c4a7 | ||
|
|
149ce70ce2 | ||
|
|
1867abbbe7 | ||
|
|
dd36ef5712 | ||
|
|
6155d836a5 | ||
|
|
75ab0dd509 | ||
|
|
c36eeadab1 | ||
|
|
09f53ea0bb | ||
|
|
52f0e0bc93 | ||
|
|
ca6153e8f1 | ||
|
|
03816373b3 | ||
|
|
513c4a4562 | ||
|
|
ecdef71580 | ||
|
|
1d787ed222 | ||
|
|
188119aa83 | ||
|
|
8b5a194dd6 | ||
|
|
1b6f96ac2b | ||
|
|
2fb3c727a7 | ||
|
|
3fca8f765c | ||
|
|
ad55c8fb96 | ||
|
|
f745f27694 | ||
|
|
784b250de8 | ||
|
|
05ec9cc424 | ||
|
|
fd79145b73 | ||
|
|
e558581667 | ||
|
|
24951e8a38 | ||
|
|
6fe48243c7 | ||
|
|
594ad27952 | ||
|
|
cfe1c44260 | ||
|
|
ea8da18338 | ||
|
|
4e36edb5d6 | ||
|
|
44bdac6e11 | ||
|
|
055c71e8d0 | ||
|
|
b5e637bed5 | ||
|
|
544bc9a70c | ||
|
|
2966420d24 | ||
|
|
7521b89b3e | ||
|
|
1a6f9b8d1c | ||
|
|
0d7c8635b3 | ||
|
|
ba180f915a | ||
|
|
d9b67ae0ef | ||
|
|
fe57a9e48f | ||
|
|
f5989aa4f2 | ||
|
|
91621704a2 | ||
|
|
16f482f723 | ||
|
|
7384d25cb3 | ||
|
|
35f788a89c | ||
|
|
3fb04aceb9 | ||
|
|
f55574df36 | ||
|
|
ca9e8fc5a7 | ||
|
|
d40e9ffc13 | ||
|
|
9aa38d99fb | ||
|
|
2e6d82a72b | ||
|
|
43476bd773 | ||
|
|
f84b3414c8 | ||
|
|
4b1edf7bb0 | ||
|
|
7e6495618b | ||
|
|
fc7c45d4d0 | ||
|
|
7f0065c806 | ||
|
|
6bfbec8c88 | ||
|
|
ce3d53d2ee | ||
|
|
2c29f6f5ab | ||
|
|
2dc1ba1d62 | ||
|
|
269676ee2e | ||
|
|
abd7ed5c70 | ||
|
|
6a3ac66208 | ||
|
|
78d737f3f4 | ||
|
|
cc259c2d15 | ||
|
|
5e231db631 | ||
|
|
3f7b8554dd | ||
|
|
a520e93b5b | ||
|
|
f3a6c541ec | ||
|
|
693e158759 | ||
|
|
c79ffbac5c | ||
|
|
a983e6cf60 | ||
|
|
68101eeffa | ||
|
|
293b8eeda8 | ||
|
|
7a1d789e9a | ||
|
|
ebbc68dfae | ||
|
|
9cad1a912a | ||
|
|
033698c51d | ||
|
|
b0a7706812 | ||
|
|
179498d971 | ||
|
|
5330248f6e | ||
|
|
0ba0ea5e1f | ||
|
|
dc84445e2e | ||
|
|
f25f0db10e | ||
|
|
75089a3af8 | ||
|
|
c725ed47f5 | ||
|
|
3692318c38 | ||
|
|
56cd29dff2 | ||
|
|
8d5d1b7dcc | ||
|
|
bd9221beaa | ||
|
|
623ecd2503 | ||
|
|
ca38a50e1a | ||
|
|
4fdc77f86f | ||
|
|
6a780f01bd | ||
|
|
a667aa2f71 | ||
|
|
539b84b561 | ||
|
|
ddde372fad | ||
|
|
ef134ffb1b | ||
|
|
0099c10e4e | ||
|
|
3f0d71411e | ||
|
|
b5568f9ace | ||
|
|
7ccdbfd596 | ||
|
|
01b79f640f | ||
|
|
d89b609960 | ||
|
|
9ad6685310 | ||
|
|
976fbf32ba | ||
|
|
5008a66a5b | ||
|
|
674a15daa1 | ||
|
|
8fa2e28729 | ||
|
|
e201268f46 | ||
|
|
8c4deb80e5 | ||
|
|
0b6e100aff | ||
|
|
51a8d5b9f0 | ||
|
|
69c2668530 | ||
|
|
e9ea4cc953 | ||
|
|
38522f60ea | ||
|
|
7756644eb1 | ||
|
|
154657a374 | ||
|
|
5df2a58003 | ||
|
|
b4bb92d136 | ||
|
|
8d0c3281cd | ||
|
|
02311538d6 | ||
|
|
19a6cc74de | ||
|
|
c83b6ed3a5 | ||
|
|
3dfb9d2e5e | ||
|
|
b5fad71b18 | ||
|
|
ffb382e3bc | ||
|
|
d0b9b6a3b4 | ||
|
|
fff011f60a | ||
|
|
258a6328a8 | ||
|
|
04c6ea78c7 | ||
|
|
ee9eb55b59 | ||
|
|
49e7417741 | ||
|
|
233e8e58e8 | ||
|
|
4ffd60cf52 | ||
|
|
43ce8222fc | ||
|
|
46798ed845 | ||
|
|
cd80d9408d | ||
|
|
a7503303d5 | ||
|
|
d2fce9b16d | ||
|
|
8db3fb03f9 | ||
|
|
19084b8182 | ||
|
|
fdc9e9d7f5 | ||
|
|
9d753f24b7 | ||
|
|
a4f82a2dc4 | ||
|
|
d2e22dc794 | ||
|
|
645c78e2f4 | ||
|
|
cb71e05c51 | ||
|
|
7c9b53c75c | ||
|
|
52eb9e4276 | ||
|
|
8deefd56db | ||
|
|
e24dbcefb6 | ||
|
|
061803d7b1 | ||
|
|
4f2887df64 | ||
|
|
162b152133 | ||
|
|
9f5a972816 | ||
|
|
923effe11d | ||
|
|
6301c707cd | ||
|
|
c23c2dbe85 | ||
|
|
515d2cd3e7 | ||
|
|
27551a8399 | ||
|
|
33967a09f6 | ||
|
|
33b366b9b9 | ||
|
|
58e93d5e1b | ||
|
|
bf9d50ccc4 | ||
|
|
59a9e2549c | ||
|
|
f55b421853 | ||
|
|
d296d91272 | ||
|
|
5df94da216 | ||
|
|
4dde59368c | ||
|
|
f509937037 | ||
|
|
5aff07561d | ||
|
|
feff5b2327 | ||
|
|
2d85c437cd | ||
|
|
0ab33ab075 | ||
|
|
597f2c0a8c | ||
|
|
16fbdcf107 | ||
|
|
ae3135c770 | ||
|
|
594d981094 | ||
|
|
91b920f18e | ||
|
|
871c5c66b4 | ||
|
|
dd2ae15531 | ||
|
|
81e7826568 | ||
|
|
477e25ae2f | ||
|
|
09191622e5 | ||
|
|
42565129ee | ||
|
|
65c5c99c68 | ||
|
|
6f347f351a | ||
|
|
3e2eb8c1a0 | ||
|
|
5e421b4024 | ||
|
|
39d9b35e27 | ||
|
|
a849f3f5d4 | ||
|
|
4ad113d836 | ||
|
|
7c7786f7d0 | ||
|
|
a2d644f708 | ||
|
|
a7eea6e4dd | ||
|
|
b443f605ed | ||
|
|
871fe7680b | ||
|
|
45c0bc3610 | ||
|
|
417ff281ee | ||
|
|
fe78f944a6 | ||
|
|
00504a3f6d | ||
|
|
470dfc9bec | ||
|
|
39b6637c7c | ||
|
|
616bb444ec | ||
|
|
1890b8cbd3 | ||
|
|
dd24fd47f7 | ||
|
|
79b30dddf9 | ||
|
|
239502368a | ||
|
|
66a031f7a0 | ||
|
|
1dca49cecc | ||
|
|
cbe1ffed55 | ||
|
|
f699adda33 | ||
|
|
ea8de883ac | ||
|
|
b950bf0e6e | ||
|
|
9452c200a0 | ||
|
|
6fb871a088 | ||
|
|
d024045638 | ||
|
|
745a3aeeac | ||
|
|
7cd867b936 | ||
|
|
e7fc6bcc6e | ||
|
|
c8b50eec1e | ||
|
|
521b216602 | ||
|
|
3254641c5a | ||
|
|
0fe74a8b43 | ||
|
|
199827635f | ||
|
|
4c3f620255 | ||
|
|
f87d2d1fcc | ||
|
|
ae2fc19fe5 | ||
|
|
354e1dc337 | ||
|
|
1824f10f07 | ||
|
|
ffc8b6fd89 | ||
|
|
a76f43b66c | ||
|
|
f50059a11a | ||
|
|
87aebd2cdf | ||
|
|
44743aade5 | ||
|
|
76cf284b77 | ||
|
|
15faa6610c | ||
|
|
ac9a1350c2 | ||
|
|
009e3f9cd7 | ||
|
|
ef4b3c99f4 | ||
|
|
6a74b1c8bf | ||
|
|
49778d2fb6 | ||
|
|
d10c3ffbe4 | ||
|
|
58d62fde4d | ||
|
|
1dbe560734 | ||
|
|
1ca6c695e6 | ||
|
|
9b8e5c5684 | ||
|
|
42119b311d | ||
|
|
49e484d796 | ||
|
|
08c29b7325 | ||
|
|
3b3dbbab04 | ||
|
|
2bc2d81486 | ||
|
|
280e00981f | ||
|
|
fb19552920 | ||
|
|
5bf8b4d946 | ||
|
|
f319b1b93a | ||
|
|
9a4eb2a368 | ||
|
|
fb406bfc24 | ||
|
|
c73f01927a | ||
|
|
5b72afe8a0 | ||
|
|
d80206376a | ||
|
|
8e71006e86 | ||
|
|
da02ed9057 | ||
|
|
2e971b13aa | ||
|
|
7e6bed7ad8 | ||
|
|
fee19ad9de | ||
|
|
deb6410a5c | ||
|
|
5cc04e41fe | ||
|
|
c40d6af1e5 | ||
|
|
6164566cad | ||
|
|
34c3c04ead | ||
|
|
5846769b43 | ||
|
|
9ff6be6f0f | ||
|
|
e458534c93 | ||
|
|
f05de6d6eb | ||
|
|
9a2442bba6 | ||
|
|
dc34d4fc31 | ||
|
|
136e8d9d02 | ||
|
|
70c200d265 | ||
|
|
94bea54db3 | ||
|
|
594039ac42 | ||
|
|
84824b1024 | ||
|
|
ef72c594c4 | ||
|
|
6e2d42daf9 | ||
|
|
8f5df45edc | ||
|
|
2fcb7e532b | ||
|
|
135c30323b | ||
|
|
18e343d405 | ||
|
|
863e32c5cd | ||
|
|
83189013c6 | ||
|
|
0a0e4f1ba2 | ||
|
|
3eeab68261 | ||
|
|
421f84e05a | ||
|
|
434082cadb | ||
|
|
e6bba01798 | ||
|
|
c567376e35 | ||
|
|
6ba5dcaa06 | ||
|
|
8a95f23a23 | ||
|
|
966ad9d3b6 | ||
|
|
a2d6bd09f3 | ||
|
|
3374ac7606 | ||
|
|
3c5b02e54a | ||
|
|
789738c45f | ||
|
|
e97e82d119 | ||
|
|
4a0e33003b | ||
|
|
9a01c0d9cb | ||
|
|
cfed28c2ff | ||
|
|
b7e4fdf4d5 | ||
|
|
57b5588498 | ||
|
|
3275542426 | ||
|
|
d65c8fb06c | ||
|
|
0ec57e7fee | ||
|
|
10a13e737e | ||
|
|
11410000b4 | ||
|
|
859a8adc31 | ||
|
|
64b101785f | ||
|
|
e82e4bcfc8 | ||
|
|
5c88a1c63e | ||
|
|
b2bdb8ed02 | ||
|
|
0af2243245 | ||
|
|
2fef2763ab | ||
|
|
f4135a0a9f | ||
|
|
9df3ce018b | ||
|
|
f6b374f829 | ||
|
|
e517cbcf78 | ||
|
|
d850d7bbad | ||
|
|
8f8acf7a83 | ||
|
|
80051b8303 | ||
|
|
99c88cb0c5 | ||
|
|
8fcda32287 | ||
|
|
ecac0f177b | ||
|
|
d08f6f8238 | ||
|
|
57b3bc0496 | ||
|
|
2330ce2c28 | ||
|
|
5c9e55f3fb | ||
|
|
2e73bcb3a6 | ||
|
|
96d0c4a1db | ||
|
|
bfad9bd87f | ||
|
|
75245b3046 | ||
|
|
11c86405bf | ||
|
|
f2e60a0e11 | ||
|
|
da5f71773a | ||
|
|
1e0b133e19 | ||
|
|
fa77808319 | ||
|
|
2dce7ad1e2 | ||
|
|
d3c17ec337 | ||
|
|
b1fa740341 | ||
|
|
5fbb9bfe3b | ||
|
|
21e64e02bd | ||
|
|
5541224288 | ||
|
|
6b49ac6b46 | ||
|
|
dc70c0d31e | ||
|
|
a15ca7c374 | ||
|
|
5729855e4f | ||
|
|
51abb021bc | ||
|
|
c523817213 | ||
|
|
408dd9bc9d | ||
|
|
9c73502bdc | ||
|
|
a19708693b | ||
|
|
8683582c40 | ||
|
|
703f39f492 | ||
|
|
95cecdbc42 | ||
|
|
4f06cece37 | ||
|
|
8838e46578 | ||
|
|
e2b51f30ed | ||
|
|
a197fc8cb8 | ||
|
|
4b8017e34b | ||
|
|
3478a6fb6c | ||
|
|
ce9012c352 | ||
|
|
d53cd3c70b | ||
|
|
73444ce59b | ||
|
|
7fff17ba7c | ||
|
|
7063e1f56a | ||
|
|
4800cff87f | ||
|
|
19089f8b17 | ||
|
|
87f09ab5b0 | ||
|
|
98e0905eb3 | ||
|
|
3d3d670cd7 | ||
|
|
60a8db1c6c | ||
|
|
a447c39f69 | ||
|
|
b1b0da5228 | ||
|
|
c9012b10c5 | ||
|
|
aea6ad0f0c | ||
|
|
e90dc047bd | ||
|
|
a8b551e518 | ||
|
|
69c906014f | ||
|
|
d20fb5ddd7 | ||
|
|
05a62c5892 | ||
|
|
f9306d9c3c | ||
|
|
3abbdb4d15 | ||
|
|
5bc70b3150 | ||
|
|
dd3b85dca3 | ||
|
|
ea3a65d0b8 | ||
|
|
b9ce9f8576 | ||
|
|
ffd8863875 | ||
|
|
39b46bb3ef | ||
|
|
6abf13be41 | ||
|
|
03e1480476 | ||
|
|
44bc937499 | ||
|
|
2dcc38b92f | ||
|
|
3c87ccc5ff | ||
|
|
bcadfd4661 | ||
|
|
c1c6d0ee3a | ||
|
|
6313ecac1c | ||
|
|
60e457167d | ||
|
|
36206ddf6d | ||
|
|
b7a50b333e | ||
|
|
2821448dd8 | ||
|
|
8807cd828f | ||
|
|
846fb397c4 | ||
|
|
2b66af29aa | ||
|
|
22b14cfc5c | ||
|
|
3776e5698f | ||
|
|
e92c314b46 | ||
|
|
2987576a0a | ||
|
|
5edadfe8ea | ||
|
|
bc49825f55 |
2
.idea/ant.xml
generated
2
.idea/ant.xml
generated
@@ -3,7 +3,7 @@
|
||||
<component name="AntConfiguration">
|
||||
<buildFile url="file://$PROJECT_DIR$/compiler/frontend/buildLexer.xml" />
|
||||
<buildFile url="file://$PROJECT_DIR$/build.xml">
|
||||
<antCommandLine value="-J-XX:MaxPermSize=100m" />
|
||||
<antCommandLine value="-J-XX:MaxPermSize=100m -J-ea" />
|
||||
<maximumHeapSize value="1024" />
|
||||
</buildFile>
|
||||
<buildFile url="file://$PROJECT_DIR$/update_dependencies.xml" />
|
||||
|
||||
1
.idea/dictionaries/Nikolay_Krasko.xml
generated
1
.idea/dictionaries/Nikolay_Krasko.xml
generated
@@ -2,6 +2,7 @@
|
||||
<dictionary name="Nikolay.Krasko">
|
||||
<words>
|
||||
<w>accessors</w>
|
||||
<w>fqname</w>
|
||||
<w>goto</w>
|
||||
<w>gradle</w>
|
||||
<w>intrinsics</w>
|
||||
|
||||
BIN
.idea/icon.png
generated
Normal file
BIN
.idea/icon.png
generated
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
13
.idea/libraries/kotlin_test.xml
generated
Normal file
13
.idea/libraries/kotlin_test.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-test">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-test.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin" />
|
||||
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin.jvm" />
|
||||
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/junit/src/main/kotlin" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
3
.idea/modules.xml
generated
3
.idea/modules.xml
generated
@@ -40,7 +40,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea-runner/idea-runner.iml" filepath="$PROJECT_DIR$/idea-runner/idea-runner.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" filepath="$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" filepath="$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" group="compiler/cli" />
|
||||
@@ -62,6 +62,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" filepath="$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" filepath="$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/serialization/serialization.iml" filepath="$PROJECT_DIR$/compiler/serialization/serialization.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/temp-jdk8/temp-jdk8.iml" filepath="$PROJECT_DIR$/temp-jdk8/temp-jdk8.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/util/util.iml" filepath="$PROJECT_DIR$/compiler/util/util.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/util.runtime/util.runtime.iml" filepath="$PROJECT_DIR$/core/util.runtime/util.runtime.iml" group="core" />
|
||||
</modules>
|
||||
|
||||
2
.idea/runConfigurations/IDEA__win_.xml
generated
2
.idea/runConfigurations/IDEA__win_.xml
generated
@@ -5,7 +5,7 @@
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=${JAVA_HOME}\lib\tools.jar,../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="1.7" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
|
||||
@@ -158,11 +158,11 @@
|
||||
<print-file-size-statistic path="${kotlin-home}/lib" file-name="kotlin-reflect.jar"/>
|
||||
|
||||
<print-file-size-statistic path="${kotlin-home}/lib" file-name="kotlin-jslib.jar"/>
|
||||
<print-file-size-statistic path="${output}" file-name="kotlin.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="builtins.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="builtins.meta.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="stdlib.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="stdlib.meta.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="kotlin.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="builtins.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="builtins.meta.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="stdlib.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="stdlib.meta.js"/>
|
||||
</target>
|
||||
|
||||
<target name="post_build" depends="zipArtifacts, revertTemplateFiles, printStatistics, remove_internal_artifacts, dont_remove_internal_artifacts"/>
|
||||
|
||||
57
build.xml
57
build.xml
@@ -12,8 +12,10 @@
|
||||
<property name="bootstrap.compiler.home" value="${bootstrap.home}/Kotlin/kotlinc"/>
|
||||
<property name="bootstrap.runtime" value="${bootstrap.compiler.home}/lib/kotlin-runtime.jar"/>
|
||||
<property name="bootstrap.reflect" value="${bootstrap.compiler.home}/lib/kotlin-reflect.jar"/>
|
||||
<property name="bootstrap.kotlin.test" value="${bootstrap.compiler.home}/lib/kotlin-test.jar" />
|
||||
|
||||
<property name="output" value="${basedir}/dist"/>
|
||||
<property name="js.stdlib.output.dir" value="${output}/js"/>
|
||||
<property name="intermediate-sources" value="out/src" />
|
||||
<property name="kotlin-home" value="${output}/kotlinc"/>
|
||||
<property name="build.number" value="snapshot"/>
|
||||
@@ -55,6 +57,7 @@
|
||||
|
||||
<path id="classpath">
|
||||
<file file="${bootstrap.runtime}"/>
|
||||
<file file="${bootstrap.kotlin.test}" />
|
||||
<file file="${bootstrap.reflect}"/>
|
||||
<fileset dir="${idea.sdk}" includes="core/*.jar"/>
|
||||
<pathelement location="${protobuf.jar}"/>
|
||||
@@ -177,19 +180,33 @@
|
||||
<sequential if:true="${bootstrap.or.local.build}">
|
||||
<copy file="${bootstrap.runtime}" tofile="${kotlin-home}/lib/kotlin-runtime-internal-bootstrap.jar"/>
|
||||
<copy file="${bootstrap.reflect}" tofile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar"/>
|
||||
<copy file="${bootstrap.kotlin.test}" tofile="${kotlin-home}/lib/kotlin-test-internal-bootstrap.jar" failonerror="false"/>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar" update="true">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="kotlin-runtime-internal-bootstrap.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-test-internal-bootstrap.jar" update="true">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="kotlin-runtime-internal-bootstrap.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</sequential>
|
||||
|
||||
<sequential unless:true="${bootstrap.or.local.build}">
|
||||
<copy file="${bootstrap.runtime}" todir="${kotlin-home}/lib"/>
|
||||
<copy file="${bootstrap.reflect}" todir="${kotlin-home}/lib"/>
|
||||
<copy file="${bootstrap.kotlin.test}" todir="${kotlin-home}/lib"/>
|
||||
</sequential>
|
||||
</target>
|
||||
|
||||
<target name="copy-dist-to-bootstrap">
|
||||
<delete dir="${basedir}/dependencies/bootstrap-compiler/Kotlin/kotlinc" />
|
||||
<copy todir="${basedir}/dependencies/bootstrap-compiler/Kotlin/kotlinc">
|
||||
<fileset dir="${basedir}/dist/kotlinc" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="compiler-sources">
|
||||
<jar jarfile="${output}/kotlin-compiler-sources.jar">
|
||||
<!-- TODO How to convert it from pathset or dirset ? -->
|
||||
@@ -308,13 +325,13 @@
|
||||
|
||||
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
|
||||
|
||||
<new-kotlin2js output="${output}/js/${compiled.builtins.js}">
|
||||
<new-kotlin2js output="${js.stdlib.output.dir}/${compiled.builtins.js}">
|
||||
<src>
|
||||
<fileset refid="kotlin.builtin.files"/>
|
||||
</src>
|
||||
</new-kotlin2js>
|
||||
|
||||
<new-kotlin2js output="${output}/js/${compiled.stdlib.js}">
|
||||
<new-kotlin2js output="${js.stdlib.output.dir}/${compiled.stdlib.js}">
|
||||
<src>
|
||||
<resources refid="js.lib.files"/>
|
||||
</src>
|
||||
@@ -334,7 +351,7 @@
|
||||
prettyprint="true"
|
||||
languagein="ECMASCRIPT5_STRICT"
|
||||
warning="${warningLevel}"
|
||||
output="${output}/js/kotlin.js">
|
||||
output="${js.stdlib.output.dir}/kotlin.js">
|
||||
|
||||
<sources dir="${stdlib.js.dir}">
|
||||
<file name="kotlin_lib_ecma5.js"/>
|
||||
@@ -343,11 +360,11 @@
|
||||
<file name="long.js"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${output}/js">
|
||||
<sources dir="${js.stdlib.output.dir}">
|
||||
<file name="${compiled.builtins.js}"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${output}/js">
|
||||
<sources dir="${js.stdlib.output.dir}">
|
||||
<file name="${compiled.stdlib.js}"/>
|
||||
</sources>
|
||||
|
||||
@@ -362,7 +379,7 @@
|
||||
|
||||
<jar jarfile="${kotlin-home}/lib/kotlin-jslib.jar" duplicate="fail">
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
<zipfileset dir="${output}/js" prefix="">
|
||||
<zipfileset dir="${js.stdlib.output.dir}" prefix="">
|
||||
<include name="kotlin.js"/>
|
||||
<include name="${compiled.stdlib.meta.js}"/>
|
||||
<include name="stdlib/**"/>
|
||||
@@ -781,7 +798,7 @@
|
||||
</target>
|
||||
|
||||
<target name="stdlib">
|
||||
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib">
|
||||
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib" additionalOptions="-Xmultifile-facades-open">
|
||||
<src>
|
||||
<include name="libraries/stdlib/src"/>
|
||||
</src>
|
||||
@@ -791,6 +808,20 @@
|
||||
</new-kotlinc>
|
||||
</target>
|
||||
|
||||
<target name="kotlin.test">
|
||||
<new-kotlinc output="${output}/classes/kotlin.test" moduleName="kotlin-test">
|
||||
<src>
|
||||
<include name="libraries/kotlin.test/shared/src/main/kotlin" />
|
||||
<include name="libraries/kotlin.test/shared/src/main/kotlin.jvm" />
|
||||
<include name="libraries/kotlin.test/junit/src/main/kotlin" />
|
||||
</src>
|
||||
<class-path>
|
||||
<pathelement path="${output}/classes/builtins"/>
|
||||
<pathelement path="libraries/lib/junit-4.11.jar"/>
|
||||
</class-path>
|
||||
</new-kotlinc>
|
||||
</target>
|
||||
|
||||
<target name="core">
|
||||
<new-kotlinc output="${output}/classes/core" moduleName="kotlin-core">
|
||||
<src>
|
||||
@@ -935,15 +966,23 @@
|
||||
</pack-runtime-jar>
|
||||
</target>
|
||||
|
||||
<target name="pack-kotlin-test">
|
||||
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
|
||||
<jar-content>
|
||||
<fileset dir="${output}/classes/kotlin.test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
|
||||
</jar-content>
|
||||
</pack-runtime-jar>
|
||||
</target>
|
||||
|
||||
<target name="runtime"
|
||||
depends="builtins,stdlib,core,reflection,pack-runtime,pack-runtime-sources"/>
|
||||
|
||||
<target name="dist"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin.test,pack-kotlin-test,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
|
||||
description="Builds redistributables from sources"/>
|
||||
|
||||
<target name="dist-quick"
|
||||
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin"
|
||||
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin.test,pack-kotlin-test,kotlin-js-stdlib,android-compiler-plugin"
|
||||
description="Builds everything, but classes are reused from project out dir, doesn't run proguard and javadoc"/>
|
||||
|
||||
<target name="dist-quick-compiler-only"
|
||||
|
||||
@@ -93,14 +93,14 @@ public class CodegenUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<FunctionDescriptor, FunctionDescriptor> getTraitMethods(ClassDescriptor descriptor) {
|
||||
public static Map<FunctionDescriptor, FunctionDescriptor> getNonPrivateTraitMethods(ClassDescriptor descriptor) {
|
||||
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>();
|
||||
for (DeclarationDescriptor declaration : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
|
||||
if (!(declaration instanceof CallableMemberDescriptor)) continue;
|
||||
|
||||
CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration;
|
||||
CallableMemberDescriptor traitMember = ImplKt.findTraitImplementation(inheritedMember);
|
||||
if (traitMember == null) continue;
|
||||
if (traitMember == null || Visibilities.isPrivate(traitMember.getVisibility())) continue;
|
||||
|
||||
assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember;
|
||||
|
||||
@@ -140,7 +140,7 @@ public class CodegenUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor getSuperClassByDelegationSpecifier(@NotNull KtDelegationSpecifier specifier, @NotNull BindingContext bindingContext) {
|
||||
public static ClassDescriptor getSuperClassBySuperTypeListEntry(@NotNull KtSuperTypeListEntry specifier, @NotNull BindingContext bindingContext) {
|
||||
KotlinType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null : "superType should not be null: " + specifier.getText();
|
||||
|
||||
|
||||
@@ -31,37 +31,41 @@ public object CodegenUtilKt {
|
||||
|
||||
// class Foo : Bar by baz
|
||||
// descriptor = Foo
|
||||
// toTrait = Bar
|
||||
// toInterface = Bar
|
||||
// delegateExpressionType = typeof(baz)
|
||||
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||
@JvmStatic
|
||||
public fun getDelegates(
|
||||
descriptor: ClassDescriptor,
|
||||
toTrait: ClassDescriptor,
|
||||
toInterface: ClassDescriptor,
|
||||
delegateExpressionType: KotlinType? = null
|
||||
): Map<CallableMemberDescriptor, CallableDescriptor> {
|
||||
if (delegateExpressionType?.isDynamic() ?: false) return mapOf();
|
||||
|
||||
return descriptor.getDefaultType().getMemberScope().getContributedDescriptors().asSequence()
|
||||
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.getKind() == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.asIterable()
|
||||
.sortedWith(MemberComparator.INSTANCE)
|
||||
.keysToMapExceptNulls {
|
||||
delegatingMember ->
|
||||
|
||||
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
|
||||
.filter { it.getContainingDeclaration() == toTrait }
|
||||
.map {
|
||||
.mapNotNull {
|
||||
overriddenDescriptor ->
|
||||
val scope = (delegateExpressionType ?: toTrait.getDefaultType()).getMemberScope()
|
||||
val name = overriddenDescriptor.getName()
|
||||
if (overriddenDescriptor.containingDeclaration == toInterface) {
|
||||
val scope = (delegateExpressionType ?: toInterface.defaultType).memberScope
|
||||
val name = overriddenDescriptor.name
|
||||
|
||||
// this is the actual member of delegateExpressionType that we are delegating to
|
||||
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
|
||||
.first {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it)).map { it.getOriginal() }.contains(overriddenDescriptor.getOriginal())
|
||||
}
|
||||
// this is the actual member of delegateExpressionType that we are delegating to
|
||||
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
|
||||
.firstOrNull {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it))
|
||||
.map { it.original }
|
||||
.contains(overriddenDescriptor.original)
|
||||
}
|
||||
}
|
||||
else null
|
||||
}
|
||||
assert(actualDelegates.size() <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
|
||||
|
||||
@@ -41,6 +41,14 @@ public class AccessorForConstructorDescriptor(
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor) = super.substitute(substitutor) as ConstructorDescriptor
|
||||
|
||||
override fun copy(
|
||||
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?, kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
|
||||
): AccessorForConstructorDescriptor {
|
||||
throw UnsupportedOperationException("Trying to copy synthetic accessor $this")
|
||||
}
|
||||
|
||||
override fun getOriginal(): AccessorForConstructorDescriptor = this
|
||||
|
||||
init {
|
||||
initialize(
|
||||
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
|
||||
|
||||
@@ -226,9 +226,9 @@ public class AsmUtil {
|
||||
int flags = getVisibilityAccessFlag(functionDescriptor);
|
||||
flags |= getVarargsFlag(functionDescriptor);
|
||||
flags |= getDeprecatedAccessFlag(functionDescriptor);
|
||||
if (DeprecationUtilKt.isAnnotatedAsHidden(functionDescriptor)
|
||||
if (DeprecationUtilKt.isHiddenInResolution(functionDescriptor)
|
||||
|| functionDescriptor instanceof PropertyAccessorDescriptor
|
||||
&& DeprecationUtilKt.isAnnotatedAsHidden(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
|
||||
&& DeprecationUtilKt.isHiddenInResolution(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
return flags;
|
||||
@@ -325,9 +325,6 @@ public class AsmUtil {
|
||||
private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||
if (isJvmInterface(containingDeclaration)) {
|
||||
return memberVisibility == Visibilities.PRIVATE ? NO_FLAG_PACKAGE_PRIVATE : ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
return ACC_PUBLIC;
|
||||
@@ -379,11 +376,6 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof PropertyDescriptor &&
|
||||
((PropertyDescriptor) memberDescriptor).isConst() || hasJvmFieldAnnotation(memberDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List actualArgsWithDeclIndex) {
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex) {
|
||||
callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -51,11 +52,19 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
List<KtObjectDeclaration> companions = new ArrayList<KtObjectDeclaration>();
|
||||
if (kind != OwnerKind.DEFAULT_IMPLS) {
|
||||
//generate nested classes first and only then generate class body. It necessary to access to nested CodegenContexts
|
||||
for (KtDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (shouldProcessFirst(declaration)) {
|
||||
generateDeclaration(declaration);
|
||||
//Generate companions after class body generation (need to record all synthetic accessors)
|
||||
if (declaration instanceof KtObjectDeclaration && ((KtObjectDeclaration) declaration).isCompanion()) {
|
||||
companions.add((KtObjectDeclaration) declaration);
|
||||
CodegenUtilKt.populateCompanionBackingFieldNamesToOuterContextIfNeeded((KtObjectDeclaration) declaration, context, state);
|
||||
}
|
||||
else {
|
||||
generateDeclaration(declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +75,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
}
|
||||
}
|
||||
|
||||
generatePrimaryConstructorProperties();
|
||||
generateConstructors();
|
||||
generateDefaultImplsIfNeeded();
|
||||
|
||||
for (KtObjectDeclaration companion : companions) {
|
||||
generateDeclaration(companion);
|
||||
}
|
||||
|
||||
if (!DescriptorUtils.isInterface(descriptor)) {
|
||||
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
|
||||
if (memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
@@ -88,8 +105,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void generateConstructors() {
|
||||
|
||||
}
|
||||
|
||||
protected void generateDefaultImplsIfNeeded() {
|
||||
|
||||
generatePrimaryConstructorProperties();
|
||||
}
|
||||
|
||||
private static boolean shouldProcessFirst(KtDeclaration declaration) {
|
||||
|
||||
@@ -57,7 +57,6 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
@@ -669,7 +668,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
});
|
||||
}
|
||||
else {
|
||||
KtMultiDeclaration multiParameter = forExpression.getMultiParameter();
|
||||
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
|
||||
assert multiParameter != null;
|
||||
|
||||
// E tmp<e> = tmp<iterator>.next()
|
||||
@@ -687,15 +686,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
assignToLoopParameter();
|
||||
|
||||
if (forExpression.getLoopParameter() == null) {
|
||||
KtMultiDeclaration multiParameter = forExpression.getMultiParameter();
|
||||
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
|
||||
assert multiParameter != null;
|
||||
|
||||
generateMultiVariables(multiParameter.getEntries());
|
||||
}
|
||||
}
|
||||
|
||||
private void generateMultiVariables(List<KtMultiDeclarationEntry> entries) {
|
||||
for (KtMultiDeclarationEntry variableDeclaration : entries) {
|
||||
private void generateMultiVariables(List<KtDestructuringDeclarationEntry> entries) {
|
||||
for (KtDestructuringDeclarationEntry variableDeclaration : entries) {
|
||||
final VariableDescriptor componentDescriptor = bindingContext.get(VARIABLE, variableDeclaration);
|
||||
|
||||
@SuppressWarnings("ConstantConditions") final Type componentAsmType = asmType(componentDescriptor.getReturnType());
|
||||
@@ -1332,7 +1331,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression, StackValue receiver) {
|
||||
public StackValue visitLambdaExpression(@NotNull KtLambdaExpression expression, StackValue receiver) {
|
||||
if (Boolean.TRUE.equals(bindingContext.get(BLOCK, expression))) {
|
||||
return gen(expression.getFunctionLiteral().getBodyExpression());
|
||||
}
|
||||
@@ -1569,9 +1568,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
|
||||
private void putDescriptorIntoFrameMap(@NotNull KtElement statement) {
|
||||
if (statement instanceof KtMultiDeclaration) {
|
||||
KtMultiDeclaration multiDeclaration = (KtMultiDeclaration) statement;
|
||||
for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
if (statement instanceof KtDestructuringDeclaration) {
|
||||
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
|
||||
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
putLocalVariableIntoFrameMap(entry);
|
||||
}
|
||||
}
|
||||
@@ -1609,9 +1608,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull Label blockEnd,
|
||||
@NotNull List<Function<StackValue, Void>> leaveTasks
|
||||
) {
|
||||
if (statement instanceof KtMultiDeclaration) {
|
||||
KtMultiDeclaration multiDeclaration = (KtMultiDeclaration) statement;
|
||||
for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
if (statement instanceof KtDestructuringDeclaration) {
|
||||
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
|
||||
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
addLeaveTaskToRemoveLocalVariableFromFrameMap(entry, blockEnd, leaveTasks);
|
||||
}
|
||||
}
|
||||
@@ -2072,7 +2071,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
if (getter != null) {
|
||||
Call call = bindingContext.get(DELEGATED_PROPERTY_CALL, getter);
|
||||
return call != null ? ((ReceiverValue) call.getExplicitReceiver()).getType() : null;
|
||||
if (call != null) {
|
||||
assert call.getExplicitReceiver() != null : "No explicit receiver for call:" + call;
|
||||
return ((ReceiverValue) call.getExplicitReceiver()).getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -2120,7 +2122,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (isBackingFieldInClassCompanion && forceField) {
|
||||
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
|
||||
}
|
||||
else if (syntheticBackingField && context.getParentContext().getContextDescriptor() != containingDeclaration) {
|
||||
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {
|
||||
fieldAccessorKind = FieldAccessorKind.FIELD_FROM_LOCAL;
|
||||
}
|
||||
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
|
||||
@@ -2161,13 +2163,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
|
||||
if (isSuper && !isJvmInterface(containingDeclaration)) {
|
||||
CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor;
|
||||
if (c != context.getParentContext()) {
|
||||
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor, superCallTarget);
|
||||
}
|
||||
}
|
||||
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget);
|
||||
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
|
||||
|
||||
@@ -2251,8 +2247,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
final SamType samType = bindingContext.get(SAM_VALUE, probablyParenthesizedExpression);
|
||||
if (samType == null || expression == null) return null;
|
||||
|
||||
if (expression instanceof KtFunctionLiteralExpression) {
|
||||
return genClosure(((KtFunctionLiteralExpression) expression).getFunctionLiteral(), samType);
|
||||
if (expression instanceof KtLambdaExpression) {
|
||||
return genClosure(((KtLambdaExpression) expression).getFunctionLiteral(), samType);
|
||||
}
|
||||
|
||||
if (expression instanceof KtNamedFunction) {
|
||||
@@ -2300,22 +2296,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
descriptor = originalIfSamAdapter;
|
||||
}
|
||||
// $default method is not private, so you need no accessor to call it
|
||||
return usesDefaultArguments(resolvedCall)
|
||||
return CallUtilKt.usesDefaultArguments(resolvedCall)
|
||||
? descriptor
|
||||
: context.accessibleDescriptor(descriptor, getSuperCallTarget(resolvedCall.getCall()));
|
||||
}
|
||||
|
||||
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
|
||||
if (valueArguments == null) return false;
|
||||
|
||||
for (ResolvedValueArgument argument : valueArguments) {
|
||||
if (argument instanceof DefaultValueArgument) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue invokeFunction(@NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
|
||||
return invokeFunction(resolvedCall.getCall(), resolvedCall, receiver);
|
||||
@@ -2325,15 +2310,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
|
||||
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
|
||||
ClassDescriptor superCallTarget = getSuperCallTarget(call);
|
||||
boolean superCall = superCallTarget != null;
|
||||
|
||||
if (superCall && !isJvmInterface(fd.getContainingDeclaration())) {
|
||||
CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + fd;
|
||||
if (c != context.getParentContext()) {
|
||||
fd = (FunctionDescriptor) c.getAccessor(fd, superCallTarget);
|
||||
}
|
||||
}
|
||||
fd = context.getAccessorForSuperCallIfNeeded(fd, superCallTarget);
|
||||
|
||||
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
|
||||
if (!codegenExtensions.isEmpty()) {
|
||||
@@ -2344,7 +2322,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
Callable callable = resolveToCallable(fd, superCall, resolvedCall);
|
||||
Callable callable = resolveToCallable(fd, superCallTarget != null, resolvedCall);
|
||||
|
||||
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
|
||||
}
|
||||
@@ -2433,6 +2411,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
||||
|
||||
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
v.aconst(null);
|
||||
v.athrow();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -2483,9 +2467,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
else {
|
||||
mappings.addParameterMappingToNewParameter(
|
||||
key.getName().getIdentifier(),
|
||||
parameterDescriptor.getName().getIdentifier()
|
||||
);
|
||||
key.getName().getIdentifier(), type,
|
||||
parameterDescriptor.getName().getIdentifier());
|
||||
}
|
||||
}
|
||||
return getOrCreateCallGenerator(
|
||||
@@ -2494,7 +2477,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue generateReceiverValue(@NotNull ReceiverValue receiverValue, boolean isSuper) {
|
||||
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
|
||||
if (receiverValue instanceof ImplicitClassReceiver) {
|
||||
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
|
||||
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
|
||||
@@ -2758,7 +2741,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull KtElement element,
|
||||
@NotNull VariableDescriptor variableDescriptor,
|
||||
@NotNull VariableDescriptor target,
|
||||
@NotNull ReceiverValue dispatchReceiver
|
||||
@Nullable ReceiverValue dispatchReceiver
|
||||
) {
|
||||
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
|
||||
|
||||
@@ -3276,7 +3259,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitMultiDeclaration(@NotNull KtMultiDeclaration multiDeclaration, StackValue receiver) {
|
||||
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
|
||||
KtExpression initializer = multiDeclaration.getInitializer();
|
||||
if (initializer == null) return StackValue.none();
|
||||
|
||||
@@ -3293,7 +3276,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.store(tempVarIndex, initializerAsmType);
|
||||
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
|
||||
|
||||
for (KtMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
|
||||
for (KtDestructuringDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration);
|
||||
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
|
||||
Call call = makeFakeCall(initializerAsReceiver);
|
||||
@@ -3689,13 +3672,8 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
|
||||
if (opToken != KtTokens.AS_SAFE) {
|
||||
if (!TypeUtils.isNullableType(rightType)) {
|
||||
v.dup();
|
||||
Label nonnull = new Label();
|
||||
v.ifnonnull(nonnull);
|
||||
genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " +
|
||||
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(rightType));
|
||||
v.mark(nonnull);
|
||||
if (!TypeUtils.isNullableType(rightType) && !TypeUtils.isReifiedTypeParameter(rightType)) {
|
||||
CodegenUtilKt.generateNullCheckForNonSafeAs(v, rightType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -3759,7 +3737,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType, new Function1<InstructionAdapter, Unit>() {
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType.isMarkedNullable() && !TypeUtils.isReifiedTypeParameter(kotlinType), new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
generateInstanceOfInstruction(kotlinType);
|
||||
@@ -3794,8 +3772,8 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
parentCodegen.getReifiedTypeParametersUsages().
|
||||
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||
}
|
||||
|
||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
|
||||
boolean putNullableFlag = ReifiedTypeInliner.isNullableMarkerInstruction(markerMethodName) && type.isMarkedNullable();
|
||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString() + (putNullableFlag ? "?" : ""));
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
|
||||
@@ -3821,8 +3799,9 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return StackValue.operation(resultType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
SwitchCodegen switchCodegen =
|
||||
SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, ExpressionCodegen.this);
|
||||
SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(
|
||||
expression, isStatement, isExhaustive(expression, isStatement), ExpressionCodegen.this
|
||||
);
|
||||
if (switchCodegen != null) {
|
||||
switchCodegen.generate();
|
||||
return Unit.INSTANCE$;
|
||||
@@ -3868,9 +3847,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
if (!hasElse && nextCondition != null) {
|
||||
v.mark(nextCondition);
|
||||
if (!isStatement) {
|
||||
putUnitInstanceOntoStackForNonExhaustiveWhen(expression);
|
||||
}
|
||||
putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
|
||||
}
|
||||
|
||||
markLineNumber(expression, isStatement);
|
||||
@@ -3883,14 +3860,24 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isExhaustive(@NotNull KtWhenExpression whenExpression, boolean isStatement) {
|
||||
if (isStatement) {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
else {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
}
|
||||
|
||||
public void putUnitInstanceOntoStackForNonExhaustiveWhen(
|
||||
@NotNull KtWhenExpression expression
|
||||
@NotNull KtWhenExpression whenExpression,
|
||||
boolean isStatement
|
||||
) {
|
||||
if (Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, expression))) {
|
||||
if (isExhaustive(whenExpression, isStatement)) {
|
||||
// when() is supposed to be exhaustive
|
||||
genThrow(v, "kotlin/NoWhenBranchMatchedException", null);
|
||||
}
|
||||
else {
|
||||
else if (!isStatement) {
|
||||
// non-exhaustive when() with no else -> Unit must be expected
|
||||
StackValue.putUnitInstance(v);
|
||||
}
|
||||
|
||||
@@ -221,8 +221,6 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
endVisit(mv, null, origin.getElement());
|
||||
|
||||
methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, bindingContext);
|
||||
}
|
||||
|
||||
private void generateMethodAnnotations(
|
||||
@@ -373,11 +371,11 @@ public class FunctionCodegen {
|
||||
else {
|
||||
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
|
||||
functionDescriptor));
|
||||
if (context.isInlineFunction()) {
|
||||
if (context.isInlineMethodContext()) {
|
||||
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
if (context.isInliningLambda()) {
|
||||
if (context instanceof InlineLambdaContext) {
|
||||
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
@@ -398,7 +396,7 @@ public class FunctionCodegen {
|
||||
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
|
||||
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind());
|
||||
|
||||
if (context.isInlineFunction() && functionFakeIndex != -1) {
|
||||
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
|
||||
mv.visitLocalVariable(
|
||||
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
|
||||
Type.INT_TYPE.getDescriptor(), null,
|
||||
@@ -406,7 +404,7 @@ public class FunctionCodegen {
|
||||
functionFakeIndex);
|
||||
}
|
||||
|
||||
if (context.isInliningLambda() && thisType != null && lambdaFakeIndex != -1) {
|
||||
if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
|
||||
String name = thisType.getClassName();
|
||||
int indexOfLambdaOrdinal = name.lastIndexOf("$");
|
||||
if (indexOfLambdaOrdinal > 0) {
|
||||
@@ -555,7 +553,7 @@ public class FunctionCodegen {
|
||||
// If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges
|
||||
if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return;
|
||||
|
||||
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor) != null;
|
||||
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
|
||||
|
||||
Set<Bridge<Method>> bridgesToGenerate;
|
||||
if (!isSpecial) {
|
||||
@@ -589,7 +587,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
|
||||
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor);
|
||||
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
|
||||
assert overridden != null;
|
||||
|
||||
Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
|
||||
@@ -911,7 +909,7 @@ public class FunctionCodegen {
|
||||
iv.ifnonnull(afterBarrier);
|
||||
}
|
||||
else {
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, new Function1<InstructionAdapter, Unit>() {
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType.isMarkedNullable(), new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateParameterType));
|
||||
|
||||
@@ -36,8 +36,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
|
||||
public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<FunctionDescriptor> {
|
||||
private final ResolvedCall<?> resolvedCall;
|
||||
private final FunctionDescriptor referencedFunction;
|
||||
@@ -82,13 +80,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
@Override
|
||||
public ReceiverValue getExtensionReceiver() {
|
||||
return extensionReceiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
@Override
|
||||
public ReceiverValue getDispatchReceiver() {
|
||||
return dispatchReceiver;
|
||||
@@ -119,7 +117,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
}
|
||||
else {
|
||||
Call call = CallMaker.makeCall(fakeExpression, NO_RECEIVER, null, fakeExpression, fakeArguments);
|
||||
Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
|
||||
result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
|
||||
}
|
||||
|
||||
@@ -157,13 +155,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
private ReceiverValue computeAndSaveReceiver(
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@Nullable ReceiverParameterDescriptor receiver
|
||||
) {
|
||||
if (receiver == null) return NO_RECEIVER;
|
||||
if (receiver == null) return null;
|
||||
|
||||
KtExpression receiverExpression = KtPsiFactoryKt
|
||||
.KtPsiFactory(state.getProject()).createExpression("callableReferenceFakeReceiver");
|
||||
|
||||
@@ -98,6 +98,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private List<PropertyAndDefaultValue> companionObjectPropertiesToCopy;
|
||||
|
||||
private final DelegationFieldsInfo delegationFieldsInfo;
|
||||
|
||||
private final List<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>> additionalTasks =
|
||||
new ArrayList<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>>();
|
||||
|
||||
@@ -112,6 +114,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
super(aClass, context, v, state, parentCodegen);
|
||||
this.classAsmType = typeMapper.mapClass(descriptor);
|
||||
this.isLocal = isLocal;
|
||||
delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -227,8 +230,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
super.generateBody();
|
||||
protected void generateDefaultImplsIfNeeded() {
|
||||
if (isInterface(descriptor) && !isLocal) {
|
||||
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
|
||||
ClassBuilder defaultImplsBuilder =
|
||||
@@ -237,7 +239,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
CodegenContext parentContext = context.getParentContext();
|
||||
assert parentContext != null : "Parent context of interface declaration should not be null";
|
||||
|
||||
ClassContext defaultImplsContext = parentContext.intoClass(descriptor, OwnerKind.DEFAULT_IMPLS, state);
|
||||
ClassContext defaultImplsContext = parentContext.intoDefaultImplsClass(descriptor, (ClassContext) context, state);
|
||||
new InterfaceImplBodyCodegen(myClass, defaultImplsContext, defaultImplsBuilder, state, this).generate();
|
||||
}
|
||||
}
|
||||
@@ -371,7 +373,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
generateCompanionObjectBackingFieldCopies();
|
||||
|
||||
DelegationFieldsInfo delegationFieldsInfo = getDelegationFieldsInfo(myClass.getDelegationSpecifiers());
|
||||
generateTraitMethods();
|
||||
|
||||
generateDelegates(delegationFieldsInfo);
|
||||
|
||||
if (!isInterface(descriptor) || kind == OwnerKind.DEFAULT_IMPLS) {
|
||||
generateSyntheticAccessors();
|
||||
}
|
||||
|
||||
generateEnumMethods();
|
||||
|
||||
generateFunctionsForDataClasses();
|
||||
|
||||
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
|
||||
|
||||
generateToArray();
|
||||
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
|
||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateConstructors() {
|
||||
try {
|
||||
lookupConstructorExpressionsInClosureIfPresent();
|
||||
generatePrimaryConstructor(delegationFieldsInfo);
|
||||
@@ -388,26 +414,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
catch (RuntimeException e) {
|
||||
throw new RuntimeException("Error generating constructors of class " + myClass.getName() + " with kind " + kind, e);
|
||||
}
|
||||
|
||||
generateTraitMethods();
|
||||
|
||||
generateDelegates(delegationFieldsInfo);
|
||||
|
||||
generateSyntheticAccessors();
|
||||
|
||||
generateEnumMethods();
|
||||
|
||||
generateFunctionsForDataClasses();
|
||||
|
||||
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
|
||||
|
||||
generateToArray();
|
||||
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
|
||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGenericToArrayPresent() {
|
||||
@@ -958,10 +964,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass);
|
||||
|
||||
if (isCompanionObject(descriptor)) {
|
||||
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSecondaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
|
||||
@@ -1012,9 +1014,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatorByExpressionSpecifier) specifier, fieldsInfo);
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatedSuperTypeEntry) specifier, fieldsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,41 +1155,41 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return StackValue.field(type, classAsmType, name, false, StackValue.none());
|
||||
}
|
||||
}
|
||||
private final Map<KtDelegatorByExpressionSpecifier, Field> fields = new HashMap<KtDelegatorByExpressionSpecifier, Field>();
|
||||
private final Map<KtDelegatedSuperTypeEntry, Field> fields = new HashMap<KtDelegatedSuperTypeEntry, Field>();
|
||||
|
||||
@NotNull
|
||||
public Field getInfo(KtDelegatorByExpressionSpecifier specifier) {
|
||||
public Field getInfo(KtDelegatedSuperTypeEntry specifier) {
|
||||
return fields.get(specifier);
|
||||
}
|
||||
|
||||
private void addField(KtDelegatorByExpressionSpecifier specifier, PropertyDescriptor propertyDescriptor) {
|
||||
private void addField(KtDelegatedSuperTypeEntry specifier, PropertyDescriptor propertyDescriptor) {
|
||||
fields.put(specifier,
|
||||
new Field(typeMapper.mapType(propertyDescriptor), propertyDescriptor.getName().asString(), false));
|
||||
}
|
||||
|
||||
private void addField(KtDelegatorByExpressionSpecifier specifier, Type type, String name) {
|
||||
private void addField(KtDelegatedSuperTypeEntry specifier, Type type, String name) {
|
||||
fields.put(specifier, new Field(type, name, true));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtDelegationSpecifier> delegationSpecifiers) {
|
||||
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtSuperTypeListEntry> delegationSpecifiers) {
|
||||
DelegationFieldsInfo result = new DelegationFieldsInfo();
|
||||
int n = 0;
|
||||
for (KtDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
KtExpression expression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||
for (KtSuperTypeListEntry specifier : delegationSpecifiers) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
|
||||
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext);
|
||||
|
||||
|
||||
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
|
||||
result.addField((KtDelegatorByExpressionSpecifier) specifier, propertyDescriptor);
|
||||
result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor);
|
||||
}
|
||||
else {
|
||||
KotlinType expressionType = expression != null ? bindingContext.getType(expression) : null;
|
||||
Type asmType =
|
||||
expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(getSuperClass(specifier));
|
||||
result.addField((KtDelegatorByExpressionSpecifier) specifier, asmType, "$delegate_" + n);
|
||||
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, "$delegate_" + n);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
@@ -1196,14 +1198,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassDescriptor getSuperClass(@NotNull KtDelegationSpecifier specifier) {
|
||||
return CodegenUtil.getSuperClassByDelegationSpecifier(specifier, bindingContext);
|
||||
private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) {
|
||||
return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
|
||||
}
|
||||
|
||||
private void genCallToDelegatorByExpressionSpecifier(
|
||||
InstructionAdapter iv,
|
||||
ExpressionCodegen codegen,
|
||||
KtDelegatorByExpressionSpecifier specifier,
|
||||
KtDelegatedSuperTypeEntry specifier,
|
||||
DelegationFieldsInfo fieldsInfo
|
||||
) {
|
||||
KtExpression expression = specifier.getDelegateExpression();
|
||||
@@ -1248,7 +1250,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void lookupReceiver(@NotNull ReceiverValue value) {
|
||||
private void lookupReceiver(@Nullable ReceiverValue value) {
|
||||
if (value instanceof ImplicitReceiver) {
|
||||
if (value instanceof ExtensionReceiver) {
|
||||
ReceiverParameterDescriptor parameter =
|
||||
@@ -1303,9 +1305,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
KtExpression delegateExpression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
|
||||
assert delegateExpression != null;
|
||||
delegateExpression.accept(visitor);
|
||||
}
|
||||
@@ -1331,7 +1333,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
private void generateTraitMethods() {
|
||||
if (isInterface(descriptor)) return;
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getTraitMethods(descriptor).entrySet()) {
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor traitFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!(traitFun instanceof JavaCallableMemberDescriptor)) {
|
||||
@@ -1559,7 +1561,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List args) {
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> args) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1571,7 +1573,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
for (KtEnumEntry enumEntry : enumEntries) {
|
||||
ClassDescriptor descriptor = getNotNull(bindingContext, BindingContext.CLASS, enumEntry);
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL,
|
||||
int isDeprecated = KotlinBuiltIns.isDeprecated(descriptor) ? ACC_DEPRECATED : 0;
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL | isDeprecated,
|
||||
descriptor.getName().asString(), classAsmType.getDescriptor(), null, null);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(descriptor, null);
|
||||
}
|
||||
@@ -1619,7 +1622,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.aconst(enumEntry.getName());
|
||||
iv.iconst(ordinal);
|
||||
|
||||
List<KtDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
|
||||
List<KtSuperTypeListEntry> delegationSpecifiers = enumEntry.getSuperTypeListEntries();
|
||||
if (delegationSpecifiers.size() == 1 && !enumEntryNeedSubclass(bindingContext, enumEntry)) {
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(delegationSpecifiers.get(0), bindingContext);
|
||||
|
||||
@@ -1637,11 +1640,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateDelegates(DelegationFieldsInfo delegationFieldsInfo) {
|
||||
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatorByExpressionSpecifier) specifier);
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatedSuperTypeEntry) specifier);
|
||||
generateDelegateField(field);
|
||||
KtExpression delegateExpression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
|
||||
KotlinType delegateExpressionType = delegateExpression != null ? bindingContext.getType(delegateExpression) : null;
|
||||
generateDelegates(getSuperClass(specifier), delegateExpressionType, field);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class InterfaceImplBodyCodegen(
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(
|
||||
myClass, V1_6, ACC_PUBLIC or ACC_FINAL,
|
||||
myClass, V1_6, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
@@ -63,7 +63,7 @@ public class InterfaceImplBodyCodegen(
|
||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||
val classDescriptorImpl = ClassDescriptorImpl(
|
||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||
Modality.FINAL, Collections.emptyList(), SourceElement.NO_SOURCE)
|
||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE)
|
||||
|
||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||
return classDescriptorImpl
|
||||
@@ -103,6 +103,8 @@ public class InterfaceImplBodyCodegen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateSyntheticAccessors()
|
||||
}
|
||||
|
||||
private fun generateDelegationToSuperTraitImpl(descriptor: FunctionDescriptor, implementation: FunctionDescriptor) {
|
||||
|
||||
@@ -134,12 +134,13 @@ public class JvmCodegenUtil {
|
||||
@NotNull PropertyDescriptor property,
|
||||
boolean forGetter,
|
||||
boolean isDelegated,
|
||||
@NotNull MethodContext context
|
||||
@NotNull MethodContext contextBeforeInline
|
||||
) {
|
||||
if (JetTypeMapper.isAccessor(property)) return false;
|
||||
|
||||
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();
|
||||
// Inline functions can't use direct access because a field may not be visible at the call site
|
||||
if (context.isInlineFunction()) {
|
||||
if (context.isInlineMethodContext()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,7 +165,7 @@ public class JvmCodegenUtil {
|
||||
return Visibilities.isPrivate(property.getVisibility()) || accessor.getModality() == FINAL;
|
||||
}
|
||||
|
||||
private static boolean isDebuggerContext(@NotNull MethodContext context) {
|
||||
private static boolean isDebuggerContext(@NotNull CodegenContext context) {
|
||||
KtFile file = DescriptorToSourceUtils.getContainingFile(context.getContextDescriptor());
|
||||
return file != null && CodeFragmentUtilKt.getSuppressDiagnosticsInDebugMode(file);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
@@ -65,8 +64,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlag
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
|
||||
@@ -281,7 +279,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
|
||||
protected void writeOuterClassAndEnclosingMethod() {
|
||||
CodegenContext context = this.context.getParentContext();
|
||||
while (context instanceof MethodContext && ((MethodContext) context).isInliningLambda()) {
|
||||
|
||||
while (context instanceof InlineLambdaContext) {
|
||||
// If this is a lambda which will be inlined, skip its MethodContext and enclosing ClosureContext
|
||||
//noinspection ConstantConditions
|
||||
context = context.getParentContext().getParentContext();
|
||||
@@ -525,7 +524,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
//noinspection ConstantConditions
|
||||
value = createOrGetClInitCodegen().generatePropertyReference(
|
||||
delegatedProperties.get(i).getDelegate(), property, property,
|
||||
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : ReceiverValue.NO_RECEIVER
|
||||
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -684,7 +683,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
|
||||
);
|
||||
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor);
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) && !isInterface(functionDescriptor.getContainingDeclaration());
|
||||
int reg = hasDispatchReceiver ? 1 : 0;
|
||||
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
||||
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
@@ -50,6 +51,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.*
|
||||
|
||||
public class MultifileClassCodegen(
|
||||
@@ -86,12 +88,18 @@ public class MultifileClassCodegen(
|
||||
|
||||
val singleSourceFile = if (previouslyCompiledCallables.isNotEmpty()) null else filesWithCallables.singleOrNull()
|
||||
|
||||
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES,
|
||||
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6,
|
||||
if (state.generateOpenMultifileClasses) OPEN_FACADE_CLASS_ATTRIBUTES else FACADE_CLASS_ATTRIBUTES,
|
||||
facadeClassType.internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY)
|
||||
if (singleSourceFile != null) {
|
||||
classBuilder.visitSource(singleSourceFile.name, null)
|
||||
}
|
||||
|
||||
if (state.generateOpenMultifileClasses) {
|
||||
generateMultifileFacadeClassConstructor(classBuilder, originFile)
|
||||
}
|
||||
|
||||
classBuilder
|
||||
}
|
||||
|
||||
@@ -148,6 +156,16 @@ public class MultifileClassCodegen(
|
||||
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null)
|
||||
}
|
||||
|
||||
|
||||
private fun generateMultifileFacadeClassConstructor(classBuilder: ClassBuilder, originFile: KtFile?) {
|
||||
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null)
|
||||
val v = InstructionAdapter(mv)
|
||||
v.load(0, facadeClassType)
|
||||
v.invokespecial("java/lang/Object", "<init>", "()V", false)
|
||||
v.visitInsn(Opcodes.RETURN)
|
||||
FunctionCodegen.endVisit(v, "multifile class constructor", originFile)
|
||||
}
|
||||
|
||||
private fun generatePart(
|
||||
file: KtFile,
|
||||
generateCallableMemberTasks: MutableMap<CallableMemberDescriptor, () -> Unit>,
|
||||
@@ -279,7 +297,8 @@ public class MultifileClassCodegen(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL
|
||||
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER
|
||||
private val OPEN_FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_SUPER
|
||||
|
||||
private fun getOnlyPackageFragment(packageFqName: FqName, files: Collection<KtFile>, bindingContext: BindingContext): PackageFragmentDescriptor? {
|
||||
val fragments = SmartList<PackageFragmentDescriptor>()
|
||||
|
||||
@@ -46,7 +46,7 @@ public class MultifileClassPartCodegen(
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(element, Opcodes.V1_6,
|
||||
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC,
|
||||
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC or Opcodes.ACC_SUPER,
|
||||
filePartType.internalName,
|
||||
null,
|
||||
"java/lang/Object",
|
||||
|
||||
@@ -154,7 +154,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
||||
this.typeConstructor = TypeConstructorImpl.createForClass(
|
||||
this,
|
||||
Annotations.Companion.getEMPTY(),
|
||||
!getModality().isOverridable(),
|
||||
ModalityKt.isFinalClass(this),
|
||||
getName().asString(),
|
||||
typeParameters,
|
||||
supertypes
|
||||
|
||||
@@ -63,7 +63,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
@Override
|
||||
protected void generateDeclaration() {
|
||||
v.defineClass(element, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
|
||||
packagePartType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
|
||||
@@ -127,8 +127,6 @@ public class PropertyCodegen {
|
||||
if (isAccessorNeeded(declaration, descriptor, setter)) {
|
||||
generateSetter(declaration, descriptor, setter);
|
||||
}
|
||||
|
||||
context.recordSyntheticAccessorIfNeeded(descriptor, bindingContext);
|
||||
}
|
||||
|
||||
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
|
||||
|
||||
@@ -47,11 +47,11 @@ public class PropertyReferenceCodegen(
|
||||
classBuilder: ClassBuilder,
|
||||
private val classDescriptor: ClassDescriptor,
|
||||
private val target: VariableDescriptor,
|
||||
dispatchReceiver: ReceiverValue
|
||||
dispatchReceiver: ReceiverValue?
|
||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||
|
||||
private val dispatchReceiverType = if (dispatchReceiver.exists()) dispatchReceiver.type else null
|
||||
private val dispatchReceiverType = dispatchReceiver?.type
|
||||
|
||||
private val extensionReceiverType = target.extensionReceiverParameter?.type
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ public class SamWrapperCodegen {
|
||||
samType.getJavaClassDescriptor().getContainingDeclaration(),
|
||||
fqName.shortName(),
|
||||
Modality.FINAL,
|
||||
ClassKind.CLASS,
|
||||
Collections.singleton(samType.getType()),
|
||||
SourceElement.NO_SOURCE
|
||||
);
|
||||
@@ -85,7 +86,7 @@ public class SamWrapperCodegen {
|
||||
ClassBuilder cv = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), asmType, file);
|
||||
cv.defineClass(file,
|
||||
V1_6,
|
||||
ACC_FINAL,
|
||||
ACC_FINAL | ACC_SUPER,
|
||||
asmType.getInternalName(),
|
||||
null,
|
||||
OBJECT_TYPE.getInternalName(),
|
||||
|
||||
@@ -88,7 +88,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
|
||||
v.defineClass(scriptDeclaration,
|
||||
V1_6,
|
||||
ACC_PUBLIC,
|
||||
ACC_PUBLIC | ACC_SUPER,
|
||||
classType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
|
||||
@@ -23,6 +23,7 @@ import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
|
||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -502,19 +504,19 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
ReceiverValue callExtensionReceiver = (ReceiverValue) resolvedCall.getExtensionReceiver();
|
||||
if (callDispatchReceiver.exists() || callExtensionReceiver.exists()
|
||||
if (callDispatchReceiver != null || callExtensionReceiver != null
|
||||
|| isLocalFunCall(callableMethod) || isCallToMemberObjectImportedByName(resolvedCall)) {
|
||||
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
|
||||
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
|
||||
if (descriptor.getOriginal() instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
callDispatchReceiver = callExtensionReceiver;
|
||||
callExtensionReceiver = ReceiverValue.NO_RECEIVER;
|
||||
callExtensionReceiver = null;
|
||||
dispatchReceiverParameter = extensionReceiverParameter;
|
||||
extensionReceiverParameter = null;
|
||||
}
|
||||
|
||||
boolean hasExtensionReceiver = callExtensionReceiver.exists();
|
||||
boolean hasExtensionReceiver = callExtensionReceiver != null;
|
||||
StackValue dispatchReceiver = platformStaticCallIfPresent(
|
||||
genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, callDispatchReceiver, false),
|
||||
descriptor
|
||||
@@ -532,11 +534,11 @@ public abstract class StackValue {
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull ResolvedCall resolvedCall,
|
||||
@Nullable Callable callableMethod,
|
||||
ReceiverValue receiverValue,
|
||||
@Nullable ReceiverValue receiverValue,
|
||||
boolean isExtension
|
||||
) {
|
||||
if (receiver == none()) {
|
||||
if (receiverValue.exists()) {
|
||||
if (receiverValue != null) {
|
||||
return codegen.generateReceiverValue(receiverValue, false);
|
||||
}
|
||||
else if (isLocalFunCall(callableMethod) && !isExtension) {
|
||||
@@ -548,7 +550,7 @@ public abstract class StackValue {
|
||||
return singleton(((ImportedFromObjectCallableDescriptor) resolvedCall.getResultingDescriptor()).getContainingObject(), codegen.typeMapper);
|
||||
}
|
||||
}
|
||||
else if (receiverValue.exists()) {
|
||||
else if (receiverValue != null) {
|
||||
return receiver;
|
||||
}
|
||||
return none();
|
||||
@@ -834,7 +836,7 @@ public abstract class StackValue {
|
||||
|
||||
ReceiverValue receiverParameter = (ReceiverValue) resolvedGetCall.getExtensionReceiver();
|
||||
int receiverIndex = -1;
|
||||
if (receiverParameter.exists()) {
|
||||
if (receiverParameter != null) {
|
||||
Type type = codegen.typeMapper.mapType(receiverParameter.getType());
|
||||
receiverIndex = frame.enterTemp(type);
|
||||
v.store(receiverIndex, type);
|
||||
@@ -842,7 +844,7 @@ public abstract class StackValue {
|
||||
|
||||
ReceiverValue dispatchReceiver = resolvedGetCall.getDispatchReceiver();
|
||||
int thisIndex = -1;
|
||||
if (dispatchReceiver.exists()) {
|
||||
if (dispatchReceiver != null) {
|
||||
thisIndex = frame.enterTemp(OBJECT_TYPE);
|
||||
v.store(thisIndex, OBJECT_TYPE);
|
||||
}
|
||||
@@ -863,14 +865,14 @@ public abstract class StackValue {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
if (resolvedSetCall.getDispatchReceiver().exists()) {
|
||||
if (resolvedSetCall.getExtensionReceiver().exists()) {
|
||||
if (resolvedSetCall.getDispatchReceiver() != null) {
|
||||
if (resolvedSetCall.getExtensionReceiver() != null) {
|
||||
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, v);
|
||||
}
|
||||
v.load(realReceiverIndex, realReceiverType);
|
||||
}
|
||||
else {
|
||||
if (resolvedSetCall.getExtensionReceiver().exists()) {
|
||||
if (resolvedSetCall.getExtensionReceiver() != null) {
|
||||
v.load(realReceiverIndex, realReceiverType);
|
||||
}
|
||||
else {
|
||||
@@ -970,8 +972,8 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
if (call.getDispatchReceiver().exists()) {
|
||||
if (call.getExtensionReceiver().exists()) {
|
||||
if (call.getDispatchReceiver() != null) {
|
||||
if (call.getExtensionReceiver() != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1090,6 +1092,12 @@ public abstract class StackValue {
|
||||
else {
|
||||
getter.genInvokeInstruction(v);
|
||||
coerce(getter.getReturnType(), type, v);
|
||||
|
||||
KotlinType returnType = descriptor.getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
v.aconst(null);
|
||||
v.athrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
correctContainerForLambda(callableDescriptor, element),
|
||||
Name.special("<closure-" + simpleName + ">"),
|
||||
Modality.FINAL,
|
||||
ClassKind.CLASS,
|
||||
supertypes,
|
||||
KotlinSourceElementKt.toSourceElement(element)
|
||||
);
|
||||
@@ -128,7 +129,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
if (element instanceof KtObjectDeclaration &&
|
||||
element.getParent() instanceof KtObjectLiteralExpression &&
|
||||
child instanceof KtDelegationSpecifierList) {
|
||||
child instanceof KtSuperTypeList) {
|
||||
// If we're passing an anonymous object's super call, it means "container" is ConstructorDescriptor of that object.
|
||||
// To reach outer context, we should call getContainingDeclaration() twice
|
||||
// TODO: this is probably not entirely correct, mostly because DECLARATION_TO_DESCRIPTOR can return null
|
||||
@@ -177,7 +178,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
@Override
|
||||
public void visitEnumEntry(@NotNull KtEnumEntry enumEntry) {
|
||||
if (enumEntry.getDeclarations().isEmpty()) {
|
||||
for (KtDelegationSpecifier specifier : enumEntry.getDelegationSpecifiers()) {
|
||||
for (KtSuperTypeListEntry specifier : enumEntry.getSuperTypeListEntries()) {
|
||||
specifier.accept(this);
|
||||
}
|
||||
return;
|
||||
@@ -247,7 +248,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
String name = inventAnonymousClassName();
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
KtDelegationSpecifierList delegationSpecifierList = object.getDelegationSpecifierList();
|
||||
KtSuperTypeList delegationSpecifierList = object.getSuperTypeList();
|
||||
if (delegationSpecifierList != null) {
|
||||
delegationSpecifierList.accept(this);
|
||||
}
|
||||
@@ -263,8 +264,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression) {
|
||||
KtFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
||||
public void visitLambdaExpression(@NotNull KtLambdaExpression lambdaExpression) {
|
||||
KtFunctionLiteral functionLiteral = lambdaExpression.getFunctionLiteral();
|
||||
FunctionDescriptor functionDescriptor =
|
||||
(FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, functionLiteral);
|
||||
// working around a problem with shallow analysis
|
||||
@@ -277,7 +278,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
classStack.push(classDescriptor);
|
||||
nameStack.push(name);
|
||||
super.visitFunctionLiteralExpression(expression);
|
||||
super.visitLambdaExpression(lambdaExpression);
|
||||
nameStack.pop();
|
||||
classStack.pop();
|
||||
}
|
||||
@@ -431,8 +432,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDelegationToSuperCallSpecifier(@NotNull KtDelegatorToSuperCall call) {
|
||||
super.visitDelegationToSuperCallSpecifier(call);
|
||||
public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
|
||||
super.visitSuperTypeCallEntry(call);
|
||||
checkSamCall(call);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ public final class PsiCodegenPredictor {
|
||||
// TODO: Method won't work for declarations inside companion objects
|
||||
// TODO: Method won't give correct class name for traits implementations
|
||||
|
||||
if (declaration instanceof KtPropertyAccessor) {
|
||||
return getPredefinedJvmInternalName(((KtPropertyAccessor) declaration).getProperty(), fileClassesProvider);
|
||||
}
|
||||
KtDeclaration parentDeclaration = KtStubbedPsiUtil.getContainingDeclaration(declaration);
|
||||
|
||||
String parentInternalName;
|
||||
@@ -73,8 +76,8 @@ public final class PsiCodegenPredictor {
|
||||
else {
|
||||
KtFile containingFile = declaration.getContainingKtFile();
|
||||
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
Name name = ((KtNamedFunction) declaration).getNameAsName();
|
||||
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) {
|
||||
Name name = ((KtNamedDeclaration) declaration).getNameAsName();
|
||||
return name == null ? null : FileClasses.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmDescriptor
|
||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -51,7 +51,7 @@ object BuiltinSpecialBridgesUtil {
|
||||
|
||||
val functionHandle = DescriptorBasedFunctionHandle(function)
|
||||
val fake = !functionHandle.isDeclaration
|
||||
val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmDescriptor()!!
|
||||
val overriddenBuiltin = function.getOverriddenBuiltinReflectingJvmDescriptor()!!
|
||||
|
||||
val reachableDeclarations = findAllReachableDeclarations(function)
|
||||
|
||||
@@ -99,7 +99,7 @@ object BuiltinSpecialBridgesUtil {
|
||||
): Boolean {
|
||||
if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false
|
||||
|
||||
val builtin = getOverriddenBuiltinWithDifferentJvmDescriptor()!!
|
||||
val builtin = getOverriddenBuiltinReflectingJvmDescriptor()!!
|
||||
return signatureByDescriptor(this) == signatureByDescriptor(builtin)
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ private fun <Signature> needGenerateSpecialBridge(
|
||||
|| originalOverridden.containingDeclaration is JavaClassDescriptor
|
||||
|| DescriptorUtils.isInterface(originalOverridden.containingDeclaration)) return@firstOverridden false
|
||||
|
||||
val overriddenSpecial = originalOverridden.getOverriddenBuiltinWithDifferentJvmDescriptor()?.original ?: return@firstOverridden false
|
||||
val overriddenSpecial = originalOverridden.getOverriddenBuiltinReflectingJvmDescriptor()?.original ?: return@firstOverridden false
|
||||
|
||||
signatureByDescriptor(originalOverridden) != signatureByDescriptor(overriddenSpecial)
|
||||
} != null) return false
|
||||
|
||||
@@ -17,17 +17,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
fun generateIsCheck(
|
||||
v: InstructionAdapter,
|
||||
type: KotlinType,
|
||||
isNullable: Boolean,
|
||||
generateInstanceOfInstruction: (InstructionAdapter) -> Unit
|
||||
) {
|
||||
if (type.isMarkedNullable) {
|
||||
if (isNullable) {
|
||||
val nope = Label()
|
||||
val end = Label()
|
||||
|
||||
@@ -51,6 +59,39 @@ fun generateIsCheck(
|
||||
}
|
||||
}
|
||||
|
||||
fun generateNullCheckForNonSafeAs(
|
||||
v: InstructionAdapter,
|
||||
type: KotlinType
|
||||
) {
|
||||
with(v) {
|
||||
dup()
|
||||
val nonnull = Label()
|
||||
ifnonnull(nonnull)
|
||||
AsmUtil.genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
|
||||
mark(nonnull)
|
||||
}
|
||||
}
|
||||
|
||||
public fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
|
||||
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }
|
||||
|
||||
fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) {
|
||||
val descriptor = state.bindingContext.get(BindingContext.CLASS, companion)
|
||||
|
||||
if (descriptor == null || ErrorUtils.isError(descriptor)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!AsmUtil.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
return
|
||||
}
|
||||
val properties = companion.declarations.filterIsInstance<KtProperty>()
|
||||
|
||||
properties.forEach {
|
||||
val variableDescriptor = state.bindingContext.get(BindingContext.VARIABLE, it)
|
||||
if (variableDescriptor is PropertyDescriptor) {
|
||||
outerContext.getFieldName(variableDescriptor, it.hasDelegate())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.context;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ReadOnly;
|
||||
import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -27,7 +28,6 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.storage.NullableLazyValue;
|
||||
@@ -37,7 +37,7 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.NEED_SYNTHETIC_ACCESSOR;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
|
||||
@@ -267,6 +267,10 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return new MultifileClassFacadeContext(descriptor, this, multifileClassType, filePartType);
|
||||
}
|
||||
|
||||
public ClassContext intoDefaultImplsClass(ClassDescriptor descriptor, ClassContext interfaceContext, GenerationState state) {
|
||||
return new DefaultImplsClassContext(state.getTypeMapper(), descriptor, OwnerKind.DEFAULT_IMPLS, this, null, interfaceContext);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) {
|
||||
if (descriptor.isCompanionObject()) {
|
||||
@@ -279,11 +283,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
ClassContext classContext = new ClassContext(state.getTypeMapper(), descriptor, kind, this, null);
|
||||
|
||||
//We can't call descriptor.getCompanionObjectDescriptor() on light class generation
|
||||
// because it triggers companion light class generation via putting it to BindingContext.CLASS
|
||||
// (so MemberCodegen doesn't skip it in genClassOrObject).
|
||||
if (state.getTypeMapper().getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES &&
|
||||
descriptor.getCompanionObjectDescriptor() != null) {
|
||||
if (descriptor.getCompanionObjectDescriptor() != null) {
|
||||
//We need to create companion object context ahead of time
|
||||
// because otherwise we can't generate synthetic accessor for private members in companion object
|
||||
classContext.intoClass(descriptor.getCompanionObjectDescriptor(), OwnerKind.IMPLEMENTATION, state);
|
||||
@@ -298,12 +298,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
@NotNull
|
||||
public MethodContext intoFunction(FunctionDescriptor descriptor) {
|
||||
return new MethodContext(descriptor, getContextKind(), this, null, false);
|
||||
return new MethodContext(descriptor, getContextKind(), this, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor) {
|
||||
return new MethodContext(descriptor, getContextKind(), this, null, true);
|
||||
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor, boolean isCrossInline) {
|
||||
return new InlineLambdaContext(descriptor, getContextKind(), this, null, isCrossInline);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -365,11 +365,24 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
private <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallTarget);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessorForSuperCallIfNeeded(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
if (superCallTarget != null && !isJvmInterface(descriptor.getContainingDeclaration())) {
|
||||
CodegenContext afterInline = getFirstCrossInlineOrNonInlineContext();
|
||||
CodegenContext c = afterInline.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + descriptor;
|
||||
if (c != afterInline.getParentContext()) {
|
||||
return (D) c.getAccessor(descriptor, superCallTarget);
|
||||
}
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessor(
|
||||
@NotNull D possiblySubstitutedDescriptor,
|
||||
@@ -502,32 +515,27 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ReadOnly
|
||||
public Collection<? extends AccessorForCallableDescriptor<?>> getAccessors() {
|
||||
return accessors == null ? Collections.<AccessorForCallableDescriptor<CallableMemberDescriptor>>emptySet() : accessors.values();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D accessibleDescriptor(
|
||||
@NotNull D descriptor,
|
||||
@Nullable ClassDescriptor superCallTarget
|
||||
) {
|
||||
CodegenContext properContext = getFirstCrossInlineOrNonInlineContext();
|
||||
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
|
||||
boolean isInliningContext = isInlineMethodContext();
|
||||
boolean isInliningContext = properContext.isInlineMethodContext();
|
||||
if (!isInliningContext && (
|
||||
!hasThisDescriptor() ||
|
||||
enclosing == getThisDescriptor() ||
|
||||
enclosing == getClassOrPackageParentContext().getContextDescriptor())) {
|
||||
!properContext.hasThisDescriptor() ||
|
||||
enclosing == properContext.getThisDescriptor() ||
|
||||
enclosing == properContext.getClassOrPackageParentContext().getContextDescriptor())) {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
return accessibleDescriptorIfNeeded(descriptor, superCallTarget, isInliningContext);
|
||||
}
|
||||
|
||||
public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
|
||||
if (hasThisDescriptor() && Boolean.TRUE.equals(bindingContext.get(NEED_SYNTHETIC_ACCESSOR, descriptor))) {
|
||||
// Not a super call because neither constructors nor private members can be targets of super calls
|
||||
accessibleDescriptorIfNeeded(descriptor, /* superCallTarget = */ null, false);
|
||||
}
|
||||
return (D) properContext.accessibleDescriptorIfNeeded(descriptor, superCallTarget, isInliningContext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -632,7 +640,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CodegenContext findChildContext(@NotNull DeclarationDescriptor child) {
|
||||
protected CodegenContext findChildContext(@NotNull DeclarationDescriptor child) {
|
||||
return childContexts == null ? null : childContexts.get(child);
|
||||
}
|
||||
|
||||
@@ -640,18 +648,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return value instanceof StackValue.Field && ((StackValue.Field) value).isStaticPut;
|
||||
}
|
||||
|
||||
private boolean isInsideInliningContext() {
|
||||
CodegenContext current = this;
|
||||
while (current != null) {
|
||||
if (current instanceof MethodContext && ((MethodContext) current).isInlineFunction()) {
|
||||
return true;
|
||||
}
|
||||
current = current.getParentContext();
|
||||
}
|
||||
public boolean isInlineMethodContext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInlineMethodContext() {
|
||||
return this instanceof MethodContext && ((MethodContext) this).isInlineFunction();
|
||||
@NotNull
|
||||
public CodegenContext getFirstCrossInlineOrNonInlineContext() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ConstructorContext extends MethodContext {
|
||||
@NotNull CodegenContext parent,
|
||||
@Nullable MutableClosure closure
|
||||
) {
|
||||
super(contextDescriptor, kind, parent, closure, false);
|
||||
super(contextDescriptor, kind, parent, closure);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AccessorForCallableDescriptor
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
|
||||
class DefaultImplsClassContext(
|
||||
typeMapper: JetTypeMapper,
|
||||
contextDescriptor: ClassDescriptor,
|
||||
contextKind: OwnerKind,
|
||||
parentContext: CodegenContext<*>?,
|
||||
localLookup: ((DeclarationDescriptor) -> Boolean)?,
|
||||
val interfaceContext: ClassContext
|
||||
) : ClassContext(typeMapper, contextDescriptor, contextKind, parentContext, localLookup) {
|
||||
|
||||
override fun getCompanionObjectContext(): CodegenContext<*>? {
|
||||
return interfaceContext.companionObjectContext
|
||||
}
|
||||
|
||||
override fun getAccessors(): Collection<AccessorForCallableDescriptor<*>> {
|
||||
val accessors = super.getAccessors()
|
||||
val alreadyExistKeys = accessors.map ({ Pair(it.calleeDescriptor, it.superCallTarget) })
|
||||
val filtered = interfaceContext.accessors.toMap ({ Pair(it.calleeDescriptor, it.superCallTarget) }, {it}) - alreadyExistKeys
|
||||
return accessors + filtered.values
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context
|
||||
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
|
||||
class InlineLambdaContext(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
contextKind: OwnerKind,
|
||||
parentContext: CodegenContext<*>,
|
||||
closure: MutableClosure?,
|
||||
val isCrossInline: Boolean
|
||||
) : MethodContext(functionDescriptor, contextKind, parentContext, closure) {
|
||||
|
||||
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
|
||||
if (isCrossInline) return this
|
||||
|
||||
val parent = parentContext as? ClosureContext ?:
|
||||
throw AssertionError("Parent of inlining lambda body should be ClosureContext, but: $parentContext")
|
||||
|
||||
val grandParent = parent.parentContext ?:
|
||||
throw AssertionError("Parent context of lambda class context should exist: $contextDescriptor")
|
||||
return grandParent.firstCrossInlineOrNonInlineContext
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
private final boolean isInliningLambda;
|
||||
private Label methodStartLabel;
|
||||
private Label methodEndLabel;
|
||||
|
||||
@@ -44,12 +43,10 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull OwnerKind contextKind,
|
||||
@NotNull CodegenContext parentContext,
|
||||
@Nullable MutableClosure closure,
|
||||
boolean isInliningLambda
|
||||
@Nullable MutableClosure closure
|
||||
) {
|
||||
super(JvmCodegenUtil.getDirectMember(functionDescriptor), contextKind, parentContext, closure,
|
||||
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null);
|
||||
this.isInliningLambda = isInliningLambda;
|
||||
this.functionDescriptor = functionDescriptor;
|
||||
}
|
||||
|
||||
@@ -117,14 +114,10 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
return "Method: " + getContextDescriptor();
|
||||
}
|
||||
|
||||
public boolean isInlineFunction() {
|
||||
public boolean isInlineMethodContext() {
|
||||
return InlineUtil.isInline(getContextDescriptor());
|
||||
}
|
||||
|
||||
public boolean isInliningLambda() {
|
||||
return isInliningLambda;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionDescriptor getFunctionDescriptor() {
|
||||
return functionDescriptor;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,10 +27,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -66,8 +62,6 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
private final Map<String, List<String>> fieldNames = new HashMap<String, List<String>>();
|
||||
|
||||
private final TypeRemapper typeRemapper;
|
||||
|
||||
public AnonymousObjectTransformer(
|
||||
@NotNull String objectInternalName,
|
||||
@NotNull InliningContext inliningContext,
|
||||
@@ -82,12 +76,12 @@ public class AnonymousObjectTransformer {
|
||||
this.newLambdaType = newLambdaType;
|
||||
|
||||
reader = InlineCodegenUtil.buildClassReaderByInternalName(state, objectInternalName);
|
||||
typeRemapper = new TypeRemapper(inliningContext.typeMapping);
|
||||
transformationResult = InlineResult.create();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InlineResult doTransform(@NotNull AnonymousObjectGeneration anonymousObjectGen, @NotNull FieldRemapper parentRemapper) {
|
||||
final List<InnerClassNode> innerClassNodes = new ArrayList<InnerClassNode>();
|
||||
ClassBuilder classBuilder = createClassBuilder();
|
||||
final List<MethodNode> methodsToTransform = new ArrayList<MethodNode>();
|
||||
|
||||
@@ -102,6 +96,11 @@ public class AnonymousObjectTransformer {
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(String name, String outerName, String innerName, int access) {
|
||||
innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(@NotNull String owner, String name, String desc) {
|
||||
InliningContext parent = inliningContext.getParent();
|
||||
@@ -193,7 +192,7 @@ public class AnonymousObjectTransformer {
|
||||
String oldFunReturnType = returnType.getInternalName();
|
||||
String newFunReturnType = funResult.getChangedTypes().get(oldFunReturnType);
|
||||
if (newFunReturnType != null) {
|
||||
typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
|
||||
inliningContext.typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
|
||||
}
|
||||
}
|
||||
deferringMethods.add(deferringVisitor);
|
||||
@@ -207,6 +206,10 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder);
|
||||
|
||||
for (InnerClassNode node : innerClassNodes) {
|
||||
classBuilder.getVisitor().visitInnerClass(node.name, node.outerName, node.innerName, node.access);
|
||||
}
|
||||
|
||||
classBuilder.done();
|
||||
|
||||
anonymousObjectGen.setNewLambdaType(newLambdaType);
|
||||
@@ -237,7 +240,7 @@ public class AnonymousObjectTransformer {
|
||||
@NotNull ParametersBuilder capturedBuilder,
|
||||
boolean isConstructor
|
||||
) {
|
||||
ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode.instructions);
|
||||
ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode);
|
||||
Parameters parameters = isConstructor ? capturedBuilder.buildParameters() : getMethodParametersWithCaptured(capturedBuilder, sourceNode);
|
||||
|
||||
RegeneratedLambdaFieldRemapper remapper =
|
||||
@@ -345,7 +348,7 @@ public class AnonymousObjectTransformer {
|
||||
@NotNull
|
||||
private ClassBuilder createClassBuilder() {
|
||||
ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
|
||||
return new RemappingClassBuilder(classBuilder, typeRemapper);
|
||||
return new RemappingClassBuilder(classBuilder, inliningContext.typeRemapper);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.modules.TargetId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
@@ -245,7 +246,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
|
||||
MethodNode node = nodeAndSmap.getNode();
|
||||
ReifiedTypeParametersUsages reificationResult = reifiedTypeInliner.reifyInstructions(node.instructions);
|
||||
ReifiedTypeParametersUsages reificationResult = reifiedTypeInliner.reifyInstructions(node);
|
||||
generateClosuresBodies();
|
||||
|
||||
//through generation captured parameters will be added to invocationParamBuilder
|
||||
@@ -309,7 +310,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
MethodContext parentContext = codegen.getContext();
|
||||
|
||||
MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor);
|
||||
MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor, info.isCrossInline);
|
||||
|
||||
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(descriptor);
|
||||
Method asmMethod = jvmMethodSignature.getAsmMethod();
|
||||
@@ -538,26 +539,34 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
/*lambda or callable reference*/
|
||||
public static boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
|
||||
public boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
|
||||
//TODO deparenthisise typed
|
||||
KtExpression deparenthesized = KtPsiUtil.deparenthesize(expression);
|
||||
|
||||
if (deparenthesized instanceof KtCallableReferenceExpression) {
|
||||
// TODO: support inline of property references passed to inlinable function parameters
|
||||
SimpleFunctionDescriptor functionReference = state.getBindingContext().get(BindingContext.FUNCTION, deparenthesized);
|
||||
if (functionReference == null) return false;
|
||||
}
|
||||
|
||||
return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) &&
|
||||
isInlinableParameterExpression(deparenthesized);
|
||||
}
|
||||
|
||||
protected static boolean isInlinableParameterExpression(KtExpression deparenthesized) {
|
||||
return deparenthesized instanceof KtFunctionLiteralExpression ||
|
||||
return deparenthesized instanceof KtLambdaExpression ||
|
||||
deparenthesized instanceof KtNamedFunction ||
|
||||
deparenthesized instanceof KtCallableReferenceExpression;
|
||||
}
|
||||
|
||||
public void rememberClosure(KtExpression expression, Type type, int parameterIndex) {
|
||||
public void rememberClosure(KtExpression expression, Type type, ValueParameterDescriptor parameter) {
|
||||
KtExpression lambda = KtPsiUtil.deparenthesize(expression);
|
||||
assert isInlinableParameterExpression(lambda) : "Couldn't find inline expression in " + expression.getText();
|
||||
|
||||
LambdaInfo info = new LambdaInfo(lambda, typeMapper);
|
||||
|
||||
ParameterInfo closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameterIndex);
|
||||
LambdaInfo info = new LambdaInfo(lambda, typeMapper, parameter.isCrossinline());
|
||||
|
||||
ParameterInfo closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.getIndex());
|
||||
closureInfo.setLambda(info);
|
||||
expressionMap.put(closureInfo.getIndex(), info);
|
||||
}
|
||||
@@ -630,7 +639,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
int parameterIndex
|
||||
) {
|
||||
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
|
||||
rememberClosure(argumentExpression, parameterType, valueParameterDescriptor.getIndex());
|
||||
rememberClosure(argumentExpression, parameterType, valueParameterDescriptor);
|
||||
}
|
||||
else {
|
||||
StackValue value = codegen.gen(argumentExpression);
|
||||
@@ -778,7 +787,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
@Override
|
||||
public void reorderArgumentsIfNeeded(
|
||||
@NotNull List actualArgsWithDeclIndex, @NotNull List valueParameterTypes
|
||||
@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex, @NotNull List<? extends Type> valueParameterTypes
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.MemberCodegen;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
|
||||
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -131,7 +132,7 @@ public class InlineCodegenUtil {
|
||||
CodegenContext<?> parentContext = context.getParentContext();
|
||||
while (parentContext != null) {
|
||||
if (parentContext instanceof MethodContext) {
|
||||
if (((MethodContext) parentContext).isInlineFunction()) {
|
||||
if (((MethodContext) parentContext).isInlineMethodContext()) {
|
||||
//just init default one to one mapping
|
||||
codegen.getOrCreateSourceMapper();
|
||||
break;
|
||||
@@ -311,8 +312,7 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) {
|
||||
InsnList instructions = to.instructions;
|
||||
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull InsnList instructions, @NotNull AbstractInsnNode beforeNode) {
|
||||
ListIterator<AbstractInsnNode> iterator = from.instructions.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
AbstractInsnNode next = iterator.next();
|
||||
@@ -320,6 +320,10 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) {
|
||||
insertNodeBefore(from, to.instructions, beforeNode);
|
||||
}
|
||||
|
||||
|
||||
public static MethodNode createEmptyMethodNode() {
|
||||
return new MethodNode(API, 0, "fake", "()V", null, null);
|
||||
@@ -395,7 +399,7 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
|
||||
public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) {
|
||||
return context.isInlineFunction() || context.isInliningLambda();
|
||||
return context.isInlineMethodContext() || context instanceof InlineLambdaContext;
|
||||
}
|
||||
|
||||
public static int getConstant(AbstractInsnNode ins) {
|
||||
|
||||
@@ -35,7 +35,7 @@ public class InliningContext {
|
||||
|
||||
public final NameGenerator nameGenerator;
|
||||
|
||||
public final Map<String, String> typeMapping;
|
||||
public final TypeRemapper typeRemapper;
|
||||
|
||||
public final ReifiedTypeInliner reifedTypeInliner;
|
||||
|
||||
@@ -48,7 +48,7 @@ public class InliningContext {
|
||||
@NotNull Map<Integer, LambdaInfo> map,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull Map<String, String> typeMapping,
|
||||
@NotNull TypeRemapper typeRemapper,
|
||||
@NotNull ReifiedTypeInliner reifedTypeInliner,
|
||||
boolean isInliningLambda,
|
||||
boolean classRegeneration
|
||||
@@ -57,7 +57,7 @@ public class InliningContext {
|
||||
expressionMap = map;
|
||||
this.state = state;
|
||||
this.nameGenerator = nameGenerator;
|
||||
this.typeMapping = typeMapping;
|
||||
this.typeRemapper = typeRemapper;
|
||||
this.reifedTypeInliner = reifedTypeInliner;
|
||||
this.isInliningLambda = isInliningLambda;
|
||||
this.classRegeneration = classRegeneration;
|
||||
@@ -78,13 +78,12 @@ public class InliningContext {
|
||||
}
|
||||
|
||||
public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator,
|
||||
@NotNull Map<String, String> additionalTypeMappings,
|
||||
@NotNull Map<String, String> newTypeMappings,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
|
||||
) {
|
||||
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
|
||||
newTypeMappings.putAll(additionalTypeMappings);
|
||||
return new RegeneratedClassContext(this, expressionMap, state, generator,
|
||||
newTypeMappings, reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
|
||||
new TypeRemapper(typeRemapper, newTypeMappings),
|
||||
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
|
||||
@@ -97,10 +96,8 @@ public class InliningContext {
|
||||
boolean isInliningLambda,
|
||||
boolean isRegeneration
|
||||
) {
|
||||
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
|
||||
newTypeMappings.putAll(additionalTypeMappings);
|
||||
return new InliningContext(this, expressionMap, state, generator,
|
||||
newTypeMappings, reifedTypeInliner, isInliningLambda, isRegeneration);
|
||||
new TypeRemapper(typeRemapper, additionalTypeMappings), reifedTypeInliner, isInliningLambda, isRegeneration);
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteralExpression;
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
@@ -50,6 +50,8 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
|
||||
private final CalculatedClosure closure;
|
||||
|
||||
public final boolean isCrossInline;
|
||||
|
||||
private SMAPAndMethodNode node;
|
||||
|
||||
private List<CapturedParamDesc> capturedVars;
|
||||
@@ -60,9 +62,10 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
|
||||
private final Type closureClassType;
|
||||
|
||||
LambdaInfo(@NotNull KtExpression expr, @NotNull JetTypeMapper typeMapper) {
|
||||
this.expression = expr instanceof KtFunctionLiteralExpression ?
|
||||
((KtFunctionLiteralExpression) expr).getFunctionLiteral() : expr;
|
||||
LambdaInfo(@NotNull KtExpression expr, @NotNull JetTypeMapper typeMapper, boolean isCrossInline) {
|
||||
this.isCrossInline = isCrossInline;
|
||||
this.expression = expr instanceof KtLambdaExpression ?
|
||||
((KtLambdaExpression) expr).getFunctionLiteral() : expr;
|
||||
|
||||
this.typeMapper = typeMapper;
|
||||
BindingContext bindingContext = typeMapper.getBindingContext();
|
||||
|
||||
@@ -78,7 +78,7 @@ public class MethodInliner {
|
||||
public MethodInliner(
|
||||
@NotNull MethodNode node,
|
||||
@NotNull Parameters parameters,
|
||||
@NotNull InliningContext parent,
|
||||
@NotNull InliningContext inliningContext,
|
||||
@NotNull FieldRemapper nodeRemapper,
|
||||
boolean isSameModule,
|
||||
@NotNull String errorPrefix,
|
||||
@@ -86,12 +86,12 @@ public class MethodInliner {
|
||||
) {
|
||||
this.node = node;
|
||||
this.parameters = parameters;
|
||||
this.inliningContext = parent;
|
||||
this.inliningContext = inliningContext;
|
||||
this.nodeRemapper = nodeRemapper;
|
||||
this.isSameModule = isSameModule;
|
||||
this.errorPrefix = errorPrefix;
|
||||
this.sourceMapper = sourceMapper;
|
||||
this.typeMapper = parent.state.getTypeMapper();
|
||||
this.typeMapper = inliningContext.state.getTypeMapper();
|
||||
this.result = InlineResult.create();
|
||||
}
|
||||
|
||||
@@ -153,8 +153,9 @@ public class MethodInliner {
|
||||
|
||||
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
|
||||
|
||||
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
|
||||
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode,
|
||||
new TypeRemapper(currentTypeMapping));
|
||||
remapper);
|
||||
|
||||
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
|
||||
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
|
||||
@@ -167,7 +168,7 @@ public class MethodInliner {
|
||||
//TODO: need poping of type but what to do with local funs???
|
||||
String oldClassName = anonymousObjectGen.getOwnerInternalName();
|
||||
String newClassName = inliningContext.nameGenerator.genLambdaClassName();
|
||||
currentTypeMapping.put(oldClassName, newClassName);
|
||||
remapper.addMapping(oldClassName, newClassName);
|
||||
AnonymousObjectTransformer transformer =
|
||||
new AnonymousObjectTransformer(oldClassName,
|
||||
inliningContext
|
||||
@@ -261,7 +262,14 @@ public class MethodInliner {
|
||||
visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
|
||||
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor());
|
||||
}
|
||||
super.visitMethodInsn(opcode, anonymousObjectGen.getNewLambdaType().getInternalName(), name, anonymousObjectGen.getNewConstructorDescriptor(), itf);
|
||||
String newInternalName = anonymousObjectGen.getNewLambdaType().getInternalName();
|
||||
super.visitMethodInsn(opcode, newInternalName, name, anonymousObjectGen.getNewConstructorDescriptor(), itf);
|
||||
|
||||
//TODO: add new inner class also for other contexts
|
||||
if (inliningContext.getParent() instanceof RegeneratedClassContext) {
|
||||
inliningContext.getParent().typeRemapper.addAdditionalMappings(anonymousObjectGen.getOwnerInternalName(), newInternalName);
|
||||
}
|
||||
|
||||
anonymousObjectGen = null;
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf);
|
||||
@@ -551,7 +559,7 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
private boolean isAlreadyRegenerated(@NotNull String owner) {
|
||||
return inliningContext.typeMapping.containsKey(owner);
|
||||
return inliningContext.typeRemapper.hasNoAdditionalMapping(owner);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -30,12 +30,12 @@ public class RegeneratedClassContext extends InliningContext {
|
||||
@NotNull Map<Integer, LambdaInfo> map,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull Map<String, String> typeMapping,
|
||||
@NotNull TypeRemapper typeRemapper,
|
||||
@NotNull ReifiedTypeInliner reifiedTypeInliner,
|
||||
boolean isInliningLambda,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
|
||||
) {
|
||||
super(parent, map, state, nameGenerator, typeMapping, reifiedTypeInliner, isInliningLambda, true);
|
||||
super(parent, map, state, nameGenerator, typeRemapper, reifiedTypeInliner, isInliningLambda, true);
|
||||
this.anonymousObjectGeneration = anonymousObjectGeneration;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,16 +18,22 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||
import org.jetbrains.kotlin.codegen.generateNullCheckForNonSafeAs
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureReader
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureWriter
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
private class ParameterNameAndNullability(val name: String, val nullable: Boolean)
|
||||
|
||||
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
|
||||
|
||||
companion object {
|
||||
@@ -64,15 +70,23 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE), false
|
||||
);
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun isNullableMarkerInstruction(marker: String) = INSTANCEOF_MARKER_METHOD_NAME == marker ||
|
||||
CHECKCAST_MARKER_METHOD_NAME == marker
|
||||
}
|
||||
|
||||
private var maxStackSize = 0
|
||||
|
||||
/**
|
||||
* @return set of type parameters' identifiers contained in markers that should be reified further
|
||||
* e.g. when we're generating inline function containing reified T
|
||||
* and another function containing reifiable parts is inlined into that function
|
||||
*/
|
||||
public fun reifyInstructions(instructions: InsnList): ReifiedTypeParametersUsages {
|
||||
public fun reifyInstructions(node: MethodNode): ReifiedTypeParametersUsages {
|
||||
if (parametersMapping == null) return ReifiedTypeParametersUsages()
|
||||
val instructions = node.instructions
|
||||
maxStackSize = 0
|
||||
var result = ReifiedTypeParametersUsages()
|
||||
for (insn in instructions.toArray()) {
|
||||
if (isParametrisedReifiedMarker(insn)) {
|
||||
@@ -83,6 +97,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
}
|
||||
}
|
||||
|
||||
node.maxStack = node.maxStack + maxStackSize
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -127,20 +142,25 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
* or null if it shouldn't
|
||||
*/
|
||||
private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? {
|
||||
val mapping = getTypeParameterMapping(insn) ?: return null
|
||||
val parameter = getParameter(insn) ?: return null
|
||||
val mapping = parametersMapping?.get(parameter.name) ?: return null
|
||||
val kotlinType =
|
||||
if (isNullableMarkerInstruction(insn.name) && parameter.nullable)
|
||||
TypeUtils.makeNullable(mapping.type)
|
||||
else
|
||||
mapping.type
|
||||
|
||||
|
||||
val asmType = mapping.asmType
|
||||
if (asmType != null) {
|
||||
val jetType = mapping.type ?: return null
|
||||
|
||||
// process* methods return false if marker should be reified further
|
||||
// or it's invalid (may be emitted explicitly in code)
|
||||
// they return true if instruction is reified and marker can be deleted
|
||||
if (when (insn.name) {
|
||||
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
|
||||
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = false)
|
||||
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = true)
|
||||
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, jetType, asmType)
|
||||
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = false)
|
||||
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, kotlinType, asmType, safe = true)
|
||||
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, kotlinType, asmType)
|
||||
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
|
||||
else -> false
|
||||
}) {
|
||||
@@ -150,7 +170,8 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
|
||||
return null
|
||||
} else {
|
||||
instructions.set(insn.getPrevious()!!, LdcInsnNode(mapping.newName))
|
||||
val nullableSuffix = if (isNullableMarkerInstruction(insn.name) && kotlinType.isMarkedNullable) "?" else ""
|
||||
instructions.set(insn.previous!!, LdcInsnNode(mapping.newName + nullableSuffix))
|
||||
return mapping.newName
|
||||
}
|
||||
}
|
||||
@@ -158,20 +179,66 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
||||
|
||||
private fun processCheckcast(insn: MethodInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type, safe: Boolean) =
|
||||
private fun processCheckcast(insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
jetType: KotlinType,
|
||||
asmType: Type,
|
||||
safe: Boolean) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
|
||||
if (instanceofInsn !is TypeInsnNode) return false
|
||||
|
||||
addNullCheckForAsIfNeeded(insn.previous!!, instructions, jetType, safe)
|
||||
TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun addNullCheckForAsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, jetType: KotlinType, safe: Boolean) {
|
||||
if (!safe && !TypeUtils.isNullableType(jetType)) {
|
||||
val methodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateNullCheckForNonSafeAs(InstructionAdapter(methodNode), jetType)
|
||||
|
||||
InlineCodegenUtil.insertNodeBefore(methodNode, instructions, insn)
|
||||
maxStackSize = Math.max(maxStackSize, 4)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processInstanceof(insn: MethodInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { instanceofInsn: AbstractInsnNode ->
|
||||
if (instanceofInsn !is TypeInsnNode) return false
|
||||
|
||||
addNullCheckForIsIfNeeded(insn, instructions, jetType)
|
||||
TypeIntrinsics.instanceOf(instanceofInsn, instructions, jetType, asmType)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun addNullCheckForIsIfNeeded(insn: AbstractInsnNode, instructions: InsnList, type: KotlinType) {
|
||||
if (TypeUtils.isNullableType(type)) {
|
||||
val instanceOf = insn.next
|
||||
insertNullCheckAround(instructions, insn.previous!!, instanceOf)
|
||||
maxStackSize = Math.max(maxStackSize, 2)
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertNullCheckAround(instructions: InsnList, start: AbstractInsnNode, end: AbstractInsnNode) {
|
||||
val methodNode = MethodNode(InlineCodegenUtil.API)
|
||||
var splitIndex: Int = -1
|
||||
generateIsCheck(InstructionAdapter(methodNode), true) {
|
||||
splitIndex = methodNode.instructions.size()
|
||||
}
|
||||
assert(splitIndex >= 0) {
|
||||
"Split index should be non-negative, but $splitIndex"
|
||||
}
|
||||
|
||||
val nullCheckInsns = methodNode.instructions.toArray()
|
||||
nullCheckInsns.take(splitIndex).forEach {
|
||||
instructions.insertBefore(start, it)
|
||||
}
|
||||
|
||||
nullCheckInsns.drop(splitIndex).reversed().forEach {
|
||||
instructions.insert(end, it)
|
||||
}
|
||||
}
|
||||
|
||||
inline private fun rewriteNextTypeInsn(
|
||||
marker: MethodInsnNode,
|
||||
expectedNextOpcode: Int,
|
||||
@@ -195,17 +262,16 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getParameterName(insn: MethodInsnNode): String? {
|
||||
private fun getParameter(insn: MethodInsnNode): ParameterNameAndNullability? {
|
||||
val prev = insn.getPrevious()!!
|
||||
|
||||
return when (prev.getOpcode()) {
|
||||
val parameterNameWithFlag = when (prev.getOpcode()) {
|
||||
Opcodes.LDC -> (prev as LdcInsnNode).cst as String
|
||||
else -> null
|
||||
else -> return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTypeParameterMapping(insn: MethodInsnNode): ReifiedTypeParameterMapping? {
|
||||
return parametersMapping?.get(getParameterName(insn) ?: return null)
|
||||
val parameterName = if (parameterNameWithFlag.endsWith("?")) parameterNameWithFlag.dropLast(1) else parameterNameWithFlag
|
||||
return ParameterNameAndNullability(parameterName, parameterName !== parameterNameWithFlag)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,8 +282,8 @@ public class ReifiedTypeParameterMappings() {
|
||||
mappingsByName[name] = ReifiedTypeParameterMapping(name, type, asmType, newName = null, signature = signature)
|
||||
}
|
||||
|
||||
public fun addParameterMappingToNewParameter(name: String, newName: String) {
|
||||
mappingsByName[name] = ReifiedTypeParameterMapping(name, type = null, asmType = null, newName = newName, signature = null)
|
||||
public fun addParameterMappingToNewParameter(name: String, type: KotlinType, newName: String) {
|
||||
mappingsByName[name] = ReifiedTypeParameterMapping(name, type = type, asmType = null, newName = newName, signature = null)
|
||||
}
|
||||
|
||||
operator fun get(name: String): ReifiedTypeParameterMapping? {
|
||||
@@ -226,7 +292,7 @@ public class ReifiedTypeParameterMappings() {
|
||||
}
|
||||
|
||||
public class ReifiedTypeParameterMapping(
|
||||
val name: String, val type: KotlinType?, val asmType: Type?, val newName: String?, val signature: String?
|
||||
val name: String, val type: KotlinType, val asmType: Type?, val newName: String?, val signature: String?
|
||||
)
|
||||
|
||||
public class ReifiedTypeParametersUsages {
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class RootInliningContext extends InliningContext {
|
||||
@@ -38,7 +37,7 @@ public class RootInliningContext extends InliningContext {
|
||||
@NotNull String classNameToInline,
|
||||
@NotNull ReifiedTypeInliner inliner
|
||||
) {
|
||||
super(null, map, state, nameGenerator, Collections.<String, String>emptyMap(), inliner, false, false);
|
||||
super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false);
|
||||
this.callElement = callElement;
|
||||
this.startContext = startContext;
|
||||
this.classNameToInline = classNameToInline;
|
||||
|
||||
@@ -23,14 +23,43 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TypeRemapper extends Remapper {
|
||||
//typeMapping field could be changed outside through method processing
|
||||
private final Map<String, String> typeMapping;
|
||||
|
||||
private Map<String, String> additionalMappings;
|
||||
|
||||
//typeMapping could be changed outside through method processing
|
||||
public TypeRemapper(@NotNull Map<String, String> typeMapping) {
|
||||
//typeMapping field could be changed outside through method processing
|
||||
private TypeRemapper(@NotNull Map<String, String> typeMapping) {
|
||||
this.typeMapping = typeMapping;
|
||||
}
|
||||
|
||||
public TypeRemapper(@NotNull TypeRemapper remapper, @NotNull Map<String, String> newTypeMappings) {
|
||||
this(createNewAndMerge(remapper, newTypeMappings));
|
||||
}
|
||||
|
||||
public static TypeRemapper createEmpty() {
|
||||
return new TypeRemapper(new HashMap<String, String>());
|
||||
}
|
||||
|
||||
public static TypeRemapper createFrom(Map<String, String> mappings) {
|
||||
return new TypeRemapper(mappings);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, String> createNewAndMerge(@NotNull TypeRemapper remapper, @NotNull Map<String, String> additionalTypeMappings) {
|
||||
Map<String, String> map = new HashMap<String, String>(remapper.typeMapping);
|
||||
map.putAll(additionalTypeMappings);
|
||||
return map;
|
||||
}
|
||||
|
||||
public void addMapping(String type, String newType) {
|
||||
typeMapping.put(type, newType);
|
||||
}
|
||||
|
||||
public boolean hasNoAdditionalMapping(String type) {
|
||||
return typeMapping.containsKey(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String map(String type) {
|
||||
String newType = typeMapping.get(type);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.intrinsics;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import kotlin.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -63,11 +65,12 @@ public class IntrinsicMethods {
|
||||
namedMethods.put("kotlin.javaClass.function", new JavaClassFunction());
|
||||
namedMethods.put("kotlin.javaClass.property", new JavaClassProperty());
|
||||
namedMethods.put("kotlin.KClass.java.property", new KClassJavaProperty());
|
||||
namedMethods.put("kotlin.arrays.array", new JavaClassArray());
|
||||
namedMethods.put("kotlin.jvm.internal.unsafe.monitorEnter", MonitorInstruction.MONITOR_ENTER);
|
||||
namedMethods.put("kotlin.jvm.internal.unsafe.monitorExit", MonitorInstruction.MONITOR_EXIT);
|
||||
namedMethods.put("kotlin.jvm.isArrayOf", new IsArrayOf());
|
||||
|
||||
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOf", 1, new JavaClassArray());
|
||||
|
||||
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
|
||||
for (Name method : primitiveCastMethods) {
|
||||
String methodName = method.asString();
|
||||
@@ -94,6 +97,10 @@ public class IntrinsicMethods {
|
||||
declareIntrinsicFunction(typeName, "equals", 1, EQUALS);
|
||||
declareIntrinsicFunction(typeName, "hashCode", 0, HASH_CODE);
|
||||
declareIntrinsicFunction(typeName, "toString", 0, TO_STRING);
|
||||
|
||||
intrinsicsMap.registerIntrinsic(
|
||||
BUILT_INS_PACKAGE_FQ_NAME, null, StringsKt.decapitalize(type.getArrayTypeName().asString()) + "Of", 1, new JavaClassArray()
|
||||
);
|
||||
}
|
||||
|
||||
declareBinaryOp("plus", IADD);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
}
|
||||
|
||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver().getType())
|
||||
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver()!!.getType())
|
||||
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), classType, null) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
if (isPrimitive(classType)) {
|
||||
|
||||
@@ -91,27 +91,28 @@ public class OptimizationBasicInterpreter extends BasicInterpreter {
|
||||
public BasicValue merge(
|
||||
@NotNull BasicValue v, @NotNull BasicValue w
|
||||
) {
|
||||
if (!v.equals(w)) {
|
||||
if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) {
|
||||
return BasicValue.UNINITIALIZED_VALUE;
|
||||
}
|
||||
|
||||
// if merge of two references then `lub` is java/lang/Object
|
||||
// arrays also are BasicValues with reference type's
|
||||
if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) {
|
||||
return BasicValue.REFERENCE_VALUE;
|
||||
}
|
||||
|
||||
assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays";
|
||||
|
||||
// if merge of something can be stored in int var (int, char, boolean, byte, character)
|
||||
if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE &&
|
||||
w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) {
|
||||
return BasicValue.INT_VALUE;
|
||||
}
|
||||
|
||||
if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) {
|
||||
return BasicValue.UNINITIALIZED_VALUE;
|
||||
}
|
||||
return v;
|
||||
// Objects must be equal, others can just have the same sort
|
||||
if (v.getType().getSort() == w.getType().getSort() && (v.getType().getSort() != Type.OBJECT || v.equals(w))) {
|
||||
return v;
|
||||
}
|
||||
|
||||
// if merge of two references then `lub` is java/lang/Object
|
||||
// arrays also are BasicValues with reference type's
|
||||
if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) {
|
||||
return BasicValue.REFERENCE_VALUE;
|
||||
}
|
||||
|
||||
assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays";
|
||||
|
||||
// if merge of something can be stored in int var (int, char, boolean, byte, character)
|
||||
if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE &&
|
||||
w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) {
|
||||
return BasicValue.INT_VALUE;
|
||||
}
|
||||
|
||||
return BasicValue.UNINITIALIZED_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
@@ -53,8 +52,18 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
|
||||
// Avoid errors when some classes are not loaded for some reason
|
||||
private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache, moduleName)
|
||||
private val reportDiagnosticsTasks = ArrayList<() -> Unit>()
|
||||
|
||||
fun reportDiagnostics() {
|
||||
reportDiagnosticsTasks.forEach { it() }
|
||||
reportDiagnosticsTasks.clear()
|
||||
}
|
||||
|
||||
override fun handleClashingSignatures(data: ConflictingJvmDeclarationsData) {
|
||||
reportDiagnosticsTasks.add { reportConflictingJvmSignatures(data) }
|
||||
}
|
||||
|
||||
private fun reportConflictingJvmSignatures(data: ConflictingJvmDeclarationsData) {
|
||||
val noOwnImplementations = data.signatureOrigins.all { it.originKind in EXTERNAL_SOURCES_KINDS }
|
||||
|
||||
val elements = LinkedHashSet<PsiElement>()
|
||||
@@ -82,6 +91,14 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
classOrigin: JvmDeclarationOrigin,
|
||||
classInternalName: String?,
|
||||
signatures: MultiMap<RawSignature, JvmDeclarationOrigin>
|
||||
) {
|
||||
reportDiagnosticsTasks.add { reportClashingSignaturesInHierarchy(classOrigin, classInternalName, signatures) }
|
||||
}
|
||||
|
||||
private fun reportClashingSignaturesInHierarchy(
|
||||
classOrigin: JvmDeclarationOrigin,
|
||||
classInternalName: String?,
|
||||
signatures: MultiMap<RawSignature, JvmDeclarationOrigin>
|
||||
) {
|
||||
val descriptor = classOrigin.descriptor
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
@@ -157,7 +174,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
descriptor.getParentJavaStaticClassScope()?.run {
|
||||
getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
|
||||
.filter {
|
||||
it is FunctionDescriptor && Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, it, descriptor)
|
||||
it is FunctionDescriptor && Visibilities.isVisibleWithIrrelevantReceiver(it, descriptor)
|
||||
}
|
||||
.forEach(::processMember)
|
||||
}
|
||||
@@ -165,7 +182,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
return groupedBySignature
|
||||
}
|
||||
|
||||
public fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
|
||||
private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (descriptor is SamAdapterDescriptor<*>) return true
|
||||
|
||||
return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.codegen.state
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.`when`.MappingsClassesForWhenByEnum
|
||||
@@ -28,6 +30,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
@@ -63,19 +66,20 @@ public class GenerationState @JvmOverloads constructor(
|
||||
// TODO: get rid of it with the proper module infrastructure
|
||||
public val outDirectory: File? = null,
|
||||
public val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
|
||||
public val generateOpenMultifileClasses: Boolean = false,
|
||||
public val progress: Progress = Progress.DEAF
|
||||
) {
|
||||
public abstract class GenerateClassFilter {
|
||||
public abstract fun shouldAnnotateClass(classOrObject: KtClassOrObject): Boolean
|
||||
public abstract fun shouldGenerateClass(classOrObject: KtClassOrObject): Boolean
|
||||
public abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||
public abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||
public abstract fun shouldGeneratePackagePart(jetFile: KtFile): Boolean
|
||||
public abstract fun shouldGenerateScript(script: KtScript): Boolean
|
||||
|
||||
companion object {
|
||||
public val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
|
||||
override fun shouldAnnotateClass(classOrObject: KtClassOrObject): Boolean = true
|
||||
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = true
|
||||
|
||||
override fun shouldGenerateClass(classOrObject: KtClassOrObject): Boolean = true
|
||||
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean = true
|
||||
|
||||
override fun shouldGenerateScript(script: KtScript): Boolean = true
|
||||
|
||||
@@ -96,7 +100,10 @@ public class GenerationState @JvmOverloads constructor(
|
||||
private var used = false
|
||||
|
||||
public val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace
|
||||
public val collectedExtraJvmDiagnostics: Diagnostics get() = extraJvmDiagnosticsTrace.bindingContext.diagnostics
|
||||
public val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics {
|
||||
duplicateSignatureFactory.reportDiagnostics()
|
||||
extraJvmDiagnosticsTrace.bindingContext.diagnostics
|
||||
}
|
||||
|
||||
public val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode()
|
||||
@@ -110,6 +117,7 @@ public class GenerationState @JvmOverloads constructor(
|
||||
public val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
|
||||
public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
|
||||
public val factory: ClassFileFactory
|
||||
private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics
|
||||
|
||||
public val replSpecific = ForRepl()
|
||||
|
||||
@@ -135,12 +143,13 @@ public class GenerationState @JvmOverloads constructor(
|
||||
|
||||
init {
|
||||
val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization)
|
||||
var interceptedBuilderFactory: ClassBuilderFactory = BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
duplicateSignatureFactory = BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
optimizationClassBuilderFactory, this.bindingContext, diagnostics, fileClassesProvider,
|
||||
getIncrementalCacheForThisTarget(),
|
||||
this.moduleName)
|
||||
|
||||
interceptedBuilderFactory = BuilderFactoryForDuplicateClassNameDiagnostics(interceptedBuilderFactory, diagnostics);
|
||||
var interceptedBuilderFactory: ClassBuilderFactory
|
||||
= BuilderFactoryForDuplicateClassNameDiagnostics(duplicateSignatureFactory, diagnostics)
|
||||
|
||||
val interceptExtensions = ClassBuilderInterceptorExtension.getInstances(project)
|
||||
|
||||
@@ -168,3 +177,20 @@ public class GenerationState @JvmOverloads constructor(
|
||||
interceptedBuilderFactory.close()
|
||||
}
|
||||
}
|
||||
|
||||
private class LazyJvmDiagnostics(compute: () -> Diagnostics): Diagnostics {
|
||||
private val delegate by lazy(LazyThreadSafetyMode.SYNCHRONIZED, compute)
|
||||
|
||||
override val modificationTracker: ModificationTracker
|
||||
get() = delegate.modificationTracker
|
||||
|
||||
override fun all(): Collection<Diagnostic> = delegate.all()
|
||||
|
||||
override fun forElement(psiElement: PsiElement) = delegate.forElement(psiElement)
|
||||
|
||||
override fun isEmpty() = delegate.isEmpty()
|
||||
|
||||
override fun noSuppression() = delegate.noSuppression()
|
||||
|
||||
override fun iterator() = delegate.iterator()
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.Pair;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
|
||||
@@ -50,7 +49,7 @@ import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteralExpression;
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
|
||||
@@ -405,10 +404,11 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
TypeConstructor constructor = jetType.getConstructor();
|
||||
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||
if (constructor instanceof IntersectionTypeConstructor) {
|
||||
jetType = CommonSupertypes.commonSupertype(new ArrayList<KotlinType>(constructor.getSupertypes()));
|
||||
constructor = jetType.getConstructor();
|
||||
}
|
||||
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
|
||||
|
||||
if (descriptor == null) {
|
||||
throw new UnsupportedOperationException("no descriptor for type constructor of " + jetType);
|
||||
@@ -581,7 +581,14 @@ public class JetTypeMapper {
|
||||
@NotNull TypeMappingMode mode
|
||||
) {
|
||||
if (signatureVisitor != null) {
|
||||
if (hasNothingInArguments(type) || type.getArguments().isEmpty()) {
|
||||
|
||||
// Nothing mapping rules:
|
||||
// Map<Nothing, Foo> -> Map
|
||||
// Map<Foo, List<Nothing>> -> Map<Foo, List>
|
||||
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
|
||||
// In<Nothing, Nothing> -> In
|
||||
// Inv<in Nothing, Foo> -> Inv
|
||||
if (hasNothingInNonContravariantPosition(type) || type.getArguments().isEmpty()) {
|
||||
signatureVisitor.writeAsmType(asmType);
|
||||
return;
|
||||
}
|
||||
@@ -638,7 +645,11 @@ public class JetTypeMapper {
|
||||
TypeParameterDescriptor parameter = item.getFirst();
|
||||
TypeProjection argument = item.getSecond();
|
||||
|
||||
if (argument.isStarProjection()) {
|
||||
if (
|
||||
argument.isStarProjection() ||
|
||||
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
|
||||
KotlinBuiltIns.isNothing(argument.getType()) && parameter.getVariance() == Variance.IN_VARIANCE
|
||||
) {
|
||||
signatureVisitor.writeUnboundedWildcard();
|
||||
}
|
||||
else {
|
||||
@@ -656,22 +667,22 @@ public class JetTypeMapper {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasNothingInArguments(KotlinType jetType) {
|
||||
boolean hasNothingInArguments = CollectionsKt.any(jetType.getArguments(), new Function1<TypeProjection, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(TypeProjection projection) {
|
||||
return KotlinBuiltIns.isNothingOrNullableNothing(projection.getType());
|
||||
}
|
||||
});
|
||||
private static boolean hasNothingInNonContravariantPosition(KotlinType kotlinType) {
|
||||
List<TypeParameterDescriptor> parameters = kotlinType.getConstructor().getParameters();
|
||||
List<TypeProjection> arguments = kotlinType.getArguments();
|
||||
|
||||
if (hasNothingInArguments) return true;
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
TypeProjection projection = arguments.get(i);
|
||||
|
||||
return CollectionsKt.any(jetType.getArguments(), new Function1<TypeProjection, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(TypeProjection projection) {
|
||||
return !projection.isStarProjection() && hasNothingInArguments(projection.getType());
|
||||
}
|
||||
});
|
||||
if (projection.isStarProjection()) continue;
|
||||
|
||||
KotlinType type = projection.getType();
|
||||
|
||||
if (KotlinBuiltIns.isNullableNothing(type) ||
|
||||
KotlinBuiltIns.isNothing(type) && parameters.get(i).getVariance() != Variance.IN_VARIANCE) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -748,7 +759,7 @@ public class JetTypeMapper {
|
||||
ClassDescriptor ownerForDefault = (ClassDescriptor) baseMethodDescriptor.getContainingDeclaration();
|
||||
ownerForDefaultImpl = isJvmInterface(ownerForDefault) ? mapDefaultImpls(ownerForDefault) : mapClass(ownerForDefault);
|
||||
|
||||
if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE)) {
|
||||
if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE || isAccessor(descriptor))) {
|
||||
thisClass = mapClass(currentOwner);
|
||||
if (declarationOwner instanceof JavaClassDescriptor) {
|
||||
invokeOpcode = INVOKESPECIAL;
|
||||
@@ -778,7 +789,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
FunctionDescriptor overriddenSpecialBuiltinFunction =
|
||||
SpecialBuiltinMembers.<FunctionDescriptor>getOverriddenBuiltinWithDifferentJvmDescriptor(functionDescriptor.getOriginal());
|
||||
SpecialBuiltinMembers.<FunctionDescriptor>getOverriddenBuiltinReflectingJvmDescriptor(functionDescriptor.getOriginal());
|
||||
FunctionDescriptor functionToCall = overriddenSpecialBuiltinFunction != null && !superCall
|
||||
? overriddenSpecialBuiltinFunction.getOriginal()
|
||||
: functionDescriptor.getOriginal();
|
||||
@@ -888,7 +899,7 @@ public class JetTypeMapper {
|
||||
PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
|
||||
if (element instanceof KtFunctionLiteral) {
|
||||
PsiElement expression = element.getParent();
|
||||
if (expression instanceof KtFunctionLiteralExpression) {
|
||||
if (expression instanceof KtLambdaExpression) {
|
||||
SamType samType = bindingContext.get(SAM_VALUE, (KtExpression) expression);
|
||||
if (samType != null) {
|
||||
return samType.getAbstractMethod().getName().asString();
|
||||
@@ -957,7 +968,7 @@ public class JetTypeMapper {
|
||||
public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
|
||||
if (f.getInitialSignatureDescriptor() != null && f != f.getInitialSignatureDescriptor()) {
|
||||
// Overrides of special builtin in Kotlin classes always have special signature
|
||||
if (SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(f) == null ||
|
||||
if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(f) == null ||
|
||||
f.getContainingDeclaration().getOriginal() instanceof JavaClassDescriptor) {
|
||||
return mapSignature(f.getInitialSignatureDescriptor(), kind);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ internal class TypeMappingMode private constructor(
|
||||
val skipDeclarationSiteWildcards: Boolean = false,
|
||||
val skipDeclarationSiteWildcardsIfPossible: Boolean = false,
|
||||
private val genericArgumentMode: TypeMappingMode? = null,
|
||||
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode
|
||||
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode,
|
||||
private val genericInvariantArgumentMode: TypeMappingMode? = genericArgumentMode
|
||||
) {
|
||||
companion object {
|
||||
/**
|
||||
@@ -86,11 +87,18 @@ internal class TypeMappingMode private constructor(
|
||||
else
|
||||
null
|
||||
|
||||
val invariantArgumentMode =
|
||||
if (canBeUsedInSupertypePosition)
|
||||
getOptimalModeForSignaturePart(type, isForAnnotationParameter, canBeUsedInSupertypePosition = false)
|
||||
else
|
||||
null
|
||||
|
||||
return TypeMappingMode(
|
||||
isForAnnotationParameter = isForAnnotationParameter,
|
||||
skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition,
|
||||
skipDeclarationSiteWildcardsIfPossible = true,
|
||||
genericContravariantArgumentMode = contravariantArgumentMode)
|
||||
genericContravariantArgumentMode = contravariantArgumentMode,
|
||||
genericInvariantArgumentMode = invariantArgumentMode)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@@ -107,6 +115,7 @@ internal class TypeMappingMode private constructor(
|
||||
fun toGenericArgumentMode(effectiveVariance: Variance): TypeMappingMode =
|
||||
when (effectiveVariance) {
|
||||
Variance.IN_VARIANCE -> genericContravariantArgumentMode ?: this
|
||||
Variance.INVARIANT -> genericInvariantArgumentMode ?: this
|
||||
else -> genericArgumentMode ?: this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ private fun KotlinType.canHaveSubtypesIgnoringNullability(): Boolean {
|
||||
|
||||
when (descriptor) {
|
||||
is TypeParameterDescriptor -> return true
|
||||
is ClassDescriptor -> if (descriptor.modality.isOverridable) return true
|
||||
is ClassDescriptor -> if (!descriptor.isFinalClass) return true
|
||||
}
|
||||
|
||||
for ((parameter, argument) in constructor.parameters.zip(arguments)) {
|
||||
|
||||
@@ -30,10 +30,11 @@ public class EnumSwitchCodegen extends SwitchCodegen {
|
||||
public EnumSwitchCodegen(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull WhenByEnumsMapping mapping
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
super(expression, isStatement, isExhaustive, codegen);
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,10 @@ public class IntegralConstantsSwitchCodegen extends SwitchCodegen {
|
||||
public IntegralConstantsSwitchCodegen(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
super(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -47,7 +47,7 @@ public class MappingClassesForWhenByEnumCodegen {
|
||||
cb.defineClass(
|
||||
srcFile,
|
||||
V1_6,
|
||||
ACC_FINAL | ACC_SYNTHETIC | ACC_PUBLIC,
|
||||
ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_SYNTHETIC,
|
||||
mappingsClass.getInternalName(),
|
||||
null,
|
||||
OBJECT_TYPE.getInternalName(),
|
||||
|
||||
@@ -40,9 +40,10 @@ public class StringSwitchCodegen extends SwitchCodegen {
|
||||
public StringSwitchCodegen(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
super(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.*;
|
||||
abstract public class SwitchCodegen {
|
||||
protected final KtWhenExpression expression;
|
||||
protected final boolean isStatement;
|
||||
protected final boolean isExhaustive;
|
||||
protected final ExpressionCodegen codegen;
|
||||
protected final BindingContext bindingContext;
|
||||
protected final Type subjectType;
|
||||
@@ -49,10 +50,11 @@ abstract public class SwitchCodegen {
|
||||
|
||||
public SwitchCodegen(
|
||||
@NotNull KtWhenExpression expression, boolean isStatement,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
boolean isExhaustive, @NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
this.expression = expression;
|
||||
this.isStatement = isStatement;
|
||||
this.isExhaustive = isExhaustive;
|
||||
this.codegen = codegen;
|
||||
this.bindingContext = codegen.getBindingContext();
|
||||
|
||||
@@ -70,7 +72,7 @@ abstract public class SwitchCodegen {
|
||||
boolean hasElse = expression.getElseExpression() != null;
|
||||
|
||||
// if there is no else-entry and it's statement then default --- endLabel
|
||||
defaultLabel = (hasElse || !isStatement) ? elseLabel : endLabel;
|
||||
defaultLabel = (hasElse || !isStatement || isExhaustive) ? elseLabel : endLabel;
|
||||
|
||||
generateSubject();
|
||||
|
||||
@@ -79,9 +81,9 @@ abstract public class SwitchCodegen {
|
||||
generateEntries();
|
||||
|
||||
// there is no else-entry but this is not statement, so we should return Unit
|
||||
if (!hasElse && !isStatement) {
|
||||
if (!hasElse && (!isStatement || isExhaustive)) {
|
||||
v.visitLabel(elseLabel);
|
||||
codegen.putUnitInstanceOntoStackForNonExhaustiveWhen(expression);
|
||||
codegen.putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
|
||||
}
|
||||
|
||||
codegen.markLineNumber(expression, isStatement);
|
||||
|
||||
@@ -102,6 +102,7 @@ public class SwitchCodegenUtil {
|
||||
public static SwitchCodegen buildAppropriateSwitchCodegenIfPossible(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
BindingContext bindingContext = codegen.getBindingContext();
|
||||
@@ -114,15 +115,15 @@ public class SwitchCodegenUtil {
|
||||
WhenByEnumsMapping mapping = codegen.getBindingContext().get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression);
|
||||
|
||||
if (mapping != null) {
|
||||
return new EnumSwitchCodegen(expression, isStatement, codegen, mapping);
|
||||
return new EnumSwitchCodegen(expression, isStatement, isExhaustive, codegen, mapping);
|
||||
}
|
||||
|
||||
if (isIntegralConstantsSwitch(expression, subjectType, bindingContext)) {
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, codegen);
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
if (isStringConstantsSwitch(expression, subjectType, bindingContext)) {
|
||||
return new StringSwitchCodegen(expression, isStatement, codegen);
|
||||
return new StringSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -16,27 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.serialization.builtins
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.constants.NullValue
|
||||
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.serialization.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
public class BuiltInsSerializerExtension : SerializerExtension() {
|
||||
private val stringTable = StringTableImpl()
|
||||
private val annotationSerializer = AnnotationSerializer(stringTable)
|
||||
|
||||
override fun getStringTable(): StringTable = stringTable
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
|
||||
public class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
||||
override fun shouldUseTypeTable(): Boolean = true
|
||||
|
||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
||||
for (annotation in descriptor.annotations) {
|
||||
proto.addExtension(BuiltInsProtoBuf.classAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializePackage(packageFragments: Collection<PackageFragmentDescriptor>, proto: ProtoBuf.Package.Builder) {
|
||||
if (packageFragments.isEmpty()) return
|
||||
|
||||
val classes = packageFragments.flatMap {
|
||||
it.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance<ClassDescriptor>()
|
||||
}
|
||||
@@ -44,40 +37,7 @@ public class BuiltInsSerializerExtension : SerializerExtension() {
|
||||
for (descriptor in DescriptorSerializer.sort(classes)) {
|
||||
proto.addExtension(BuiltInsProtoBuf.className, stringTable.getSimpleNameIndex(descriptor.name))
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeConstructor(descriptor: ConstructorDescriptor, proto: ProtoBuf.Constructor.Builder) {
|
||||
for (annotation in descriptor.annotations) {
|
||||
proto.addExtension(BuiltInsProtoBuf.constructorAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
|
||||
for (annotation in descriptor.annotations) {
|
||||
proto.addExtension(BuiltInsProtoBuf.functionAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
|
||||
for (annotation in descriptor.annotations) {
|
||||
proto.addExtension(BuiltInsProtoBuf.propertyAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||
}
|
||||
val compileTimeConstant = descriptor.compileTimeInitializer ?: return
|
||||
if (compileTimeConstant !is NullValue) {
|
||||
val valueProto = annotationSerializer.valueProto(compileTimeConstant)
|
||||
proto.setExtension(BuiltInsProtoBuf.compileTimeValue, valueProto.build())
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeValueParameter(descriptor: ValueParameterDescriptor, proto: ProtoBuf.ValueParameter.Builder) {
|
||||
for (annotation in descriptor.annotations) {
|
||||
proto.addExtension(BuiltInsProtoBuf.parameterAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||
}
|
||||
}
|
||||
|
||||
override fun serializeType(type: KotlinType, proto: ProtoBuf.Type.Builder) {
|
||||
for (annotation in type.annotations) {
|
||||
proto.addExtension(BuiltInsProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||
}
|
||||
proto.setExtension(BuiltInsProtoBuf.packageFqName, stringTable.getPackageFqNameIndex(packageFragments.first().fqName))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,3 +17,11 @@
|
||||
package org.jetbrains.kotlin.cli.common
|
||||
|
||||
public val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = "kotlin.environment.keepalive"
|
||||
|
||||
|
||||
fun String?.toBooleanLenient(): Boolean? = when (this?.toLowerCase()) {
|
||||
null -> false
|
||||
in listOf("", "yes", "true", "on", "y") -> true
|
||||
in listOf("no", "false", "off", "n") -> false
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -64,6 +64,9 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
@Argument(value = "Xreport-perf", description = "Report detailed performance statistics")
|
||||
public boolean reportPerf;
|
||||
|
||||
@Argument(value = "Xmultifile-facades-open", description = "Compile multifile facade classes as open")
|
||||
public boolean multifileFacadesOpen;
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
public String[] friendPaths;
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GroupingMessageCollector implements MessageCollector {
|
||||
|
||||
private final MessageCollector delegate;
|
||||
@@ -48,13 +50,14 @@ public class GroupingMessageCollector implements MessageCollector {
|
||||
public void flush() {
|
||||
boolean hasError = false;
|
||||
|
||||
for (String path : groupedMessages.keySet()) {
|
||||
Collection<String> keys = sortedKeys();
|
||||
for (String path : keys) {
|
||||
for (Message message : groupedMessages.get(path)) {
|
||||
hasError |= CompilerMessageSeverity.ERRORS.contains(message.severity);
|
||||
}
|
||||
}
|
||||
|
||||
for (String path : groupedMessages.keySet()) {
|
||||
for (String path : keys) {
|
||||
for (Message message : groupedMessages.get(path)) {
|
||||
if (!hasError || CompilerMessageSeverity.ERRORS.contains(message.severity)) {
|
||||
delegate.report(message.severity, message.message, message.location);
|
||||
@@ -65,6 +68,22 @@ public class GroupingMessageCollector implements MessageCollector {
|
||||
groupedMessages.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<String> sortedKeys() {
|
||||
List<String> sortedKeys = new ArrayList<String>(groupedMessages.keySet());
|
||||
// ensure that messages with no location i.e. perf, incomplete hierarchy are always reported first
|
||||
Collections.sort(sortedKeys, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
if (o1 == o2) return 0;
|
||||
if (o1 == null) return -1;
|
||||
if (o2 == null) return 1;
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
});
|
||||
return sortedKeys;
|
||||
}
|
||||
|
||||
private static class Message {
|
||||
private final CompilerMessageSeverity severity;
|
||||
private final String message;
|
||||
|
||||
@@ -275,6 +275,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions)
|
||||
configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline)
|
||||
configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize)
|
||||
configuration.put(JVMConfigurationKeys.MULTIFILE_FACADES_OPEN, arguments.multifileFacadesOpen);
|
||||
}
|
||||
|
||||
private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> {
|
||||
|
||||
@@ -80,11 +80,13 @@ public class CliLightClassGenerationSupport(project: Project) : LightClassGenera
|
||||
}
|
||||
|
||||
override fun getContextForPackage(files: Collection<KtFile>): LightClassConstructionContext {
|
||||
return getContext()
|
||||
return LightClassConstructionContext(bindingContext, module)
|
||||
}
|
||||
|
||||
override fun getContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
|
||||
return getContext()
|
||||
//force resolve companion for light class generation
|
||||
bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||
return LightClassConstructionContext(bindingContext, module)
|
||||
}
|
||||
|
||||
private fun getContext(): LightClassConstructionContext {
|
||||
|
||||
@@ -35,7 +35,9 @@ import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.PersistentFSConstants
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.FileContextProvider
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
@@ -60,6 +62,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
|
||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
@@ -110,6 +113,10 @@ public class KotlinCoreEnvironment private constructor(
|
||||
it
|
||||
}
|
||||
|
||||
init {
|
||||
PersistentFSConstants.setMaxIntellisenseFileSize(FileUtilRt.LARGE_FOR_CONTENT_LOADING)
|
||||
}
|
||||
|
||||
init {
|
||||
val project = projectEnvironment.getProject()
|
||||
project.registerService(javaClass<DeclarationProviderFactoryService>(), CliDeclarationProviderFactoryService(sourceFiles))
|
||||
@@ -258,7 +265,7 @@ public class KotlinCoreEnvironment private constructor(
|
||||
val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration, configFilePaths)
|
||||
// Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally
|
||||
// breaks a lot of tests, therefore it is disabled for production and enabled for tests
|
||||
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null) {
|
||||
if (!(System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY).toBooleanLenient() ?: false)) {
|
||||
// JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ)
|
||||
// All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well
|
||||
Disposer.register(parentDisposable, object : Disposable {
|
||||
@@ -312,8 +319,7 @@ public class KotlinCoreEnvironment private constructor(
|
||||
|
||||
public fun disposeApplicationEnvironment() {
|
||||
synchronized (APPLICATION_LOCK) {
|
||||
if (ourApplicationEnvironment == null) return
|
||||
val environment = ourApplicationEnvironment
|
||||
val environment = ourApplicationEnvironment ?: return
|
||||
ourApplicationEnvironment = null
|
||||
Disposer.dispose(environment.getParentDisposable())
|
||||
}
|
||||
|
||||
@@ -438,7 +438,8 @@ public class KotlinToJVMBytecodeCompiler {
|
||||
targetId,
|
||||
moduleName,
|
||||
outputDirectory,
|
||||
incrementalCompilationComponents
|
||||
incrementalCompilationComponents,
|
||||
configuration.get(JVMConfigurationKeys.MULTIFILE_FACADES_OPEN, false)
|
||||
);
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ public class JVMConfigurationKeys {
|
||||
CompilerConfigurationKey.create("disable inline");
|
||||
public static final CompilerConfigurationKey<Boolean> DISABLE_OPTIMIZATION =
|
||||
CompilerConfigurationKey.create("disable optimization");
|
||||
public static final CompilerConfigurationKey<Boolean> MULTIFILE_FACADES_OPEN =
|
||||
CompilerConfigurationKey.create("compile multifile facade classes as open");
|
||||
|
||||
public static final CompilerConfigurationKey<IncrementalCompilationComponents> INCREMENTAL_COMPILATION_COMPONENTS =
|
||||
CompilerConfigurationKey.create("incremental cache provider");
|
||||
|
||||
@@ -65,7 +65,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM;
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession;
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.JetClassLikeInfo;
|
||||
import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo;
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.*;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
@@ -478,7 +478,7 @@ public class ReplInterpreter {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassMemberDeclarationProvider getClassMemberDeclarationProvider(@NotNull JetClassLikeInfo classLikeInfo) {
|
||||
public ClassMemberDeclarationProvider getClassMemberDeclarationProvider(@NotNull KtClassLikeInfo classLikeInfo) {
|
||||
return delegateFactory.getClassMemberDeclarationProvider(classLikeInfo);
|
||||
}
|
||||
|
||||
@@ -492,6 +492,11 @@ public class ReplInterpreter {
|
||||
return this.delegateFactory.getPackageMemberDeclarationProvider(packageFqName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diagnoseMissingPackageFragment(KtFile file) {
|
||||
this.delegateFactory.diagnoseMissingPackageFragment(file);
|
||||
}
|
||||
|
||||
public static class AdaptablePackageMemberDeclarationProvider extends DelegatePackageMemberDeclarationProvider {
|
||||
@NotNull
|
||||
private PackageMemberDeclarationProvider delegateProvider;
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.JavaClassFinderPostConstruct
|
||||
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
|
||||
import org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.TopLevelDescriptorProvider
|
||||
@@ -54,9 +53,8 @@ class ReplFileScopeProvider(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
qualifiedExpressionResolver: QualifiedExpressionResolver,
|
||||
bindingTrace: BindingTrace,
|
||||
ktImportsFactory: KtImportsFactory,
|
||||
additionalScopes: Iterable<FileScopeProvider.AdditionalScopes>
|
||||
) : FileScopeProviderImpl(topLevelDescriptorProvider, storageManager, moduleDescriptor, qualifiedExpressionResolver, bindingTrace, ktImportsFactory, additionalScopes) {
|
||||
ktImportsFactory: KtImportsFactory
|
||||
) : FileScopeProviderImpl(topLevelDescriptorProvider, storageManager, moduleDescriptor, qualifiedExpressionResolver, bindingTrace, ktImportsFactory) {
|
||||
|
||||
override fun getFileResolutionScope(file: KtFile): LexicalScope
|
||||
= lastLineScopeProvider.lastLineScope ?: super.getFileResolutionScope(file)
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="junit-4.12" level="project" />
|
||||
<orderEntry type="library" exported="" name="javax.inject" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="kotlin-test" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.client
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
|
||||
import org.jetbrains.kotlin.daemon.common.RmiFriendlyCompilationCancelledException
|
||||
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
|
||||
import org.jetbrains.kotlin.incremental.components.LookupInfo
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
@@ -80,6 +82,13 @@ class CompilerCallbackServicesFacadeServer(
|
||||
override fun lookupTracker_isDoNothing(): Boolean = lookupTracker_isDoNothing
|
||||
|
||||
override fun compilationCanceledStatus_checkCanceled() {
|
||||
compilationCancelledStatus!!.checkCanceled()
|
||||
try {
|
||||
compilationCancelledStatus!!.checkCanceled()
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
// avoid passing exceptions that may have different serialVersionUID on across rmi border
|
||||
// TODO: doublecheck whether we need to distinguish different cancellation exceptions
|
||||
throw RmiFriendlyCompilationCancelledException()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.daemon.common
|
||||
import org.jetbrains.kotlin.incremental.components.LookupInfo
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import java.io.Serializable
|
||||
import java.rmi.Remote
|
||||
import java.rmi.RemoteException
|
||||
|
||||
@@ -81,7 +82,13 @@ interface CompilerCallbackServicesFacade : Remote {
|
||||
|
||||
// ----------------------------------------------------
|
||||
// CompilationCanceledStatus
|
||||
@Throws(RemoteException::class)
|
||||
@Throws(RemoteException::class, RmiFriendlyCompilationCancelledException::class)
|
||||
fun compilationCanceledStatus_checkCanceled(): Unit
|
||||
}
|
||||
|
||||
|
||||
class RmiFriendlyCompilationCancelledException: Exception(), Serializable {
|
||||
companion object {
|
||||
private val serialVersionUID: Long = 8228357578L // just a random number, but should never be changed to avoid deserialization problems
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.daemon
|
||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
@@ -75,6 +76,10 @@ class CompileServiceImpl(
|
||||
val onShutdown: () -> Unit
|
||||
) : CompileService {
|
||||
|
||||
init {
|
||||
System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
|
||||
}
|
||||
|
||||
// wrapped in a class to encapsulate alive check logic
|
||||
private class ClientOrSessionProxy(val aliveFlagPath: String?) {
|
||||
val registered = nowSeconds()
|
||||
|
||||
@@ -61,7 +61,7 @@ class LazyClasspathWatcher(classpath: Iterable<String>,
|
||||
fileIds = classpath
|
||||
.map { File(it) }
|
||||
.asSequence()
|
||||
.flatMap { FileTreeWalk(it, filter = ::isClasspathFile) }
|
||||
.flatMap { it.walk().filter(::isClasspathFile) }
|
||||
.map { FileId(it, it.lastModified(), it.md5Digest()) }
|
||||
.toArrayList()
|
||||
val nowMs = TimeUnit.MILLISECONDS.toMillis(System.nanoTime())
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.DummyProfiler
|
||||
import org.jetbrains.kotlin.daemon.common.Profiler
|
||||
import org.jetbrains.kotlin.daemon.common.RmiFriendlyCompilationCancelledException
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledException
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
val CANCELED_STATUS_CHECK_THRESHOLD_NS = TimeUnit.MILLISECONDS.toNanos(100)
|
||||
@@ -30,7 +32,12 @@ class RemoteCompilationCanceledStatusClient(val facade: CompilerCallbackServices
|
||||
val curNanos = System.nanoTime()
|
||||
if (curNanos - lastChecked > CANCELED_STATUS_CHECK_THRESHOLD_NS) {
|
||||
profiler.withMeasure(this) {
|
||||
facade.compilationCanceledStatus_checkCanceled()
|
||||
try {
|
||||
facade.compilationCanceledStatus_checkCanceled()
|
||||
}
|
||||
catch (e: RmiFriendlyCompilationCancelledException) {
|
||||
throw CompilationCanceledException()
|
||||
}
|
||||
}
|
||||
lastChecked = curNanos
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.container.*
|
||||
import org.jetbrains.kotlin.context.LazyResolveToken
|
||||
import org.jetbrains.kotlin.context.ModuleContext
|
||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.frontend.di.configureModule
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
|
||||
import org.jetbrains.kotlin.load.java.JavaFlexibleTypeCapabilitiesProvider
|
||||
import org.jetbrains.kotlin.load.java.components.*
|
||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver
|
||||
import org.jetbrains.kotlin.load.java.sam.SamConversionResolverImpl
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaPropertyInitializerEvaluatorImpl
|
||||
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.synthetic.AdditionalScopesWithJavaSyntheticExtensions
|
||||
|
||||
public fun StorageComponentContainer.configureJavaTopDownAnalysis(moduleContentScope: GlobalSearchScope, project: Project, lookupTracker: LookupTracker) {
|
||||
useInstance(moduleContentScope)
|
||||
@@ -65,7 +64,6 @@ public fun StorageComponentContainer.configureJavaTopDownAnalysis(moduleContentS
|
||||
useImpl<JavaSourceElementFactoryImpl>()
|
||||
useImpl<JavaLazyAnalyzerPostConstruct>()
|
||||
useImpl<JavaFlexibleTypeCapabilitiesProvider>()
|
||||
useImpl<AdditionalScopesWithJavaSyntheticExtensions>()
|
||||
}
|
||||
|
||||
public fun createContainerForLazyResolveWithJava(
|
||||
|
||||
@@ -27,10 +27,8 @@ import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.upperIfFlexible
|
||||
|
||||
public class RuntimeAssertionInfo(public val needNotNullAssertion: Boolean, public val message: String) {
|
||||
public interface DataFlowExtras {
|
||||
@@ -53,7 +51,7 @@ public class RuntimeAssertionInfo(public val needNotNullAssertion: Boolean, publ
|
||||
dataFlowExtras: DataFlowExtras
|
||||
): RuntimeAssertionInfo? {
|
||||
fun assertNotNull(): Boolean {
|
||||
if (expectedType.isError() || expressionType.isError()) return false
|
||||
if (expectedType.isError || expressionType.isError) return false
|
||||
|
||||
// T : Any, T! = T..T?
|
||||
// Let T$ will be copy of T! with enhanced nullability.
|
||||
@@ -94,7 +92,7 @@ public object RuntimeAssertionsTypeChecker : AdditionalTypeChecker {
|
||||
override val canBeNull: Boolean
|
||||
get() = c.dataFlowInfo.getPredictableNullability(dataFlowValue).canBeNull()
|
||||
override val possibleTypes: Set<KotlinType>
|
||||
get() = c.dataFlowInfo.getPossibleTypes(dataFlowValue)
|
||||
get() = c.dataFlowInfo.getCollectedTypes(dataFlowValue)
|
||||
override val presentableText: String
|
||||
get() = StringUtil.trimMiddle(expression.getText(), 50)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition;
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
@@ -28,20 +29,30 @@ import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import java.util.List;
|
||||
|
||||
public class SamAdapterOverridabilityCondition implements ExternalOverridabilityCondition {
|
||||
@NotNull
|
||||
@Override
|
||||
public boolean isOverridable(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||
if (!(subDescriptor instanceof SimpleFunctionDescriptor)) {
|
||||
return true;
|
||||
public Result isOverridable(
|
||||
@NotNull CallableDescriptor superDescriptor,
|
||||
@NotNull CallableDescriptor subDescriptor,
|
||||
@Nullable ClassDescriptor subClassDescriptor
|
||||
) {
|
||||
if (!(subDescriptor instanceof SimpleFunctionDescriptor) || !(superDescriptor instanceof SimpleFunctionDescriptor)) {
|
||||
return Result.UNKNOWN;
|
||||
}
|
||||
|
||||
SimpleFunctionDescriptor superOriginal = getOriginalOfSamAdapterFunction((SimpleFunctionDescriptor) superDescriptor);
|
||||
SimpleFunctionDescriptor subOriginal = getOriginalOfSamAdapterFunction((SimpleFunctionDescriptor) subDescriptor);
|
||||
if (superOriginal == null || subOriginal == null) { // super or sub is/overrides DECLARATION
|
||||
return subOriginal == null; // DECLARATION can override anything
|
||||
return subOriginal == null ? Result.UNKNOWN : Result.INCOMPATIBLE; // DECLARATION can override anything
|
||||
}
|
||||
|
||||
OverridingUtil.OverrideCompatibilityInfo basicResult = OverridingUtil.DEFAULT
|
||||
.isOverridableByWithoutExternalConditions(superDescriptor, subDescriptor, /* checkReturnType = */ false);
|
||||
|
||||
if (basicResult.getResult() != OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) return Result.UNKNOWN;
|
||||
|
||||
// inheritor if SYNTHESIZED can override inheritor of SYNTHESIZED if their originals have same erasure
|
||||
return equalErasure(superOriginal, subOriginal);
|
||||
return equalErasure(superOriginal, subOriginal) ? Result.UNKNOWN : Result.INCOMPATIBLE;
|
||||
}
|
||||
|
||||
private static boolean equalErasure(@NotNull FunctionDescriptor fun1, @NotNull FunctionDescriptor fun2) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.load.java.structure.impl;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.load.java.structure.*;
|
||||
@@ -113,8 +112,8 @@ public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implement
|
||||
|
||||
// parameters including ones from outer class
|
||||
Iterable<PsiTypeParameter> parameters = classifier instanceof JavaClassImpl
|
||||
? getReversedTypeParameters((JavaClassImpl) classifier)
|
||||
: Collections.<PsiTypeParameter>emptyList();
|
||||
? getTypeParameters(((JavaClassImpl) classifier).getPsi())
|
||||
: Collections.<PsiTypeParameter>emptyList();
|
||||
|
||||
JavaTypeSubstitutor substitutor = getSubstitutor();
|
||||
|
||||
@@ -126,16 +125,32 @@ public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implement
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Collection<PsiTypeParameter> getReversedTypeParameters(@NotNull JavaClassImpl classifier) {
|
||||
Iterable<PsiTypeParameter> parameters = PsiUtil.typeParametersIterable(classifier.getPsi());
|
||||
List<PsiTypeParameter> result = new ArrayList<PsiTypeParameter>();
|
||||
// Copy-pasted from PsiUtil.typeParametersIterable
|
||||
// The only change is using `Collections.addAll(result, typeParameters)` instead of reversing type parameters of `currentOwner`
|
||||
// Result differs in cases like:
|
||||
// class Outer<H1> {
|
||||
// class Inner<H2, H3> {}
|
||||
// }
|
||||
//
|
||||
// PsiUtil.typeParametersIterable returns H3, H2, H1
|
||||
// But we would like to have H2, H3, H1 as such order is consistent with our type representation
|
||||
@NotNull
|
||||
public static List<PsiTypeParameter> getTypeParameters(@NotNull PsiClass owner) {
|
||||
List<PsiTypeParameter> result = null;
|
||||
|
||||
for (PsiTypeParameter parameter : parameters) {
|
||||
result.add(parameter);
|
||||
PsiTypeParameterListOwner currentOwner = owner;
|
||||
while (currentOwner != null) {
|
||||
PsiTypeParameter[] typeParameters = currentOwner.getTypeParameters();
|
||||
if (typeParameters.length > 0) {
|
||||
if (result == null) result = new ArrayList<PsiTypeParameter>(typeParameters.length);
|
||||
Collections.addAll(result, typeParameters);
|
||||
}
|
||||
|
||||
if (currentOwner.hasModifierProperty(PsiModifier.STATIC)) break;
|
||||
currentOwner = currentOwner.getContainingClass();
|
||||
}
|
||||
|
||||
Collections.reverse(result);
|
||||
|
||||
if (result == null) return Collections.emptyList();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin;
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class KotlinBinaryClassCache implements Disposable {
|
||||
private static class RequestCache {
|
||||
VirtualFile virtualFile;
|
||||
long modificationStamp;
|
||||
VirtualFileKotlinClass virtualFileKotlinClass;
|
||||
|
||||
public VirtualFileKotlinClass cache(VirtualFile file, VirtualFileKotlinClass aClass) {
|
||||
virtualFile = file;
|
||||
virtualFileKotlinClass = aClass;
|
||||
modificationStamp = file.getModificationStamp();
|
||||
|
||||
return aClass;
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadLocal<RequestCache> cache =
|
||||
new ThreadLocal<RequestCache>() {
|
||||
@Override
|
||||
protected RequestCache initialValue() {
|
||||
return new RequestCache();
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
public static KotlinJvmBinaryClass getKotlinBinaryClass(@NotNull final VirtualFile file) {
|
||||
if (file.getFileType() != JavaClassFileType.INSTANCE) return null;
|
||||
|
||||
KotlinBinaryClassCache service = ServiceManager.getService(KotlinBinaryClassCache.class);
|
||||
RequestCache requestCache = service.cache.get();
|
||||
|
||||
if (file.getModificationStamp() == requestCache.modificationStamp && file.equals(requestCache.virtualFile)) {
|
||||
return requestCache.virtualFileKotlinClass;
|
||||
}
|
||||
else {
|
||||
VirtualFileKotlinClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFileKotlinClass>() {
|
||||
@Override
|
||||
public VirtualFileKotlinClass compute() {
|
||||
//noinspection deprecation
|
||||
return VirtualFileKotlinClass.Factory.create(file);
|
||||
}
|
||||
});
|
||||
|
||||
return requestCache.cache(file, aClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// This is only relevant for tests. We create a new instance of Application for each test, and so a new instance of this service is
|
||||
// also created for each test. However all tests share the same event dispatch thread, which would collect all instances of this
|
||||
// thread-local if they're not removed properly. Each instance would transitively retain VFS resulting in OutOfMemoryError
|
||||
cache.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
|
||||
class KotlinBinaryClassCache : Disposable {
|
||||
private class RequestCache {
|
||||
internal var virtualFile: VirtualFile? = null
|
||||
internal var modificationStamp: Long = 0
|
||||
internal var virtualFileKotlinClass: VirtualFileKotlinClass? = null
|
||||
|
||||
fun cache(file: VirtualFile, aClass: VirtualFileKotlinClass?): VirtualFileKotlinClass? {
|
||||
virtualFile = file
|
||||
virtualFileKotlinClass = aClass
|
||||
modificationStamp = file.modificationStamp
|
||||
|
||||
return aClass
|
||||
}
|
||||
}
|
||||
|
||||
private val cache = object : ThreadLocal<RequestCache>() {
|
||||
override fun initialValue(): RequestCache {
|
||||
return RequestCache()
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
// This is only relevant for tests. We create a new instance of Application for each test, and so a new instance of this service is
|
||||
// also created for each test. However all tests share the same event dispatch thread, which would collect all instances of this
|
||||
// thread-local if they're not removed properly. Each instance would transitively retain VFS resulting in OutOfMemoryError
|
||||
cache.remove()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun getKotlinBinaryClass(file: VirtualFile, fileContent: ByteArray? = null): KotlinJvmBinaryClass? {
|
||||
if (file.fileType !== JavaClassFileType.INSTANCE) return null
|
||||
|
||||
val service = ServiceManager.getService(KotlinBinaryClassCache::class.java)
|
||||
val requestCache = service.cache.get()
|
||||
|
||||
if (file.modificationStamp == requestCache.modificationStamp && file == requestCache.virtualFile) {
|
||||
return requestCache.virtualFileKotlinClass
|
||||
}
|
||||
else {
|
||||
val aClass = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
//noinspection deprecation
|
||||
VirtualFileKotlinClass.create(file, fileContent)
|
||||
})
|
||||
|
||||
return requestCache.cache(file, aClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,12 @@ public class VirtualFileKotlinClass private constructor(
|
||||
private val perfCounter = PerformanceCounter.create("Binary class from Kotlin file")
|
||||
|
||||
@Deprecated("Use KotlinBinaryClassCache")
|
||||
fun create(file: VirtualFile): VirtualFileKotlinClass? {
|
||||
fun create(file: VirtualFile, fileContent: ByteArray?): VirtualFileKotlinClass? {
|
||||
return perfCounter.time {
|
||||
assert(file.getFileType() == JavaClassFileType.INSTANCE) { "Trying to read binary data from a non-class file $file" }
|
||||
|
||||
try {
|
||||
val byteContent = file.contentsToByteArray(false)
|
||||
val byteContent = fileContent ?: file.contentsToByteArray(false)
|
||||
if (!byteContent.isEmpty()) {
|
||||
return@time FileBasedKotlinClass.create(byteContent) {
|
||||
name, header, innerClasses ->
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.PackageData
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
@@ -130,7 +130,7 @@ public class IncrementalPackageFragmentProvider(
|
||||
MemberScope.Empty
|
||||
}
|
||||
else {
|
||||
ChainedScope("Member scope for incremental compilation: union of package parts data", *scopes.toTypedArray())
|
||||
ChainedMemberScope("Member scope for incremental compilation: union of package parts data", scopes)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,9 +153,9 @@ public class IncrementalPackageFragmentProvider(
|
||||
MemberScope.Empty
|
||||
else {
|
||||
val scopes = partsData.map { IncrementalPackageScope(JvmProtoBufUtil.readPackageDataFrom(it.data, it.strings)) }
|
||||
ChainedScope(
|
||||
ChainedMemberScope(
|
||||
"Member scope for incremental compilation: union of multifile class parts data for $multifileClassFqName",
|
||||
*scopes.toTypedArray<MemberScope>())
|
||||
scopes)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class JavaClassOnCompanionChecker : CallChecker {
|
||||
if (descriptor !is PropertyDescriptor || descriptor.name.asString() != "javaClass") return
|
||||
|
||||
val container = descriptor.containingDeclaration
|
||||
if (container !is PackageFragmentDescriptor || container.fqName.asString() != "kotlin") return
|
||||
if (container !is PackageFragmentDescriptor || container.fqName.asString() != "kotlin.jvm") return
|
||||
|
||||
val actualType = descriptor.type
|
||||
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.isInsideJvmMultifileClassFile
|
||||
@@ -35,12 +32,10 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
|
||||
class JvmFieldApplicabilityChecker : DeclarationChecker {
|
||||
|
||||
enum class Problem(val errorMessage: String) {
|
||||
NOT_A_PROPERTY("JvmField can only be applied to a property"),
|
||||
internal enum class Problem(val errorMessage: String) {
|
||||
NOT_FINAL("JvmField can only be applied to final property"),
|
||||
PRIVATE("JvmField has no effect on a private property"),
|
||||
CUSTOM_ACCESSOR("JvmField cannot be applied to a property with a custom accessor"),
|
||||
NO_BACKING_FIELD("JvmField can only be applied to a property with backing field"),
|
||||
OVERRIDES("JvmField cannot be applied to a property that overrides some other property"),
|
||||
LATEINIT("JvmField cannot be applied to lateinit property"),
|
||||
CONST("JvmField cannot be applied to const property"),
|
||||
@@ -57,10 +52,11 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
||||
val annotation = descriptor.findJvmFieldAnnotation() ?: return
|
||||
|
||||
val problem = when {
|
||||
descriptor !is PropertyDescriptor -> NOT_A_PROPERTY
|
||||
descriptor.modality.isOverridable -> NOT_FINAL
|
||||
// First two cases just prevent duplication of WRONG_ANNOTATION_TARGET
|
||||
descriptor !is PropertyDescriptor -> return
|
||||
!descriptor.hasBackingField(bindingContext) -> return
|
||||
descriptor.isOverridable -> NOT_FINAL
|
||||
Visibilities.isPrivate(descriptor.visibility) -> PRIVATE
|
||||
!descriptor.hasBackingField(bindingContext) -> NO_BACKING_FIELD
|
||||
descriptor.hasCustomAccessor() -> CUSTOM_ACCESSOR
|
||||
descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES
|
||||
descriptor.isLateInit -> LATEINIT
|
||||
|
||||
@@ -33,7 +33,7 @@ object JvmSimpleNameBacktickChecker : IdentifierChecker {
|
||||
}
|
||||
|
||||
override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) {
|
||||
if (declaration is KtMultiDeclaration) {
|
||||
if (declaration is KtDestructuringDeclaration) {
|
||||
declaration.entries.forEach { checkNamed(it, diagnosticHolder) }
|
||||
}
|
||||
if (declaration is KtCallableDeclaration) {
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.NEED_SYNTHETIC_ACCESSOR;
|
||||
|
||||
public class NeedSyntheticChecker implements CallChecker {
|
||||
|
||||
@Override
|
||||
public <F extends CallableDescriptor> void check(
|
||||
@NotNull ResolvedCall<F> resolvedCall,
|
||||
@NotNull BasicCallResolutionContext context
|
||||
) {
|
||||
CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor();
|
||||
if (needSyntheticAccessor(context.scope, targetDescriptor)) {
|
||||
context.trace.record(NEED_SYNTHETIC_ACCESSOR, (CallableMemberDescriptor) targetDescriptor.getOriginal(), Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//Necessary synthetic accessors in outer classes generated via old logic: CodegenContext.getAccessor
|
||||
//Generation of accessors in nested classes (to invoke from outer,
|
||||
// e.g.: from class to companion object) controlled via NEED_SYNTHETIC_ACCESSOR slice
|
||||
private static boolean needSyntheticAccessor(LexicalScope invokationScope, CallableDescriptor targetDescriptor) {
|
||||
return targetDescriptor instanceof CallableMemberDescriptor &&
|
||||
isPrivate(targetDescriptor) &&
|
||||
targetDescriptor.getContainingDeclaration() != invokationScope.getOwnerDescriptor().getContainingDeclaration();
|
||||
}
|
||||
|
||||
private static boolean isPrivate(@NotNull CallableDescriptor targetDescriptor) {
|
||||
return Visibilities.isPrivate(targetDescriptor.getVisibility()) ||
|
||||
(targetDescriptor instanceof PropertyDescriptor &&
|
||||
((PropertyDescriptor) targetDescriptor).getSetter() != null &&
|
||||
Visibilities.isPrivate(((PropertyDescriptor) targetDescriptor).getSetter().getVisibility()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.usesDefaultArguments
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
|
||||
class SuperCallWithDefaultArgumentsChecker : CallChecker {
|
||||
override fun <F : CallableDescriptor> check(resolvedCall: ResolvedCall<F>, context: BasicCallResolutionContext) {
|
||||
val superCallExpression = getSuperCallExpression(resolvedCall.call)
|
||||
if (superCallExpression == null || !resolvedCall.usesDefaultArguments()) return
|
||||
context.trace.report(ErrorsJvm.SUPER_CALL_WITH_DEFAULT_PARAMETERS.on(superCallExpression.parent, resolvedCall.resultingDescriptor.name.asString()))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
|
||||
class UnsupportedSyntheticCallableReferenceChecker : CallChecker {
|
||||
override fun <F : CallableDescriptor> check(resolvedCall: ResolvedCall<F>, context: BasicCallResolutionContext) {
|
||||
val expression = context.call.callElement
|
||||
if (expression !is KtNameReferenceExpression || expression.parent !is KtCallableReferenceExpression) return
|
||||
|
||||
// TODO: support references to synthetic Java extension properties (KT-8575)
|
||||
if (resolvedCall.resultingDescriptor is SyntheticJavaPropertyDescriptor) {
|
||||
context.trace.report(UNSUPPORTED.on(expression, "reference to the synthetic extension property for a Java get/set method"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.annotations.hasIntrinsicAnnotation
|
||||
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation
|
||||
@@ -115,7 +114,7 @@ public class JvmNameAnnotationChecker : DeclarationChecker {
|
||||
|
||||
if (descriptor is CallableMemberDescriptor) {
|
||||
val callableMemberDescriptor = descriptor
|
||||
if (DescriptorUtils.isOverride(callableMemberDescriptor) || callableMemberDescriptor.modality.isOverridable) {
|
||||
if (DescriptorUtils.isOverride(callableMemberDescriptor) || callableMemberDescriptor.isOverridable) {
|
||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
||||
}
|
||||
}
|
||||
@@ -215,8 +214,6 @@ public class ReifiedTypeParameterAnnotationChecker : DeclarationChecker {
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext
|
||||
) {
|
||||
if (descriptor.hasIntrinsicAnnotation()) return
|
||||
|
||||
if (descriptor is CallableDescriptor && !InlineUtil.isInline(descriptor)) {
|
||||
checkTypeParameterDescriptorsAreNotReified(descriptor.getTypeParameters(), diagnosticHolder)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
}
|
||||
};
|
||||
|
||||
public static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap();
|
||||
public static final DiagnosticFactoryToRendererMap MAP = new DiagnosticFactoryToRendererMap("JVM");
|
||||
static {
|
||||
MAP.put(ErrorsJvm.CONFLICTING_JVM_DECLARATIONS, "Platform declaration clash: {0}", CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||
MAP.put(ErrorsJvm.ACCIDENTAL_OVERRIDE, "Accidental override: {0}", CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||
@@ -99,6 +99,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(ErrorsJvm.UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of a type parameter cannot be an array");
|
||||
|
||||
MAP.put(ErrorsJvm.INAPPLICABLE_JVM_FIELD, "{0}", Renderers.TO_STRING);
|
||||
|
||||
MAP.put(ErrorsJvm.SUPER_CALL_WITH_DEFAULT_PARAMETERS, "Super-calls with default arguments are not allowed. Please specify all arguments of ''super.{0}'' explicitly", Renderers.TO_STRING);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -79,6 +79,8 @@ public interface ErrorsJvm {
|
||||
|
||||
DiagnosticFactory0<PsiElement> UPPER_BOUND_CANNOT_BE_ARRAY = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, String> SUPER_CALL_WITH_DEFAULT_PARAMETERS = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
enum NullabilityInformationSource {
|
||||
KOTLIN {
|
||||
@NotNull
|
||||
|
||||
@@ -43,11 +43,15 @@ public object JvmPlatform : TargetPlatform("JVM") {
|
||||
override val platformConfigurator: PlatformConfigurator = JvmPlatformConfigurator
|
||||
}
|
||||
|
||||
private val DEFAULT_IMPORTS_FOR_JVM = ArrayList<ImportPath>().apply {
|
||||
private val DEFAULT_IMPORTS_FOR_JVM: List<ImportPath> = ArrayList<ImportPath>().apply {
|
||||
add(ImportPath("java.lang.*"))
|
||||
add(ImportPath("kotlin.*"))
|
||||
add(ImportPath("kotlin.annotation.*"))
|
||||
add(ImportPath("kotlin.jvm.*"))
|
||||
add(ImportPath("kotlin.collections.*"))
|
||||
add(ImportPath("kotlin.ranges.*"))
|
||||
add(ImportPath("kotlin.sequences.*"))
|
||||
add(ImportPath("kotlin.text.*"))
|
||||
add(ImportPath("kotlin.io.*"))
|
||||
|
||||
fun addAllClassifiersFromScope(scope: MemberScope) {
|
||||
|
||||
@@ -22,8 +22,10 @@ import org.jetbrains.kotlin.jvm.RuntimeAssertionsTypeChecker
|
||||
import org.jetbrains.kotlin.load.kotlin.JavaAnnotationCallChecker
|
||||
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeFunChecker
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.checkers.SuperCallWithDefaultArgumentsChecker
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmOverloadFilter
|
||||
import org.jetbrains.kotlin.resolve.jvm.checkers.*
|
||||
import org.jetbrains.kotlin.synthetic.JavaSyntheticScopes
|
||||
import org.jetbrains.kotlin.types.DynamicTypesSettings
|
||||
|
||||
|
||||
@@ -43,11 +45,12 @@ public object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
),
|
||||
|
||||
additionalCallCheckers = listOf(
|
||||
NeedSyntheticChecker(),
|
||||
JavaAnnotationCallChecker(),
|
||||
TraitDefaultMethodCallChecker(),
|
||||
JavaClassOnCompanionChecker(),
|
||||
ProtectedInSuperClassCompanionCallChecker()
|
||||
ProtectedInSuperClassCompanionCallChecker(),
|
||||
UnsupportedSyntheticCallableReferenceChecker(),
|
||||
SuperCallWithDefaultArgumentsChecker()
|
||||
),
|
||||
|
||||
additionalTypeCheckers = listOf(
|
||||
@@ -72,5 +75,6 @@ public object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
super.configure(container)
|
||||
|
||||
container.useImpl<ReflectionAPICallChecker>()
|
||||
container.useImpl<JavaSyntheticScopes>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,17 +29,16 @@ import org.jetbrains.kotlin.incremental.record
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.BaseImportingScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectSyntheticExtensionProperties
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeFirstWord
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
import kotlin.properties.Delegates
|
||||
@@ -49,7 +48,7 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
|
||||
val setMethod: FunctionDescriptor?
|
||||
|
||||
companion object {
|
||||
fun findByGetterOrSetter(getterOrSetter: FunctionDescriptor, resolutionScope: HierarchicalScope): SyntheticJavaPropertyDescriptor? {
|
||||
fun findByGetterOrSetter(getterOrSetter: FunctionDescriptor, syntheticScopes: SyntheticScopes): SyntheticJavaPropertyDescriptor? {
|
||||
val name = getterOrSetter.getName()
|
||||
if (name.isSpecial()) return null
|
||||
val identifier = name.getIdentifier()
|
||||
@@ -58,11 +57,16 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
|
||||
val owner = getterOrSetter.getContainingDeclaration() as? ClassDescriptor ?: return null
|
||||
|
||||
val originalGetterOrSetter = getterOrSetter.original
|
||||
return resolutionScope.collectSyntheticExtensionProperties(listOf(owner.defaultType))
|
||||
return syntheticScopes.collectSyntheticExtensionProperties(listOf(owner.defaultType))
|
||||
.filterIsInstance<SyntheticJavaPropertyDescriptor>()
|
||||
.firstOrNull { originalGetterOrSetter == it.getMethod || originalGetterOrSetter == it.setMethod }
|
||||
}
|
||||
|
||||
fun findByGetterOrSetter(getterOrSetter: FunctionDescriptor, syntheticScope: SyntheticScope)
|
||||
= findByGetterOrSetter(getterOrSetter, object : SyntheticScopes {
|
||||
override val scopes: Collection<SyntheticScope> = listOf(syntheticScope)
|
||||
})
|
||||
|
||||
fun propertyNameByGetMethodName(methodName: Name): Name?
|
||||
= org.jetbrains.kotlin.load.java.propertyNameByGetMethodName(methodName)
|
||||
|
||||
@@ -71,7 +75,7 @@ interface SyntheticJavaPropertyDescriptor : PropertyDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val lookupTracker: LookupTracker) : BaseImportingScope(null) {
|
||||
class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val lookupTracker: LookupTracker) : SyntheticScope {
|
||||
private val syntheticPropertyInClass = storageManager.createMemoizedFunction<Pair<ClassDescriptor, Name>, SyntheticPropertyHolder> { pair ->
|
||||
syntheticPropertyInClassNotCached(pair.first, pair.second)
|
||||
}
|
||||
@@ -163,7 +167,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getContributedSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
|
||||
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
|
||||
var result: SmartList<PropertyDescriptor>? = null
|
||||
val processedTypes: MutableSet<TypeConstructor>? = if (receiverTypes.size() > 1) HashSet<TypeConstructor>() else null
|
||||
for (type in receiverTypes) {
|
||||
@@ -193,7 +197,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getContributedSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> {
|
||||
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> {
|
||||
val result = ArrayList<PropertyDescriptor>()
|
||||
val processedTypes = HashSet<TypeConstructor>()
|
||||
receiverTypes.forEach { result.collectSyntheticProperties(it.constructor, processedTypes) }
|
||||
@@ -255,9 +259,8 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return Name.identifier("set" + identifier.removePrefix(prefix))
|
||||
}
|
||||
|
||||
override fun printStructure(p: Printer) {
|
||||
p.println(javaClass.simpleName)
|
||||
}
|
||||
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptyList()
|
||||
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> = emptyList()
|
||||
|
||||
private data class SyntheticPropertyHolder(val descriptor: PropertyDescriptor?, val lookedNames: List<Name>) {
|
||||
companion object {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user