mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-23 15:51:59 +00:00
Compare commits
863 Commits
native-sup
...
FIR-import
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4380d054a9 | ||
|
|
1a86a2a922 | ||
|
|
90678400a7 | ||
|
|
3b318efd0d | ||
|
|
1f63072abe | ||
|
|
7a589d69da | ||
|
|
16d3bf7716 | ||
|
|
d66619b1c2 | ||
|
|
90529dfda4 | ||
|
|
0cd25353bc | ||
|
|
fcc6395b14 | ||
|
|
29cc727c5a | ||
|
|
3ede93df11 | ||
|
|
784d9f14f6 | ||
|
|
0eb5934e09 | ||
|
|
5d2a3c097c | ||
|
|
af5d4b3156 | ||
|
|
fd4c07f0e6 | ||
|
|
839d936918 | ||
|
|
aa4e87fc4b | ||
|
|
2131a314b0 | ||
|
|
9c3b367b93 | ||
|
|
ce1d6e7217 | ||
|
|
a4206a543a | ||
|
|
db25343f90 | ||
|
|
55880ef013 | ||
|
|
5b8acd69e3 | ||
|
|
edc648813d | ||
|
|
ac8e1a0124 | ||
|
|
b61608aba7 | ||
|
|
6ec7b8e0d3 | ||
|
|
38902149d2 | ||
|
|
4a10d954fc | ||
|
|
709a28060f | ||
|
|
63c5e18149 | ||
|
|
a1c0c679ee | ||
|
|
1ed136a621 | ||
|
|
3aff7112e0 | ||
|
|
ac5eeb885f | ||
|
|
7fc6f06b70 | ||
|
|
ebe9d59df7 | ||
|
|
406bd7c980 | ||
|
|
5c0d516044 | ||
|
|
dd28d55c7d | ||
|
|
9ccaef2f6b | ||
|
|
b83df18e22 | ||
|
|
4c30888d89 | ||
|
|
2c98153c6c | ||
|
|
e3d7edb6ce | ||
|
|
31b4db7f67 | ||
|
|
17421ed14d | ||
|
|
e86b1f2761 | ||
|
|
8d48f9d719 | ||
|
|
b79762ec63 | ||
|
|
06478f5147 | ||
|
|
210b5a8ca2 | ||
|
|
9299ea8f5d | ||
|
|
d381b4d3eb | ||
|
|
6d71d024e2 | ||
|
|
a5e508a083 | ||
|
|
0678a56ca4 | ||
|
|
9653fe2fcf | ||
|
|
6decd06b1b | ||
|
|
285620cb28 | ||
|
|
1338d6d66f | ||
|
|
41ccea6807 | ||
|
|
c496d8ed50 | ||
|
|
0260dc813f | ||
|
|
79f7cb11f0 | ||
|
|
ecba862dc9 | ||
|
|
790c5632ea | ||
|
|
bccca5cfa8 | ||
|
|
91b435b4bc | ||
|
|
44d9ff6c71 | ||
|
|
df5872281b | ||
|
|
c72cf02e6c | ||
|
|
0bdbcbc662 | ||
|
|
70d0c1a0ae | ||
|
|
374eec04d4 | ||
|
|
570c770d58 | ||
|
|
c770a80ab9 | ||
|
|
3a105debb3 | ||
|
|
e9c932260c | ||
|
|
29ff4d6677 | ||
|
|
995ac7aac2 | ||
|
|
e2bf43c54f | ||
|
|
5fb1bbe3f3 | ||
|
|
05f6ed40f1 | ||
|
|
b1e82c78da | ||
|
|
7887bafc5b | ||
|
|
763e72603a | ||
|
|
ad9953724f | ||
|
|
01091ba1aa | ||
|
|
bbac1d802f | ||
|
|
605afbae90 | ||
|
|
827494abbe | ||
|
|
6e2e6794aa | ||
|
|
e3a332c393 | ||
|
|
1a1b7938fb | ||
|
|
f868964e25 | ||
|
|
4f0c31eff3 | ||
|
|
23c210e9f2 | ||
|
|
9dc53c38f3 | ||
|
|
a44d70e79d | ||
|
|
47b8e54f84 | ||
|
|
d75434ac71 | ||
|
|
8ac2582e24 | ||
|
|
99a131d0ab | ||
|
|
180215f3f8 | ||
|
|
1ef3906481 | ||
|
|
d853fcb642 | ||
|
|
06e0fde74f | ||
|
|
0bf9a795aa | ||
|
|
b13d270d77 | ||
|
|
0af2a0dc19 | ||
|
|
5032c106af | ||
|
|
94e1701089 | ||
|
|
5003388d38 | ||
|
|
9c7c0c8952 | ||
|
|
3dc4d01adc | ||
|
|
8fc6b91f66 | ||
|
|
9a31e04062 | ||
|
|
0fc2a07ee4 | ||
|
|
94d87bfb67 | ||
|
|
02e6fb348d | ||
|
|
853d90d906 | ||
|
|
35d4b7dfd9 | ||
|
|
63146b98bb | ||
|
|
855e2707e3 | ||
|
|
43c8c44441 | ||
|
|
8281416dfa | ||
|
|
a16318624b | ||
|
|
a88bfb726d | ||
|
|
5d040c459b | ||
|
|
71f109387a | ||
|
|
6a66663739 | ||
|
|
eb2a33ebee | ||
|
|
1a86411139 | ||
|
|
fe233de825 | ||
|
|
249bdb969c | ||
|
|
2dd8b526fb | ||
|
|
0f94c0901f | ||
|
|
1c761c7864 | ||
|
|
3c3e7b617b | ||
|
|
a2b7912db9 | ||
|
|
205bd3f829 | ||
|
|
c25cdb4264 | ||
|
|
e103bea211 | ||
|
|
7075509b1e | ||
|
|
9f2e5cdc4d | ||
|
|
e573911e16 | ||
|
|
ee63a6b3af | ||
|
|
5db23f1a81 | ||
|
|
bde6d841c1 | ||
|
|
0d1f7965d4 | ||
|
|
d91f6f8c43 | ||
|
|
940861c245 | ||
|
|
5232f080d6 | ||
|
|
cf31e4d58c | ||
|
|
fea397a2ad | ||
|
|
dcdd42ba00 | ||
|
|
da06e49b19 | ||
|
|
d36ee02499 | ||
|
|
3a0e539eee | ||
|
|
558345b057 | ||
|
|
523b662680 | ||
|
|
abec171685 | ||
|
|
ca2367f2b5 | ||
|
|
bda1ef8d57 | ||
|
|
26da0b9e7e | ||
|
|
c63eb18b3c | ||
|
|
28e2683146 | ||
|
|
69f74b2a51 | ||
|
|
d4e0f53583 | ||
|
|
840ee66fd0 | ||
|
|
4942ed5e7a | ||
|
|
376eef05f5 | ||
|
|
a23aae590e | ||
|
|
9b49c23668 | ||
|
|
8ea8acc7f7 | ||
|
|
ed64d42d45 | ||
|
|
eb6580acdd | ||
|
|
d9a8a00069 | ||
|
|
8be3e902a8 | ||
|
|
aab28e6cc7 | ||
|
|
648e8acbde | ||
|
|
b6be72bb11 | ||
|
|
0fd68d29f4 | ||
|
|
5304754e88 | ||
|
|
f68ce4b35b | ||
|
|
8ce1d09f8a | ||
|
|
c2315f065a | ||
|
|
71e72ec6c2 | ||
|
|
6596a6ba75 | ||
|
|
7826f44180 | ||
|
|
77e687df92 | ||
|
|
3f20453ccf | ||
|
|
9ab4d727e9 | ||
|
|
2df8adc50b | ||
|
|
54f3982709 | ||
|
|
02c1ae62c3 | ||
|
|
99e1d4ab45 | ||
|
|
28e43b0487 | ||
|
|
c4aab8340b | ||
|
|
02277d0293 | ||
|
|
4c38d55f21 | ||
|
|
5a057f8ca6 | ||
|
|
783f27c554 | ||
|
|
bad9534abd | ||
|
|
8013a56286 | ||
|
|
6d592ae66b | ||
|
|
dfc3bda3b4 | ||
|
|
ea9d4037e6 | ||
|
|
d8fda8b153 | ||
|
|
e3d930a6a1 | ||
|
|
ac2bc22f54 | ||
|
|
d3ec145f13 | ||
|
|
e6de8e9cd3 | ||
|
|
fc4f7303d3 | ||
|
|
b86211b434 | ||
|
|
4f04d4503a | ||
|
|
db0021718f | ||
|
|
605396f9e2 | ||
|
|
6bddf36725 | ||
|
|
3744a00f77 | ||
|
|
00e0f430ac | ||
|
|
af2235fd1d | ||
|
|
c73885142a | ||
|
|
daa6e9b562 | ||
|
|
a5bcd3495e | ||
|
|
d11fbac511 | ||
|
|
a8aab3fbe5 | ||
|
|
e21159c28f | ||
|
|
3f0bd20235 | ||
|
|
b7d7d1eb01 | ||
|
|
0201694f84 | ||
|
|
a8abd8cceb | ||
|
|
882a12d916 | ||
|
|
749fd5dd80 | ||
|
|
487b1e96be | ||
|
|
ca335880eb | ||
|
|
3866c85a34 | ||
|
|
27dc160aef | ||
|
|
81b4031a35 | ||
|
|
a0f4d5a637 | ||
|
|
174fd41564 | ||
|
|
84d9f8250c | ||
|
|
3fcf6e7719 | ||
|
|
c3af3cc482 | ||
|
|
26d77183df | ||
|
|
7553fd2766 | ||
|
|
061aa63a73 | ||
|
|
7488056249 | ||
|
|
c65e246e02 | ||
|
|
248e09ff2c | ||
|
|
5c83c247d7 | ||
|
|
688fc386b6 | ||
|
|
b08f966428 | ||
|
|
42888572cb | ||
|
|
8852ef9e75 | ||
|
|
9041d717a2 | ||
|
|
c4d0b5493a | ||
|
|
36c73eedbf | ||
|
|
75dc8ce1c3 | ||
|
|
dc750cdbb3 | ||
|
|
3f252b15e1 | ||
|
|
bd27460694 | ||
|
|
7074909230 | ||
|
|
bdc3daf972 | ||
|
|
0210ec3114 | ||
|
|
f543170998 | ||
|
|
2f1f32bbf4 | ||
|
|
17b7bbce8c | ||
|
|
3dd16da315 | ||
|
|
dd1c9fa9f0 | ||
|
|
82b59c5044 | ||
|
|
89f7ced0d4 | ||
|
|
e73ff16b35 | ||
|
|
749556f565 | ||
|
|
c7bde6a5e6 | ||
|
|
44d56cb278 | ||
|
|
6be65e7d1a | ||
|
|
04cadf3f58 | ||
|
|
1aa9d5673b | ||
|
|
8c6337f3f6 | ||
|
|
7afb81a7df | ||
|
|
7fbfad814e | ||
|
|
ac69fa14d5 | ||
|
|
9af7316845 | ||
|
|
281f09f077 | ||
|
|
1b04945625 | ||
|
|
37a88fda78 | ||
|
|
78d4abf954 | ||
|
|
294bd8c7fa | ||
|
|
748dc203e5 | ||
|
|
d77a0f109b | ||
|
|
5af114da07 | ||
|
|
9b40981368 | ||
|
|
57ae60e9dc | ||
|
|
f22133be7e | ||
|
|
416d33fc92 | ||
|
|
9a725b99b2 | ||
|
|
2e5ee242c7 | ||
|
|
3be5f2b843 | ||
|
|
1c8e75eb34 | ||
|
|
539c55c5b2 | ||
|
|
0285cae2fd | ||
|
|
8fc5fefc7f | ||
|
|
b500239bd1 | ||
|
|
3c75dd7b5a | ||
|
|
920c200693 | ||
|
|
a43be4cbe8 | ||
|
|
c01362a943 | ||
|
|
4ee0a666cb | ||
|
|
f61980732b | ||
|
|
e90cf4b955 | ||
|
|
4a372458d6 | ||
|
|
85ba5f11d6 | ||
|
|
ee5bc95da5 | ||
|
|
73138073f1 | ||
|
|
524ae9df7d | ||
|
|
b7d0d20739 | ||
|
|
1aab3c890c | ||
|
|
f3bb952148 | ||
|
|
daf6036bc0 | ||
|
|
76a3f23df0 | ||
|
|
b0c3461eab | ||
|
|
725cb88f41 | ||
|
|
d7b885159e | ||
|
|
f4a637a72e | ||
|
|
23734bae3e | ||
|
|
c44d3a8d68 | ||
|
|
30fc76a602 | ||
|
|
4819223b74 | ||
|
|
1bc0c4092c | ||
|
|
dd91727a78 | ||
|
|
ed73513d48 | ||
|
|
4bfa90dc25 | ||
|
|
45c5a168a3 | ||
|
|
6f95e4ae3b | ||
|
|
8538866778 | ||
|
|
ecb3f10e47 | ||
|
|
84dc28374c | ||
|
|
2c313e12e5 | ||
|
|
b55b0c1ff1 | ||
|
|
6fa436911a | ||
|
|
5480bf69e8 | ||
|
|
70e60ea9bc | ||
|
|
6532916dd2 | ||
|
|
5e7d974767 | ||
|
|
6d73aa29e0 | ||
|
|
813e4c966a | ||
|
|
189b05f8a4 | ||
|
|
02fbb03d6a | ||
|
|
d756d93af1 | ||
|
|
8891733074 | ||
|
|
75b27f890a | ||
|
|
4fb434c0de | ||
|
|
023e4e3a0e | ||
|
|
b5d3520db9 | ||
|
|
62edf29cbf | ||
|
|
dd682bd37d | ||
|
|
e74469fdfc | ||
|
|
da9c486a70 | ||
|
|
c50e880173 | ||
|
|
b1c4590537 | ||
|
|
d6beddaac5 | ||
|
|
27beadad18 | ||
|
|
08822ff14b | ||
|
|
21b71f3bb1 | ||
|
|
9f9033870c | ||
|
|
bb9e9ac1ee | ||
|
|
896913907b | ||
|
|
712c9cbfe6 | ||
|
|
04ba1cff05 | ||
|
|
6a6a28f8cd | ||
|
|
f871e9dc79 | ||
|
|
f9cefdaa44 | ||
|
|
28c84d0e00 | ||
|
|
6dbb51d7a7 | ||
|
|
a24e58f5a0 | ||
|
|
03b289b899 | ||
|
|
0765cb9c62 | ||
|
|
55c8b35eee | ||
|
|
199ae3bac8 | ||
|
|
4c85616ee3 | ||
|
|
009f18f1f4 | ||
|
|
c59779f5b9 | ||
|
|
c183c5b36a | ||
|
|
63500216f0 | ||
|
|
5b8208c751 | ||
|
|
99f63f2ebd | ||
|
|
eb528c3d65 | ||
|
|
21952960f6 | ||
|
|
ade640eadb | ||
|
|
623c6803d6 | ||
|
|
729da29e49 | ||
|
|
d2740db88f | ||
|
|
7a5c05b72d | ||
|
|
b09ec3cbb3 | ||
|
|
282407c4a7 | ||
|
|
0efb4cc5f6 | ||
|
|
58a8411575 | ||
|
|
334c776b92 | ||
|
|
12a31637d1 | ||
|
|
3a40e3f041 | ||
|
|
039d41679e | ||
|
|
d89947bd5a | ||
|
|
b611facd71 | ||
|
|
088cd4b5e3 | ||
|
|
16dd6ebe61 | ||
|
|
ab05f17d1d | ||
|
|
fedb9ad035 | ||
|
|
7c2c4e68ce | ||
|
|
5140e674b4 | ||
|
|
5c4adc1100 | ||
|
|
7b7cf39388 | ||
|
|
ab90b2b901 | ||
|
|
0b23ddb947 | ||
|
|
1901331ee5 | ||
|
|
e7bed58ebe | ||
|
|
6e0391f9ec | ||
|
|
0191e3d1cf | ||
|
|
bbc73ec0e5 | ||
|
|
ca4547c40a | ||
|
|
e7100838d0 | ||
|
|
41bd29c3e9 | ||
|
|
ce9028e367 | ||
|
|
2441df820b | ||
|
|
499146db0e | ||
|
|
0303fc036c | ||
|
|
bfa6d57e34 | ||
|
|
7b7f87a3b7 | ||
|
|
6065095e24 | ||
|
|
99454aa78d | ||
|
|
056c61090d | ||
|
|
2d52865415 | ||
|
|
8d3e997a82 | ||
|
|
9f6575c57f | ||
|
|
7624dbbb20 | ||
|
|
258999fa9e | ||
|
|
0dd04c3424 | ||
|
|
792ff3c39e | ||
|
|
7949ac1080 | ||
|
|
c4337f753e | ||
|
|
0c81e30d46 | ||
|
|
1a20b1f357 | ||
|
|
0c97d99d77 | ||
|
|
f06ea6fddd | ||
|
|
d26c0f777b | ||
|
|
12ec4fdce0 | ||
|
|
df6ccbca49 | ||
|
|
7d5efe7f51 | ||
|
|
ad9b700ec4 | ||
|
|
40b3514a47 | ||
|
|
5713298108 | ||
|
|
cb398ea6b1 | ||
|
|
7b66a4d295 | ||
|
|
b2b23ac282 | ||
|
|
f2a51f96a5 | ||
|
|
04f1f6086b | ||
|
|
29568d2f48 | ||
|
|
d0ed76ebc8 | ||
|
|
c1b3e72ae8 | ||
|
|
60758b86ee | ||
|
|
666b660f79 | ||
|
|
1f0e9f24c5 | ||
|
|
1109b795da | ||
|
|
8338a0dd85 | ||
|
|
10810aa90f | ||
|
|
44f87e4951 | ||
|
|
8d054ba346 | ||
|
|
3f452b2af2 | ||
|
|
6741a550d9 | ||
|
|
ac24bb0433 | ||
|
|
da1fcb008b | ||
|
|
a97f2bb992 | ||
|
|
a258908fbb | ||
|
|
cc1be5f559 | ||
|
|
1be491504a | ||
|
|
0833f23d02 | ||
|
|
18c181641f | ||
|
|
c4283de9cb | ||
|
|
3f24f8bd8d | ||
|
|
65e3559c09 | ||
|
|
fef61eca51 | ||
|
|
81ae54c05b | ||
|
|
4f650bb056 | ||
|
|
54988932a3 | ||
|
|
7c05f77cb7 | ||
|
|
c3dd24e9b2 | ||
|
|
05301e37d8 | ||
|
|
b388f7fde0 | ||
|
|
1abcfc76df | ||
|
|
76b51b1058 | ||
|
|
269410d7aa | ||
|
|
43a4b84b44 | ||
|
|
0d103e7f0c | ||
|
|
0da1b9b80f | ||
|
|
7c1d374ed5 | ||
|
|
3142627269 | ||
|
|
c1013cc198 | ||
|
|
af1fc5b668 | ||
|
|
64b23812c0 | ||
|
|
1f4d91da1c | ||
|
|
fd57a43665 | ||
|
|
189fe95d8a | ||
|
|
1ff12d00e4 | ||
|
|
07e305e5f4 | ||
|
|
80c3e59dd5 | ||
|
|
e1f746f23c | ||
|
|
127451e1d9 | ||
|
|
22c77ffbb2 | ||
|
|
4f01a438c4 | ||
|
|
3a973973ce | ||
|
|
391e4c2ad1 | ||
|
|
bd3adbd457 | ||
|
|
6d4f927f7e | ||
|
|
5e33860652 | ||
|
|
8e455f5a14 | ||
|
|
7d89205618 | ||
|
|
65f23f3c4e | ||
|
|
6cd13341ee | ||
|
|
ba32ed7404 | ||
|
|
bffe9e45e8 | ||
|
|
850d72f13f | ||
|
|
edc8cf3ed0 | ||
|
|
c1bb3479df | ||
|
|
88cc900dc7 | ||
|
|
2e6d53a43f | ||
|
|
20d7210239 | ||
|
|
26602c8443 | ||
|
|
f9a419f940 | ||
|
|
1869ed09bc | ||
|
|
3e4d8eba76 | ||
|
|
de261df6f5 | ||
|
|
affa881421 | ||
|
|
405bd91597 | ||
|
|
487f500f85 | ||
|
|
055215c54f | ||
|
|
985934a40a | ||
|
|
71d640f3f8 | ||
|
|
f34f306d90 | ||
|
|
7eb8123d26 | ||
|
|
dda1673096 | ||
|
|
b79dcbe8e6 | ||
|
|
005955326f | ||
|
|
ff0b051a64 | ||
|
|
bc27cabb1a | ||
|
|
bbd15db308 | ||
|
|
6a860dd042 | ||
|
|
974837654e | ||
|
|
a5f1ed9a5d | ||
|
|
cd2ff41ef5 | ||
|
|
a078526c4d | ||
|
|
8f8c431524 | ||
|
|
eb597fbf22 | ||
|
|
43027d0581 | ||
|
|
074aa47dc0 | ||
|
|
d3ee14c5d2 | ||
|
|
2d425d4e0a | ||
|
|
bb53a1c3d2 | ||
|
|
358e64fdb0 | ||
|
|
4423ef9087 | ||
|
|
8e347f9f39 | ||
|
|
beaf6df8c5 | ||
|
|
3e90d367f2 | ||
|
|
9d27771f86 | ||
|
|
3ca81b95c2 | ||
|
|
18b53f331a | ||
|
|
68dfe9bf14 | ||
|
|
3aee3dfdd9 | ||
|
|
9a79254f7e | ||
|
|
faf09a2aac | ||
|
|
cff648a505 | ||
|
|
a807397f65 | ||
|
|
aa56c50218 | ||
|
|
d03237bebc | ||
|
|
ec8bdff5c7 | ||
|
|
6022fb4ec3 | ||
|
|
0f898dc6dc | ||
|
|
95010de32e | ||
|
|
8d2b1950e6 | ||
|
|
8536ef5b43 | ||
|
|
947ea88d5e | ||
|
|
d9593c7a34 | ||
|
|
7e49005bab | ||
|
|
0ca59b3a40 | ||
|
|
24e7bafa7d | ||
|
|
a6f2af03e7 | ||
|
|
09cd038e4b | ||
|
|
a4f5cced47 | ||
|
|
de36d919aa | ||
|
|
83faba6424 | ||
|
|
47baaf10c6 | ||
|
|
625ff00f62 | ||
|
|
6850d7be0c | ||
|
|
c5a81c4e8b | ||
|
|
7030a485be | ||
|
|
f6b805a973 | ||
|
|
8a7ff4cd24 | ||
|
|
106db57975 | ||
|
|
43e4616fdf | ||
|
|
b194be7665 | ||
|
|
fd3dfe0710 | ||
|
|
125a136663 | ||
|
|
a0ae4dd387 | ||
|
|
a6c7f4294c | ||
|
|
1008adaf02 | ||
|
|
7b1c564b87 | ||
|
|
85bdb8b787 | ||
|
|
06ecca4144 | ||
|
|
9f16e4f709 | ||
|
|
3f2c73b4a9 | ||
|
|
b5f73ebd0f | ||
|
|
6d9fb4f382 | ||
|
|
4ca0c60066 | ||
|
|
95633b6027 | ||
|
|
6736987239 | ||
|
|
7ff72e9d90 | ||
|
|
66b5dd92d9 | ||
|
|
1face1c334 | ||
|
|
38652372ce | ||
|
|
c753a98d02 | ||
|
|
a789fd92fe | ||
|
|
86ba5ebf29 | ||
|
|
64d2cdf0c2 | ||
|
|
082801efb4 | ||
|
|
86141be61f | ||
|
|
8c01cd48a5 | ||
|
|
1d7ee22bdc | ||
|
|
af29dced98 | ||
|
|
9e0708e85a | ||
|
|
d793221a7b | ||
|
|
b469afdfcb | ||
|
|
7d6adbd088 | ||
|
|
5dea245a37 | ||
|
|
c0f4933356 | ||
|
|
d7f2eeb6e8 | ||
|
|
bc6e091004 | ||
|
|
a293aded5d | ||
|
|
5e9b31ca2c | ||
|
|
5229ed0217 | ||
|
|
ed7dd6fccb | ||
|
|
b31de355db | ||
|
|
818171108e | ||
|
|
ab07377200 | ||
|
|
db418123d4 | ||
|
|
35a0b42796 | ||
|
|
69f5cf7095 | ||
|
|
a2cdb14610 | ||
|
|
d90cda65a1 | ||
|
|
0cc3625dc1 | ||
|
|
ca742b1552 | ||
|
|
7166c011bf | ||
|
|
a2c5c515de | ||
|
|
7d5a304cf6 | ||
|
|
89bec8ec59 | ||
|
|
084071e2e5 | ||
|
|
14818a4fc1 | ||
|
|
c4038729ea | ||
|
|
50deac7a26 | ||
|
|
6ef6fe4a47 | ||
|
|
11b948f004 | ||
|
|
0660e4d616 | ||
|
|
2e709a81fa | ||
|
|
e24f68c357 | ||
|
|
65ee837bfe | ||
|
|
140c5d7689 | ||
|
|
b7da2ad675 | ||
|
|
6cb1ba9d41 | ||
|
|
94789c50b9 | ||
|
|
9694882db6 | ||
|
|
b6c4bd270c | ||
|
|
2e2b15853e | ||
|
|
54e7fe6c52 | ||
|
|
2473362373 | ||
|
|
4a3af36909 | ||
|
|
3014c3b33b | ||
|
|
362ee126d1 | ||
|
|
81406a2bac | ||
|
|
0f8b46b7d7 | ||
|
|
39d28f1c92 | ||
|
|
2bba4f5aa8 | ||
|
|
7dd168d4ef | ||
|
|
3bb405bee4 | ||
|
|
139c582ce2 | ||
|
|
8db5fd4b9b | ||
|
|
373ddcf55d | ||
|
|
d5f203a978 | ||
|
|
b38e9b6b05 | ||
|
|
39f5418c01 | ||
|
|
35056543a2 | ||
|
|
2dd5b8fa70 | ||
|
|
a4b2e5964a | ||
|
|
fe9ce45e1d | ||
|
|
cb47b0cde1 | ||
|
|
f4af656e20 | ||
|
|
97999a6415 | ||
|
|
ea69d26bac | ||
|
|
fa9a3868b7 | ||
|
|
03ea8603ce | ||
|
|
7d2bc5c0f6 | ||
|
|
8e66dadb47 | ||
|
|
e242a8b08b | ||
|
|
affc827998 | ||
|
|
c0ef1311ba | ||
|
|
c4ddf2e9ae | ||
|
|
323602eb5f | ||
|
|
a8b44c9e18 | ||
|
|
6bb77ba51d | ||
|
|
e66f3fa59e | ||
|
|
20b86d85c3 | ||
|
|
9cbc87ce57 | ||
|
|
e1e02b072b | ||
|
|
82baf6cbb1 | ||
|
|
956f8ad5e9 | ||
|
|
ed8aad6149 | ||
|
|
073f4f51fd | ||
|
|
ea1abb0680 | ||
|
|
1b889c976a | ||
|
|
7a7fa56d74 | ||
|
|
aac96c476a | ||
|
|
9c812c6e2b | ||
|
|
4d3d376db8 | ||
|
|
feb7239189 | ||
|
|
1f675c8a74 | ||
|
|
73907106e9 | ||
|
|
94e6f986e7 | ||
|
|
782aa94513 | ||
|
|
94531f992d | ||
|
|
d760299dc1 | ||
|
|
d9760f00f6 | ||
|
|
7b3973db52 | ||
|
|
082c44cb5c | ||
|
|
382379d785 | ||
|
|
d3540a01a7 | ||
|
|
cbe3c69457 | ||
|
|
619e2bc0db | ||
|
|
9e6637dced | ||
|
|
b7afb4a58e | ||
|
|
de989c4050 | ||
|
|
0059fcceb9 | ||
|
|
88fb76bffc | ||
|
|
d5b3dc8a2a | ||
|
|
6bfb5c59a3 | ||
|
|
b1c2daf1fe | ||
|
|
bf4be12239 | ||
|
|
6786b9ece2 | ||
|
|
7e0a658de7 | ||
|
|
928fe19801 | ||
|
|
ffb83bbdf0 | ||
|
|
ccd4bc1bff | ||
|
|
80bec0898f | ||
|
|
5a64067601 | ||
|
|
14d8425e27 | ||
|
|
1de0dbd67d | ||
|
|
9253f88220 | ||
|
|
4970e90412 | ||
|
|
469b11e0aa | ||
|
|
5ac64bcc1d | ||
|
|
a417630c24 | ||
|
|
863c0051ce | ||
|
|
044419eda5 | ||
|
|
5dc563a9af | ||
|
|
c268dcecd2 | ||
|
|
5fc2267665 | ||
|
|
f1b97bb9be | ||
|
|
39c76c7b11 | ||
|
|
e712007904 | ||
|
|
433afcd669 | ||
|
|
a03bfb3561 | ||
|
|
9ae478e4fc | ||
|
|
81cf3fbc28 | ||
|
|
9e6d6ad9da | ||
|
|
0c94aefb87 | ||
|
|
c8351c3da0 | ||
|
|
313c27859a | ||
|
|
1b93f07a76 | ||
|
|
8cd3b46f05 | ||
|
|
359909dcff | ||
|
|
4975ef7db5 | ||
|
|
808e83a01e | ||
|
|
0b5a6f61bb | ||
|
|
b8c982bb72 | ||
|
|
9e701f96de | ||
|
|
d2536f207c | ||
|
|
341f7c348a | ||
|
|
f04733ef33 | ||
|
|
03f092fd39 | ||
|
|
76d1d6ff12 | ||
|
|
3a5de13dd4 | ||
|
|
3e79bd2b0e | ||
|
|
8c8f0639f8 | ||
|
|
356b02cb91 | ||
|
|
43dcbbcce1 | ||
|
|
4b138ae2b8 | ||
|
|
8be1929634 | ||
|
|
9bfbe8a90a | ||
|
|
504c9c02d7 | ||
|
|
a58f7b5599 | ||
|
|
81435c98fa | ||
|
|
941e5ae1b2 | ||
|
|
84587eb0f9 | ||
|
|
03820245eb | ||
|
|
6c49c1eabd | ||
|
|
e7a6ce3626 | ||
|
|
df0d91ef9e | ||
|
|
9353cfb526 | ||
|
|
2d356b89b5 | ||
|
|
3cc606577c | ||
|
|
f340bc9f91 | ||
|
|
e213dc261e | ||
|
|
85ba637796 | ||
|
|
c768130f89 | ||
|
|
e9fc65c7ae | ||
|
|
273889d1a9 | ||
|
|
792c5f8b3f | ||
|
|
3e3ffd14a9 | ||
|
|
f63cf9d506 | ||
|
|
8365836753 | ||
|
|
6b2a1497e2 | ||
|
|
50d9dbbfc1 | ||
|
|
cba99a1e67 | ||
|
|
9bc5b753aa | ||
|
|
b389e29db5 | ||
|
|
ead9b31e03 | ||
|
|
7e9704e50d | ||
|
|
24a905293f | ||
|
|
bcf1b9c804 | ||
|
|
7f4f07659c | ||
|
|
9cb8a35275 | ||
|
|
c1cc722ac4 | ||
|
|
fc3c4ad883 | ||
|
|
b53194ef1a | ||
|
|
aa74511378 | ||
|
|
1cc0c12f87 | ||
|
|
f79fbe778f | ||
|
|
38be1f6947 | ||
|
|
bc722f9c5f | ||
|
|
2c920b732c | ||
|
|
3cf1c56794 | ||
|
|
c3f6ba3302 | ||
|
|
272ee252d8 | ||
|
|
b9f141d4aa | ||
|
|
a18770fbbb | ||
|
|
03340d770b | ||
|
|
ef915096a5 | ||
|
|
4b0bc4a438 | ||
|
|
ee1ec22e4c | ||
|
|
3da9d79fc2 | ||
|
|
3a2d25a422 | ||
|
|
456bf9808d | ||
|
|
25882c5b46 | ||
|
|
472be61356 | ||
|
|
c4e794b21f | ||
|
|
41a8678b95 | ||
|
|
584410b14b | ||
|
|
e7807cc168 | ||
|
|
c1829782b7 | ||
|
|
59241a9c1f | ||
|
|
000e7493a1 | ||
|
|
7b46d22877 |
1
.idea/dictionaries/4u7.xml
generated
1
.idea/dictionaries/4u7.xml
generated
@@ -3,6 +3,7 @@
|
||||
<words>
|
||||
<w>cidr</w>
|
||||
<w>foldable</w>
|
||||
<w>redirector</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
2
.idea/dictionaries/Nikolay_Krasko.xml
generated
2
.idea/dictionaries/Nikolay_Krasko.xml
generated
@@ -7,9 +7,9 @@
|
||||
<w>fqname</w>
|
||||
<w>goto</w>
|
||||
<w>gradle</w>
|
||||
<w>infos</w>
|
||||
<w>intrinsics</w>
|
||||
<w>kdoc</w>
|
||||
<w>kompiler</w>
|
||||
<w>memoize</w>
|
||||
<w>memoized</w>
|
||||
<w>multiline</w>
|
||||
|
||||
3
.idea/dictionaries/dzharkov.xml
generated
3
.idea/dictionaries/dzharkov.xml
generated
@@ -7,6 +7,7 @@
|
||||
<w>experimentality</w>
|
||||
<w>insn</w>
|
||||
<w>liveness</w>
|
||||
<w>parameterless</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
</component>
|
||||
|
||||
6
.idea/inspectionProfiles/idea_default.xml
generated
6
.idea/inspectionProfiles/idea_default.xml
generated
@@ -105,6 +105,12 @@
|
||||
<Problem reference="org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler#addSpace" reason="Method was replaced with outher methods in 182. Use addSpaceEx instead." />
|
||||
<Problem reference="com.intellij.psi.codeStyle.CommonCodeStyleSettings#copyFrom" reason="Absent in 173. Use CompatibilityKt.copyFromEx instead." />
|
||||
<Problem reference="com.intellij.psi.codeStyle.CommonCodeStyleSettingsManager#copy" reason="Removed since 181. Use CompatibilityKt.copyFromEx instead." />
|
||||
<Problem reference="com.intellij.notification.NotificationAction#createSimple" reason="Absent in 173." />
|
||||
<Problem reference="com.intellij.notification.NotificationAction#create" reason="Absent in 173." />
|
||||
<Problem reference="com.intellij.util.JdomKt#element" reason="Removed in 191" />
|
||||
<Problem reference="com.intellij.execution.JavaRunConfigurationExtensionManager#getInstance" reason="Can't be used in Kotlin, because method was replaced with property after J2K in 191. Use JavaRunConfigurationExtensionManagerUtil instead." />
|
||||
<Problem reference="com.intellij.execution.configurations.RunConfigurationBase" reason="Generalized in 191. Use RunConfigurationBaseAny instead in signatures." />
|
||||
<Problem reference="com.intellij.execution.configurations.ModuleBasedConfiguration" reason="Generalized in 191. Use ModuleBasedConfigurationElement instead." />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
|
||||
13
.idea/runConfigurations/run_IR_test_in_node_js.xml
generated
Normal file
13
.idea/runConfigurations/run_IR_test_in_node_js.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="run IR test in node.js" type="js.build_tools.npm">
|
||||
<package-json value="$PROJECT_DIR$/js/js.translator/testData/package.json" />
|
||||
<command value="run" />
|
||||
<scripts>
|
||||
<script value="runIrTestInNode" />
|
||||
</scripts>
|
||||
<arguments value="$FilePath$" />
|
||||
<node-interpreter value="project" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
213
ChangeLog.md
213
ChangeLog.md
@@ -292,7 +292,220 @@
|
||||
|
||||
- [`KT-25541`](https://youtrack.jetbrains.com/issue/KT-25541) Incorrect parameter names in reflection for inner class constructor from Java class compiled with "-parameters"
|
||||
|
||||
## 1.2.71
|
||||
|
||||
### Compiler
|
||||
|
||||
- [`KT-26806`](https://youtrack.jetbrains.com/issue/KT-26806) Defining constants using kotlin.math is broken in 1.2.70
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-26399`](https://youtrack.jetbrains.com/issue/KT-26399) Kotlin Migration: NPE at KotlinMigrationProjectComponent$onImportFinished$1.run()
|
||||
- [`KT-26794`](https://youtrack.jetbrains.com/issue/KT-26794) Bad version detection during migration in Android Studio 3.2
|
||||
- [`KT-26823`](https://youtrack.jetbrains.com/issue/KT-26823) Fix deadlock in databinding with AndroidX which led to Android Studio hanging
|
||||
- [`KT-26889`](https://youtrack.jetbrains.com/issue/KT-26889) Don't show migration dialog if no actual migrations are available
|
||||
- [`KT-25177`](https://youtrack.jetbrains.com/issue/KT-25177) Report asDynamic on dynamic type as a warning
|
||||
- [`KT-25454`](https://youtrack.jetbrains.com/issue/KT-25454) Extract function: make default visibility private
|
||||
|
||||
### JavaScript
|
||||
|
||||
- [`KT-26466`](https://youtrack.jetbrains.com/issue/KT-26466) Uncaught ReferenceError: println is not defined
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-26208`](https://youtrack.jetbrains.com/issue/KT-26208) inspectClassesForKotlinIC slows down continuous mode in Gradle
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-26929`](https://youtrack.jetbrains.com/issue/KT-26929) Kotlin Reflect and Proguard: can’t find referenced class kotlin.annotations.jvm.ReadOnly/Mutable
|
||||
|
||||
## 1.2.70
|
||||
|
||||
### Compiler
|
||||
|
||||
- [`KT-13860`](https://youtrack.jetbrains.com/issue/KT-13860) Avoid creating KtImportDirective PSI elements for default imports in LazyImportScope
|
||||
- [`KT-22201`](https://youtrack.jetbrains.com/issue/KT-22201) Generate nullability annotations for data class toString and equals methods.
|
||||
- [`KT-23870`](https://youtrack.jetbrains.com/issue/KT-23870) SAM adapter method returns null-values for "genericParameterTypes"
|
||||
- [`KT-24597`](https://youtrack.jetbrains.com/issue/KT-24597) IDE doesn't report missing constructor on inheritance of an expected class in common module
|
||||
- [`KT-25120`](https://youtrack.jetbrains.com/issue/KT-25120) RequireKotlin on nested class and its members is not loaded correctly
|
||||
- [`KT-25193`](https://youtrack.jetbrains.com/issue/KT-25193) Names of parameters from Java interface methods implemented by delegation are lost
|
||||
- [`KT-25405`](https://youtrack.jetbrains.com/issue/KT-25405) Mismatching descriptor type parameters on inner types
|
||||
- [`KT-25604`](https://youtrack.jetbrains.com/issue/KT-25604) Disable callable references to exprerimental suspend functions
|
||||
- [`KT-25665`](https://youtrack.jetbrains.com/issue/KT-25665) Add a warning for annotations which target non-existent accessors
|
||||
- [`KT-25894`](https://youtrack.jetbrains.com/issue/KT-25894) Do not generate body for functions from Any in light class builder mode
|
||||
- [`KT-20772`](https://youtrack.jetbrains.com/issue/KT-20772) Incorrect smart cast on enum members
|
||||
- [`KT-24657`](https://youtrack.jetbrains.com/issue/KT-24657) Compiler performance issues with big files
|
||||
- [`KT-25745`](https://youtrack.jetbrains.com/issue/KT-25745) Do not report warning about annotations on non-existing accessors for JvmStatic properties
|
||||
- [`KT-25746`](https://youtrack.jetbrains.com/issue/KT-25746) Improve message for warning about annotations that have target to non-existing accessors
|
||||
- [`KT-25810`](https://youtrack.jetbrains.com/issue/KT-25810) New Inference: Overload resolution ambiguity on method 'provideDelegate(Nothing?, KProperty<*>)' when there's more than one `provideDelegate` operator in scope
|
||||
- [`KT-25973`](https://youtrack.jetbrains.com/issue/KT-25973) Report metadata version mismatch upon discovering a .kotlin_module file in the dependencies with an incompatible metadata version
|
||||
- [`KT-22281`](https://youtrack.jetbrains.com/issue/KT-22281) JVM: Incorrect comparison of Double and Float when types are derived from smart-casts
|
||||
- [`KT-22649`](https://youtrack.jetbrains.com/issue/KT-22649) Compiler: wrong code generated / Couldn't transform method node - using inline extension property inside lambda
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-18301`](https://youtrack.jetbrains.com/issue/KT-18301) kotlin needs crazy amount of memory
|
||||
- [`KT-23668`](https://youtrack.jetbrains.com/issue/KT-23668) Methods with internal visibility have different mangling names in IDE and in compiler
|
||||
- [`KT-24892`](https://youtrack.jetbrains.com/issue/KT-24892) please remove usages of com.intellij.util.containers.ConcurrentFactoryMap#ConcurrentFactoryMap deprecated long ago
|
||||
- [`KT-25144`](https://youtrack.jetbrains.com/issue/KT-25144) Quick fix “Change signature” changes class of argument when applied for descendant classes with enabled -Xnew-inference option
|
||||
- [`KT-25356`](https://youtrack.jetbrains.com/issue/KT-25356) Update Gradle Kotlin-DSL icon according to new IDEA 2018.2 icons style
|
||||
- [`KT-20056`](https://youtrack.jetbrains.com/issue/KT-20056) TCE on creating object of an anonymous class in Kotlin script
|
||||
- [`KT-25092`](https://youtrack.jetbrains.com/issue/KT-25092) SourcePsi should be physical leaf element but got OPERATION_REFERENCE
|
||||
- [`KT-25249`](https://youtrack.jetbrains.com/issue/KT-25249) Uast operates "Unit" type instead of "void"
|
||||
- [`KT-25255`](https://youtrack.jetbrains.com/issue/KT-25255) Preferences | Languages & Frameworks | Kotlin Updates: show currently installed version
|
||||
- [`KT-25297`](https://youtrack.jetbrains.com/issue/KT-25297) Inconsistency in `KotlinULambdaExpression` and `KotlinLocalFunctionULambdaExpression`
|
||||
- [`KT-25515`](https://youtrack.jetbrains.com/issue/KT-25515) Add/remove analysis-related compiler setting does not update IDE project model immediately
|
||||
- [`KT-25524`](https://youtrack.jetbrains.com/issue/KT-25524) UAST: proper resolve for function variable call
|
||||
- [`KT-25640`](https://youtrack.jetbrains.com/issue/KT-25640) "Configure Kotlin" action changes values of language and API version in project settings
|
||||
|
||||
### IDE. Debugger
|
||||
|
||||
- [`KT-25147`](https://youtrack.jetbrains.com/issue/KT-25147) Conditional breakpoints doesn't work in `common` code of MPP
|
||||
- [`KT-25152`](https://youtrack.jetbrains.com/issue/KT-25152) MPP debug doesn't navigate to `common` code if there are same named files in `common` and `platform` parts
|
||||
|
||||
### IDE. Gradle
|
||||
|
||||
- [`KT-22732`](https://youtrack.jetbrains.com/issue/KT-22732) TestNG runner is always used for TestNG tests even when Use Gradle runner is selected
|
||||
- [`KT-25913`](https://youtrack.jetbrains.com/issue/KT-25913) Honor 'store generated project files externally option' for Kotlin facets imported from Gradle
|
||||
- [`KT-25955`](https://youtrack.jetbrains.com/issue/KT-25955) Support expect/actual in new MPP imported into IDEA
|
||||
|
||||
### IDE. Inspections and Intentions
|
||||
|
||||
#### New Features
|
||||
|
||||
- [`KT-6633`](https://youtrack.jetbrains.com/issue/KT-6633) Inspection to detect unnecessary "with" calls
|
||||
- [`KT-25146`](https://youtrack.jetbrains.com/issue/KT-25146) Add quick-fix for default parameter value removal
|
||||
- [`KT-7675`](https://youtrack.jetbrains.com/issue/KT-7675) Create inspection to replace if with let
|
||||
- [`KT-13515`](https://youtrack.jetbrains.com/issue/KT-13515) Add intention to replace '?.let' with null check
|
||||
- [`KT-13854`](https://youtrack.jetbrains.com/issue/KT-13854) Need intention actions: to convert property with getter to initializer
|
||||
- [`KT-15476`](https://youtrack.jetbrains.com/issue/KT-15476) Inspection to convert non-lazy chains of collection functions into sequences
|
||||
- [`KT-22068`](https://youtrack.jetbrains.com/issue/KT-22068) Force usage of “it” in .forEach{} calls
|
||||
- [`KT-23445`](https://youtrack.jetbrains.com/issue/KT-23445) Inspection and quickfix to replace `assertTrue(a == b)` with `assertEquals(a, b)`
|
||||
- [`KT-25270`](https://youtrack.jetbrains.com/issue/KT-25270) "return@foo" outside of lambda should have quickfix to remove "@foo" label
|
||||
|
||||
#### Fixes
|
||||
|
||||
- [`KT-11154`](https://youtrack.jetbrains.com/issue/KT-11154) Spell checking inspection is not suppressable
|
||||
- [`KT-18681`](https://youtrack.jetbrains.com/issue/KT-18681) "Replace 'if' with 'when'" generates unnecessary else block
|
||||
- [`KT-24001`](https://youtrack.jetbrains.com/issue/KT-24001) "Suspicious combination of == and ===" false positive
|
||||
- [`KT-24385`](https://youtrack.jetbrains.com/issue/KT-24385) Convert lambda to reference refactor produces red code with companion object
|
||||
- [`KT-24694`](https://youtrack.jetbrains.com/issue/KT-24694) Move lambda out of parentheses should not be applied for multiple functional parameters
|
||||
- [`KT-25089`](https://youtrack.jetbrains.com/issue/KT-25089) False-positive "Call chain on collection type can be simplified" for `map` and `joinToString` on a `HashMap`
|
||||
- [`KT-25169`](https://youtrack.jetbrains.com/issue/KT-25169) Impossible to suppress UAST/JVM inspections
|
||||
- [`KT-25321`](https://youtrack.jetbrains.com/issue/KT-25321) Safe delete of a class property implementing constructor parameter at the platform side doesn't remove all the related declarations
|
||||
- [`KT-25539`](https://youtrack.jetbrains.com/issue/KT-25539) `Make class open` quick fix doesn't update all the related implementations of a multiplatform class
|
||||
- [`KT-25608`](https://youtrack.jetbrains.com/issue/KT-25608) Confusing "Redundant override" inspection message
|
||||
- [`KT-16422`](https://youtrack.jetbrains.com/issue/KT-16422) Replace lambda with method reference inspections fails
|
||||
- [`KT-21999`](https://youtrack.jetbrains.com/issue/KT-21999) Convert lambda to reference adds this with incorrect label
|
||||
- [`KT-23467`](https://youtrack.jetbrains.com/issue/KT-23467) False positive `suspicious callable reference` on scoping function called on another lambda
|
||||
- [`KT-25044`](https://youtrack.jetbrains.com/issue/KT-25044) "Implement member" quick-fix should not generate 'actual' modifier with expect declaration in interface only
|
||||
- [`KT-25579`](https://youtrack.jetbrains.com/issue/KT-25579) Redundant semicolon erroneously reported during local var modifier ambiguity
|
||||
- [`KT-25633`](https://youtrack.jetbrains.com/issue/KT-25633) “Add kotlin-XXX.jar to the classpath” quick fix adds dependency with invalid version in Gradle-based projects
|
||||
- [`KT-25739`](https://youtrack.jetbrains.com/issue/KT-25739) "Convert to run" / "Convert to with" intentions incorrectly process references to Java static members
|
||||
- [`KT-25928`](https://youtrack.jetbrains.com/issue/KT-25928) "Let extend" quick fix is suggested in case of nullable/non-null TYPE_MISMATCH collision
|
||||
- [`KT-26042`](https://youtrack.jetbrains.com/issue/KT-26042) False positive "Remove redundant '.let' call" for lambda with destructured arguments
|
||||
|
||||
### IDE. KDoc
|
||||
|
||||
- [`KT-22815`](https://youtrack.jetbrains.com/issue/KT-22815) Update quick documentation
|
||||
- [`KT-22648`](https://youtrack.jetbrains.com/issue/KT-22648) Quick Doc popup: break (long?) declarations into several lines
|
||||
|
||||
### IDE. Libraries
|
||||
|
||||
- [`KT-25129`](https://youtrack.jetbrains.com/issue/KT-25129) Idea freezes when Kotlin plugin tries to determine if jar is js lib in jvm module
|
||||
|
||||
### IDE. Navigation
|
||||
|
||||
- [`KT-25317`](https://youtrack.jetbrains.com/issue/KT-25317) `Go to actual declaration` keyboard shortcut doesn't work for `expect object`, showing "No implementations found" message
|
||||
- [`KT-25492`](https://youtrack.jetbrains.com/issue/KT-25492) Find usages: keep `Expected functions` option state while searching for usages of a regular function
|
||||
- [`KT-25498`](https://youtrack.jetbrains.com/issue/KT-25498) `Find Usages` doesn't show `Supertype` usages of `actual` declarations with constructor
|
||||
|
||||
### IDE. Project View
|
||||
|
||||
- [`KT-22823`](https://youtrack.jetbrains.com/issue/KT-22823) Text pasted into package is parsed as Kotlin before Java
|
||||
|
||||
### IDE. Refactorings
|
||||
|
||||
- [`KT-22072`](https://youtrack.jetbrains.com/issue/KT-22072) "Convert MutableMap.put to assignment" should not be applicable when put is used as expression
|
||||
- [`KT-23590`](https://youtrack.jetbrains.com/issue/KT-23590) Incorrect conflict warning "Internal function will not be accessible" when moving class from jvm to common module
|
||||
- [`KT-23594`](https://youtrack.jetbrains.com/issue/KT-23594) Incorrect conflict warning about IllegalStateException when moving class from jvm to common module
|
||||
- [`KT-23772`](https://youtrack.jetbrains.com/issue/KT-23772) MPP: Refactor / Rename class does not update name of file containing related expect/actual class
|
||||
- [`KT-23914`](https://youtrack.jetbrains.com/issue/KT-23914) Safe search false positives during moves between common and actual modules
|
||||
- [`KT-25326`](https://youtrack.jetbrains.com/issue/KT-25326) Refactor/Safe Delete doesn't report `actual object` usages
|
||||
- [`KT-25438`](https://youtrack.jetbrains.com/issue/KT-25438) Refactor/Safe delete of a multiplatform companion object: usage is not reported
|
||||
- [`KT-25857`](https://youtrack.jetbrains.com/issue/KT-25857) Refactoring → Move moves whole file in case of moving class from Kotlin script
|
||||
- [`KT-25858`](https://youtrack.jetbrains.com/issue/KT-25858) Refactoring → Move can be called only for class declarations in Kotlin script
|
||||
|
||||
### IDE. Script
|
||||
|
||||
- [`KT-25814`](https://youtrack.jetbrains.com/issue/KT-25814) IDE scripting console -> kotlin (JSR-223) - compilation errors - unresolved IDEA classes
|
||||
- [`KT-25822`](https://youtrack.jetbrains.com/issue/KT-25822) jvmTarget from the script compiler options is ignored in the IDE
|
||||
|
||||
### IDE. Multiplatform
|
||||
|
||||
- [`KT-23368`](https://youtrack.jetbrains.com/issue/KT-23368) IDE: Build: JPS errors are reported for valid non-multiplatform module depending on multiplatform one
|
||||
|
||||
### IDE. Ultimate
|
||||
|
||||
- [`KT-25595`](https://youtrack.jetbrains.com/issue/KT-25595) Rename Kotlin-specific "Protractor" run configuration to distinguish it from the one provided by NodeJS plugin
|
||||
- [`KT-19309`](https://youtrack.jetbrains.com/issue/KT-19309) Spring JPA Repository IntelliJ tooling with Kotlin
|
||||
|
||||
### IDE. Tests Support
|
||||
|
||||
- [`KT-26228`](https://youtrack.jetbrains.com/issue/KT-26228) NoClassDefFoundError: org/jetbrains/kotlin/idea/run/KotlinTestNgConfigurationProducer on running a JUnit test with TestNG plugin disabled
|
||||
|
||||
### Reflection
|
||||
|
||||
- [`KT-25541`](https://youtrack.jetbrains.com/issue/KT-25541) Incorrect parameter names in reflection for inner class constructor from Java class compiled with "-parameters"
|
||||
|
||||
### Tools. CLI
|
||||
|
||||
- [`KT-21910`](https://youtrack.jetbrains.com/issue/KT-21910) Add `-Xfriend-paths` compiler argument to support internal visibility checks in production/test sources from external build systems
|
||||
- [`KT-25554`](https://youtrack.jetbrains.com/issue/KT-25554) Do not report warnings when `-XXLanguage` was used to turn on deprecation
|
||||
- [`KT-25196`](https://youtrack.jetbrains.com/issue/KT-25196) Optional expected annotation is visible in platforms where it doesn't have actual
|
||||
|
||||
### Tools. JPS
|
||||
|
||||
- [`KT-25540`](https://youtrack.jetbrains.com/issue/KT-25540) JPS JS IC does not recompile usages from other modules when package is different
|
||||
|
||||
### Tools. kapt
|
||||
|
||||
- [`KT-25396`](https://youtrack.jetbrains.com/issue/KT-25396) KAPT Error: Unknown option: infoAsWarnings
|
||||
- [`KT-26211`](https://youtrack.jetbrains.com/issue/KT-26211) Kotlin plugin 1.2.60+ breaks IDEA source/resource/test roots in a Maven project with Kapt
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-25025`](https://youtrack.jetbrains.com/issue/KT-25025) Inter-project IC for JS in Gradle
|
||||
- [`KT-25455`](https://youtrack.jetbrains.com/issue/KT-25455) Gradle IC: when class signature is changed its indirect subclasses in different module are not recompiled
|
||||
|
||||
### Tools. JPS
|
||||
|
||||
- [`KT-25998`](https://youtrack.jetbrains.com/issue/KT-25998) Build process starts compiling w/o any changes (on release version)
|
||||
- [`KT-25977`](https://youtrack.jetbrains.com/issue/KT-25977) Can not run a Kotlin test
|
||||
- [`KT-26072`](https://youtrack.jetbrains.com/issue/KT-26072) MPP compilation issue
|
||||
- [`KT-26113`](https://youtrack.jetbrains.com/issue/KT-26113) Build takes around 20 seconds in already fully built IDEA project
|
||||
|
||||
### Tools. Scripts
|
||||
|
||||
- [`KT-26142`](https://youtrack.jetbrains.com/issue/KT-26142) update maven-central remote repository url
|
||||
|
||||
### Tools. Incremental Compile
|
||||
|
||||
- [`KT-26528`](https://youtrack.jetbrains.com/issue/KT-26528) ISE “To save disabled cache status [delete] should be called (this behavior is kept for compatibility)” on compiling project with enabled IC in Maven
|
||||
|
||||
### JavaScript
|
||||
|
||||
- [`KT-22053`](https://youtrack.jetbrains.com/issue/KT-22053) JS: Secondary constructor of Throwable inheritor doesn't call to primary one
|
||||
- [`KT-26064`](https://youtrack.jetbrains.com/issue/KT-26064) JS inliner calls wrong constructor in incremental build
|
||||
- [`KT-26117`](https://youtrack.jetbrains.com/issue/KT-26117) JS runtime error: ArrayList_init instead of ArrayList_init_0
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-18067`](https://youtrack.jetbrains.com/issue/KT-18067) KotlinJS - String.compareTo(other: String, ignoreCase: Boolean = false): Int
|
||||
- [`KT-19507`](https://youtrack.jetbrains.com/issue/KT-19507) Using @JvmName from stdlib-common fails to compile in JS module.
|
||||
- [`KT-19508`](https://youtrack.jetbrains.com/issue/KT-19508) Add @JsName to stdlib-common for controlling JS implementation
|
||||
- [`KT-24478`](https://youtrack.jetbrains.com/issue/KT-24478) Annotate relevant standard library annotations with @OptionalExpectation
|
||||
- [`KT-25980`](https://youtrack.jetbrains.com/issue/KT-25980) JvmSynthetic annotation has no description in the docs
|
||||
|
||||
## 1.2.60
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ plugins {
|
||||
dependencies {
|
||||
compile(commonDep("org.apache.ant", "ant"))
|
||||
compile(project(":kotlin-preloader"))
|
||||
compile(projectDist(":kotlin-stdlib"))
|
||||
compile(project(":kotlin-stdlib"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -14,17 +14,17 @@ dependencies {
|
||||
compileOnly(project(":js:js.serializer"))
|
||||
compileOnly(project(":js:js.frontend"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("annotations", "asm-all", "trove4j", "util") }
|
||||
compileOnly(intellijDep()) { includeJars("annotations", "asm-all", "trove4j", "util", rootProject = rootProject) }
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
|
||||
testCompileOnly(project(":compiler:cli-common"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(protobufFull())
|
||||
testCompile(projectDist(":kotlin-stdlib"))
|
||||
testCompile(project(":kotlin-stdlib"))
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi") }
|
||||
|
||||
testRuntime(projectDist(":kotlin-reflect"))
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.build
|
||||
|
||||
val DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS = listOf("kt", "kts")
|
||||
|
||||
@@ -23,10 +23,7 @@ import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import gnu.trove.THashSet
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.incremental.storage.*
|
||||
import org.jetbrains.kotlin.incremental.storage.version.clean
|
||||
import org.jetbrains.kotlin.incremental.storage.version.localCacheVersionManager
|
||||
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
@@ -264,11 +261,6 @@ open class IncrementalJvmCache(
|
||||
return protoMap[JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)]?.bytes
|
||||
}
|
||||
|
||||
override fun clean() {
|
||||
super.clean()
|
||||
localCacheVersionManager(targetDataRoot, IncrementalCompilation.isEnabledForJvm()).clean()
|
||||
}
|
||||
|
||||
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
|
||||
|
||||
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
|
||||
|
||||
@@ -21,11 +21,8 @@ import java.io.File
|
||||
fun File.isJavaFile() =
|
||||
extension.equals("java", ignoreCase = true)
|
||||
|
||||
fun File.isKotlinFile(): Boolean =
|
||||
extension.let {
|
||||
"kt".equals(it, ignoreCase = true) ||
|
||||
"kts".equals(it, ignoreCase = true)
|
||||
}
|
||||
fun File.isKotlinFile(sourceFilesExtensions: List<String>): Boolean =
|
||||
!isJavaFile() && sourceFilesExtensions.any { it.equals(extension, ignoreCase = true) }
|
||||
|
||||
fun File.isClassFile(): Boolean =
|
||||
extension.equals("class", ignoreCase = true)
|
||||
|
||||
@@ -67,12 +67,18 @@ fun getModificationsToPerform(
|
||||
val underscore = fileName.indexOf("_")
|
||||
|
||||
if (underscore != -1) {
|
||||
val module = fileName.substring(0, underscore)
|
||||
var moduleName = fileName.substring(0, underscore)
|
||||
var moduleFileName = fileName.substring(underscore + 1)
|
||||
if (moduleName.all { it.isDigit() }) {
|
||||
val (moduleName1, moduleFileName1) = moduleFileName.split("_")
|
||||
moduleName = moduleName1
|
||||
moduleFileName = moduleFileName1
|
||||
}
|
||||
|
||||
assert(moduleNames != null) { "File name has module prefix, but multi-module environment is absent" }
|
||||
assert(module in moduleNames!!) { "Module not found for file with prefix: $fileName" }
|
||||
assert(moduleName in moduleNames!!) { "Module not found for file with prefix: $fileName" }
|
||||
|
||||
return Pair(module, fileName.substring(underscore + 1))
|
||||
return Pair(moduleName, moduleFileName)
|
||||
}
|
||||
|
||||
assert(moduleNames == null) { "Test is multi-module, but file has no module prefix: $fileName" }
|
||||
|
||||
@@ -13,12 +13,12 @@ import proguard.gradle.ProGuardTask
|
||||
buildscript {
|
||||
extra["defaultSnapshotVersion"] = "1.3-SNAPSHOT"
|
||||
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.3.0-dev-322", onlySuccessBootstrap = false))
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.3.20-dev-564", onlySuccessBootstrap = false))
|
||||
|
||||
repositories {
|
||||
repositories.withRedirector(project) {
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
maven("https://plugins.gradle.org/m2")
|
||||
}
|
||||
}
|
||||
|
||||
// a workaround for kotlin compiler classpath in kotlin project: sometimes gradle substitutes
|
||||
// kotlin-stdlib external dependency with local project :kotlin-stdlib in kotlinCompilerClasspath configuration.
|
||||
@@ -35,7 +35,7 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
`build-scan`
|
||||
`build-scan` version "1.15"
|
||||
idea
|
||||
id("jps-compatible")
|
||||
}
|
||||
@@ -107,6 +107,7 @@ extra["JDK_17"] = jdkPath("1.7")
|
||||
extra["JDK_18"] = jdkPath("1.8")
|
||||
extra["JDK_9"] = jdkPath("9")
|
||||
extra["JDK_10"] = jdkPathIfFound("10")
|
||||
extra["JDK_11"] = jdkPathIfFound("11")
|
||||
|
||||
rootProject.apply {
|
||||
from(rootProject.file("versions.gradle.kts"))
|
||||
@@ -122,8 +123,8 @@ extra["versions.junit"] = "4.12"
|
||||
extra["versions.javaslang"] = "2.0.6"
|
||||
extra["versions.ant"] = "1.8.2"
|
||||
extra["versions.android"] = "2.3.1"
|
||||
extra["versions.kotlinx-coroutines-core"] = "0.20"
|
||||
extra["versions.kotlinx-coroutines-jdk8"] = "0.20"
|
||||
extra["versions.kotlinx-coroutines-core"] = "0.26.1-eap13"
|
||||
extra["versions.kotlinx-coroutines-jdk8"] = "0.26.1-eap13"
|
||||
extra["versions.json"] = "20160807"
|
||||
extra["versions.native-platform"] = "0.14"
|
||||
extra["versions.ant-launcher"] = "1.8.0"
|
||||
@@ -161,6 +162,8 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:resolution",
|
||||
":compiler:serialization",
|
||||
":compiler:psi",
|
||||
":compiler:fir:tree",
|
||||
":compiler:fir:psi2fir",
|
||||
":compiler:frontend",
|
||||
":compiler:frontend.java",
|
||||
":compiler:frontend.script",
|
||||
@@ -260,21 +263,20 @@ allprojects {
|
||||
|
||||
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
|
||||
|
||||
repositories {
|
||||
repositories.withRedirector(project) {
|
||||
intellijSdkRepo(project)
|
||||
androidDxJarRepo(project)
|
||||
mirrorRepo?.let(::maven)
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
|
||||
val commonCompilerArgs = listOfNotNull(
|
||||
"-Xallow-kotlin-package",
|
||||
"-Xread-deserialized-contracts",
|
||||
"-Xprogressive".takeIf { hasProperty("test.progressive.mode") }, // TODO: change to "-progressive" after bootstrap
|
||||
"-XXLanguage:-ReleaseCoroutines"
|
||||
"-Xprogressive".takeIf { hasProperty("test.progressive.mode") } // TODO: change to "-progressive" after bootstrap
|
||||
)
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
@@ -383,14 +385,14 @@ val ideaPlugin by task<Task> {
|
||||
}
|
||||
|
||||
tasks {
|
||||
"clean" {
|
||||
create("clean") {
|
||||
doLast {
|
||||
delete("$buildDir/repo")
|
||||
delete(distDir)
|
||||
}
|
||||
}
|
||||
|
||||
"cleanupArtifacts" {
|
||||
create("cleanupArtifacts") {
|
||||
doLast {
|
||||
delete(ideaPluginDir)
|
||||
delete(ideaUltimatePluginDir)
|
||||
@@ -398,7 +400,7 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
"coreLibsTest" {
|
||||
create("coreLibsTest") {
|
||||
(coreLibProjects + listOf(
|
||||
":kotlin-stdlib:samples",
|
||||
":kotlin-test:kotlin-test-js:kotlin-test-js-it",
|
||||
@@ -409,34 +411,35 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
"gradlePluginTest" {
|
||||
create("gradlePluginTest") {
|
||||
gradlePluginProjects.forEach {
|
||||
dependsOn(it + ":check")
|
||||
}
|
||||
}
|
||||
|
||||
"gradlePluginIntegrationTest" {
|
||||
create("gradlePluginIntegrationTest") {
|
||||
dependsOn(":kotlin-gradle-plugin-integration-tests:check")
|
||||
}
|
||||
|
||||
"jvmCompilerTest" {
|
||||
create("jvmCompilerTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":compiler:test",
|
||||
":compiler:container:test",
|
||||
":compiler:tests-java8:test")
|
||||
":compiler:tests-java8:test",
|
||||
":compiler:tests-spec:remoteRunTests")
|
||||
}
|
||||
|
||||
"jsCompilerTest" {
|
||||
create("jsCompilerTest") {
|
||||
dependsOn(":js:js.tests:test")
|
||||
dependsOn(":js:js.tests:runMocha")
|
||||
}
|
||||
|
||||
"scriptingTest" {
|
||||
create("scriptingTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":kotlin-script-util:test")
|
||||
}
|
||||
|
||||
"compilerTest" {
|
||||
create("compilerTest") {
|
||||
dependsOn("jvmCompilerTest")
|
||||
dependsOn("jsCompilerTest")
|
||||
|
||||
@@ -445,44 +448,44 @@ tasks {
|
||||
dependsOn(":compiler:incremental-compilation-impl:test")
|
||||
}
|
||||
|
||||
"toolsTest" {
|
||||
create("toolsTest") {
|
||||
dependsOn(":tools:kotlinp:test")
|
||||
}
|
||||
|
||||
"examplesTest" {
|
||||
create("examplesTest") {
|
||||
dependsOn("dist")
|
||||
(project(":examples").subprojects + project(":kotlin-gradle-subplugin-example")).forEach { p ->
|
||||
dependsOn("${p.path}:check")
|
||||
}
|
||||
}
|
||||
|
||||
"distTest" {
|
||||
create("distTest") {
|
||||
dependsOn("compilerTest")
|
||||
dependsOn("toolsTest")
|
||||
dependsOn("gradlePluginTest")
|
||||
dependsOn("examplesTest")
|
||||
}
|
||||
|
||||
"specTest" {
|
||||
create("specTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":compiler:tests-spec:test")
|
||||
}
|
||||
|
||||
"androidCodegenTest" {
|
||||
create("androidCodegenTest") {
|
||||
dependsOn(":compiler:android-tests:test")
|
||||
}
|
||||
|
||||
"jps-tests" {
|
||||
create("jps-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":jps-plugin:test")
|
||||
}
|
||||
|
||||
"idea-plugin-main-tests" {
|
||||
create("idea-plugin-main-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":idea:test")
|
||||
}
|
||||
|
||||
"idea-plugin-additional-tests" {
|
||||
create("idea-plugin-additional-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":idea:idea-gradle:test",
|
||||
":idea:idea-maven:test",
|
||||
@@ -490,20 +493,20 @@ tasks {
|
||||
":eval4j:test")
|
||||
}
|
||||
|
||||
"idea-plugin-tests" {
|
||||
create("idea-plugin-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn("idea-plugin-main-tests",
|
||||
"idea-plugin-additional-tests")
|
||||
}
|
||||
|
||||
"android-ide-tests" {
|
||||
create("android-ide-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":plugins:android-extensions-ide:test",
|
||||
":idea:idea-android:test",
|
||||
":kotlin-annotation-processing:test")
|
||||
}
|
||||
|
||||
"plugins-tests" {
|
||||
create("plugins-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":kotlin-annotation-processing:test",
|
||||
":kotlin-source-sections-compiler-plugin:test",
|
||||
@@ -511,11 +514,12 @@ tasks {
|
||||
":kotlin-noarg-compiler-plugin:test",
|
||||
":kotlin-sam-with-receiver-compiler-plugin:test",
|
||||
":plugins:uast-kotlin:test",
|
||||
":kotlin-annotation-processing-gradle:test")
|
||||
":kotlin-annotation-processing-gradle:test",
|
||||
":kotlinx-serialization-ide-plugin:test")
|
||||
}
|
||||
|
||||
|
||||
"ideaPluginTest" {
|
||||
create("ideaPluginTest") {
|
||||
dependsOn(
|
||||
"idea-plugin-tests",
|
||||
"jps-tests",
|
||||
@@ -526,12 +530,15 @@ tasks {
|
||||
}
|
||||
|
||||
|
||||
"test" {
|
||||
create("test") {
|
||||
doLast {
|
||||
throw GradleException("Don't use directly, use aggregate tasks *-check instead")
|
||||
}
|
||||
}
|
||||
"check" { dependsOn("test") }
|
||||
|
||||
create("check") {
|
||||
dependsOn("test")
|
||||
}
|
||||
}
|
||||
|
||||
fun CopySpec.setExecutablePermissions() {
|
||||
|
||||
712
build.gradle.kts.191
Normal file
712
build.gradle.kts.191
Normal file
@@ -0,0 +1,712 @@
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Project
|
||||
import java.util.*
|
||||
import java.io.File
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import proguard.gradle.ProGuardTask
|
||||
|
||||
buildscript {
|
||||
extra["defaultSnapshotVersion"] = "1.3-SNAPSHOT"
|
||||
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.3.20-dev-564", onlySuccessBootstrap = false))
|
||||
|
||||
repositories.withRedirector(project) {
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
maven("https://plugins.gradle.org/m2")
|
||||
}
|
||||
|
||||
// a workaround for kotlin compiler classpath in kotlin project: sometimes gradle substitutes
|
||||
// kotlin-stdlib external dependency with local project :kotlin-stdlib in kotlinCompilerClasspath configuration.
|
||||
// see also configureCompilerClasspath@
|
||||
val bootstrapCompilerClasspath by configurations.creating
|
||||
|
||||
dependencies {
|
||||
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
|
||||
|
||||
classpath("com.gradle.publish:plugin-publish-plugin:0.9.7")
|
||||
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
|
||||
classpath("net.sf.proguard:proguard-gradle:5.3.3")
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
`build-scan` version "1.15"
|
||||
idea
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
pill {
|
||||
excludedDirs(
|
||||
"out",
|
||||
"buildSrc/build",
|
||||
"buildSrc/prepare-deps/android-dx/build",
|
||||
"buildSrc/prepare-deps/intellij-sdk/build"
|
||||
)
|
||||
}
|
||||
|
||||
buildScan {
|
||||
setTermsOfServiceUrl("https://gradle.com/terms-of-service")
|
||||
setTermsOfServiceAgree("yes")
|
||||
}
|
||||
|
||||
val configuredJdks: List<JdkId> =
|
||||
getConfiguredJdks().also {
|
||||
it.forEach {
|
||||
logger.info("Using ${it.majorVersion} home: ${it.homeDir}")
|
||||
}
|
||||
}
|
||||
|
||||
val defaultSnapshotVersion: String by extra
|
||||
val buildNumber by extra(findProperty("build.number")?.toString() ?: defaultSnapshotVersion)
|
||||
val kotlinVersion by extra(findProperty("deployVersion")?.toString() ?: buildNumber)
|
||||
|
||||
val kotlinLanguageVersion by extra("1.3")
|
||||
|
||||
allprojects {
|
||||
group = "org.jetbrains.kotlin"
|
||||
version = kotlinVersion
|
||||
}
|
||||
|
||||
extra["kotlin_root"] = rootDir
|
||||
|
||||
val cidrKotlinPlugin by configurations.creating
|
||||
|
||||
dependencies {
|
||||
cidrKotlinPlugin(project(":prepare:cidr-plugin", "runtimeJar"))
|
||||
}
|
||||
|
||||
val commonBuildDir = File(rootDir, "build")
|
||||
val distDir by extra("$rootDir/dist")
|
||||
val distKotlinHomeDir by extra("$distDir/kotlinc")
|
||||
val distLibDir = "$distKotlinHomeDir/lib"
|
||||
val commonLocalDataDir = "$rootDir/local"
|
||||
val ideaSandboxDir = "$commonLocalDataDir/ideaSandbox"
|
||||
val ideaUltimateSandboxDir = "$commonLocalDataDir/ideaUltimateSandbox"
|
||||
val ideaPluginDir = "$distDir/artifacts/ideaPlugin/Kotlin"
|
||||
val ideaUltimatePluginDir = "$distDir/artifacts/ideaUltimatePlugin/Kotlin"
|
||||
val cidrPluginDir = "$distDir/artifacts/cidrPlugin/Kotlin"
|
||||
|
||||
// TODO: use "by extra()" syntax where possible
|
||||
extra["distLibDir"] = project.file(distLibDir)
|
||||
extra["libsDir"] = project.file(distLibDir)
|
||||
extra["commonLocalDataDir"] = project.file(commonLocalDataDir)
|
||||
extra["ideaSandboxDir"] = project.file(ideaSandboxDir)
|
||||
extra["ideaUltimateSandboxDir"] = project.file(ideaUltimateSandboxDir)
|
||||
extra["ideaPluginDir"] = project.file(ideaPluginDir)
|
||||
extra["ideaUltimatePluginDir"] = project.file(ideaUltimatePluginDir)
|
||||
extra["cidrPluginDir"] = project.file(cidrPluginDir)
|
||||
extra["isSonatypeRelease"] = false
|
||||
|
||||
extra["JDK_16"] = jdkPath("1.6")
|
||||
extra["JDK_17"] = jdkPath("1.7")
|
||||
extra["JDK_18"] = jdkPath("1.8")
|
||||
extra["JDK_9"] = jdkPath("9")
|
||||
extra["JDK_10"] = jdkPathIfFound("10")
|
||||
extra["JDK_11"] = jdkPathIfFound("11")
|
||||
|
||||
rootProject.apply {
|
||||
from(rootProject.file("versions.gradle.kts"))
|
||||
from(rootProject.file("report.gradle.kts"))
|
||||
}
|
||||
|
||||
extra["versions.protobuf-java"] = "2.6.1"
|
||||
extra["versions.javax.inject"] = "1"
|
||||
extra["versions.jsr305"] = "1.3.9"
|
||||
extra["versions.jansi"] = "1.16"
|
||||
extra["versions.jline"] = "3.3.1"
|
||||
extra["versions.junit"] = "4.12"
|
||||
extra["versions.javaslang"] = "2.0.6"
|
||||
extra["versions.ant"] = "1.8.2"
|
||||
extra["versions.android"] = "2.3.1"
|
||||
extra["versions.kotlinx-coroutines-core"] = "0.26.1-eap13"
|
||||
extra["versions.kotlinx-coroutines-jdk8"] = "0.26.1-eap13"
|
||||
extra["versions.json"] = "20160807"
|
||||
extra["versions.native-platform"] = "0.14"
|
||||
extra["versions.ant-launcher"] = "1.8.0"
|
||||
extra["versions.robolectric"] = "3.1"
|
||||
extra["versions.org.springframework"] = "4.2.0.RELEASE"
|
||||
extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
|
||||
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
|
||||
val intellijUltimateEnabled = project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild
|
||||
val effectSystemEnabled by extra(project.getBooleanProperty("kotlin.compiler.effectSystemEnabled") ?: false)
|
||||
val newInferenceEnabled by extra(project.getBooleanProperty("kotlin.compiler.newInferenceEnabled") ?: false)
|
||||
|
||||
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
|
||||
|
||||
extra["intellijUltimateEnabled"] = intellijUltimateEnabled
|
||||
extra["intellijSeparateSdks"] = intellijSeparateSdks
|
||||
|
||||
extra["IntellijCoreDependencies"] =
|
||||
listOf("annotations",
|
||||
"asm-all-7.0-beta",
|
||||
"guava",
|
||||
"jdom",
|
||||
"jna",
|
||||
"log4j",
|
||||
"picocontainer",
|
||||
"snappy-in-java",
|
||||
"streamex",
|
||||
"trove4j")
|
||||
|
||||
|
||||
extra["compilerModules"] = arrayOf(
|
||||
":compiler:util",
|
||||
":compiler:container",
|
||||
":compiler:resolution",
|
||||
":compiler:serialization",
|
||||
":compiler:psi",
|
||||
":compiler:frontend",
|
||||
":compiler:frontend.java",
|
||||
":compiler:frontend.script",
|
||||
":compiler:cli-common",
|
||||
":compiler:daemon-common",
|
||||
":compiler:daemon",
|
||||
":compiler:ir.tree",
|
||||
":compiler:ir.psi2ir",
|
||||
":compiler:ir.backend.common",
|
||||
":compiler:backend.js",
|
||||
":compiler:backend-common",
|
||||
":compiler:backend",
|
||||
":compiler:plugin-api",
|
||||
":compiler:light-classes",
|
||||
":compiler:cli",
|
||||
":compiler:incremental-compilation-impl",
|
||||
":js:js.ast",
|
||||
":js:js.serializer",
|
||||
":js:js.parser",
|
||||
":js:js.frontend",
|
||||
":js:js.translator",
|
||||
":js:js.dce",
|
||||
":compiler",
|
||||
":kotlin-build-common",
|
||||
":core:metadata",
|
||||
":core:metadata.jvm",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":core:deserialization",
|
||||
":core:util.runtime"
|
||||
)
|
||||
|
||||
val coreLibProjects = listOf(
|
||||
":kotlin-stdlib",
|
||||
":kotlin-stdlib-common",
|
||||
":kotlin-stdlib-js",
|
||||
":kotlin-stdlib-jre7",
|
||||
":kotlin-stdlib-jre8",
|
||||
":kotlin-stdlib-jdk7",
|
||||
":kotlin-stdlib-jdk8",
|
||||
":kotlin-test:kotlin-test-common",
|
||||
":kotlin-test:kotlin-test-jvm",
|
||||
":kotlin-test:kotlin-test-junit",
|
||||
":kotlin-test:kotlin-test-junit5",
|
||||
":kotlin-test:kotlin-test-testng",
|
||||
":kotlin-test:kotlin-test-js",
|
||||
":kotlin-reflect"
|
||||
)
|
||||
|
||||
val gradlePluginProjects = listOf(
|
||||
":kotlin-gradle-plugin",
|
||||
":kotlin-gradle-plugin:plugin-marker",
|
||||
":kotlin-gradle-plugin-api",
|
||||
// ":kotlin-gradle-plugin-integration-tests", // TODO: build fails
|
||||
":kotlin-allopen",
|
||||
":kotlin-allopen:plugin-marker",
|
||||
":kotlin-annotation-processing-gradle",
|
||||
":kotlin-noarg",
|
||||
":kotlin-noarg:plugin-marker",
|
||||
":kotlin-sam-with-receiver"
|
||||
)
|
||||
|
||||
apply {
|
||||
from("libraries/commonConfiguration.gradle")
|
||||
from("libraries/configureGradleTools.gradle")
|
||||
}
|
||||
|
||||
apply {
|
||||
if (extra["isSonatypeRelease"] as? Boolean == true) {
|
||||
logger.info("Applying configuration for sonatype release")
|
||||
from("libraries/prepareSonatypeStaging.gradle")
|
||||
}
|
||||
}
|
||||
|
||||
fun Task.listConfigurationContents(configName: String) {
|
||||
doFirst {
|
||||
project.configurations.findByName(configName)?.let {
|
||||
println("$configName configuration files:\n${it.allArtifacts.files.files.joinToString("\n ", " ")}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val defaultJvmTarget = "1.8"
|
||||
val defaultJavaHome = jdkPath(defaultJvmTarget!!)
|
||||
val ignoreTestFailures by extra(project.findProperty("ignoreTestFailures")?.toString()?.toBoolean() ?: project.hasProperty("teamcity"))
|
||||
|
||||
allprojects {
|
||||
|
||||
jvmTarget = defaultJvmTarget
|
||||
javaHome = defaultJavaHome
|
||||
|
||||
// There are problems with common build dir:
|
||||
// - some tests (in particular js and binary-compatibility-validator depend on the fixed (default) location
|
||||
// - idea seems unable to exclude common builddir from indexing
|
||||
// therefore it is disabled by default
|
||||
// buildDir = File(commonBuildDir, project.name)
|
||||
|
||||
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
|
||||
|
||||
repositories.withRedirector(project) {
|
||||
intellijSdkRepo(project)
|
||||
androidDxJarRepo(project)
|
||||
mirrorRepo?.let(::maven)
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
jcenter()
|
||||
}
|
||||
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
|
||||
val commonCompilerArgs = listOfNotNull(
|
||||
"-Xallow-kotlin-package",
|
||||
"-Xread-deserialized-contracts",
|
||||
"-Xprogressive".takeIf { hasProperty("test.progressive.mode") } // TODO: change to "-progressive" after bootstrap
|
||||
)
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
kotlinOptions {
|
||||
languageVersion = kotlinLanguageVersion
|
||||
apiVersion = kotlinLanguageVersion
|
||||
freeCompilerArgs = commonCompilerArgs
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = commonCompilerArgs + listOf("-Xnormalize-constructor-calls=enable")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(VerificationTask::class.java as Class<Task>) {
|
||||
(this as VerificationTask).ignoreFailures = ignoreTestFailures
|
||||
}
|
||||
|
||||
tasks.withType<Javadoc> {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
task<Jar>("javadocJar") {
|
||||
classifier = "javadoc"
|
||||
}
|
||||
|
||||
tasks.withType<Jar> {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
task("listArchives") { listConfigurationContents("archives") }
|
||||
|
||||
task("listRuntimeJar") { listConfigurationContents("runtimeJar") }
|
||||
|
||||
task("listDistJar") { listConfigurationContents("distJar") }
|
||||
|
||||
afterEvaluate {
|
||||
logger.info("configuring project $name to compile to the target jvm version $jvmTarget using jdk: $javaHome")
|
||||
if (javaHome != defaultJavaHome || jvmTarget != defaultJvmTarget) {
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
}
|
||||
|
||||
fun File.toProjectRootRelativePathOrSelf() = (relativeToOrNull(rootDir)?.takeUnless { it.startsWith("..") } ?: this).path
|
||||
|
||||
fun FileCollection.printClassPath(role: String) =
|
||||
println("${project.path} $role classpath:\n ${joinToString("\n ") { it.toProjectRootRelativePathOrSelf() } }")
|
||||
|
||||
try { javaPluginConvention() } catch (_: UnknownDomainObjectException) { null }?.let { javaConvention ->
|
||||
task("printCompileClasspath") { doFirst { javaConvention.sourceSets["main"].compileClasspath.printClassPath("compile") } }
|
||||
task("printRuntimeClasspath") { doFirst { javaConvention.sourceSets["main"].runtimeClasspath.printClassPath("runtime") } }
|
||||
task("printTestCompileClasspath") { doFirst { javaConvention.sourceSets["test"].compileClasspath.printClassPath("test compile") } }
|
||||
task("printTestRuntimeClasspath") { doFirst { javaConvention.sourceSets["test"].runtimeClasspath.printClassPath("test runtime") } }
|
||||
}
|
||||
|
||||
run configureCompilerClasspath@ {
|
||||
val bootstrapCompilerClasspath by rootProject.buildscript.configurations
|
||||
configurations.findByName("kotlinCompilerClasspath")?.let {
|
||||
dependencies.add(it.name, files(bootstrapCompilerClasspath))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gradle.taskGraph.whenReady {
|
||||
if (isTeamcityBuild) {
|
||||
logger.warn("CI build profile is active (IC is off, proguard is on). Use -Pteamcity=false to reproduce local build")
|
||||
for (task in allTasks) {
|
||||
when (task) {
|
||||
is AbstractKotlinCompile<*> -> task.incremental = false
|
||||
is JavaCompile -> task.options.isIncremental = false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn("Local build profile is active (IC is on, proguard is off). Use -Pteamcity=true to reproduce TC build")
|
||||
for (task in allTasks) {
|
||||
when (task) {
|
||||
// todo: remove when Gradle 4.10+ is used (Java IC on by default)
|
||||
is JavaCompile -> task.options.isIncremental = true
|
||||
is org.gradle.jvm.tasks.Jar -> task.entryCompression = ZipEntryCompression.STORED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dist by task<Copy> {
|
||||
val childDistTasks = getTasksByName("dist", true) - this@task
|
||||
dependsOn(childDistTasks)
|
||||
|
||||
into(distDir)
|
||||
from(files("compiler/cli/bin")) { into("kotlinc/bin") }
|
||||
from(files("license")) { into("kotlinc/license") }
|
||||
}
|
||||
|
||||
val copyCompilerToIdeaPlugin by task<Copy> {
|
||||
dependsOn(dist)
|
||||
into(ideaPluginDir)
|
||||
from(distDir) { include("kotlinc/**") }
|
||||
}
|
||||
|
||||
val ideaPlugin by task<Task> {
|
||||
dependsOn(copyCompilerToIdeaPlugin)
|
||||
val childIdeaPluginTasks = getTasksByName("ideaPlugin", true) - this@task
|
||||
dependsOn(childIdeaPluginTasks)
|
||||
}
|
||||
|
||||
tasks {
|
||||
create("clean") {
|
||||
doLast {
|
||||
delete("$buildDir/repo")
|
||||
delete(distDir)
|
||||
}
|
||||
}
|
||||
|
||||
create("cleanupArtifacts") {
|
||||
doLast {
|
||||
delete(ideaPluginDir)
|
||||
delete(ideaUltimatePluginDir)
|
||||
delete(cidrPluginDir)
|
||||
}
|
||||
}
|
||||
|
||||
create("coreLibsTest") {
|
||||
(coreLibProjects + listOf(
|
||||
":kotlin-stdlib:samples",
|
||||
":kotlin-test:kotlin-test-js:kotlin-test-js-it",
|
||||
":kotlinx-metadata-jvm",
|
||||
":tools:binary-compatibility-validator"
|
||||
)).forEach {
|
||||
dependsOn(it + ":check")
|
||||
}
|
||||
}
|
||||
|
||||
create("gradlePluginTest") {
|
||||
gradlePluginProjects.forEach {
|
||||
dependsOn(it + ":check")
|
||||
}
|
||||
}
|
||||
|
||||
create("gradlePluginIntegrationTest") {
|
||||
dependsOn(":kotlin-gradle-plugin-integration-tests:check")
|
||||
}
|
||||
|
||||
create("jvmCompilerTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":compiler:test",
|
||||
":compiler:container:test",
|
||||
":compiler:tests-java8:test",
|
||||
":compiler:tests-spec:remoteRunTests")
|
||||
}
|
||||
|
||||
create("jsCompilerTest") {
|
||||
dependsOn(":js:js.tests:test")
|
||||
dependsOn(":js:js.tests:runMocha")
|
||||
}
|
||||
|
||||
create("scriptingTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":kotlin-script-util:test")
|
||||
}
|
||||
|
||||
create("compilerTest") {
|
||||
dependsOn("jvmCompilerTest")
|
||||
dependsOn("jsCompilerTest")
|
||||
|
||||
dependsOn("scriptingTest")
|
||||
dependsOn(":kotlin-build-common:test")
|
||||
dependsOn(":compiler:incremental-compilation-impl:test")
|
||||
}
|
||||
|
||||
create("toolsTest") {
|
||||
dependsOn(":tools:kotlinp:test")
|
||||
}
|
||||
|
||||
create("examplesTest") {
|
||||
dependsOn("dist")
|
||||
(project(":examples").subprojects + project(":kotlin-gradle-subplugin-example")).forEach { p ->
|
||||
dependsOn("${p.path}:check")
|
||||
}
|
||||
}
|
||||
|
||||
create("distTest") {
|
||||
dependsOn("compilerTest")
|
||||
dependsOn("toolsTest")
|
||||
dependsOn("gradlePluginTest")
|
||||
dependsOn("examplesTest")
|
||||
}
|
||||
|
||||
create("specTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":compiler:tests-spec:test")
|
||||
}
|
||||
|
||||
create("androidCodegenTest") {
|
||||
dependsOn(":compiler:android-tests:test")
|
||||
}
|
||||
|
||||
create("jps-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":jps-plugin:test")
|
||||
}
|
||||
|
||||
create("idea-plugin-main-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":idea:test")
|
||||
}
|
||||
|
||||
create("idea-plugin-additional-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":idea:idea-gradle:test",
|
||||
":idea:idea-maven:test",
|
||||
":j2k:test",
|
||||
":eval4j:test")
|
||||
}
|
||||
|
||||
create("idea-plugin-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn("idea-plugin-main-tests",
|
||||
"idea-plugin-additional-tests")
|
||||
}
|
||||
|
||||
create("android-ide-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":plugins:android-extensions-ide:test",
|
||||
":idea:idea-android:test",
|
||||
":kotlin-annotation-processing:test")
|
||||
}
|
||||
|
||||
create("plugins-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":kotlin-annotation-processing:test",
|
||||
":kotlin-source-sections-compiler-plugin:test",
|
||||
":kotlin-allopen-compiler-plugin:test",
|
||||
":kotlin-noarg-compiler-plugin:test",
|
||||
":kotlin-sam-with-receiver-compiler-plugin:test",
|
||||
":plugins:uast-kotlin:test",
|
||||
":kotlin-annotation-processing-gradle:test",
|
||||
":kotlinx-serialization-ide-plugin:test")
|
||||
}
|
||||
|
||||
|
||||
create("ideaPluginTest") {
|
||||
dependsOn(
|
||||
"idea-plugin-tests",
|
||||
"jps-tests",
|
||||
"plugins-tests",
|
||||
"android-ide-tests",
|
||||
":generators:test"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
create("test") {
|
||||
doLast {
|
||||
throw GradleException("Don't use directly, use aggregate tasks *-check instead")
|
||||
}
|
||||
}
|
||||
|
||||
create("check") {
|
||||
dependsOn("test")
|
||||
}
|
||||
}
|
||||
|
||||
fun CopySpec.setExecutablePermissions() {
|
||||
filesMatching("**/bin/*") { mode = 0b111101101 }
|
||||
filesMatching("**/bin/*.bat") { mode = 0b110100100 }
|
||||
}
|
||||
|
||||
val zipCompiler by task<Zip> {
|
||||
dependsOn(dist)
|
||||
destinationDir = file(distDir)
|
||||
archiveName = "kotlin-compiler-$kotlinVersion.zip"
|
||||
|
||||
from(distKotlinHomeDir)
|
||||
into("kotlinc")
|
||||
setExecutablePermissions()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("Compiler artifacts packed to $archivePath")
|
||||
}
|
||||
}
|
||||
|
||||
val zipTestData by task<Zip> {
|
||||
destinationDir = file(distDir)
|
||||
archiveName = "kotlin-test-data.zip"
|
||||
from("compiler/testData") { into("compiler") }
|
||||
from("idea/testData") { into("ide") }
|
||||
from("idea/idea-completion/testData") { into("ide/completion") }
|
||||
from("libraries/stdlib/common/test") { into("stdlib/common") }
|
||||
from("libraries/stdlib/test") { into("stdlib/test") }
|
||||
doLast {
|
||||
logger.lifecycle("Test data packed to $archivePath")
|
||||
}
|
||||
}
|
||||
|
||||
val zipPlugin by task<Zip> {
|
||||
val src = when (project.findProperty("pluginArtifactDir") as String?) {
|
||||
"Kotlin" -> ideaPluginDir
|
||||
"KotlinUltimate" -> ideaUltimatePluginDir
|
||||
null -> if (project.hasProperty("ultimate")) ideaUltimatePluginDir else ideaPluginDir
|
||||
else -> error("Unsupported plugin artifact dir")
|
||||
}
|
||||
val destPath = project.findProperty("pluginZipPath") as String?
|
||||
val dest = File(destPath ?: "$buildDir/kotlin-plugin.zip")
|
||||
destinationDir = dest.parentFile
|
||||
archiveName = dest.name
|
||||
doFirst {
|
||||
if (destPath == null) throw GradleException("Specify target zip path with 'pluginZipPath' property")
|
||||
}
|
||||
|
||||
from(src)
|
||||
into("Kotlin")
|
||||
setExecutablePermissions()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("Plugin artifacts packed to $archivePath")
|
||||
}
|
||||
}
|
||||
|
||||
val cidrPlugin by task<Copy> {
|
||||
dependsOn(ideaPlugin)
|
||||
into(cidrPluginDir)
|
||||
from(ideaPluginDir) {
|
||||
exclude("lib/kotlin-plugin.jar")
|
||||
|
||||
exclude("lib/android-lint.jar")
|
||||
exclude("lib/android-ide.jar")
|
||||
exclude("lib/android-output-parser-ide.jar")
|
||||
exclude("lib/android-extensions-ide.jar")
|
||||
exclude("lib/android-extensions-compiler.jar")
|
||||
exclude("lib/kapt3-idea.jar")
|
||||
exclude("lib/jps-ide.jar")
|
||||
exclude("lib/jps/**")
|
||||
exclude("kotlinc/**")
|
||||
exclude("lib/maven-ide.jar")
|
||||
}
|
||||
from(cidrKotlinPlugin) { into("lib") }
|
||||
}
|
||||
|
||||
val zipCidrPlugin by task<Zip> {
|
||||
val destPath = project.findProperty("pluginZipPath") as String?
|
||||
?: "$distDir/artifacts/kotlin-plugin-$kotlinVersion-CIDR.zip"
|
||||
val destFile = File(destPath)
|
||||
|
||||
destinationDir = destFile.parentFile
|
||||
archiveName = destFile.name
|
||||
|
||||
from(cidrPlugin)
|
||||
into("Kotlin")
|
||||
setExecutablePermissions()
|
||||
|
||||
doLast {
|
||||
logger.lifecycle("Plugin artifacts packed to $archivePath")
|
||||
}
|
||||
}
|
||||
|
||||
configure<IdeaModel> {
|
||||
module {
|
||||
excludeDirs = files(
|
||||
project.buildDir,
|
||||
commonLocalDataDir,
|
||||
".gradle",
|
||||
"dependencies",
|
||||
"dist"
|
||||
).toSet()
|
||||
}
|
||||
}
|
||||
|
||||
fun jdkPathIfFound(version: String): String? {
|
||||
val jdkName = "JDK_${version.replace(".", "")}"
|
||||
val jdkMajorVersion = JdkMajorVersion.valueOf(jdkName)
|
||||
return configuredJdks.find { it.majorVersion == jdkMajorVersion }?.homeDir?.canonicalPath
|
||||
}
|
||||
|
||||
fun jdkPath(version: String): String = jdkPathIfFound(version)
|
||||
?: throw GradleException ("Please set environment variable JDK_${version.replace(".", "")} to point to JDK $version installation")
|
||||
|
||||
fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
|
||||
tasks.withType<JavaCompile> {
|
||||
if (name != "compileJava9Java") {
|
||||
options.isFork = true
|
||||
options.forkOptions.javaHome = file(javaHome)
|
||||
options.compilerArgs.add("-proc:none")
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jdkHome = javaHome
|
||||
kotlinOptions.jvmTarget = javaVersion
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
executable = File(javaHome, "bin/java").canonicalPath
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("findShadowJarsInClasspath").doLast {
|
||||
fun Collection<File>.printSorted(indent: String = " ") {
|
||||
sortedBy { it.path }.forEach { println(indent + it.relativeTo(rootProject.projectDir)) }
|
||||
}
|
||||
|
||||
val shadowJars = hashSetOf<File>()
|
||||
for (project in rootProject.allprojects) {
|
||||
for (task in project.tasks) {
|
||||
when (task) {
|
||||
is ShadowJar -> {
|
||||
shadowJars.add(fileFrom(task.archivePath))
|
||||
}
|
||||
is ProGuardTask -> {
|
||||
shadowJars.addAll(task.outputs.files.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println("Shadow jars:")
|
||||
shadowJars.printSorted()
|
||||
|
||||
fun Project.checkConfig(configName: String) {
|
||||
val config = configurations.findByName(configName) ?: return
|
||||
val shadowJarsInConfig = config.resolvedConfiguration.files.filter { it in shadowJars }
|
||||
if (shadowJarsInConfig.isNotEmpty()) {
|
||||
println()
|
||||
println("Project $project contains shadow jars in configuration '$configName':")
|
||||
shadowJarsInConfig.printSorted()
|
||||
}
|
||||
}
|
||||
|
||||
for (project in rootProject.allprojects) {
|
||||
project.checkConfig("compileClasspath")
|
||||
project.checkConfig("testCompileClasspath")
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
|
||||
buildscript {
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
val buildSrcKotlinVersion: String by extra(findProperty("buildSrc.kotlin.version")?.toString() ?: embeddedKotlinVersion)
|
||||
val buildSrcKotlinRepo: String? by extra(findProperty("buildSrc.kotlin.repo") as String?)
|
||||
extra["versions.shadow"] = "2.0.2"
|
||||
extra["versions.native-platform"] = "0.14"
|
||||
|
||||
repositories {
|
||||
if (cacheRedirectorEnabled) {
|
||||
maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com")
|
||||
}
|
||||
|
||||
buildSrcKotlinRepo?.let {
|
||||
maven(url = it)
|
||||
}
|
||||
@@ -17,6 +23,8 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
logger.info("buildSrcKotlinVersion: " + extra["buildSrcKotlinVersion"])
|
||||
logger.info("buildSrc kotlin compiler version: " + org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)
|
||||
logger.info("buildSrc stdlib version: " + KotlinVersion.CURRENT)
|
||||
@@ -32,12 +40,12 @@ plugins {
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
(plugins) {
|
||||
"pill-configurable" {
|
||||
plugins {
|
||||
register("pill-configurable") {
|
||||
id = "pill-configurable"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
|
||||
}
|
||||
"jps-compatible" {
|
||||
register("jps-compatible") {
|
||||
id = "jps-compatible"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatiblePlugin"
|
||||
}
|
||||
@@ -58,8 +66,6 @@ val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY
|
||||
val intellijUltimateEnabled by extra(project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild)
|
||||
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
|
||||
|
||||
extra["intellijRepo"] = "https://www.jetbrains.com/intellij-repository"
|
||||
|
||||
extra["intellijReleaseType"] = if (extra["versions.intellijSdk"]?.toString()?.endsWith("SNAPSHOT") == true)
|
||||
"snapshots"
|
||||
else
|
||||
@@ -70,10 +76,14 @@ extra["versions.androidDxSources"] = "5.0.0_r2"
|
||||
extra["customDepsOrg"] = "kotlin.build.custom.deps"
|
||||
|
||||
repositories {
|
||||
if (cacheRedirectorEnabled) {
|
||||
maven("https://cache-redirector.jetbrains.com/jcenter.bintray.com")
|
||||
}
|
||||
|
||||
extra["buildSrcKotlinRepo"]?.let {
|
||||
maven(url = it)
|
||||
}
|
||||
maven(url = "https://repo.gradle.org/gradle/ext-releases-local") // for native-platform
|
||||
|
||||
jcenter()
|
||||
}
|
||||
|
||||
@@ -82,9 +92,7 @@ dependencies {
|
||||
compile("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
|
||||
compile("net.rubygrapefruit:native-platform-windows-i386:${property("versions.native-platform")}")
|
||||
compile("com.jakewharton.dex:dex-method-list:3.0.0")
|
||||
// TODO: adding the dep to the plugin breaks the build unexpectedly, resolve and uncomment
|
||||
// compile("org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.extra["bootstrap_kotlin_version"]}")
|
||||
// Shadow plugin is used in many projects of the main build. Once it's no longer used in buildSrc, please move this dependency to the root project
|
||||
|
||||
compile("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
|
||||
compile("org.ow2.asm:asm-all:6.0_BETA")
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@ org.gradle.parallel=false
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
@@ -3,6 +3,8 @@ org.gradle.parallel=false
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ org.gradle.parallel=false
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ org.gradle.parallel=false
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
|
||||
11
buildSrc/gradle.properties.as34
Normal file
11
buildSrc/gradle.properties.as34
Normal file
@@ -0,0 +1,11 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.parallel=false
|
||||
org.gradle.configureondemand=false
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
intellijUltimateEnabled=false
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import org.gradle.api.publish.ivy.internal.artifact.DefaultIvyArtifact
|
||||
import org.gradle.api.publish.ivy.internal.artifact.FileBasedIvyArtifact
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyConfiguration
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyPublicationIdentity
|
||||
import org.gradle.api.publish.ivy.internal.publisher.IvyDescriptorFileGenerator
|
||||
@@ -92,8 +92,8 @@ val prepareIvyXml by tasks.creating {
|
||||
with(IvyDescriptorFileGenerator(DefaultIvyPublicationIdentity(customDepsOrg, dxModuleName, dxRevision))) {
|
||||
addConfiguration(DefaultIvyConfiguration("default"))
|
||||
addConfiguration(DefaultIvyConfiguration("sources"))
|
||||
addArtifact(DefaultIvyArtifact(File(dxRepoModuleDir, "dx.jar"), "dx", "jar", "jar", null).also { it.conf = "default" })
|
||||
addArtifact(DefaultIvyArtifact(File(dxRepoModuleDir, "dx-sources.jar"), "dx", "jar", "sources", "sources").also { it.conf = "sources" })
|
||||
addArtifact(FileBasedIvyArtifact(File(dxRepoModuleDir, "dx.jar"), DefaultIvyPublicationIdentity(customDepsOrg, "dx", dxRevision)).also { it.conf = "default" })
|
||||
addArtifact(FileBasedIvyArtifact(File(dxRepoModuleDir, "dx-sources.jar"), DefaultIvyPublicationIdentity(customDepsOrg, "dx", dxRevision)).also { it.conf = "sources" })
|
||||
writeTo(ivyFile)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,15 @@
|
||||
|
||||
@file:Suppress("PropertyName")
|
||||
|
||||
import org.gradle.api.publish.ivy.internal.artifact.DefaultIvyArtifact
|
||||
import org.gradle.api.publish.ivy.internal.artifact.FileBasedIvyArtifact
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyConfiguration
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyPublicationIdentity
|
||||
import org.gradle.api.publish.ivy.internal.publisher.IvyDescriptorFileGenerator
|
||||
import java.io.File
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
|
||||
}
|
||||
}
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
val intellijUltimateEnabled: Boolean by rootProject.extra
|
||||
val intellijRepo: String by rootProject.extra
|
||||
val intellijReleaseType: String by rootProject.extra
|
||||
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
|
||||
val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelease") as String?
|
||||
@@ -66,8 +56,14 @@ repositories {
|
||||
}
|
||||
}
|
||||
}
|
||||
maven { setUrl("$intellijRepo/$intellijReleaseType") }
|
||||
maven { setUrl("https://plugins.jetbrains.com/maven") }
|
||||
|
||||
if (cacheRedirectorEnabled) {
|
||||
maven("https://cache-redirector.jetbrains.com/www.jetbrains.com/intellij-repository/$intellijReleaseType")
|
||||
maven("https://cache-redirector.jetbrains.com/plugins.jetbrains.com/maven")
|
||||
}
|
||||
|
||||
maven("https://www.jetbrains.com/intellij-repository/$intellijReleaseType")
|
||||
maven("https://plugins.jetbrains.com/maven")
|
||||
}
|
||||
|
||||
val intellij by configurations.creating
|
||||
@@ -152,12 +148,9 @@ val unzipIntellijCore by tasks.creating { configureExtractFromConfigurationTask(
|
||||
|
||||
val unzipJpsStandalone by tasks.creating { configureExtractFromConfigurationTask(`jps-standalone`) { zipTree(it.singleFile) } }
|
||||
|
||||
val copyIntellijSdkSources by tasks.creating(ShadowJar::class.java) {
|
||||
val copyIntellijSdkSources by tasks.creating(Copy::class.java) {
|
||||
from(sources)
|
||||
baseName = "ideaIC"
|
||||
version = intellijVersion
|
||||
classifier = "sources"
|
||||
destinationDir = File(repoDir, sources.name)
|
||||
into(File(repoDir, sources.name))
|
||||
}
|
||||
|
||||
val copyJpsBuildTest by tasks.creating { configureExtractFromConfigurationTask(`jps-build-test`) { it.singleFile } }
|
||||
@@ -171,12 +164,12 @@ fun writeIvyXml(moduleName: String, fileName: String, jarFiles: FileCollection,
|
||||
jarFiles.asFileTree.files.forEach {
|
||||
if (it.isFile && it.extension == "jar") {
|
||||
val relativeName = it.toRelativeString(baseDir).removeSuffix(".jar")
|
||||
addArtifact(DefaultIvyArtifact(it, relativeName, "jar", "jar", null).also { it.conf = "default" })
|
||||
addArtifact(FileBasedIvyArtifact(it, DefaultIvyPublicationIdentity(customDepsOrg, relativeName, intellijVersion)).also { it.conf = "default" })
|
||||
}
|
||||
}
|
||||
if (sourcesJar != null) {
|
||||
val sourcesArtifactName = sourcesJar.name.removeSuffix(".jar").substringBefore("-")
|
||||
addArtifact(DefaultIvyArtifact(sourcesJar, sourcesArtifactName, "jar", "sources", "sources").also { it.conf = "sources" })
|
||||
addArtifact(FileBasedIvyArtifact(sourcesJar, DefaultIvyPublicationIdentity(customDepsOrg, sourcesArtifactName, intellijVersion)).also { it.conf = "sources" })
|
||||
}
|
||||
writeTo(File(customDepsRepoModulesDir, "$fileName.ivy.xml"))
|
||||
}
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
|
||||
@file:Suppress("PropertyName")
|
||||
|
||||
import org.gradle.api.publish.ivy.internal.artifact.DefaultIvyArtifact
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyConfiguration
|
||||
import org.gradle.api.publish.ivy.internal.publication.DefaultIvyPublicationIdentity
|
||||
import org.gradle.api.publish.ivy.internal.publisher.IvyDescriptorFileGenerator
|
||||
import java.io.File
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
|
||||
}
|
||||
}
|
||||
|
||||
val intellijUltimateEnabled: Boolean by rootProject.extra
|
||||
val intellijRepo: String by rootProject.extra
|
||||
val intellijReleaseType: String by rootProject.extra
|
||||
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
|
||||
val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelease") as String?
|
||||
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
|
||||
val intellijSeparateSdks: Boolean by rootProject.extra
|
||||
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
|
||||
val installIntellijUltimate = intellijUltimateEnabled
|
||||
|
||||
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
|
||||
if (intellijVersionDelimiterIndex == -1) {
|
||||
error("Invalid IDEA version $intellijVersion")
|
||||
}
|
||||
|
||||
val platformBaseVersion = intellijVersion.substring(0, intellijVersionDelimiterIndex)
|
||||
|
||||
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
|
||||
|
||||
logger.info("intellijVersion: $intellijVersion")
|
||||
logger.info("androidStudioRelease: $androidStudioRelease")
|
||||
logger.info("androidStudioBuild: $androidStudioBuild")
|
||||
|
||||
logger.info("intellijSeparateSdks: $intellijSeparateSdks")
|
||||
logger.info("installIntellijCommunity: $installIntellijCommunity")
|
||||
logger.info("installIntellijUltimate: $installIntellijUltimate")
|
||||
|
||||
val studioOs by lazy {
|
||||
when {
|
||||
OperatingSystem.current().isWindows -> "windows"
|
||||
OperatingSystem.current().isMacOsX -> "mac"
|
||||
OperatingSystem.current().isLinux -> "linux"
|
||||
else -> {
|
||||
logger.error("Unknown operating system for android tools: ${OperatingSystem.current().name}")
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
if (androidStudioRelease != null) {
|
||||
ivy {
|
||||
artifactPattern("https://dl.google.com/dl/android/studio/ide-zips/$androidStudioRelease/[artifact]-[revision]-$studioOs.zip")
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
maven { setUrl("$intellijRepo/$intellijReleaseType") }
|
||||
maven { setUrl("https://plugins.jetbrains.com/maven") }
|
||||
}
|
||||
|
||||
val intellij by configurations.creating
|
||||
val intellijUltimate by configurations.creating
|
||||
val sources by configurations.creating
|
||||
val `jps-standalone` by configurations.creating
|
||||
val `jps-build-test` by configurations.creating
|
||||
val `intellij-core` by configurations.creating
|
||||
val `plugins-NodeJS` by configurations.creating
|
||||
|
||||
val customDepsRepoDir = File(buildDir, "repo")
|
||||
val customDepsOrg: String by rootProject.extra
|
||||
val customDepsRevision = intellijVersion
|
||||
val customDepsRepoModulesDir = File(customDepsRepoDir, "$customDepsOrg/$customDepsRevision")
|
||||
val repoDir = customDepsRepoModulesDir
|
||||
|
||||
dependencies {
|
||||
if (androidStudioRelease != null) {
|
||||
intellij("google:android-studio-ide:$androidStudioBuild")
|
||||
} else {
|
||||
if (installIntellijCommunity) {
|
||||
intellij("com.jetbrains.intellij.idea:ideaIC:$intellijVersion")
|
||||
}
|
||||
if (installIntellijUltimate) {
|
||||
intellijUltimate("com.jetbrains.intellij.idea:ideaIU:$intellijVersion")
|
||||
}
|
||||
}
|
||||
sources("com.jetbrains.intellij.idea:ideaIC:$intellijVersion:sources@jar")
|
||||
`jps-standalone`("com.jetbrains.intellij.idea:jps-standalone:$intellijVersion")
|
||||
`jps-build-test`("com.jetbrains.intellij.idea:jps-build-test:$intellijVersion")
|
||||
`intellij-core`("com.jetbrains.intellij.idea:intellij-core:$intellijVersion")
|
||||
if (intellijUltimateEnabled) {
|
||||
`plugins-NodeJS`("com.jetbrains.plugins:NodeJS:${rootProject.extra["versions.idea.NodeJS"]}@zip")
|
||||
}
|
||||
}
|
||||
|
||||
fun Task.configureExtractFromConfigurationTask(sourceConfig: Configuration,
|
||||
pathRemap: (String) -> String = { it },
|
||||
extractor: (Configuration) -> Any) {
|
||||
dependsOn(sourceConfig)
|
||||
inputs.files(sourceConfig)
|
||||
val targetDir = File(repoDir, sourceConfig.name)
|
||||
outputs.dirs(targetDir)
|
||||
doFirst {
|
||||
project.copy {
|
||||
from(extractor(sourceConfig))
|
||||
into(targetDir)
|
||||
eachFile {
|
||||
path = pathRemap(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removePathPrefix(path: String): String {
|
||||
if (androidStudioRelease == null) return path
|
||||
val slashes = if (studioOs == "mac") 2 else 1
|
||||
var result = path
|
||||
repeat(slashes) {
|
||||
result = result.substringAfter('/')
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val unzipIntellijSdk by tasks.creating {
|
||||
configureExtractFromConfigurationTask(intellij, pathRemap = { removePathPrefix(it) }) {
|
||||
zipTree(it.singleFile).matching {
|
||||
exclude("**/plugins/Kotlin/**")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unzipIntellijUltimateSdk by tasks.creating {
|
||||
configureExtractFromConfigurationTask(intellijUltimate) {
|
||||
zipTree(it.singleFile).matching {
|
||||
exclude("plugins/Kotlin/**")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unzipIntellijCore by tasks.creating { configureExtractFromConfigurationTask(`intellij-core`) { zipTree(it.singleFile) } }
|
||||
|
||||
val unzipJpsStandalone by tasks.creating { configureExtractFromConfigurationTask(`jps-standalone`) { zipTree(it.singleFile) } }
|
||||
|
||||
val copyIntellijSdkSources by tasks.creating(ShadowJar::class.java) {
|
||||
from(sources)
|
||||
baseName = "ideaIC"
|
||||
version = intellijVersion
|
||||
classifier = "sources"
|
||||
destinationDir = File(repoDir, sources.name)
|
||||
}
|
||||
|
||||
val copyJpsBuildTest by tasks.creating { configureExtractFromConfigurationTask(`jps-build-test`) { it.singleFile } }
|
||||
|
||||
val unzipNodeJSPlugin by tasks.creating { configureExtractFromConfigurationTask(`plugins-NodeJS`) { zipTree(it.singleFile) } }
|
||||
|
||||
fun writeIvyXml(moduleName: String, fileName: String, jarFiles: FileCollection, baseDir: File, sourcesJar: File?) {
|
||||
with(IvyDescriptorFileGenerator(DefaultIvyPublicationIdentity(customDepsOrg, moduleName, intellijVersion))) {
|
||||
addConfiguration(DefaultIvyConfiguration("default"))
|
||||
addConfiguration(DefaultIvyConfiguration("sources"))
|
||||
jarFiles.asFileTree.files.forEach {
|
||||
if (it.isFile && it.extension == "jar") {
|
||||
val relativeName = it.toRelativeString(baseDir).removeSuffix(".jar")
|
||||
addArtifact(DefaultIvyArtifact(it, relativeName, "jar", "jar", null).also { it.conf = "default" })
|
||||
}
|
||||
}
|
||||
if (sourcesJar != null) {
|
||||
val sourcesArtifactName = sourcesJar.name.removeSuffix(".jar").substringBefore("-")
|
||||
addArtifact(DefaultIvyArtifact(sourcesJar, sourcesArtifactName, "jar", "sources", "sources").also { it.conf = "sources" })
|
||||
}
|
||||
writeTo(File(customDepsRepoModulesDir, "$fileName.ivy.xml"))
|
||||
}
|
||||
}
|
||||
|
||||
val prepareIvyXmls by tasks.creating {
|
||||
dependsOn(unzipIntellijCore, unzipJpsStandalone, copyIntellijSdkSources, copyJpsBuildTest)
|
||||
|
||||
val intellijSdkDir = File(repoDir, intellij.name)
|
||||
val intellijUltimateSdkDir = File(repoDir, intellijUltimate.name)
|
||||
|
||||
if (installIntellijCommunity) {
|
||||
dependsOn(unzipIntellijSdk)
|
||||
inputs.dir(intellijSdkDir)
|
||||
outputs.file(File(repoDir, "${intellij.name}.ivy.xml"))
|
||||
}
|
||||
|
||||
if (installIntellijUltimate) {
|
||||
dependsOn(unzipIntellijUltimateSdk)
|
||||
inputs.dir(intellijUltimateSdkDir)
|
||||
outputs.file(File(repoDir, "${intellijUltimate.name}.ivy.xml"))
|
||||
}
|
||||
|
||||
val flatDeps = listOf(`intellij-core`, `jps-standalone`, `jps-build-test`)
|
||||
flatDeps.forEach {
|
||||
inputs.dir(File(repoDir, it.name))
|
||||
outputs.file(File(repoDir, "${it.name}.ivy.xml"))
|
||||
}
|
||||
inputs.dir(File(repoDir, sources.name))
|
||||
|
||||
if (intellijUltimateEnabled) {
|
||||
dependsOn(unzipNodeJSPlugin)
|
||||
inputs.dir(File(repoDir, `plugins-NodeJS`.name))
|
||||
outputs.file(File(repoDir, "${`plugins-NodeJS`.name}.ivy.xml"))
|
||||
}
|
||||
|
||||
doFirst {
|
||||
val sourcesFile = if (sources.isEmpty) null else File(repoDir, "${sources.name}/${sources.singleFile.name}")
|
||||
|
||||
if (installIntellijCommunity) {
|
||||
val libDir = File(intellijSdkDir, "lib")
|
||||
writeIvyXml(intellij.name,
|
||||
intellij.name,
|
||||
fileTree(libDir).filter {
|
||||
it.parentFile == libDir && !it.name.startsWith("kotlin-")
|
||||
},
|
||||
libDir,
|
||||
sourcesFile)
|
||||
|
||||
File(intellijSdkDir, "plugins").listFiles { it: File -> it.isDirectory }.forEach {
|
||||
writeIvyXml(it.name, "intellij.plugin.${it.name}", files("$it/lib/"), File(it, "lib"), sourcesFile)
|
||||
}
|
||||
}
|
||||
|
||||
if (installIntellijUltimate) {
|
||||
val libDir = File(intellijUltimateSdkDir, "lib")
|
||||
writeIvyXml(intellij.name, // important! the module name should be "intellij"
|
||||
intellijUltimate.name,
|
||||
fileTree(libDir).filter {
|
||||
it.parentFile == libDir && !it.name.startsWith("kotlin-")
|
||||
},
|
||||
libDir,
|
||||
sourcesFile)
|
||||
|
||||
File(intellijUltimateSdkDir, "plugins").listFiles { it: File -> it.isDirectory }.forEach {
|
||||
writeIvyXml(it.name, "intellijUltimate.plugin.${it.name}", files("$it/lib/"), File(it, "lib"), sourcesFile)
|
||||
}
|
||||
}
|
||||
|
||||
flatDeps.forEach {
|
||||
writeIvyXml(it.name, it.name, files("$repoDir/${it.name}"), File(repoDir, it.name), sourcesFile)
|
||||
}
|
||||
|
||||
if (intellijUltimateEnabled) {
|
||||
val nodeJsBaseDir = "${`plugins-NodeJS`.name}/NodeJS/lib"
|
||||
writeIvyXml("NodeJS", `plugins-NodeJS`.name, files("$repoDir/$nodeJsBaseDir"), File(repoDir, nodeJsBaseDir), sourcesFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val build by tasks.creating {
|
||||
dependsOn(prepareIvyXmls)
|
||||
}
|
||||
|
||||
val clean by tasks.creating(Delete::class) {
|
||||
delete(customDepsRepoModulesDir)
|
||||
delete(buildDir)
|
||||
}
|
||||
@@ -1,3 +1,15 @@
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
if (cacheRedirectorEnabled == 'true') {
|
||||
maven {
|
||||
url "https://cache-redirector.jetbrains.com/plugins.gradle.org/m2"
|
||||
}
|
||||
}
|
||||
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
include "prepare-deps:android-dx",
|
||||
"prepare-deps:intellij-sdk"
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.gradle.api.file.DuplicatesStrategy
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact
|
||||
import org.gradle.api.plugins.BasePluginConvention
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import java.io.File
|
||||
@@ -57,15 +56,14 @@ fun Project.noDefaultJar() {
|
||||
defaultJarTask.enabled = false
|
||||
defaultJarTask.actions = emptyList()
|
||||
configurations.forEach { cfg ->
|
||||
cfg.artifacts.removeAll {
|
||||
(it as? ArchivePublishArtifact)?.archiveTask?.let { it == defaultJarTask } ?: false
|
||||
cfg.artifacts.removeAll { artifact ->
|
||||
artifact.file in defaultJarTask.outputs.files
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun<T> Project.runtimeJarArtifactBy(task: Task, artifactRef: T, body: ConfigurablePublishArtifact.() -> Unit = {}) {
|
||||
fun Project.runtimeJarArtifactBy(task: Task, artifactRef: Any, body: ConfigurablePublishArtifact.() -> Unit = {}) {
|
||||
addArtifact("archives", task, artifactRef, body)
|
||||
addArtifact("runtimeJar", task, artifactRef, body)
|
||||
configurations.findByName("runtime")?.let {
|
||||
@@ -80,17 +78,17 @@ fun<T: Jar> Project.runtimeJar(task: T, body: T.() -> Unit = {}): T {
|
||||
}
|
||||
return task.apply {
|
||||
setupPublicJar(project.the<BasePluginConvention>().archivesBaseName)
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||
body()
|
||||
project.runtimeJarArtifactBy(this, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.runtimeJar(taskName: String = "jar", body: Jar.() -> Unit = {}): Jar = runtimeJar(getOrCreateTask(taskName, body))
|
||||
fun Project.runtimeJar(body: Jar.() -> Unit = {}): Jar = runtimeJar(getOrCreateTask("jar", body), { })
|
||||
|
||||
fun Project.sourcesJar(sourceSet: String? = "main", body: Jar.() -> Unit = {}): Jar =
|
||||
getOrCreateTask("sourcesJar") {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||
classifier = "sources"
|
||||
try {
|
||||
if (sourceSet != null) {
|
||||
@@ -107,7 +105,7 @@ fun Project.sourcesJar(sourceSet: String? = "main", body: Jar.() -> Unit = {}):
|
||||
|
||||
fun Project.javadocJar(body: Jar.() -> Unit = {}): Jar =
|
||||
getOrCreateTask("javadocJar") {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||
classifier = "javadoc"
|
||||
tasks.findByName("javadoc")?.let{ it as Javadoc }?.takeIf { it.enabled }?.let {
|
||||
dependsOn(it)
|
||||
@@ -202,14 +200,14 @@ fun Jar.setupPublicJar(baseName: String, classifier: String = "") {
|
||||
}
|
||||
|
||||
|
||||
fun<T> Project.addArtifact(configuration: Configuration, task: Task, artifactRef: T, body: ConfigurablePublishArtifact.() -> Unit = {}) {
|
||||
fun Project.addArtifact(configuration: Configuration, task: Task, artifactRef: Any, body: ConfigurablePublishArtifact.() -> Unit = {}) {
|
||||
artifacts.add(configuration.name, artifactRef) {
|
||||
builtBy(task)
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
fun<T> Project.addArtifact(configurationName: String, task: Task, artifactRef: T, body: ConfigurablePublishArtifact.() -> Unit = {}) =
|
||||
fun Project.addArtifact(configurationName: String, task: Task, artifactRef: Any, body: ConfigurablePublishArtifact.() -> Unit = {}) =
|
||||
addArtifact(configurations.getOrCreate(configurationName), task, artifactRef, body)
|
||||
|
||||
fun Project.cleanArtifacts() {
|
||||
|
||||
65
buildSrc/src/main/kotlin/copyright.kt
Normal file
65
buildSrc/src/main/kotlin/copyright.kt
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package tasks
|
||||
|
||||
import groovy.util.Node
|
||||
import groovy.util.XmlParser
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
||||
|
||||
|
||||
open class WriteCopyrightToFile : DefaultTask() {
|
||||
|
||||
@InputFile
|
||||
var path = project.file("${project.rootDir}/.idea/copyright/apache.xml")
|
||||
|
||||
@OutputFile
|
||||
var outputFile: File? = null
|
||||
|
||||
@Input
|
||||
var commented: Boolean = true
|
||||
|
||||
@TaskAction
|
||||
fun write() {
|
||||
if (commented) {
|
||||
outputFile!!.writeText(project.readCopyrightCommented())
|
||||
} else {
|
||||
outputFile!!.writeText(project.readCopyright())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Project.readCopyright(): String {
|
||||
val file = rootDir.resolve(".idea/copyright/apache.xml")
|
||||
|
||||
assert(file.exists()) {
|
||||
"File $file with copyright not found"
|
||||
}
|
||||
|
||||
|
||||
val xmlParser = XmlParser()
|
||||
val node = xmlParser.parse(file)
|
||||
assert(node.attribute("name") == "CopyrightManager") {
|
||||
"Copyright format changed occasionally?"
|
||||
}
|
||||
|
||||
val copyrightBlock = node.children().filterIsInstance<Node>().single()
|
||||
val noticeNode = copyrightBlock.children().filterIsInstance<Node>().single { it.attribute("name") == "notice" }
|
||||
return noticeNode.attribute("value").toString().replace("$today.year", GregorianCalendar()[Calendar.YEAR].toString())
|
||||
}
|
||||
|
||||
fun Project.readCopyrightCommented(): String {
|
||||
return "/*\n" + readCopyright().prependIndent(" * ") + "\n */"
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ private fun Project.compilerShadowJar(taskName: String, body: ShadowJar.() -> Un
|
||||
|
||||
return task<ShadowJar>(taskName) {
|
||||
destinationDir = File(buildDir, "libs")
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||
from(compilerJar)
|
||||
body()
|
||||
}
|
||||
@@ -97,7 +97,7 @@ fun Project.embeddableCompilerDummyForDependenciesRewriting(taskName: String = "
|
||||
|
||||
return task<ShadowJar>(taskName) {
|
||||
destinationDir = File(buildDir, "libs")
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE)
|
||||
from(compilerDummyJar)
|
||||
configureEmbeddableCompilerRelocation(withJavaxInject = false)
|
||||
body()
|
||||
@@ -119,7 +119,7 @@ fun Project.rewriteDepsToShadedJar(originalJarTask: Jar, shadowJarTask: Jar, bod
|
||||
// which leads to the content of that JAR being excluded as well:
|
||||
exclude { it.file == compilerDummyJarFile }
|
||||
|
||||
classifier = null
|
||||
classifier = ""
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ fun Project.configureInstrumentation() {
|
||||
val instrumentationClasspathCfg = configurations.create("instrumentationClasspath")
|
||||
|
||||
dependencies {
|
||||
instrumentationClasspathCfg(intellijDep()) { includeJars("javac2", "jdom", "asm-all") }
|
||||
instrumentationClasspathCfg(intellijDep()) { includeJars("javac2", "jdom", "asm-all", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
@@ -105,12 +105,12 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
get() = project.files(sourceSet!!.allSource.srcDirs.filter { !sourceSet!!.resources.contains(it) && it.exists() })
|
||||
|
||||
@get:OutputDirectory
|
||||
var output: File? = null
|
||||
lateinit var output: File
|
||||
|
||||
@TaskAction
|
||||
fun instrumentClasses() {
|
||||
logger.info("input files are: ${originalClassesDirs?.joinToString("; ", transform = { "'${it.name}'${if (it.exists()) "" else " (does not exists)" }"})}")
|
||||
output?.deleteRecursively()
|
||||
output.deleteRecursively()
|
||||
copyOriginalClasses()
|
||||
|
||||
val classpath = instrumentationClasspath!!
|
||||
|
||||
@@ -54,7 +54,7 @@ fun Project.configureInstrumentation() {
|
||||
val instrumentationClasspathCfg = configurations.create("instrumentationClasspath")
|
||||
|
||||
dependencies {
|
||||
instrumentationClasspathCfg(intellijDep()) { includeJars("javac2", "jdom", "asm-all", "jgoodies-forms") }
|
||||
instrumentationClasspathCfg(intellijDep()) { includeJars("javac2", "jdom", "asm-all", "jgoodies-forms", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
@@ -105,12 +105,12 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
get() = project.files(sourceSet!!.allSource.srcDirs.filter { !sourceSet!!.resources.contains(it) && it.exists() })
|
||||
|
||||
@get:OutputDirectory
|
||||
var output: File? = null
|
||||
lateinit var output: File
|
||||
|
||||
@TaskAction
|
||||
fun instrumentClasses() {
|
||||
logger.info("input files are: ${originalClassesDirs?.joinToString("; ", transform = { "'${it.name}'${if (it.exists()) "" else " (does not exists)" }"})}")
|
||||
output?.deleteRecursively()
|
||||
output.deleteRecursively()
|
||||
copyOriginalClasses()
|
||||
|
||||
val classpath = instrumentationClasspath!!
|
||||
|
||||
57
buildSrc/src/main/kotlin/jbCacheRedirector.kt
Normal file
57
buildSrc/src/main/kotlin/jbCacheRedirector.kt
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.dsl.RepositoryHandler
|
||||
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
|
||||
import java.net.URI
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/ADM-23180
|
||||
val mirroredUrls = listOf(
|
||||
"https://dl.bintray.com/groovy/maven",
|
||||
"https://dl.bintray.com/kotlin/kotlin-dev",
|
||||
"https://dl.bintray.com/kotlin/kotlin-eap",
|
||||
"https://dl.google.com/dl/android/maven2",
|
||||
"https://dl.google.com/go",
|
||||
"https://download.jetbrains.com",
|
||||
"https://jcenter.bintray.com",
|
||||
"https://jetbrains.bintray.com/dekaf",
|
||||
"https://jetbrains.bintray.com/intellij-jdk",
|
||||
"https://jetbrains.bintray.com/intellij-plugin-service",
|
||||
"https://jetbrains.bintray.com/intellij-third-party-dependencies",
|
||||
"https://jetbrains.bintray.com/markdown",
|
||||
"https://jetbrains.bintray.com/teamcity-rest-client",
|
||||
"https://jetbrains.bintray.com/test-discovery",
|
||||
"https://jitpack.io",
|
||||
"https://maven.exasol.com/artifactory/exasol-releases",
|
||||
"https://plugins.gradle.org/m2",
|
||||
"https://plugins.jetbrains.com/maven",
|
||||
"https://repo.grails.org/grails/core",
|
||||
"https://repo.jenkins-ci.org/releases",
|
||||
"https://repo.spring.io/milestone",
|
||||
"https://repo1.maven.org/maven2",
|
||||
"https://services.gradle.org",
|
||||
"https://www.jetbrains.com/intellij-repository",
|
||||
"https://www.myget.org/F/intellij-go-snapshots/maven",
|
||||
"https://www.myget.org/F/rd-snapshots/maven"
|
||||
)
|
||||
|
||||
fun URI.toCacheRedirectorUri() = URI("https://cache-redirector.jetbrains.com/$host/$path")
|
||||
|
||||
fun RepositoryHandler.redirect() = filterIsInstance<MavenArtifactRepository>().forEach { repository ->
|
||||
val uri = repository.url
|
||||
if (uri.toString().trimEnd('/') in mirroredUrls) {
|
||||
repository.url = uri.toCacheRedirectorUri()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.cacheRedirectorEnabled(): Boolean = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
fun RepositoryHandler.withRedirector(project: Project, configuration: RepositoryHandler.() -> Unit) {
|
||||
configuration()
|
||||
if (project.cacheRedirectorEnabled()) {
|
||||
redirect()
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import net.rubygrapefruit.platform.WindowsRegistry.Key.HKEY_LOCAL_MACHINE
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
enum class JdkMajorVersion {
|
||||
JDK_16, JDK_17, JDK_18, JDK_9, JDK_10
|
||||
JDK_16, JDK_17, JDK_18, JDK_9, JDK_10, JDK_11
|
||||
}
|
||||
|
||||
val jdkAlternativeVarNames = mapOf(JdkMajorVersion.JDK_9 to listOf("JDK_19"))
|
||||
|
||||
@@ -173,7 +173,7 @@ fun generateKotlinPluginArtifactFile(rootProject: Project): PFile {
|
||||
for (dependencyInfo in listOf(configuration).collectDependencies()) {
|
||||
val dependency = (dependencyInfo as? DependencyInfo.ResolvedDependencyInfo)?.dependency ?: continue
|
||||
|
||||
if (dependency.configuration == "runtimeElements") {
|
||||
if (dependency.isModuleDependency) {
|
||||
archiveForJar.add(ModuleOutput(dependency.moduleName + ".src"))
|
||||
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
||||
error("Test configurations are not allowed here")
|
||||
|
||||
@@ -235,8 +235,9 @@ private fun parseSourceRoots(project: Project): List<PSourceRoot> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val kotlinTasksBySourceSet = project.tasks
|
||||
.filter { it.name.startsWith("compile") && it.name.endsWith("Kotlin") }
|
||||
val kotlinTasksBySourceSet = project.tasks.names
|
||||
.filter { it.startsWith("compile") && it.endsWith("Kotlin") }
|
||||
.map { project.tasks.getByName(it) }
|
||||
.associateBy { it.invokeInternal("getSourceSetName") }
|
||||
|
||||
val sourceRoots = mutableListOf<PSourceRoot>()
|
||||
@@ -413,7 +414,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
mainRoots += if (dependency.configuration == "runtimeElements" && scope != Scope.TEST) {
|
||||
mainRoots += if (dependency.isModuleDependency && scope != Scope.TEST) {
|
||||
POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
|
||||
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
|
||||
POrderRoot(
|
||||
@@ -489,6 +490,9 @@ sealed class DependencyInfo(val scope: Scope) {
|
||||
class CustomDependencyInfo(scope: Scope, val files: List<File>) : DependencyInfo(scope)
|
||||
}
|
||||
|
||||
val ResolvedDependency.isModuleDependency
|
||||
get() = configuration in JpsCompatiblePlugin.MODULE_CONFIGURATIONS
|
||||
|
||||
fun List<CollectedConfiguration>.collectDependencies(): List<DependencyInfo> {
|
||||
val dependencies = mutableListOf<DependencyInfo>()
|
||||
|
||||
@@ -531,4 +535,4 @@ private val Project.sourceSets: SourceSetContainer
|
||||
lateinit var result: SourceSetContainer
|
||||
project.configure<JavaPluginConvention> { result = sourceSets }
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ class PillConfigurablePlugin : Plugin<Project> {
|
||||
|
||||
class JpsCompatiblePlugin : Plugin<Project> {
|
||||
companion object {
|
||||
val MODULE_CONFIGURATIONS = arrayOf("apiElements", "runtimeElements")
|
||||
|
||||
private fun mapper(module: String, vararg configurations: String): DependencyMapper {
|
||||
return DependencyMapper("org.jetbrains.kotlin", module, *configurations) { MappedDependency(PDependency.Library(module)) }
|
||||
}
|
||||
@@ -27,10 +29,10 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
private fun getDependencyMappers(projectLibraries: List<PLibrary>): List<DependencyMapper> {
|
||||
val mappersForKotlinLibrariesExeptStdlib = projectLibraries
|
||||
.filter { it.name != "kotlin-stdlib" }
|
||||
.mapTo(mutableListOf()) { mapper(it.name, "default", "distJar", "runtimeElements") }
|
||||
.mapTo(mutableListOf()) { mapper(it.name, "default", "distJar", *MODULE_CONFIGURATIONS) }
|
||||
|
||||
return mappersForKotlinLibrariesExeptStdlib + listOf(
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-stdlib", "distJar", "runtimeElements") {
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-stdlib", "distJar", *MODULE_CONFIGURATIONS) {
|
||||
MappedDependency(
|
||||
PDependency.Library("kotlin-stdlib"),
|
||||
listOf(PDependency.Library("annotations-13.0"))
|
||||
@@ -42,13 +44,13 @@ class JpsCompatiblePlugin : Plugin<Project> {
|
||||
listOf(PDependency.Library("annotations-13.0"))
|
||||
)
|
||||
},
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-reflect-api", "runtimeElements") {
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-reflect-api", *MODULE_CONFIGURATIONS) {
|
||||
MappedDependency(PDependency.Library("kotlin-reflect"))
|
||||
},
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-compiler-embeddable", "runtimeJar") { null },
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-stdlib-js", "distJar") { null },
|
||||
DependencyMapper("org.jetbrains.kotlin", "kotlin-compiler", "runtimeJar") { null },
|
||||
DependencyMapper("org.jetbrains.kotlin", "compiler", "runtimeElements") { null },
|
||||
DependencyMapper("org.jetbrains.kotlin", "compiler", *MODULE_CONFIGURATIONS) { null },
|
||||
DependencyMapper("kotlin.build.custom.deps", "android", "default") { dep ->
|
||||
val (sdkCommon, otherJars) = dep.moduleArtifacts.map { it.file }.partition { it.name == "sdk-common.jar" }
|
||||
val mainLibrary = PDependency.ModuleLibrary(PLibrary(dep.moduleName, otherJars))
|
||||
|
||||
@@ -108,7 +108,7 @@ open class PublishedKotlinModule : Plugin<Project> {
|
||||
val password: String? by preparePublication.extra
|
||||
val repoUrl: String by preparePublication.extra
|
||||
|
||||
var repository: MavenRemoteRepository by Delegates.notNull()
|
||||
var repository by Delegates.notNull<MavenRemoteRepository>()
|
||||
|
||||
repositories {
|
||||
withConvention(MavenRepositoryHandlerConvention::class) {
|
||||
|
||||
@@ -137,7 +137,11 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
|
||||
writeFiles(
|
||||
rawFiles.map {
|
||||
CodegenTestFiles.create(it.first, it.second, environment.project).psiFile
|
||||
try {
|
||||
CodegenTestFiles.create(it.first, it.second, environment.project).psiFile
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("Error on processing ${it.first}:\n${it.second}", e)
|
||||
}
|
||||
}, environment
|
||||
)
|
||||
Disposer.dispose(disposable)
|
||||
@@ -202,6 +206,10 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
if (fullFileText.contains("// WITH_COROUTINES")) continue
|
||||
// TODO: Support jvm assertions
|
||||
if (fullFileText.contains("// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm")) continue
|
||||
// TODO: support JVM 8 test with D8
|
||||
if (fullFileText.contains("// JVM_TARGET")) continue
|
||||
// TODO: support SKIP_JDK6 on new platforms
|
||||
if (fullFileText.contains("// SKIP_JDK6")) continue
|
||||
|
||||
if (hasBoxMethod(fullFileText)) {
|
||||
val testFiles = createTestFiles(file, fullFileText)
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
|
||||
object CodegenUtil {
|
||||
@JvmStatic
|
||||
@@ -200,16 +201,25 @@ object CodegenUtil {
|
||||
trace: DiagnosticSink?
|
||||
): List<ValueParameterDescriptor> {
|
||||
if (descriptor.isActual) {
|
||||
val actualParameters = descriptor.valueParameters
|
||||
if (actualParameters.any { it.declaresOrInheritsDefaultValue() }) {
|
||||
// This is incorrect code: actual function cannot have default values, they should be declared in the expected function.
|
||||
// But until KT-22818 is fixed, we need to provide a workaround for the exception that happens on complex default values
|
||||
// in the expected function. One may suppress the error then, and declare default values _both_ in expect and actual.
|
||||
// With this code, we'll generate actual default values if they're present, and expected default values otherwise.
|
||||
return actualParameters
|
||||
}
|
||||
|
||||
val expected = CodegenUtil.findExpectedFunctionForActual(descriptor)
|
||||
if (expected != null && expected.valueParameters.any(ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(expected)
|
||||
if (element == null) {
|
||||
if (trace != null) {
|
||||
val actualDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
|
||||
?: error("Not a source declaration: $descriptor")
|
||||
?: error("Not a source declaration: $descriptor")
|
||||
trace.report(Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(actualDeclaration))
|
||||
}
|
||||
return descriptor.valueParameters
|
||||
return actualParameters
|
||||
}
|
||||
|
||||
return expected.valueParameters
|
||||
@@ -218,12 +228,14 @@ object CodegenUtil {
|
||||
|
||||
return descriptor.valueParameters
|
||||
}
|
||||
|
||||
// This function is private here because no one is supposed to use it except for the hack above.
|
||||
// Please use ValueParameterDescriptor.hasDefaultValue instead.
|
||||
private fun ValueParameterDescriptor.declaresOrInheritsDefaultValue(): Boolean {
|
||||
return DFS.ifAny(
|
||||
listOf(this),
|
||||
{ current -> current.overriddenDescriptors.map(ValueParameterDescriptor::getOriginal) },
|
||||
{ it.declaresDefaultValue() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.isTopLevelInPackage(name: String, packageName: String): Boolean {
|
||||
if (name != this.name.asString()) return false
|
||||
|
||||
val containingDeclaration = containingDeclaration as? PackageFragmentDescriptor ?: return false
|
||||
val packageFqName = containingDeclaration.fqName.asString()
|
||||
return packageName == packageFqName
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.coroutinesIntrinsicsPackageFqName
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isTopLevelInPackage
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val COROUTINE_SUSPENDED_NAME = Name.identifier("COROUTINE_SUSPENDED")
|
||||
|
||||
@@ -48,7 +48,7 @@ class AccessorForFunctionDescriptor(
|
||||
|
||||
isSuspend = calleeDescriptor.isSuspend
|
||||
if (calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) != null) {
|
||||
userDataMap = LinkedHashMap<FunctionDescriptor.UserDataKey<*>, Any>()
|
||||
userDataMap = LinkedHashMap<CallableDescriptor.UserDataKey<*>, Any>()
|
||||
userDataMap[INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION] =
|
||||
calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)
|
||||
}
|
||||
|
||||
@@ -181,7 +181,9 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
private static boolean isInvisibleFromTheOutside(@Nullable DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof CallableMemberDescriptor && KotlinTypeMapper.isAccessor((CallableMemberDescriptor) descriptor)) return false;
|
||||
if (descriptor instanceof CallableMemberDescriptor && KotlinTypeMapper.isAccessor((CallableMemberDescriptor) descriptor)) {
|
||||
return true;
|
||||
}
|
||||
if (descriptor instanceof MemberDescriptor) {
|
||||
return AsmUtil.getVisibilityAccessFlag((MemberDescriptor) descriptor) == Opcodes.ACC_PRIVATE;
|
||||
}
|
||||
@@ -347,7 +349,7 @@ public abstract class AnnotationCodegen {
|
||||
private String getAnnotationArgumentJvmName(@Nullable ClassDescriptor annotationClass, @NotNull Name parameterName) {
|
||||
if (annotationClass == null) return parameterName.asString();
|
||||
|
||||
Collection<PropertyDescriptor> variables =
|
||||
Collection<? extends PropertyDescriptor> variables =
|
||||
annotationClass.getUnsubstitutedMemberScope().getContributedVariables(parameterName, NoLookupLocation.FROM_BACKEND);
|
||||
if (variables.size() != 1) return parameterName.asString();
|
||||
|
||||
@@ -359,7 +361,7 @@ public abstract class AnnotationCodegen {
|
||||
@NotNull ConstantValue<?> value,
|
||||
@NotNull AnnotationVisitor annotationVisitor
|
||||
) {
|
||||
AnnotationArgumentVisitor argumentVisitor = new AnnotationArgumentVisitor<Void, Void>() {
|
||||
AnnotationArgumentVisitor<Void, Void> argumentVisitor = new AnnotationArgumentVisitor<Void, Void>() {
|
||||
@Override
|
||||
public Void visitLongValue(@NotNull LongValue value, Void data) {
|
||||
return visitSimpleValue(value);
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
@@ -407,6 +408,9 @@ public class AsmUtil {
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
if (descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
if (descriptor.getVisibility() == Visibilities.PUBLIC ||
|
||||
descriptor.getVisibility() == Visibilities.PROTECTED ||
|
||||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
|
||||
@@ -479,6 +483,10 @@ public class AsmUtil {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||
|
||||
if (JvmCodegenUtil.isNonIntrinsicPrivateCompanionObjectInInterface(memberDescriptor)) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof FunctionDescriptor &&
|
||||
isInlineClassWrapperConstructor((FunctionDescriptor) memberDescriptor, kind)) {
|
||||
return ACC_PRIVATE;
|
||||
@@ -546,16 +554,8 @@ public class AsmUtil {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
// the following code is only for PRIVATE visibility of member
|
||||
if (memberDescriptor instanceof ConstructorDescriptor) {
|
||||
if (isEnumEntry(containingDeclaration)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
if (isEnumClass(containingDeclaration)) {
|
||||
//TODO: should be ACC_PRIVATE
|
||||
// see http://youtrack.jetbrains.com/issue/KT-2680
|
||||
return ACC_PROTECTED;
|
||||
}
|
||||
if (memberDescriptor instanceof ConstructorDescriptor && isEnumEntry(containingDeclaration)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -639,10 +639,18 @@ public class AsmUtil {
|
||||
) {
|
||||
assert !info.isStatic();
|
||||
Type fieldType = info.getFieldType();
|
||||
KotlinType fieldKotlinType = info.getFieldKotlinType();
|
||||
KotlinType nullableAny;
|
||||
if (fieldKotlinType != null) {
|
||||
nullableAny = fieldKotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||
} else {
|
||||
nullableAny = null;
|
||||
}
|
||||
|
||||
iv.load(ownerIndex, info.getOwnerType());//this
|
||||
if (cast) {
|
||||
iv.load(index, AsmTypes.OBJECT_TYPE); //param
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, fieldType, iv);
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, nullableAny, fieldType, fieldKotlinType, iv);
|
||||
} else {
|
||||
iv.load(index, fieldType); //param
|
||||
}
|
||||
@@ -658,8 +666,23 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static void genInvokeAppendMethod(@NotNull InstructionAdapter v, @NotNull Type type, @Nullable KotlinType kotlinType) {
|
||||
genInvokeAppendMethod(v, type, kotlinType, null);
|
||||
}
|
||||
|
||||
public static void genInvokeAppendMethod(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper
|
||||
) {
|
||||
Type appendParameterType;
|
||||
if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
|
||||
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper);
|
||||
if (specializedToString != null) {
|
||||
specializedToString.genInvokeInstruction(v);
|
||||
appendParameterType = AsmTypes.JAVA_STRING_TYPE;
|
||||
}
|
||||
else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
appendParameterType = OBJECT_TYPE;
|
||||
SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||
StackValue.coerce(type, kotlinType, appendParameterType, nullableAnyType, v);
|
||||
@@ -674,9 +697,17 @@ public class AsmUtil {
|
||||
public static StackValue genToString(
|
||||
@NotNull StackValue receiver,
|
||||
@NotNull Type receiverType,
|
||||
@Nullable KotlinType receiverKotlinType
|
||||
@Nullable KotlinType receiverKotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper
|
||||
) {
|
||||
return StackValue.operation(JAVA_STRING_TYPE, v -> {
|
||||
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(receiverKotlinType, typeMapper);
|
||||
if (specializedToString != null) {
|
||||
receiver.put(receiverType, receiverKotlinType, v);
|
||||
specializedToString.genInvokeInstruction(v);
|
||||
return null;
|
||||
}
|
||||
|
||||
Type type;
|
||||
KotlinType kotlinType;
|
||||
if (receiverKotlinType != null && InlineClassesUtilsKt.isInlineClassType(receiverKotlinType)) {
|
||||
@@ -694,6 +725,36 @@ public class AsmUtil {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CallableMethod getSpecializedToStringCallableMethodOrNull(
|
||||
@Nullable KotlinType receiverKotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper
|
||||
) {
|
||||
if (typeMapper == null) return null;
|
||||
|
||||
if (receiverKotlinType == null) return null;
|
||||
if (!InlineClassesUtilsKt.isInlineClassType(receiverKotlinType)) return null;
|
||||
if (receiverKotlinType.isMarkedNullable()) return null;
|
||||
|
||||
DeclarationDescriptor receiverTypeDescriptor = receiverKotlinType.getConstructor().getDeclarationDescriptor();
|
||||
assert receiverTypeDescriptor instanceof ClassDescriptor && ((ClassDescriptor) receiverTypeDescriptor).isInline() :
|
||||
"Inline class type expected: " + receiverKotlinType;
|
||||
ClassDescriptor receiverClassDescriptor = (ClassDescriptor) receiverTypeDescriptor;
|
||||
FunctionDescriptor toStringDescriptor = receiverClassDescriptor.getUnsubstitutedMemberScope()
|
||||
.getContributedFunctions(Name.identifier("toString"), NoLookupLocation.FROM_BACKEND)
|
||||
.stream()
|
||||
.filter(
|
||||
f -> f.getValueParameters().size() == 0
|
||||
&& KotlinBuiltIns.isString(f.getReturnType())
|
||||
&& f.getDispatchReceiverParameter() != null
|
||||
&& f.getExtensionReceiverParameter() == null
|
||||
)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AssertionError("'toString' not found in member scope of " + receiverClassDescriptor));
|
||||
|
||||
return typeMapper.mapToCallableMethod(toStringDescriptor, false, OwnerKind.ERASED_INLINE_CLASS);
|
||||
}
|
||||
|
||||
static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) {
|
||||
if (type.getSort() == Type.ARRAY) {
|
||||
Type elementType = correctElementType(type);
|
||||
@@ -907,19 +968,20 @@ public class AsmUtil {
|
||||
if (state.isCallAssertionsDisabled()) return stackValue;
|
||||
if (runtimeAssertionInfo == null || !runtimeAssertionInfo.getNeedNotNullAssertion()) return stackValue;
|
||||
|
||||
return new StackValue(stackValue.type) {
|
||||
return new StackValue(stackValue.type, stackValue.kotlinType) {
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) {
|
||||
Type innerType = stackValue.type;
|
||||
stackValue.put(innerType, v);
|
||||
KotlinType innerKotlinType = stackValue.kotlinType;
|
||||
stackValue.put(innerType, innerKotlinType, v);
|
||||
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
|
||||
v.dup();
|
||||
v.visitLdcInsn(runtimeAssertionInfo.getMessage());
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkExpressionValueIsNotNull",
|
||||
"(Ljava/lang/Object;Ljava/lang/String;)V", false);
|
||||
}
|
||||
StackValue.coerce(innerType, type, v);
|
||||
StackValue.coerce(innerType, innerKotlinType, type, kotlinType, v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.isTopLevelInPackage
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createCustomCopy
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.JVMAssertionsMode
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isTopLevelInPackage
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||
|
||||
@@ -26,14 +26,14 @@ interface CallGenerator {
|
||||
class DefaultCallGenerator(private val codegen: ExpressionCodegen) : CallGenerator {
|
||||
|
||||
override fun genCallInner(
|
||||
callableMethod: Callable,
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
callDefault: Boolean,
|
||||
codegen: ExpressionCodegen) {
|
||||
callableMethod: Callable,
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
callDefault: Boolean,
|
||||
codegen: ExpressionCodegen
|
||||
) {
|
||||
if (!callDefault) {
|
||||
callableMethod.genInvokeInstruction(codegen.v)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
(callableMethod as CallableMethod).genInvokeDefaultInstruction(codegen.v)
|
||||
}
|
||||
}
|
||||
@@ -66,15 +66,17 @@ interface CallGenerator {
|
||||
}
|
||||
|
||||
val value = codegen.gen(argumentExpression)
|
||||
value.put(parameterType, valueParameterDescriptor.original.type, v)
|
||||
value.put(parameterType, valueParameterDescriptor.unsubstitutedType, v)
|
||||
|
||||
if (isVarargInvoke) {
|
||||
v.astore(OBJECT_TYPE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun putCapturedValueOnStack(
|
||||
stackValue: StackValue, valueType: Type, paramIndex: Int) {
|
||||
private val ValueParameterDescriptor.unsubstitutedType
|
||||
get() = containingDeclaration.original.valueParameters[index].type
|
||||
|
||||
override fun putCapturedValueOnStack(stackValue: StackValue, valueType: Type, paramIndex: Int) {
|
||||
stackValue.put(stackValue.type, stackValue.kotlinType, codegen.v)
|
||||
}
|
||||
|
||||
@@ -117,26 +119,28 @@ interface CallGenerator {
|
||||
fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen)
|
||||
|
||||
fun genValueAndPut(
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
argumentExpression: KtExpression,
|
||||
parameterType: Type,
|
||||
parameterIndex: Int)
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
argumentExpression: KtExpression,
|
||||
parameterType: Type,
|
||||
parameterIndex: Int
|
||||
)
|
||||
|
||||
fun putValueIfNeeded(
|
||||
parameterType: JvmKotlinType,
|
||||
value: StackValue) {
|
||||
fun putValueIfNeeded(parameterType: JvmKotlinType, value: StackValue) {
|
||||
putValueIfNeeded(parameterType, value, ValueKind.GENERAL)
|
||||
}
|
||||
|
||||
fun putValueIfNeeded(
|
||||
parameterType: JvmKotlinType,
|
||||
value: StackValue,
|
||||
kind: ValueKind = ValueKind.GENERAL,
|
||||
parameterIndex: Int = -1)
|
||||
parameterType: JvmKotlinType,
|
||||
value: StackValue,
|
||||
kind: ValueKind = ValueKind.GENERAL,
|
||||
parameterIndex: Int = -1
|
||||
)
|
||||
|
||||
fun putCapturedValueOnStack(
|
||||
stackValue: StackValue,
|
||||
valueType: Type, paramIndex: Int)
|
||||
stackValue: StackValue,
|
||||
valueType: Type,
|
||||
paramIndex: Int
|
||||
)
|
||||
|
||||
fun processAndPutHiddenParameters(justProcess: Boolean)
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -18,15 +20,24 @@ import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptorKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
|
||||
|
||||
public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject> {
|
||||
@NotNull
|
||||
@@ -204,4 +215,121 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
protected ClassDescriptor classForInnerClassRecord() {
|
||||
return InnerClassConsumer.Companion.classForInnerClassRecord(descriptor, false);
|
||||
}
|
||||
|
||||
protected void generateDelegatesToDefaultImpl() {
|
||||
if (isJvmInterface(descriptor)) return;
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor interfaceFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !hasJvmDefaultAnnotation(interfaceFun)) {
|
||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDelegationToDefaultImpl(@NotNull FunctionDescriptor interfaceFun, @NotNull FunctionDescriptor inheritedFun) {
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
new JvmDeclarationOrigin(CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun),
|
||||
inheritedFun,
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
DeclarationDescriptor containingDeclaration = interfaceFun.getContainingDeclaration();
|
||||
if (!DescriptorUtils.isInterface(containingDeclaration)) return;
|
||||
|
||||
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
|
||||
PsiElement classForInheritedFun = descriptorToDeclaration(declarationInheritedFun);
|
||||
if (classForInheritedFun instanceof KtDeclaration) {
|
||||
codegen.markLineNumber((KtElement) classForInheritedFun, false);
|
||||
}
|
||||
|
||||
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
||||
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
|
||||
|
||||
FunctionDescriptor originalInterfaceFun = interfaceFun.getOriginal();
|
||||
Method traitMethod = typeMapper.mapAsmMethod(originalInterfaceFun, OwnerKind.DEFAULT_IMPLS);
|
||||
|
||||
putArgumentsOnStack(codegen, signature, traitMethod);
|
||||
InstructionAdapter iv = codegen.v;
|
||||
|
||||
if (KotlinBuiltIns.isCloneable(containingTrait) && traitMethod.getName().equals("clone")) {
|
||||
// A special hack for Cloneable: there's no kotlin/Cloneable$DefaultImpls class at runtime,
|
||||
// and its 'clone' method is actually located in java/lang/Object
|
||||
iv.invokespecial("java/lang/Object", "clone", "()Ljava/lang/Object;", false);
|
||||
}
|
||||
else {
|
||||
iv.invokestatic(traitImplType.getInternalName(), traitMethod.getName(), traitMethod.getDescriptor(), false);
|
||||
}
|
||||
|
||||
Type returnType = signature.getReturnType();
|
||||
StackValue.onStack(traitMethod.getReturnType(), originalInterfaceFun.getReturnType()).put(returnType, iv);
|
||||
iv.areturn(returnType);
|
||||
}
|
||||
|
||||
private void putArgumentsOnStack(
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull Method defaultImplsMethod
|
||||
) {
|
||||
InstructionAdapter iv = codegen.v;
|
||||
Type[] myArgTypes = signature.getAsmMethod().getArgumentTypes();
|
||||
Type[] toArgTypes = defaultImplsMethod.getArgumentTypes();
|
||||
boolean isErasedInlineClass =
|
||||
InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
|
||||
|
||||
int myArgI = 0;
|
||||
int argVar = 0;
|
||||
|
||||
Type receiverType = typeMapper.mapType(descriptor);
|
||||
KotlinType interfaceKotlinType = ((ClassDescriptor) inheritedFun.getContainingDeclaration()).getDefaultType();
|
||||
StackValue.local(argVar, receiverType, descriptor.getDefaultType())
|
||||
.put(OBJECT_TYPE, interfaceKotlinType, iv);
|
||||
if (isErasedInlineClass) myArgI++;
|
||||
argVar += receiverType.getSize();
|
||||
|
||||
int toArgI = 1;
|
||||
|
||||
List<ParameterDescriptor> myParameters = getParameters(inheritedFun);
|
||||
List<ParameterDescriptor> toParameters = getParameters(interfaceFun);
|
||||
assert myParameters.size() == toParameters.size() :
|
||||
"Inconsistent value parameters between delegating fun " + inheritedFun +
|
||||
"and interface fun " + interfaceFun;
|
||||
|
||||
Iterator<ParameterDescriptor> myParametersIterator = myParameters.iterator();
|
||||
Iterator<ParameterDescriptor> toParametersIterator = toParameters.iterator();
|
||||
for (; myArgI < myArgTypes.length; myArgI++, toArgI++) {
|
||||
Type myArgType = myArgTypes[myArgI];
|
||||
Type toArgType = toArgTypes[toArgI];
|
||||
|
||||
KotlinType myArgKotlinType = myParametersIterator.hasNext() ? myParametersIterator.next().getType() : null;
|
||||
KotlinType toArgKotlinType = toParametersIterator.hasNext() ? toParametersIterator.next().getType() : null;
|
||||
|
||||
StackValue.local(argVar, myArgType, myArgKotlinType)
|
||||
.put(toArgType, toArgKotlinType, iv);
|
||||
argVar += myArgType.getSize();
|
||||
}
|
||||
|
||||
assert toArgI == toArgTypes.length :
|
||||
"Invalid trait implementation signature: " + signature +
|
||||
" vs " + defaultImplsMethod + " for " + interfaceFun;
|
||||
}
|
||||
|
||||
private List<ParameterDescriptor> getParameters(FunctionDescriptor functionDescriptor) {
|
||||
List<ParameterDescriptor> valueParameterDescriptors =
|
||||
new ArrayList<>(functionDescriptor.getValueParameters().size() + 1);
|
||||
|
||||
ReceiverParameterDescriptor extensionReceiverParameter = functionDescriptor.getExtensionReceiverParameter();
|
||||
if (extensionReceiverParameter != null) {
|
||||
valueParameterDescriptors.add(extensionReceiverParameter);
|
||||
}
|
||||
|
||||
valueParameterDescriptors.addAll(functionDescriptor.getValueParameters());
|
||||
|
||||
return valueParameterDescriptors;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags;
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorUtilKt;
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
|
||||
@@ -113,7 +114,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
part.addTo(builder);
|
||||
}
|
||||
|
||||
List<String> experimental = state.getLanguageVersionSettings().getFlag(AnalysisFlag.getExperimental());
|
||||
List<String> experimental = state.getLanguageVersionSettings().getFlag(AnalysisFlags.getExperimental());
|
||||
if (!experimental.isEmpty()) {
|
||||
writeExperimentalMarkers(state.getModule(), builder, experimental);
|
||||
}
|
||||
@@ -124,7 +125,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
int flags = 0;
|
||||
if (state.getLanguageVersionSettings().getFlag(AnalysisFlag.getStrictMetadataVersionSemantics())) {
|
||||
if (state.getLanguageVersionSettings().getFlag(JvmAnalysisFlags.getStrictMetadataVersionSemantics())) {
|
||||
flags |= ModuleMapping.STRICT_METADATA_VERSION_SEMANTICS_FLAG;
|
||||
}
|
||||
return ModuleMappingKt.serializeToByteArray(moduleProto, state.getMetadataVersion(), flags);
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -390,8 +391,8 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
|
||||
if (container instanceof ClassDescriptor) {
|
||||
// TODO: getDefaultType() here is wrong and won't work for arrays
|
||||
putJavaLangClassInstance(iv, state.getTypeMapper().mapType(((ClassDescriptor) container).getDefaultType()));
|
||||
// TODO: would it work for arrays?
|
||||
putJavaLangClassInstance(iv, state.getTypeMapper().mapClass((ClassDescriptor) container));
|
||||
}
|
||||
else if (container instanceof PackageFragmentDescriptor) {
|
||||
iv.aconst(state.getTypeMapper().mapOwner(descriptor));
|
||||
@@ -437,13 +438,25 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
Pair<Integer, Type> receiverIndexAndType =
|
||||
Pair<Integer, FieldInfo> receiverIndexAndFieldInfo =
|
||||
CallableReferenceUtilKt.generateClosureFieldsInitializationFromParameters(iv, closure, args);
|
||||
if (shouldHaveBoundReferenceReceiver && receiverIndexAndType == null) {
|
||||
if (shouldHaveBoundReferenceReceiver && receiverIndexAndFieldInfo == null) {
|
||||
throw new AssertionError("No bound reference receiver in constructor parameters: " + args);
|
||||
}
|
||||
int boundReferenceReceiverParameterIndex = shouldHaveBoundReferenceReceiver ? receiverIndexAndType.getFirst() : -1;
|
||||
Type boundReferenceReceiverType = shouldHaveBoundReferenceReceiver ? receiverIndexAndType.getSecond() : null;
|
||||
|
||||
int boundReceiverParameterIndex;
|
||||
Type boundReceiverType;
|
||||
KotlinType boundReceiverKotlinType;
|
||||
if (shouldHaveBoundReferenceReceiver) {
|
||||
boundReceiverParameterIndex = receiverIndexAndFieldInfo.getFirst();
|
||||
boundReceiverType = receiverIndexAndFieldInfo.getSecond().getFieldType();
|
||||
boundReceiverKotlinType = receiverIndexAndFieldInfo.getSecond().getFieldKotlinType();
|
||||
}
|
||||
else {
|
||||
boundReceiverParameterIndex = -1;
|
||||
boundReceiverType = null;
|
||||
boundReceiverKotlinType = null;
|
||||
}
|
||||
|
||||
iv.load(0, superClassAsmType);
|
||||
|
||||
@@ -453,7 +466,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
int arity = calculateArity();
|
||||
iv.iconst(arity);
|
||||
if (shouldHaveBoundReferenceReceiver) {
|
||||
CallableReferenceUtilKt.loadBoundReferenceReceiverParameter(iv, boundReferenceReceiverParameterIndex, boundReferenceReceiverType);
|
||||
CallableReferenceUtilKt.loadBoundReferenceReceiverParameter(iv, boundReceiverParameterIndex, boundReceiverType, boundReceiverKotlinType);
|
||||
superClassConstructorDescriptor = "(ILjava/lang/Object;)V";
|
||||
}
|
||||
else {
|
||||
@@ -490,13 +503,14 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
List<FieldInfo> args = Lists.newArrayList();
|
||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
Type type = typeMapper.mapType(captureThis);
|
||||
args.add(FieldInfo.createForHiddenField(ownerType, type, CAPTURED_THIS_FIELD));
|
||||
SimpleType thisType = captureThis.getDefaultType();
|
||||
Type type = typeMapper.mapType(thisType);
|
||||
args.add(FieldInfo.createForHiddenField(ownerType, type, thisType, CAPTURED_THIS_FIELD));
|
||||
}
|
||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||
if (captureReceiverType != null) {
|
||||
String fieldName = closure.getCapturedReceiverFieldName(typeMapper.getBindingContext(), languageVersionSettings);
|
||||
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), fieldName));
|
||||
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), captureReceiverType, fieldName));
|
||||
}
|
||||
|
||||
for (EnclosedValueDescriptor enclosedValueDescriptor : closure.getCaptureVariables().values()) {
|
||||
@@ -505,7 +519,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
ExpressionTypingUtils.isLocalFunction(descriptor)) {
|
||||
args.add(
|
||||
FieldInfo.createForHiddenField(
|
||||
ownerType, enclosedValueDescriptor.getType(), enclosedValueDescriptor.getFieldName()
|
||||
ownerType,
|
||||
enclosedValueDescriptor.getType(),
|
||||
enclosedValueDescriptor.getKotlinType(),
|
||||
enclosedValueDescriptor.getFieldName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -106,8 +106,10 @@ public class ConstructorCodegen {
|
||||
}
|
||||
);
|
||||
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
OwnerKind ownerKindForDefault = context.getContextKind() == OwnerKind.ERASED_INLINE_CLASS
|
||||
? OwnerKind.ERASED_INLINE_CLASS
|
||||
: OwnerKind.IMPLEMENTATION;
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, ownerKindForDefault, DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
registerAccessorForHiddenConstructorIfNeeded(constructorDescriptor);
|
||||
|
||||
@@ -140,7 +142,10 @@ public class ConstructorCodegen {
|
||||
}
|
||||
);
|
||||
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
OwnerKind ownerKindForDefault = context.getContextKind() == OwnerKind.ERASED_INLINE_CLASS
|
||||
? OwnerKind.ERASED_INLINE_CLASS
|
||||
: OwnerKind.IMPLEMENTATION;
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, ownerKindForDefault,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtPureElement
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOriginFromPure
|
||||
@@ -223,7 +224,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
v.aconst(null)
|
||||
|
||||
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
if (functionDescriptor is ConstructorDescriptor && !functionDescriptor.containingDeclaration.isInlineClass()) {
|
||||
v.invokespecial(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
} else {
|
||||
v.invokestatic(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
@@ -250,6 +251,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
if (classDescriptor.kind != ClassKind.CLASS) return false
|
||||
|
||||
if (classOrObject.isLocal) return false
|
||||
if (classDescriptor.isInline) return false
|
||||
|
||||
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ class ErasedInlineClassBodyCodegen(
|
||||
override fun generateSyntheticPartsAfterBody() {
|
||||
super.generateSyntheticPartsAfterBody()
|
||||
|
||||
generateDelegatesToDefaultImpl()
|
||||
generateUnboxMethod()
|
||||
generateFunctionsFromAny()
|
||||
generateSpecializedEqualsStub()
|
||||
|
||||
@@ -513,7 +513,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
return StackValue.operation(asmType, v -> {
|
||||
return StackValue.operation(asmType, kotlinType, v -> {
|
||||
Label elseLabel = new Label();
|
||||
BranchedValue.Companion.condJump(condition, elseLabel, true, v);
|
||||
|
||||
@@ -833,7 +833,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StringTemplateEntry entry = entries.get(0);
|
||||
if (entry instanceof StringTemplateEntry.Expression) {
|
||||
KtExpression expr = ((StringTemplateEntry.Expression) entry).expression;
|
||||
return genToString(gen(expr), expressionType(expr), kotlinType(expr));
|
||||
return genToString(gen(expr), expressionType(expr), kotlinType(expr), typeMapper);
|
||||
}
|
||||
else {
|
||||
return StackValue.constant(((StringTemplateEntry.Constant) entry).value, type);
|
||||
@@ -1105,7 +1105,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
|
||||
assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
|
||||
assert !isPrimitive(thisOrOuter.type) || captureThis.isInline() :
|
||||
"This or outer for " + captureThis + " should be non-primitive: " + thisOrOuter.type;
|
||||
callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
|
||||
}
|
||||
}
|
||||
@@ -1938,11 +1939,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type sharedVarType = typeMapper.getSharedVarType(descriptor);
|
||||
Type varType = getVariableTypeNoSharing(variableDescriptor);
|
||||
KotlinType delegateKotlinType =
|
||||
isDelegatedLocalVariable(descriptor)
|
||||
? JvmCodegenUtil.getPropertyDelegateType((VariableDescriptorWithAccessors) descriptor, bindingContext)
|
||||
: null;
|
||||
if (sharedVarType != null) {
|
||||
return StackValue.shared(index, varType, variableDescriptor);
|
||||
return StackValue.shared(index, varType, variableDescriptor, delegateKotlinType);
|
||||
}
|
||||
else {
|
||||
return adjustVariableValue(StackValue.local(index, varType, variableDescriptor), variableDescriptor);
|
||||
return adjustVariableValue(StackValue.local(index, varType, variableDescriptor, delegateKotlinType), variableDescriptor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2064,7 +2069,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
CallableMethod callableGetter = null;
|
||||
CallableMethod callableSetter = null;
|
||||
|
||||
CodegenContext backingFieldContext = getBackingFieldContext(fieldAccessorKind, containingDeclaration);
|
||||
CodegenContext<?> backingFieldContext = getBackingFieldContext(fieldAccessorKind, containingDeclaration);
|
||||
boolean isPrivateProperty =
|
||||
fieldAccessorKind != AccessorKind.NORMAL &&
|
||||
(AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty) & ACC_PRIVATE) != 0;
|
||||
@@ -2152,7 +2157,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.property(
|
||||
propertyDescriptor, backingFieldOwner,
|
||||
typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()),
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, receiver, this, resolvedCall, skipLateinitAssertion
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, receiver, this, resolvedCall, skipLateinitAssertion,
|
||||
isDelegatedProperty && forceField ? delegateType : null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2168,7 +2174,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
CallableMethod callableSetter =
|
||||
setMethod != null ? typeMapper.mapToCallableMethod(context.accessibleDescriptor(setMethod, null), false) : null;
|
||||
return StackValue.property(propertyDescriptor, null, type, false, null, callableGetter, callableSetter, receiver, this,
|
||||
null, false);
|
||||
null, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2667,28 +2673,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
|
||||
if (receiverValue instanceof ImplicitClassReceiver) {
|
||||
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
|
||||
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
|
||||
CallableMemberDescriptor contextDescriptor = context.getContextDescriptor();
|
||||
if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) {
|
||||
return StackValue.LOCAL_0;
|
||||
}
|
||||
else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) {
|
||||
return generateThisOrOuterFromContext(receiverDescriptor, false, false);
|
||||
}
|
||||
else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) {
|
||||
return StackValue.singleton(receiverDescriptor, typeMapper);
|
||||
}
|
||||
else {
|
||||
return generateAccessorCallForCompanionObject(receiverDescriptor);
|
||||
}
|
||||
}
|
||||
else if (receiverDescriptor instanceof ScriptDescriptor) {
|
||||
return generateScriptReceiver((ScriptDescriptor) receiverDescriptor);
|
||||
}
|
||||
else {
|
||||
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper,
|
||||
receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor));
|
||||
}
|
||||
return generateInstanceReceiver(receiverDescriptor, isSuper,
|
||||
receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor));
|
||||
}
|
||||
else if (receiverValue instanceof ExtensionReceiver) {
|
||||
return generateExtensionReceiver(((ExtensionReceiver) receiverValue).getDeclarationDescriptor());
|
||||
@@ -2708,6 +2694,35 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateInstanceReceiver(
|
||||
@NotNull ClassDescriptor receiverDescriptor,
|
||||
boolean isSuper,
|
||||
boolean castReceiver
|
||||
|
||||
) {
|
||||
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
|
||||
CallableMemberDescriptor contextDescriptor = context.getContextDescriptor();
|
||||
if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) {
|
||||
return StackValue.LOCAL_0;
|
||||
}
|
||||
else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) {
|
||||
return generateThisOrOuterFromContext(receiverDescriptor, false, false);
|
||||
}
|
||||
else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) {
|
||||
return StackValue.singleton(receiverDescriptor, typeMapper);
|
||||
}
|
||||
else {
|
||||
return generateAccessorCallForCompanionObject(receiverDescriptor);
|
||||
}
|
||||
}
|
||||
else if (receiverDescriptor instanceof ScriptDescriptor) {
|
||||
return generateScriptReceiver((ScriptDescriptor) receiverDescriptor);
|
||||
}
|
||||
else {
|
||||
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper, castReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generateAccessorCallForCompanionObject(@NotNull ClassDescriptor companionObjectDescriptor) {
|
||||
DeclarationDescriptor hostClassDescriptor = companionObjectDescriptor.getContainingDeclaration();
|
||||
@@ -2839,8 +2854,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
private StackValue generateThisOrOuterFromContext(@NotNull ClassDescriptor thisOrOuterClass, boolean isSuper, boolean forceOuter) {
|
||||
CodegenContext cur = context;
|
||||
SimpleType thisType = thisOrOuterClass.getDefaultType();
|
||||
StackValue result = StackValue.local(0, asmType(thisType), thisType);
|
||||
SimpleType contextType = cur.getThisDescriptor().getDefaultType();
|
||||
StackValue result = StackValue.local(0, asmType(contextType), contextType);
|
||||
boolean inStartConstructorContext = cur instanceof ConstructorContext;
|
||||
while (cur != null) {
|
||||
ClassDescriptor thisDescriptor = cur.getThisDescriptor();
|
||||
@@ -3038,7 +3053,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
|
||||
if (functionDescriptor != null) {
|
||||
FunctionReferenceGenerationStrategy strategy = new FunctionReferenceGenerationStrategy(
|
||||
state, functionDescriptor, resolvedCall, receiver != null ? receiver.type : null, null, false
|
||||
state, functionDescriptor, resolvedCall,
|
||||
receiver != null ? new JvmKotlinType(receiver.type, receiver.kotlinType) : null,
|
||||
null, false
|
||||
);
|
||||
|
||||
return genClosure(
|
||||
@@ -3077,10 +3094,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
element.getContainingFile()
|
||||
);
|
||||
|
||||
Type receiverAsmType = receiverValue != null ? receiverValue.type : null;
|
||||
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
|
||||
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
|
||||
element, classBuilder, variableDescriptor, target, receiverAsmType
|
||||
element, classBuilder, variableDescriptor, target,
|
||||
receiverValue != null ? new JvmKotlinType(receiverValue.type, receiverValue.kotlinType) : null
|
||||
);
|
||||
codegen.generate();
|
||||
|
||||
@@ -3239,7 +3256,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
private StackValue genLazyUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
return pregenerated != null ? StackValue.coercion(pregenerated, type, null) : genLazy(expr, type);
|
||||
return genLazyUnlessProvided(pregenerated, expr, type, null);
|
||||
}
|
||||
|
||||
private StackValue genLazyUnlessProvided(
|
||||
@Nullable StackValue pregenerated,
|
||||
@NotNull KtExpression expr,
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType
|
||||
) {
|
||||
return pregenerated != null ? StackValue.coercion(pregenerated, type, kotlinType) : genLazy(expr, type, kotlinType);
|
||||
}
|
||||
|
||||
private StackValue genUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
@@ -3384,8 +3410,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
KotlinType leftKotlinType = kotlinType(left);
|
||||
KotlinType rightKotlinType = kotlinType(right);
|
||||
|
||||
StackValue leftValue = genLazyUnlessProvided(pregeneratedSubject, left, leftType);
|
||||
StackValue rightValue = genLazy(right, rightType);
|
||||
StackValue leftValue = genLazyUnlessProvided(pregeneratedSubject, left, leftType, leftKotlinType);
|
||||
StackValue rightValue = genLazy(right, rightType, rightKotlinType);
|
||||
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
KotlinType nullableAnyType = state.getModule().getBuiltIns().getNullableAnyType();
|
||||
@@ -3855,7 +3881,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
gen(expr, exprType, exprKotlinType);
|
||||
}
|
||||
|
||||
genInvokeAppendMethod(v, exprType.getSort() == Type.ARRAY ? OBJECT_TYPE : exprType, exprKotlinType);
|
||||
genInvokeAppendMethod(v, exprType, exprKotlinType, typeMapper);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -4108,9 +4134,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type varType = getVariableTypeNoSharing(variableDescriptor);
|
||||
|
||||
KotlinType delegateKotlinType = JvmCodegenUtil.getPropertyDelegateType(variableDescriptor, bindingContext);
|
||||
StackValue storeTo = sharedVarType == null ?
|
||||
StackValue.local(index, varType, variableDescriptor) :
|
||||
StackValue.shared(index, varType, variableDescriptor);
|
||||
StackValue.local(index, varType, variableDescriptor, delegateKotlinType) :
|
||||
StackValue.shared(index, varType, variableDescriptor, delegateKotlinType);
|
||||
|
||||
storeTo.putReceiver(v, false);
|
||||
if (variableDescriptor.isLateInit()) {
|
||||
@@ -4354,8 +4381,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type elementType = isGetter ? callableMethod.getReturnType() : ArrayUtil.getLastElement(argumentTypes);
|
||||
KotlinType elementKotlinType = isGetter ?
|
||||
operationDescriptor.getReturnType() :
|
||||
CollectionsKt.last(operationDescriptor.getValueParameters()).getType();
|
||||
operationDescriptor.getOriginal().getReturnType() :
|
||||
CollectionsKt.last(operationDescriptor.getOriginal().getValueParameters()).getType();
|
||||
return StackValue.collectionElement(
|
||||
collectionElementReceiver, elementType, elementKotlinType, resolvedGetCall, resolvedSetCall, this
|
||||
);
|
||||
@@ -4402,8 +4429,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public StackValue visitThisExpression(@NotNull KtThisExpression expression, StackValue receiver) {
|
||||
DeclarationDescriptor descriptor = bindingContext.get(REFERENCE_TARGET, expression.getInstanceReference());
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return generateInstanceReceiver((ClassDescriptor) descriptor, false, true);
|
||||
//TODO rewrite with context.lookupInContext()
|
||||
return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true);
|
||||
//return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true);
|
||||
}
|
||||
if (descriptor instanceof CallableDescriptor) {
|
||||
return generateExtensionReceiver((CallableDescriptor) descriptor);
|
||||
@@ -4901,7 +4929,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
@NotNull VariableDescriptorWithAccessors variableDescriptor,
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
) {
|
||||
return StackValue.delegate(typeMapper.mapType(variableDescriptor.getType()), delegateValue, metadataValue, variableDescriptor, this);
|
||||
return StackValue.localDelegate(typeMapper.mapType(variableDescriptor.getType()), delegateValue, metadataValue, variableDescriptor, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isNonCompanionObject;
|
||||
@@ -29,7 +31,9 @@ public class FieldInfo {
|
||||
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
||||
assert ownerDescriptor != null : "Owner not found for class: " + classDescriptor;
|
||||
Type ownerType = typeMapper.mapClass(ownerDescriptor);
|
||||
return new FieldInfo(ownerType, typeMapper.mapType(classDescriptor), classDescriptor.getName().asString(), true);
|
||||
KotlinType fieldKotlinType = classDescriptor.getDefaultType();
|
||||
Type fieldType = typeMapper.mapType(fieldKotlinType);
|
||||
return new FieldInfo(ownerType, fieldType, fieldKotlinType, classDescriptor.getName().asString(), true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -38,23 +42,43 @@ public class FieldInfo {
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
@NotNull String name
|
||||
) {
|
||||
Type type = typeMapper.mapType(classDescriptor);
|
||||
return new FieldInfo(type, type, name, true);
|
||||
Type owner = typeMapper.mapClass(classDescriptor);
|
||||
KotlinType fieldKotlinType = classDescriptor.getDefaultType();
|
||||
Type fieldType = typeMapper.mapType(fieldKotlinType);
|
||||
return new FieldInfo(owner, fieldType, fieldKotlinType, name, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
|
||||
return new FieldInfo(owner, fieldType, fieldName, false);
|
||||
return createForHiddenField(owner, fieldType, null, fieldName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForHiddenField(
|
||||
@NotNull Type owner,
|
||||
@NotNull Type fieldType,
|
||||
@Nullable KotlinType fieldKotlinType,
|
||||
@NotNull String fieldName
|
||||
) {
|
||||
return new FieldInfo(owner, fieldType, fieldKotlinType, fieldName, false);
|
||||
}
|
||||
|
||||
private final Type fieldType;
|
||||
private final KotlinType fieldKotlinType;
|
||||
private final Type ownerType;
|
||||
private final String fieldName;
|
||||
private final boolean isStatic;
|
||||
|
||||
private FieldInfo(@NotNull Type ownerType, @NotNull Type fieldType, @NotNull String fieldName, boolean isStatic) {
|
||||
private FieldInfo(
|
||||
@NotNull Type ownerType,
|
||||
@NotNull Type fieldType,
|
||||
@Nullable KotlinType fieldKotlinType,
|
||||
@NotNull String fieldName,
|
||||
boolean isStatic
|
||||
) {
|
||||
this.ownerType = ownerType;
|
||||
this.fieldType = fieldType;
|
||||
this.fieldKotlinType = fieldKotlinType;
|
||||
this.fieldName = fieldName;
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
@@ -64,6 +88,11 @@ public class FieldInfo {
|
||||
return fieldType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KotlinType getFieldKotlinType() {
|
||||
return fieldKotlinType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getOwnerType() {
|
||||
return ownerType;
|
||||
|
||||
@@ -68,13 +68,16 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.generateBridgeForMainFunctionIfNecessary;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.isAccessor;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -225,13 +228,10 @@ public class FunctionCodegen {
|
||||
asmMethod.getDescriptor()
|
||||
);
|
||||
|
||||
if (CodegenContextUtil.isImplementationOwner(owner, functionDescriptor)) {
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, CodegenUtilKt.unwrapFrontendVersion(functionDescriptor), asmMethod);
|
||||
}
|
||||
recordMethodForFunctionIfAppropriate(functionDescriptor, asmMethod);
|
||||
|
||||
AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(functionDescriptor, asmMethod.getReturnType());
|
||||
generateMethodAnnotationsIfRequired(functionDescriptor, asmMethod, jvmSignature, mv);
|
||||
|
||||
generateParameterAnnotations(functionDescriptor, mv, jvmSignature, memberCodegen, state);
|
||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||
|
||||
if (contextKind != OwnerKind.ERASED_INLINE_CLASS) {
|
||||
@@ -244,6 +244,8 @@ public class FunctionCodegen {
|
||||
parentBodyCodegen.addAdditionalTask(new JvmStaticInCompanionObjectGenerator(functionDescriptor, origin, state, parentBodyCodegen));
|
||||
}
|
||||
|
||||
generateBridgeForMainFunctionIfNecessary(state, v, functionDescriptor, jvmSignature, origin, methodContext.getParentContext());
|
||||
|
||||
boolean isOpenSuspendInClass =
|
||||
functionDescriptor.isSuspend() &&
|
||||
functionDescriptor.getModality() != Modality.ABSTRACT && isOverridable(functionDescriptor) &&
|
||||
@@ -266,6 +268,49 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void recordMethodForFunctionIfAppropriate(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
Method asmMethod
|
||||
) {
|
||||
if (functionDescriptor instanceof AccessorForConstructorDescriptor) {
|
||||
ConstructorDescriptor originalConstructor = ((AccessorForConstructorDescriptor) functionDescriptor).getCalleeDescriptor();
|
||||
if (shouldHideConstructorDueToInlineClassTypeValueParameters(originalConstructor)) {
|
||||
functionDescriptor = originalConstructor;
|
||||
}
|
||||
}
|
||||
else if (shouldHideConstructorDueToInlineClassTypeValueParameters(functionDescriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
functionDescriptor = CodegenUtilKt.unwrapFrontendVersion(functionDescriptor);
|
||||
|
||||
if (!CodegenContextUtil.isImplementationOwner(owner, functionDescriptor)) return;
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
|
||||
}
|
||||
|
||||
private void generateMethodAnnotationsIfRequired(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull JvmMethodGenericSignature jvmSignature,
|
||||
@NotNull MethodVisitor mv
|
||||
) {
|
||||
FunctionDescriptor annotationsOwner;
|
||||
if (shouldHideConstructorDueToInlineClassTypeValueParameters(functionDescriptor)) {
|
||||
if (functionDescriptor instanceof AccessorForConstructorDescriptor) {
|
||||
annotationsOwner = ((AccessorForConstructorDescriptor) functionDescriptor).getCalleeDescriptor();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
annotationsOwner = functionDescriptor;
|
||||
}
|
||||
|
||||
AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(annotationsOwner, asmMethod.getReturnType());
|
||||
generateParameterAnnotations(annotationsOwner, mv, jvmSignature, memberCodegen, state);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MethodVisitor newMethod(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
@@ -285,7 +330,8 @@ public class FunctionCodegen {
|
||||
@NotNull DeclarationDescriptor containingDeclaration
|
||||
) {
|
||||
return !canDelegateMethodBodyToInlineClass(origin, functionDescriptor, contextKind, containingDeclaration) ||
|
||||
!functionDescriptor.getOverriddenDescriptors().isEmpty();
|
||||
!functionDescriptor.getOverriddenDescriptors().isEmpty() ||
|
||||
CodegenUtilKt.isJvmStaticInInlineClass(functionDescriptor);
|
||||
}
|
||||
|
||||
private static boolean canDelegateMethodBodyToInlineClass(
|
||||
@@ -298,6 +344,9 @@ public class FunctionCodegen {
|
||||
if (contextKind == OwnerKind.ERASED_INLINE_CLASS) return false;
|
||||
if (origin.getOriginKind() == JvmDeclarationOriginKind.UNBOX_METHOD_OF_INLINE_CLASS) return false;
|
||||
|
||||
// Synthesized class member descriptors corresponding to JvmStatic members of companion object
|
||||
if (CodegenUtilKt.isJvmStaticInInlineClass(functionDescriptor)) return false;
|
||||
|
||||
// descriptor corresponds to the underlying value
|
||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty();
|
||||
@@ -309,7 +358,7 @@ public class FunctionCodegen {
|
||||
// base check
|
||||
boolean isInlineClass = InlineClassesUtilsKt.isInlineClass(containingDeclaration);
|
||||
boolean simpleFunctionOrProperty =
|
||||
!(functionDescriptor instanceof ConstructorDescriptor) && !KotlinTypeMapper.isAccessor(functionDescriptor);
|
||||
!(functionDescriptor instanceof ConstructorDescriptor) && !isAccessor(functionDescriptor);
|
||||
|
||||
return isInlineClass && simpleFunctionOrProperty;
|
||||
}
|
||||
@@ -444,31 +493,6 @@ public class FunctionCodegen {
|
||||
endVisit(mv, null, origin.getElement());
|
||||
}
|
||||
|
||||
private void generateDelegateForDefaultImpl(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@Nullable PsiElement element
|
||||
) {
|
||||
Method defaultImplMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.DEFAULT_IMPLS);
|
||||
|
||||
CodegenUtilKt.generateMethod(
|
||||
v, "Default Impl delegate in interface", Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC,
|
||||
new Method(defaultImplMethod.getName() + JvmAbi.DEFAULT_IMPLS_DELEGATE_SUFFIX, defaultImplMethod.getDescriptor()),
|
||||
element, JvmDeclarationOrigin.NO_ORIGIN,
|
||||
state, adapter -> {
|
||||
Method interfaceMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
Type type = typeMapper.mapOwner(functionDescriptor);
|
||||
generateDelegateToMethodBody(
|
||||
-1, adapter,
|
||||
interfaceMethod,
|
||||
type.getInternalName(),
|
||||
Opcodes.INVOKESPECIAL,
|
||||
true
|
||||
);
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static void generateParameterAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodVisitor mv,
|
||||
@@ -489,6 +513,7 @@ public class FunctionCodegen {
|
||||
@NotNull InnerClassConsumer innerClassConsumer,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
if (isAccessor(functionDescriptor)) return;
|
||||
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||
Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator();
|
||||
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
|
||||
@@ -870,7 +895,7 @@ public class FunctionCodegen {
|
||||
return parameter.getName().asString();
|
||||
}
|
||||
|
||||
private static void generateFacadeDelegateMethodBody(
|
||||
public static void generateFacadeDelegateMethodBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull MultifileClassFacadeContext context
|
||||
@@ -1130,6 +1155,10 @@ public class FunctionCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
if (InlineClassesUtilsKt.isInlineClass(contextClass) && kind != OwnerKind.ERASED_INLINE_CLASS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefaultNeeded(functionDescriptor, function)) {
|
||||
return;
|
||||
}
|
||||
@@ -1140,7 +1169,9 @@ public class FunctionCodegen {
|
||||
isEffectivelyInlineOnly(functionDescriptor) ?
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
||||
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor)) {
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor &&
|
||||
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration()))
|
||||
) {
|
||||
flags |= ACC_STATIC;
|
||||
}
|
||||
|
||||
@@ -1245,7 +1276,8 @@ public class FunctionCodegen {
|
||||
Label loadArg = new Label();
|
||||
iv.ifeq(loadArg);
|
||||
|
||||
StackValue.local(parameterIndex, type).store(loadStrategy.genValue(parameterDescriptor, codegen), iv);
|
||||
StackValue.local(parameterIndex, type, parameterDescriptor.getType())
|
||||
.store(loadStrategy.genValue(parameterDescriptor, codegen), iv);
|
||||
|
||||
iv.mark(loadArg);
|
||||
}
|
||||
@@ -1261,7 +1293,7 @@ public class FunctionCodegen {
|
||||
generator.putValueIfNeeded(new JvmKotlinType(type, null), StackValue.local(parameterIndex, type));
|
||||
}
|
||||
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, methodContext.getContextKind());
|
||||
|
||||
generator.genCall(method, null, false, codegen);
|
||||
|
||||
@@ -1561,10 +1593,13 @@ public class FunctionCodegen {
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
|
||||
String internalName = typeMapper.mapType(toClass).getInternalName();
|
||||
String internalName = typeMapper.mapClass(toClass).getInternalName();
|
||||
if (toClass.getKind() == ClassKind.INTERFACE) {
|
||||
iv.invokeinterface(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor());
|
||||
}
|
||||
else if (toClass.isInline()) {
|
||||
iv.invokestatic(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor(), false);
|
||||
}
|
||||
else {
|
||||
iv.invokevirtual(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor(), false);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
@@ -51,6 +52,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
private final FunctionDescriptor referencedFunction;
|
||||
private final FunctionDescriptor functionDescriptor;
|
||||
private final Type receiverType; // non-null for bound references
|
||||
private final KotlinType receiverKotlinType;
|
||||
private final StackValue receiverValue;
|
||||
private final boolean isInliningStrategy;
|
||||
|
||||
@@ -58,7 +60,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@Nullable Type receiverType,
|
||||
@Nullable JvmKotlinType receiverJvmKotlinType,
|
||||
@Nullable StackValue receiverValue,
|
||||
boolean isInliningStrategy
|
||||
) {
|
||||
@@ -73,7 +75,8 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
this.referencedFunction = referencedFunction;
|
||||
this.functionDescriptor = functionDescriptor;
|
||||
}
|
||||
this.receiverType = receiverType;
|
||||
this.receiverType = receiverJvmKotlinType != null ? receiverJvmKotlinType.getType() : null;
|
||||
this.receiverKotlinType = receiverJvmKotlinType != null ? receiverJvmKotlinType.getKotlinType() : null;
|
||||
this.receiverValue = receiverValue;
|
||||
this.isInliningStrategy = isInliningStrategy;
|
||||
assert receiverType != null || receiverValue == null
|
||||
@@ -240,7 +243,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
if (receiverType != null) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) codegen.getContext().getParentContext().getContextDescriptor();
|
||||
Type asmType = codegen.getState().getTypeMapper().mapClass(classDescriptor);
|
||||
return CallableReferenceUtilKt.capturedBoundReferenceReceiver(asmType, receiverType, isInliningStrategy);
|
||||
return CallableReferenceUtilKt.capturedBoundReferenceReceiver(asmType, receiverType, receiverKotlinType, isInliningStrategy);
|
||||
}
|
||||
|
||||
// 0 is this (the callable reference class), 1 is the invoke() method's first parameter
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
@@ -24,6 +23,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -34,9 +34,7 @@ import java.util.List;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.IRETURN;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
private final ClassDescriptor classDescriptor;
|
||||
@@ -83,7 +81,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
mv.visitAnnotation(Type.getDescriptor(NotNull.class), false);
|
||||
visitEndForAnnotationVisitor(mv.visitAnnotation(Type.getDescriptor(NotNull.class), false));
|
||||
|
||||
if (!generationState.getClassBuilderMode().generateBodies) {
|
||||
FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration());
|
||||
@@ -122,7 +120,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
genInvokeAppendMethod(iv, asmType, type.getKotlinType());
|
||||
genInvokeAppendMethod(iv, asmType, type.getKotlinType(), typeMapper);
|
||||
}
|
||||
|
||||
iv.aconst(")");
|
||||
@@ -218,7 +216,9 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
mv.visitParameterAnnotation(isErasedInlineClassKind ? 1 : 0, Type.getDescriptor(Nullable.class), false);
|
||||
visitEndForAnnotationVisitor(
|
||||
mv.visitParameterAnnotation(isErasedInlineClassKind ? 1 : 0, Type.getDescriptor(Nullable.class), false)
|
||||
);
|
||||
|
||||
if (!generationState.getClassBuilderMode().generateBodies) {
|
||||
FunctionCodegen.endVisit(mv, equalsMethodName, getDeclaration());
|
||||
@@ -271,6 +271,12 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
FunctionCodegen.endVisit(mv, equalsMethodName, getDeclaration());
|
||||
}
|
||||
|
||||
private static void visitEndForAnnotationVisitor(@Nullable AnnotationVisitor annotation) {
|
||||
if (annotation != null) {
|
||||
annotation.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private int generateBasicChecksAndStoreTarget(InstructionAdapter iv, Label eq, Label ne) {
|
||||
if (fieldOwnerContext.getContextKind() == OwnerKind.ERASED_INLINE_CLASS) {
|
||||
SimpleType wrapperKotlinType = classDescriptor.getDefaultType();
|
||||
|
||||
@@ -13,7 +13,6 @@ import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap;
|
||||
@@ -73,9 +72,7 @@ import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
|
||||
import static org.jetbrains.kotlin.types.Variance.INVARIANT;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -256,10 +253,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (!(myClass instanceof KtClass)) return;
|
||||
if (!descriptor.isInline()) return;
|
||||
|
||||
CodegenContext parentContext = context.getParentContext();
|
||||
assert parentContext != null : "Parent context of inline class declaration should not be null";
|
||||
|
||||
ClassContext erasedInlineClassContext = parentContext.intoWrapperForErasedInlineClass(descriptor, state);
|
||||
ClassContext erasedInlineClassContext = context.intoWrapperForErasedInlineClass(descriptor, state);
|
||||
new ErasedInlineClassBodyCodegen((KtClass) myClass, erasedInlineClassContext, v, state, this).generate();
|
||||
}
|
||||
|
||||
@@ -273,7 +267,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (inlinedValue == null) return;
|
||||
|
||||
Type valueType = typeMapper.mapType(inlinedValue.getType());
|
||||
SimpleFunctionDescriptor functionDescriptor = InlineClassDescriptorResolver.INSTANCE.createUnboxFunctionDescriptor(this.descriptor);
|
||||
SimpleFunctionDescriptor functionDescriptor = InlineClassDescriptorResolver.createUnboxFunctionDescriptor(this.descriptor);
|
||||
assert functionDescriptor != null : "FunctionDescriptor for unbox method should be not null during codegen";
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
@@ -411,7 +405,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
generateCompanionObjectBackingFieldCopies();
|
||||
|
||||
generateTraitMethods();
|
||||
generateDelegatesToDefaultImpl();
|
||||
|
||||
generateDelegates(delegationFieldsInfo);
|
||||
|
||||
@@ -473,7 +467,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<SimpleFunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getContributedFunctions(
|
||||
Collection<? extends SimpleFunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getContributedFunctions(
|
||||
Name.identifier("toArray"), NoLookupLocation.FROM_BACKEND
|
||||
);
|
||||
boolean hasGenericToArray = false;
|
||||
@@ -792,12 +786,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.DeprecatedFieldForInvisibleCompanionObject);
|
||||
boolean properVisibilityForCompanionObjectInstanceField =
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField);
|
||||
boolean hasPrivateOrProtectedProperVisibility = (properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0;
|
||||
boolean hasPackagePrivateProperVisibility = (properFieldVisibilityFlag & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)) == 0;
|
||||
boolean fieldShouldBeDeprecated =
|
||||
deprecatedFieldForInvisibleCompanionObject &&
|
||||
!properVisibilityForCompanionObjectInstanceField &&
|
||||
(properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0;
|
||||
(hasPrivateOrProtectedProperVisibility || hasPackagePrivateProperVisibility ||
|
||||
isNonIntrinsicPrivateCompanionObjectInInterface(companionObjectDescriptor));
|
||||
boolean doNotGeneratePublic =
|
||||
properVisibilityForCompanionObjectInstanceField && (properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0;
|
||||
properVisibilityForCompanionObjectInstanceField && hasPrivateOrProtectedProperVisibility;
|
||||
int fieldAccessFlags;
|
||||
if (doNotGeneratePublic) {
|
||||
fieldAccessFlags = ACC_STATIC | ACC_FINAL;
|
||||
@@ -811,6 +808,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (fieldShouldBeDeprecated) {
|
||||
fieldAccessFlags |= ACC_DEPRECATED;
|
||||
}
|
||||
if (properVisibilityForCompanionObjectInstanceField &&
|
||||
JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic(companionObjectDescriptor) &&
|
||||
Visibilities.isPrivate(companionObjectDescriptor.getVisibility())) {
|
||||
fieldAccessFlags |= ACC_SYNTHETIC;
|
||||
}
|
||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
|
||||
fieldAccessFlags, field.name, field.type.getDescriptor(), null, null);
|
||||
@@ -1051,71 +1053,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateTraitMethods() {
|
||||
if (isJvmInterface(descriptor)) return;
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor interfaceFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !hasJvmDefaultAnnotation(interfaceFun)) {
|
||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDelegationToDefaultImpl(@NotNull FunctionDescriptor interfaceFun, @NotNull FunctionDescriptor inheritedFun) {
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
new JvmDeclarationOrigin(CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun),
|
||||
inheritedFun,
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
DeclarationDescriptor containingDeclaration = interfaceFun.getContainingDeclaration();
|
||||
if (!DescriptorUtils.isInterface(containingDeclaration)) return;
|
||||
|
||||
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
|
||||
PsiElement classForInheritedFun = descriptorToDeclaration(declarationInheritedFun);
|
||||
if (classForInheritedFun instanceof KtDeclaration) {
|
||||
codegen.markLineNumber((KtElement) classForInheritedFun, false);
|
||||
}
|
||||
|
||||
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
||||
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
|
||||
|
||||
FunctionDescriptor originalInterfaceFun = interfaceFun.getOriginal();
|
||||
Method traitMethod = typeMapper.mapAsmMethod(originalInterfaceFun, OwnerKind.DEFAULT_IMPLS);
|
||||
|
||||
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
|
||||
Type[] originalArgTypes = traitMethod.getArgumentTypes();
|
||||
assert originalArgTypes.length == argTypes.length + 1 :
|
||||
"Invalid trait implementation signature: " + signature + " vs " + traitMethod + " for " + interfaceFun;
|
||||
|
||||
InstructionAdapter iv = codegen.v;
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
for (int i = 0, reg = 1; i < argTypes.length; i++) {
|
||||
StackValue.local(reg, argTypes[i]).put(originalArgTypes[i + 1], iv);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
reg += argTypes[i].getSize();
|
||||
}
|
||||
|
||||
if (KotlinBuiltIns.isCloneable(containingTrait) && traitMethod.getName().equals("clone")) {
|
||||
// A special hack for Cloneable: there's no kotlin/Cloneable$DefaultImpls class at runtime,
|
||||
// and its 'clone' method is actually located in java/lang/Object
|
||||
iv.invokespecial("java/lang/Object", "clone", "()Ljava/lang/Object;", false);
|
||||
}
|
||||
else {
|
||||
iv.invokestatic(traitImplType.getInternalName(), traitMethod.getName(), traitMethod.getDescriptor(), false);
|
||||
}
|
||||
|
||||
Type returnType = signature.getReturnType();
|
||||
StackValue.onStack(traitMethod.getReturnType(), originalInterfaceFun.getReturnType()).put(returnType, iv);
|
||||
iv.areturn(returnType);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void generateEnumEntries() {
|
||||
if (descriptor.getKind() != ClassKind.ENUM_CLASS) return;
|
||||
|
||||
|
||||
@@ -197,8 +197,8 @@ public class JvmCodegenUtil {
|
||||
if (KotlinTypeMapper.isAccessor(property)) return false;
|
||||
|
||||
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();
|
||||
// Inline functions or inline classes can't use direct access because a field may not be visible at the call site
|
||||
if (context.isInlineMethodContext() || (context.getEnclosingClass() != null && context.getEnclosingClass().isInline())) {
|
||||
// Inline functions can't use direct access because a field may not be visible at the call site
|
||||
if (context.isInlineMethodContext()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -348,6 +348,11 @@ public class JvmCodegenUtil {
|
||||
!JvmAbi.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||
}
|
||||
|
||||
public static boolean isNonIntrinsicPrivateCompanionObjectInInterface(@NotNull DeclarationDescriptorWithVisibility companionObject) {
|
||||
return isCompanionObjectInInterfaceNotIntrinsic(companionObject) &&
|
||||
Visibilities.isPrivate(companionObject.getVisibility());
|
||||
}
|
||||
|
||||
public static boolean isDeclarationOfBigArityFunctionInvoke(@Nullable DeclarationDescriptor descriptor) {
|
||||
return descriptor instanceof FunctionInvokeDescriptor && ((FunctionInvokeDescriptor) descriptor).hasBigArity();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
@@ -72,7 +73,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public final GenerationState state;
|
||||
|
||||
protected final T element;
|
||||
protected final FieldOwnerContext context;
|
||||
protected final FieldOwnerContext<?> context;
|
||||
|
||||
public final ClassBuilder v;
|
||||
public final FunctionCodegen functionCodegen;
|
||||
@@ -406,7 +407,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
return typeMapper.mapDefaultImpls(classDescriptor);
|
||||
}
|
||||
}
|
||||
return typeMapper.mapType(classDescriptor);
|
||||
return typeMapper.mapClass(classDescriptor);
|
||||
}
|
||||
else if (outermost instanceof MultifileClassFacadeContext || outermost instanceof DelegatingToPartContext) {
|
||||
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
|
||||
@@ -509,19 +510,29 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
propertyDescriptor, true, false, null, true, StackValue.LOCAL_0, null, false
|
||||
);
|
||||
|
||||
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall = bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, propertyDescriptor);
|
||||
if (provideDelegateResolvedCall == null) {
|
||||
if (property.getDelegateExpression() == null) {
|
||||
propValue.store(codegen.gen(initializer), codegen.v);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
StackValue.Property delegate = propValue.getDelegateOrNull();
|
||||
assert delegate != null : "No delegate for delegated property: " + propertyDescriptor;
|
||||
|
||||
StackValue provideDelegateReceiver = codegen.gen(initializer);
|
||||
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall =
|
||||
bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, propertyDescriptor);
|
||||
|
||||
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethod(
|
||||
codegen, provideDelegateResolvedCall, provideDelegateReceiver, propertyDescriptor
|
||||
);
|
||||
if (provideDelegateResolvedCall == null) {
|
||||
delegate.store(codegen.gen(initializer), codegen.v);
|
||||
}
|
||||
else {
|
||||
StackValue provideDelegateReceiver = codegen.gen(initializer);
|
||||
|
||||
propValue.store(delegateValue, codegen.v);
|
||||
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethod(
|
||||
codegen, provideDelegateResolvedCall, provideDelegateReceiver, propertyDescriptor
|
||||
);
|
||||
|
||||
delegate.store(delegateValue, codegen.v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Public accessible for serialization plugin to check whether call to initializeProperty(..) is legal.
|
||||
@@ -868,11 +879,15 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) &&
|
||||
!isNonDefaultInterfaceMember(functionDescriptor) &&
|
||||
!isJvmStaticInObjectOrClass;
|
||||
!isJvmStaticInObjectOrClass &&
|
||||
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration());
|
||||
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
||||
|
||||
ReceiverParameterDescriptor dispatchReceiver = functionDescriptor.getDispatchReceiverParameter();
|
||||
Type dispatchReceiverType = dispatchReceiver != null ? typeMapper.mapType(dispatchReceiver.getType()) : AsmTypes.OBJECT_TYPE;
|
||||
|
||||
int accessorParam = (hasDispatchReceiver && !accessorIsConstructor) ? 1 : 0;
|
||||
int reg = hasDispatchReceiver ? 1 : 0;
|
||||
int reg = hasDispatchReceiver ? dispatchReceiverType.getSize() : 0;
|
||||
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
|
||||
iv.anew(callableMethod.getOwner());
|
||||
iv.dup();
|
||||
@@ -881,7 +896,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
}
|
||||
else if (KotlinTypeMapper.isAccessor(accessorDescriptor) && (hasDispatchReceiver || accessorIsConstructor)) {
|
||||
if (!isJvmStaticInObjectOrClass) {
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
iv.load(0, dispatchReceiverType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ class MultifileClassCodegenImpl(
|
||||
val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType)
|
||||
val memberCodegen = createCodegenForDelegatesInMultifileFacade(facadeContext)
|
||||
for (declaration in CodegenUtil.getDeclarationsToGenerate(file, state.bindingContext)) {
|
||||
if (declaration is KtNamedFunction || declaration is KtProperty || declaration is KtTypeAlias) {
|
||||
if (shouldGenerateInFacade(declaration)) {
|
||||
val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||
if (descriptor !is MemberDescriptor) {
|
||||
throw AssertionError("Expected callable member, was " + descriptor + " for " + declaration.text)
|
||||
@@ -256,6 +256,15 @@ class MultifileClassCodegenImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldGenerateInFacade(declaration: KtDeclaration): Boolean {
|
||||
if (declaration is KtNamedFunction || declaration is KtProperty) return true
|
||||
|
||||
// In light classes, we intentionally do not analyze type aliases, since they're metadata-only
|
||||
if (declaration is KtTypeAlias && state.classBuilderMode.generateMetadata) return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun shouldGenerateInFacade(descriptor: MemberDescriptor): Boolean {
|
||||
if (Visibilities.isPrivate(descriptor.visibility)) return false
|
||||
if (AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false
|
||||
|
||||
@@ -210,6 +210,12 @@ public class PropertyCodegen {
|
||||
return !isDefaultAccessor;
|
||||
}
|
||||
|
||||
// Non-private properties with private setter should not be generated for trivial properties
|
||||
// as the class will use direct field access instead
|
||||
if (accessor != null && accessor.isSetter() && Visibilities.isPrivate(descriptor.getSetter().getVisibility())) {
|
||||
return !isDefaultAccessor;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -605,8 +611,10 @@ public class PropertyCodegen {
|
||||
assert resolvedCall != null : "Resolve call should be recorded for delegate call " + signature.toString();
|
||||
|
||||
PropertyDescriptor propertyDescriptor = propertyAccessorDescriptor.getCorrespondingProperty();
|
||||
StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
|
||||
StackValue lastValue = invokeDelegatedPropertyConventionMethod(codegen, resolvedCall, receiver, propertyDescriptor);
|
||||
StackValue.Property property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
|
||||
StackValue.Property delegate = property.getDelegateOrNull();
|
||||
assert delegate != null : "No delegate for delegated property: " + propertyDescriptor;
|
||||
StackValue lastValue = invokeDelegatedPropertyConventionMethod(codegen, resolvedCall, delegate, propertyDescriptor);
|
||||
Type asmType = signature.getReturnType();
|
||||
lastValue.put(asmType, v);
|
||||
v.areturn(asmType);
|
||||
|
||||
@@ -28,9 +28,8 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
@@ -52,8 +51,11 @@ class PropertyReferenceCodegen(
|
||||
classBuilder: ClassBuilder,
|
||||
private val localVariableDescriptorForReference: VariableDescriptor,
|
||||
private val target: VariableDescriptor,
|
||||
private val receiverType: Type?
|
||||
private val boundReceiverJvmKotlinType: JvmKotlinType?
|
||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||
|
||||
private val boundReceiverType = boundReceiverJvmKotlinType?.type
|
||||
|
||||
private val classDescriptor = context.contextDescriptor
|
||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||
|
||||
@@ -72,9 +74,9 @@ class PropertyReferenceCodegen(
|
||||
private val wrapperMethod = getWrapperMethodForPropertyReference(target, getFunction.valueParameters.size)
|
||||
|
||||
private val closure = bindingContext.get(CodegenBinding.CLOSURE, classDescriptor)!!.apply {
|
||||
assert((capturedReceiverFromOuterContext != null) == (receiverType != null)) {
|
||||
assert((capturedReceiverFromOuterContext != null) == (boundReceiverType != null)) {
|
||||
"Bound property reference can only be generated with the type of the receiver. " +
|
||||
"Captured type = $capturedReceiverFromOuterContext, actual type = $receiverType"
|
||||
"Captured type = $capturedReceiverFromOuterContext, actual type = $boundReceiverType"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,16 +131,16 @@ class PropertyReferenceCodegen(
|
||||
private fun generateConstructor() {
|
||||
generateMethod("property reference init", 0, constructor) {
|
||||
val shouldHaveBoundReferenceReceiver = closure.isForBoundCallableReference()
|
||||
val receiverIndexAndType = generateClosureFieldsInitializationFromParameters(closure, constructorArgs)
|
||||
val receiverIndexAndFieldInfo = generateClosureFieldsInitializationFromParameters(closure, constructorArgs)
|
||||
|
||||
if (receiverIndexAndType == null) {
|
||||
if (receiverIndexAndFieldInfo == null) {
|
||||
assert(!shouldHaveBoundReferenceReceiver) { "No bound reference receiver in constructor parameters: $constructorArgs" }
|
||||
load(0, OBJECT_TYPE)
|
||||
invokespecial(superAsmType.internalName, "<init>", "()V", false)
|
||||
} else {
|
||||
val (receiverIndex, receiverType) = receiverIndexAndType
|
||||
val (receiverIndex, receiverFieldInfo) = receiverIndexAndFieldInfo
|
||||
load(0, OBJECT_TYPE)
|
||||
loadBoundReferenceReceiverParameter(receiverIndex, receiverType)
|
||||
loadBoundReferenceReceiverParameter(receiverIndex, receiverFieldInfo.fieldType, receiverFieldInfo.fieldKotlinType)
|
||||
invokespecial(superAsmType.internalName, "<init>", "(Ljava/lang/Object;)V", false)
|
||||
}
|
||||
}
|
||||
@@ -155,7 +157,7 @@ class PropertyReferenceCodegen(
|
||||
getFunction,
|
||||
target,
|
||||
asmType,
|
||||
receiverType,
|
||||
boundReceiverJvmKotlinType,
|
||||
element,
|
||||
state,
|
||||
false
|
||||
@@ -176,7 +178,7 @@ class PropertyReferenceCodegen(
|
||||
setFunction,
|
||||
target,
|
||||
asmType,
|
||||
receiverType,
|
||||
boundReceiverJvmKotlinType,
|
||||
element,
|
||||
state,
|
||||
false
|
||||
@@ -247,7 +249,11 @@ class PropertyReferenceCodegen(
|
||||
else -> error("Unsupported callable reference: $callable")
|
||||
}
|
||||
val declaration = DescriptorUtils.unwrapFakeOverride(accessor).original
|
||||
val method = state.typeMapper.mapAsmMethod(declaration)
|
||||
val method =
|
||||
if (callable.containingDeclaration.isInlineClass())
|
||||
state.typeMapper.mapSignatureForInlineErasedClassSkipGeneric(declaration).asmMethod
|
||||
else
|
||||
state.typeMapper.mapAsmMethod(declaration)
|
||||
return method.name + method.descriptor
|
||||
}
|
||||
|
||||
@@ -284,19 +290,39 @@ class PropertyReferenceCodegen(
|
||||
}
|
||||
|
||||
class PropertyReferenceGenerationStrategy(
|
||||
val isGetter: Boolean,
|
||||
private val isGetter: Boolean,
|
||||
private val originalFunctionDesc: FunctionDescriptor,
|
||||
val target: VariableDescriptor,
|
||||
val asmType: Type,
|
||||
val receiverType: Type?,
|
||||
val expression: KtElement,
|
||||
private val target: VariableDescriptor,
|
||||
private val asmType: Type,
|
||||
boundReceiverJvmKotlinType: JvmKotlinType?,
|
||||
private val expression: KtElement,
|
||||
state: GenerationState,
|
||||
private val isInliningStrategy: Boolean
|
||||
) :
|
||||
FunctionGenerationStrategy.CodegenBased(state) {
|
||||
|
||||
private val boundReceiverType = boundReceiverJvmKotlinType?.type
|
||||
private val boundReceiverKotlinType = boundReceiverJvmKotlinType?.kotlinType
|
||||
|
||||
private val expectedReceiverKotlinType =
|
||||
target.extensionReceiverParameter?.type
|
||||
?: (target.containingDeclaration as? ClassDescriptor)?.defaultType
|
||||
|
||||
private val expectedReceiverType =
|
||||
if (expectedReceiverKotlinType != null)
|
||||
state.typeMapper.mapType(expectedReceiverKotlinType)
|
||||
else {
|
||||
assert(boundReceiverType == null) {
|
||||
"$target: no expected receiver, boundReceiverType is $boundReceiverType"
|
||||
}
|
||||
null
|
||||
}
|
||||
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
val v = codegen.v
|
||||
val typeMapper = state.typeMapper
|
||||
val targetKotlinType = target.type
|
||||
|
||||
if (target is PropertyImportedFromObject) {
|
||||
val containingObject = target.containingObject
|
||||
StackValue
|
||||
@@ -304,31 +330,51 @@ class PropertyReferenceCodegen(
|
||||
.put(typeMapper.mapClass(containingObject), containingObject.defaultType, v)
|
||||
}
|
||||
|
||||
if (receiverType != null) {
|
||||
val expectedReceiver =
|
||||
target.extensionReceiverParameter?.type ?: (target.containingDeclaration as? ClassDescriptor)?.defaultType
|
||||
val expectedReceiverType = if (expectedReceiver != null) typeMapper.mapType(expectedReceiver) else receiverType
|
||||
capturedBoundReferenceReceiver(asmType, expectedReceiverType, isInliningStrategy).put(expectedReceiverType, v)
|
||||
if (boundReceiverType != null) {
|
||||
capturedBoundReferenceReceiver(asmType, boundReceiverType, boundReceiverKotlinType, isInliningStrategy)
|
||||
.put(expectedReceiverType!!, expectedReceiverKotlinType, v)
|
||||
} else {
|
||||
val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1)
|
||||
receivers.forEachIndexed { i, valueParameterDescriptor ->
|
||||
StackValue.local(i + 1, OBJECT_TYPE).put(typeMapper.mapType(valueParameterDescriptor), valueParameterDescriptor.type, v)
|
||||
val nullableAny = valueParameterDescriptor.builtIns.nullableAnyType
|
||||
StackValue.local(i + 1, OBJECT_TYPE, nullableAny)
|
||||
.put(typeMapper.mapType(valueParameterDescriptor), valueParameterDescriptor.type, v)
|
||||
}
|
||||
}
|
||||
|
||||
val value = if (target is LocalVariableDescriptor) {
|
||||
codegen.findLocalOrCapturedValue(target)!!
|
||||
} else {
|
||||
codegen.intermediateValueForProperty(target as PropertyDescriptor, false, null, StackValue.none())
|
||||
val value = when {
|
||||
target is LocalVariableDescriptor -> codegen.findLocalOrCapturedValue(target)!!
|
||||
|
||||
target.isUnderlyingPropertyOfInlineClass() -> {
|
||||
if (expectedReceiverType == null)
|
||||
throw AssertionError("$target: boundReceiverType=$boundReceiverType, expectedReceiverType is null")
|
||||
|
||||
val receiver =
|
||||
if (boundReceiverType != null)
|
||||
StackValue.onStack(expectedReceiverType, expectedReceiverKotlinType)
|
||||
else
|
||||
StackValue.none()
|
||||
|
||||
StackValue.underlyingValueOfInlineClass(typeMapper.mapType(targetKotlinType), targetKotlinType, receiver)
|
||||
}
|
||||
|
||||
else -> codegen.intermediateValueForProperty(target as PropertyDescriptor, false, null, StackValue.none())
|
||||
}
|
||||
|
||||
codegen.markStartLineNumber(expression)
|
||||
val type = target.type
|
||||
|
||||
if (isGetter) {
|
||||
value.put(OBJECT_TYPE, type, v)
|
||||
value.put(OBJECT_TYPE, targetKotlinType, v)
|
||||
} else {
|
||||
val functionDescriptor = codegen.context.functionDescriptor
|
||||
value.store(StackValue.local(codegen.frameMap.getIndex(functionDescriptor.valueParameters.last()), OBJECT_TYPE, type), v)
|
||||
value.store(
|
||||
StackValue.local(
|
||||
codegen.frameMap.getIndex(
|
||||
codegen.context.functionDescriptor.valueParameters.last()
|
||||
),
|
||||
OBJECT_TYPE, targetKotlinType
|
||||
),
|
||||
v
|
||||
)
|
||||
}
|
||||
v.areturn(signature.returnType)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.isTopLevelInPackage
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
|
||||
@@ -25,15 +25,16 @@ import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
|
||||
public class SamCodegenUtil {
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
public static FunctionDescriptor getOriginalIfSamAdapter(@NotNull FunctionDescriptor fun) {
|
||||
if (fun instanceof SamAdapterDescriptor<?> || fun instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
//noinspection unchecked
|
||||
return ((SyntheticMemberDescriptor<FunctionDescriptor>) fun).getBaseDescriptorForSynthetic();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends FunctionDescriptor> T resolveSamAdapter(@NotNull T descriptor) {
|
||||
FunctionDescriptor original = getOriginalIfSamAdapter(descriptor);
|
||||
return original != null ? (T) original : descriptor;
|
||||
|
||||
@@ -77,7 +77,7 @@ class ScriptCodegen private constructor(
|
||||
classBuilder: ClassBuilder,
|
||||
methodContext: MethodContext
|
||||
) {
|
||||
val scriptDefinition = scriptContext.script.kotlinScriptDefinition.value
|
||||
val scriptDefinition = scriptContext.script.kotlinScriptDefinition
|
||||
|
||||
val jvmSignature = typeMapper.mapScriptSignature(
|
||||
scriptDescriptor,
|
||||
|
||||
@@ -25,7 +25,10 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.ValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
||||
@@ -160,16 +163,26 @@ public abstract class StackValue {
|
||||
|
||||
@NotNull
|
||||
public static StackValue local(int index, @NotNull Type type, @NotNull VariableDescriptor descriptor) {
|
||||
return local(index, type, descriptor, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue local(int index, @NotNull Type type, @NotNull VariableDescriptor descriptor, @Nullable KotlinType delegateKotlinType) {
|
||||
if (descriptor.isLateInit()) {
|
||||
assert delegateKotlinType == null :
|
||||
"Delegated property can't be lateinit: " + descriptor + ", delegate type: " + delegateKotlinType;
|
||||
return new LateinitLocal(index, type, descriptor.getType(), descriptor.getName());
|
||||
}
|
||||
else {
|
||||
return new Local(index, type, descriptor.getType());
|
||||
return new Local(
|
||||
index, type,
|
||||
delegateKotlinType != null ? delegateKotlinType : descriptor.getType()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Delegate delegate(
|
||||
public static Delegate localDelegate(
|
||||
@NotNull Type type,
|
||||
@NotNull StackValue delegateValue,
|
||||
@NotNull StackValue metadataValue,
|
||||
@@ -186,7 +199,16 @@ public abstract class StackValue {
|
||||
|
||||
@NotNull
|
||||
public static StackValue shared(int index, @NotNull Type type, @NotNull VariableDescriptor descriptor) {
|
||||
return new Shared(index, type, descriptor.getType(), descriptor.isLateInit(), descriptor.getName());
|
||||
return shared(index, type, descriptor, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue shared(int index, @NotNull Type type, @NotNull VariableDescriptor descriptor, @Nullable KotlinType delegateKotlinType) {
|
||||
return new Shared(
|
||||
index, type,
|
||||
delegateKotlinType != null ? delegateKotlinType : descriptor.getType(),
|
||||
descriptor.isLateInit(), descriptor.getName()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -318,7 +340,19 @@ public abstract class StackValue {
|
||||
|
||||
@NotNull
|
||||
public static Field field(@NotNull Type type, @NotNull Type owner, @NotNull String name, boolean isStatic, @NotNull StackValue receiver) {
|
||||
return field(type, null, owner, name, isStatic, receiver, null);
|
||||
return field(type, null, owner, name, isStatic, receiver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Field field(
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@NotNull Type owner,
|
||||
@NotNull String name,
|
||||
boolean isStatic,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
return field(type, kotlinType, owner, name, isStatic, receiver, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -341,7 +375,14 @@ public abstract class StackValue {
|
||||
|
||||
@NotNull
|
||||
public static Field field(@NotNull FieldInfo info, @NotNull StackValue receiver) {
|
||||
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), info.isStatic(), receiver);
|
||||
return field(
|
||||
info.getFieldType(),
|
||||
info.getFieldKotlinType(),
|
||||
Type.getObjectType(info.getOwnerInternalName()),
|
||||
info.getFieldName(),
|
||||
info.isStatic(),
|
||||
receiver
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -363,10 +404,11 @@ public abstract class StackValue {
|
||||
@NotNull StackValue receiver,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@Nullable ResolvedCall resolvedCall,
|
||||
boolean skipLateinitAssertion
|
||||
boolean skipLateinitAssertion,
|
||||
@Nullable KotlinType delegateKotlinType
|
||||
) {
|
||||
return new Property(descriptor, backingFieldOwner, getter, setter, isStaticBackingField, fieldName, type, receiver, codegen,
|
||||
resolvedCall, skipLateinitAssertion);
|
||||
resolvedCall, skipLateinitAssertion, delegateKotlinType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -721,7 +763,7 @@ public abstract class StackValue {
|
||||
) {
|
||||
// Coerce 'this' for the case when it is smart cast.
|
||||
// Do not coerce for other cases due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints).
|
||||
boolean coerceType = descriptor.getKind() == ClassKind.INTERFACE || (castReceiver && !isSuper);
|
||||
boolean coerceType = descriptor.getKind() == ClassKind.INTERFACE || descriptor.isInline() || (castReceiver && !isSuper);
|
||||
return new ThisOuter(codegen, descriptor, isSuper, coerceType);
|
||||
}
|
||||
|
||||
@@ -1426,7 +1468,7 @@ public abstract class StackValue {
|
||||
|
||||
Type lastParameterType = ArraysKt.last(setter.getParameterTypes());
|
||||
KotlinType lastParameterKotlinType =
|
||||
CollectionsKt.last(resolvedSetCall.getResultingDescriptor().getValueParameters()).getType();
|
||||
CollectionsKt.last(resolvedSetCall.getResultingDescriptor().getOriginal().getValueParameters()).getType();
|
||||
|
||||
coerce(topOfStackType, topOfStackKotlinType, lastParameterType, lastParameterKotlinType, v);
|
||||
|
||||
@@ -1460,7 +1502,6 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Field extends StackValueWithSimpleReceiver {
|
||||
public final Type owner;
|
||||
public final String name;
|
||||
@@ -1508,12 +1549,13 @@ public abstract class StackValue {
|
||||
private final ExpressionCodegen codegen;
|
||||
private final ResolvedCall resolvedCall;
|
||||
private final boolean skipLateinitAssertion;
|
||||
private final KotlinType delegateKotlinType;
|
||||
|
||||
public Property(
|
||||
@NotNull PropertyDescriptor descriptor, @Nullable Type backingFieldOwner, @Nullable CallableMethod getter,
|
||||
@Nullable CallableMethod setter, boolean isStaticBackingField, @Nullable String fieldName, @NotNull Type type,
|
||||
@NotNull StackValue receiver, @NotNull ExpressionCodegen codegen, @Nullable ResolvedCall resolvedCall,
|
||||
boolean skipLateinitAssertion
|
||||
boolean skipLateinitAssertion, @Nullable KotlinType delegateKotlinType
|
||||
) {
|
||||
super(type, descriptor.getType(), isStatic(isStaticBackingField, getter), isStatic(isStaticBackingField, setter), receiver, true);
|
||||
this.backingFieldOwner = backingFieldOwner;
|
||||
@@ -1524,6 +1566,44 @@ public abstract class StackValue {
|
||||
this.codegen = codegen;
|
||||
this.resolvedCall = resolvedCall;
|
||||
this.skipLateinitAssertion = skipLateinitAssertion;
|
||||
this.delegateKotlinType = delegateKotlinType;
|
||||
}
|
||||
|
||||
private static class DelegatePropertyConstructorMarker {
|
||||
private DelegatePropertyConstructorMarker() {}
|
||||
public static final DelegatePropertyConstructorMarker MARKER = new DelegatePropertyConstructorMarker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a delegating property, create a "property" corresponding to the underlying delegate itself.
|
||||
* This will take care of backing fields, accessors, and other such stuff.
|
||||
* Note that we just replace <code>kotlinType</code> with the <code>delegateKotlinType</code>
|
||||
* (so that type coercion will work properly),
|
||||
* and <code>delegateKotlinType</code> with <code>null</code>
|
||||
* (so that the resulting property has no underlying delegate of its own).
|
||||
*
|
||||
* @param delegating delegating property
|
||||
* @param marker intent marker
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private Property(@NotNull Property delegating, @NotNull DelegatePropertyConstructorMarker marker) {
|
||||
super(delegating.type, delegating.delegateKotlinType,
|
||||
delegating.isStaticPut, delegating.isStaticStore, delegating.receiver, true);
|
||||
|
||||
this.backingFieldOwner = delegating.backingFieldOwner;
|
||||
this.getter = delegating.getter;
|
||||
this.setter = delegating.setter;
|
||||
this.descriptor = delegating.descriptor;
|
||||
this.fieldName = delegating.fieldName;
|
||||
this.codegen = delegating.codegen;
|
||||
this.resolvedCall = delegating.resolvedCall;
|
||||
this.skipLateinitAssertion = delegating.skipLateinitAssertion;
|
||||
this.delegateKotlinType = null;
|
||||
}
|
||||
|
||||
public Property getDelegateOrNull() {
|
||||
if (delegateKotlinType == null) return null;
|
||||
return new Property(this, DelegatePropertyConstructorMarker.MARKER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,10 +21,10 @@ import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class CoercionValue(
|
||||
val value: StackValue,
|
||||
private val castType: Type,
|
||||
private val castKotlinType: KotlinType?,
|
||||
private val underlyingKotlinType: KotlinType? // type of the underlying parameter for inline class
|
||||
val value: StackValue,
|
||||
private val castType: Type,
|
||||
private val castKotlinType: KotlinType?,
|
||||
private val underlyingKotlinType: KotlinType? // type of the underlying parameter for inline class
|
||||
) : StackValue(castType, castKotlinType, value.canHaveSideEffects()) {
|
||||
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
@@ -55,8 +55,8 @@ class CoercionValue(
|
||||
|
||||
|
||||
class StackValueWithLeaveTask(
|
||||
val stackValue: StackValue,
|
||||
val leaveTasks: (StackValue) -> Unit
|
||||
val stackValue: StackValue,
|
||||
val leaveTasks: (StackValue) -> Unit
|
||||
) : StackValue(stackValue.type, stackValue.kotlinType) {
|
||||
|
||||
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
|
||||
@@ -89,22 +89,22 @@ class FunctionCallStackValue(
|
||||
|
||||
fun ValueParameterDescriptor.findJavaDefaultArgumentValue(targetType: Type, typeMapper: KotlinTypeMapper): StackValue {
|
||||
val descriptorWithDefaultValue = DFS.dfs(
|
||||
listOf(this.original),
|
||||
{ it.original.overriddenDescriptors.map(ValueParameterDescriptor::getOriginal) },
|
||||
object : DFS.AbstractNodeHandler<ValueParameterDescriptor, ValueParameterDescriptor?>() {
|
||||
var result: ValueParameterDescriptor? = null
|
||||
listOf(this.original),
|
||||
{ it.original.overriddenDescriptors.map(ValueParameterDescriptor::getOriginal) },
|
||||
object : DFS.AbstractNodeHandler<ValueParameterDescriptor, ValueParameterDescriptor?>() {
|
||||
var result: ValueParameterDescriptor? = null
|
||||
|
||||
override fun beforeChildren(current: ValueParameterDescriptor?): Boolean {
|
||||
if (current?.declaresDefaultValue() == true && current.getDefaultValueFromAnnotation() != null) {
|
||||
result = current
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
override fun beforeChildren(current: ValueParameterDescriptor?): Boolean {
|
||||
if (current?.declaresDefaultValue() == true && current.getDefaultValueFromAnnotation() != null) {
|
||||
result = current
|
||||
return false
|
||||
}
|
||||
|
||||
override fun result(): ValueParameterDescriptor? = result
|
||||
return true
|
||||
}
|
||||
|
||||
override fun result(): ValueParameterDescriptor? = result
|
||||
}
|
||||
) ?: error("Should be at least one descriptor with default value: $this")
|
||||
|
||||
val defaultValue = descriptorWithDefaultValue.getDefaultValueFromAnnotation()
|
||||
|
||||
@@ -959,11 +959,18 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
private boolean isWhenWithEnums(@NotNull KtWhenExpression expression) {
|
||||
return WhenChecker.isWhenByEnum(expression, bindingContext) &&
|
||||
switchCodegenProvider.checkAllItemsAreConstantsSatisfying(
|
||||
expression,
|
||||
constant -> constant instanceof EnumValue || constant instanceof NullValue
|
||||
);
|
||||
ClassId enumClassId = WhenChecker.getClassIdForEnumSubject(expression, bindingContext);
|
||||
if (enumClassId == null) return false;
|
||||
|
||||
return switchCodegenProvider.checkAllItemsAreConstantsSatisfying(
|
||||
expression,
|
||||
constant -> isEnumEntryOrNull(enumClassId, constant)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean isEnumEntryOrNull(ClassId enumClassId, ConstantValue<?> constant) {
|
||||
return (constant instanceof EnumValue && ((EnumValue) constant).getEnumClassId().equals(enumClassId)) ||
|
||||
constant instanceof NullValue;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -24,69 +24,77 @@ import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
fun capturedBoundReferenceReceiver(ownerType: Type, expectedReceiverType: Type, isInliningStrategy: Boolean): StackValue =
|
||||
StackValue.operation(expectedReceiverType) { iv ->
|
||||
iv.load(0, ownerType)
|
||||
iv.getfield(
|
||||
ownerType.internalName,
|
||||
//HACK for inliner - it should recognize field as captured receiver
|
||||
if (isInliningStrategy) AsmUtil.CAPTURED_RECEIVER_FIELD else AsmUtil.BOUND_REFERENCE_RECEIVER,
|
||||
AsmTypes.OBJECT_TYPE.descriptor
|
||||
)
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, expectedReceiverType, iv)
|
||||
}
|
||||
fun capturedBoundReferenceReceiver(
|
||||
ownerType: Type,
|
||||
expectedReceiverType: Type,
|
||||
expectedReceiverKotlinType: KotlinType?,
|
||||
isInliningStrategy: Boolean
|
||||
): StackValue =
|
||||
StackValue.operation(expectedReceiverType) { iv ->
|
||||
iv.load(0, ownerType)
|
||||
iv.getfield(
|
||||
ownerType.internalName,
|
||||
//HACK for inliner - it should recognize field as captured receiver
|
||||
if (isInliningStrategy) AsmUtil.CAPTURED_RECEIVER_FIELD else AsmUtil.BOUND_REFERENCE_RECEIVER,
|
||||
AsmTypes.OBJECT_TYPE.descriptor
|
||||
)
|
||||
val nullableAny = expectedReceiverKotlinType?.run { builtIns.nullableAnyType }
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, nullableAny, expectedReceiverType, expectedReceiverKotlinType, iv)
|
||||
}
|
||||
|
||||
fun ClassDescriptor.isSyntheticClassForCallableReference(): Boolean =
|
||||
this is SyntheticClassDescriptorForLambda &&
|
||||
(this.source as? KotlinSourceElement)?.psi is KtCallableReferenceExpression
|
||||
this is SyntheticClassDescriptorForLambda &&
|
||||
(this.source as? KotlinSourceElement)?.psi is KtCallableReferenceExpression
|
||||
|
||||
fun CalculatedClosure.isForCallableReference(): Boolean =
|
||||
closureClass.isSyntheticClassForCallableReference()
|
||||
closureClass.isSyntheticClassForCallableReference()
|
||||
|
||||
fun CalculatedClosure.isForBoundCallableReference(): Boolean =
|
||||
isForCallableReference() && capturedReceiverFromOuterContext != null
|
||||
isForCallableReference() && capturedReceiverFromOuterContext != null
|
||||
|
||||
fun InstructionAdapter.loadBoundReferenceReceiverParameter(index: Int, type: Type) {
|
||||
fun InstructionAdapter.loadBoundReferenceReceiverParameter(index: Int, type: Type, kotlinType: KotlinType?) {
|
||||
load(index, type)
|
||||
StackValue.coerce(type, AsmTypes.OBJECT_TYPE, this)
|
||||
val nullableAny = kotlinType?.run { builtIns.nullableAnyType }
|
||||
StackValue.coerce(type, kotlinType, AsmTypes.OBJECT_TYPE, nullableAny, this)
|
||||
}
|
||||
|
||||
fun CalculatedClosure.isBoundReferenceReceiverField(fieldInfo: FieldInfo): Boolean =
|
||||
isForBoundCallableReference() &&
|
||||
fieldInfo.fieldName == AsmUtil.CAPTURED_RECEIVER_FIELD
|
||||
isForBoundCallableReference() &&
|
||||
fieldInfo.fieldName == AsmUtil.CAPTURED_RECEIVER_FIELD
|
||||
|
||||
fun InstructionAdapter.generateClosureFieldsInitializationFromParameters(closure: CalculatedClosure, args: List<FieldInfo>): Pair<Int, Type>? {
|
||||
fun InstructionAdapter.generateClosureFieldsInitializationFromParameters(
|
||||
closure: CalculatedClosure,
|
||||
args: List<FieldInfo>
|
||||
): Pair<Int, FieldInfo>? {
|
||||
var k = 1
|
||||
var boundReferenceReceiverParameterIndex = -1
|
||||
var boundReferenceReceiverType: Type? = null
|
||||
var boundReferenceReceiverFieldInfo: FieldInfo? = null
|
||||
for (fieldInfo in args) {
|
||||
if (closure.isBoundReferenceReceiverField(fieldInfo)) {
|
||||
boundReferenceReceiverParameterIndex = k
|
||||
boundReferenceReceiverType = fieldInfo.fieldType
|
||||
boundReferenceReceiverFieldInfo = fieldInfo
|
||||
k += fieldInfo.fieldType.size
|
||||
continue
|
||||
}
|
||||
k = AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, k, this)
|
||||
}
|
||||
|
||||
return when {
|
||||
boundReferenceReceiverType != null ->
|
||||
Pair(boundReferenceReceiverParameterIndex, boundReferenceReceiverType)
|
||||
else ->
|
||||
null
|
||||
}
|
||||
return boundReferenceReceiverFieldInfo?.let { Pair(boundReferenceReceiverParameterIndex, it) }
|
||||
}
|
||||
|
||||
fun computeExpectedNumberOfReceivers(referencedFunction: FunctionDescriptor, isBound: Boolean): Int {
|
||||
val receivers = (if (referencedFunction.dispatchReceiverParameter != null) 1 else 0) +
|
||||
(if (referencedFunction.extensionReceiverParameter != null) 1 else 0) -
|
||||
(if (isBound) 1 else 0)
|
||||
(if (referencedFunction.extensionReceiverParameter != null) 1 else 0) -
|
||||
(if (isBound) 1 else 0)
|
||||
|
||||
if (receivers < 0 && referencedFunction is ConstructorDescriptor &&
|
||||
DescriptorUtils.isObject(referencedFunction.containingDeclaration.containingDeclaration)) {
|
||||
DescriptorUtils.isObject(referencedFunction.containingDeclaration.containingDeclaration)
|
||||
) {
|
||||
//reference to object nested class
|
||||
//TODO: seems problem should be fixed on frontend side (note that object instance are captured by generated class)
|
||||
return 0
|
||||
|
||||
@@ -12,8 +12,11 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.continuationAsmType
|
||||
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
|
||||
import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX
|
||||
import org.jetbrains.kotlin.codegen.inline.ReificationArgument
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
@@ -30,19 +33,18 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSubclass
|
||||
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getFirstArgumentExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor.CoroutinesCompatibilityMode
|
||||
@@ -52,6 +54,7 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
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.commons.Method
|
||||
@@ -250,6 +253,9 @@ fun CallableDescriptor.isJvmStaticInObjectOrClassOrInterface(): Boolean =
|
||||
fun CallableDescriptor.isJvmStaticInCompanionObject(): Boolean =
|
||||
isJvmStaticIn { DescriptorUtils.isCompanionObject(it) }
|
||||
|
||||
fun CallableDescriptor.isJvmStaticInInlineClass(): Boolean =
|
||||
isJvmStaticIn { it.isInlineClass() }
|
||||
|
||||
private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor) -> Boolean): Boolean =
|
||||
when (this) {
|
||||
is PropertyAccessorDescriptor -> {
|
||||
@@ -464,4 +470,197 @@ fun recordCallLabelForLambdaArgument(declaration: KtFunctionLiteral, bindingTrac
|
||||
val call = callExpression.getResolvedCall(bindingTrace.bindingContext) ?: return
|
||||
|
||||
storeLabelName(call.resultingDescriptor.name.asString())
|
||||
}
|
||||
}
|
||||
|
||||
private val ARRAY_OF_STRINGS_TYPE = Type.getType("[Ljava/lang/String;")
|
||||
private val METHOD_DESCRIPTOR_FOR_MAIN = Type.getMethodDescriptor(Type.VOID_TYPE, ARRAY_OF_STRINGS_TYPE)
|
||||
|
||||
fun generateBridgeForMainFunctionIfNecessary(
|
||||
state: GenerationState,
|
||||
packagePartClassBuilder: ClassBuilder,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
signatureOfRealDeclaration: JvmMethodGenericSignature,
|
||||
origin: JvmDeclarationOrigin,
|
||||
parentContext: CodegenContext<*>
|
||||
) {
|
||||
val originElement = origin.element ?: return
|
||||
if (functionDescriptor.name.asString() != "main" || !DescriptorUtils.isTopLevelDeclaration(functionDescriptor)) return
|
||||
|
||||
val unwrappedFunctionDescriptor = functionDescriptor.unwrapInitialDescriptorForSuspendFunction()
|
||||
val isParameterless =
|
||||
unwrappedFunctionDescriptor.extensionReceiverParameter == null && unwrappedFunctionDescriptor.valueParameters.isEmpty()
|
||||
|
||||
if (!functionDescriptor.isSuspend && !isParameterless) return
|
||||
if (!state.mainFunctionDetector.isMain(unwrappedFunctionDescriptor, false, true)) return
|
||||
|
||||
val bridgeMethodVisitor = packagePartClassBuilder.newMethod(
|
||||
Synthetic(originElement, functionDescriptor),
|
||||
ACC_PUBLIC or ACC_STATIC or ACC_SYNTHETIC,
|
||||
"main",
|
||||
METHOD_DESCRIPTOR_FOR_MAIN, null, null
|
||||
)
|
||||
|
||||
if (parentContext is MultifileClassFacadeContext) {
|
||||
bridgeMethodVisitor.visitCode()
|
||||
FunctionCodegen.generateFacadeDelegateMethodBody(
|
||||
bridgeMethodVisitor,
|
||||
Method("main", METHOD_DESCRIPTOR_FOR_MAIN),
|
||||
parentContext
|
||||
)
|
||||
bridgeMethodVisitor.visitEnd()
|
||||
return
|
||||
}
|
||||
|
||||
val lambdaInternalName =
|
||||
if (functionDescriptor.isSuspend)
|
||||
generateLambdaForRunSuspend(
|
||||
state,
|
||||
originElement,
|
||||
packagePartClassBuilder.thisName,
|
||||
signatureOfRealDeclaration,
|
||||
isParameterless
|
||||
)
|
||||
else
|
||||
null
|
||||
|
||||
bridgeMethodVisitor.apply {
|
||||
visitCode()
|
||||
|
||||
if (lambdaInternalName != null) {
|
||||
visitTypeInsn(NEW, lambdaInternalName)
|
||||
visitInsn(DUP)
|
||||
visitVarInsn(ALOAD, 0)
|
||||
visitMethodInsn(
|
||||
INVOKESPECIAL,
|
||||
lambdaInternalName,
|
||||
"<init>",
|
||||
METHOD_DESCRIPTOR_FOR_MAIN,
|
||||
false
|
||||
)
|
||||
|
||||
visitMethodInsn(
|
||||
INVOKESTATIC,
|
||||
"kotlin/coroutines/jvm/internal/RunSuspendKt", "runSuspend",
|
||||
Type.getMethodDescriptor(
|
||||
Type.VOID_TYPE,
|
||||
Type.getObjectType(NUMBERED_FUNCTION_PREFIX + "1")
|
||||
),
|
||||
false
|
||||
)
|
||||
} else {
|
||||
visitMethodInsn(
|
||||
INVOKESTATIC,
|
||||
packagePartClassBuilder.thisName, "main",
|
||||
Type.getMethodDescriptor(
|
||||
Type.VOID_TYPE
|
||||
),
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
visitInsn(RETURN)
|
||||
visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateLambdaForRunSuspend(
|
||||
state: GenerationState,
|
||||
originElement: PsiElement,
|
||||
packagePartClassInternalName: String,
|
||||
signatureOfRealDeclaration: JvmMethodGenericSignature,
|
||||
parameterless: Boolean
|
||||
): String {
|
||||
val internalName = "$packagePartClassInternalName$$\$main"
|
||||
val lambdaBuilder = state.factory.newVisitor(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
Type.getObjectType(internalName),
|
||||
originElement.containingFile
|
||||
)
|
||||
|
||||
lambdaBuilder.defineClass(
|
||||
originElement, state.classFileVersion,
|
||||
ACC_FINAL or ACC_SUPER or ACC_SYNTHETIC,
|
||||
internalName, null,
|
||||
AsmTypes.LAMBDA.internalName,
|
||||
arrayOf(NUMBERED_FUNCTION_PREFIX + "1")
|
||||
)
|
||||
|
||||
lambdaBuilder.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
ACC_PRIVATE or ACC_FINAL,
|
||||
"args",
|
||||
ARRAY_OF_STRINGS_TYPE.descriptor, null, null
|
||||
)
|
||||
|
||||
lambdaBuilder.newMethod(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE or ACC_SYNTHETIC,
|
||||
"<init>",
|
||||
METHOD_DESCRIPTOR_FOR_MAIN, null, null
|
||||
).apply {
|
||||
visitCode()
|
||||
visitVarInsn(ALOAD, 0)
|
||||
visitVarInsn(ALOAD, 1)
|
||||
visitFieldInsn(
|
||||
PUTFIELD,
|
||||
lambdaBuilder.thisName,
|
||||
"args",
|
||||
ARRAY_OF_STRINGS_TYPE.descriptor
|
||||
)
|
||||
|
||||
visitVarInsn(ALOAD, 0)
|
||||
visitInsn(ICONST_1)
|
||||
visitMethodInsn(
|
||||
INVOKESPECIAL,
|
||||
AsmTypes.LAMBDA.internalName,
|
||||
"<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE),
|
||||
false
|
||||
)
|
||||
visitInsn(RETURN)
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
lambdaBuilder.newMethod(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
ACC_PUBLIC or ACC_FINAL or ACC_SYNTHETIC,
|
||||
"invoke",
|
||||
Type.getMethodDescriptor(AsmTypes.OBJECT_TYPE, AsmTypes.OBJECT_TYPE), null, null
|
||||
).apply {
|
||||
visitCode()
|
||||
|
||||
if (!parameterless) {
|
||||
// Actually, the field for arguments may also be removed in case of parameterless main,
|
||||
// but probably it'd much easier when IR is ready
|
||||
visitVarInsn(ALOAD, 0)
|
||||
visitFieldInsn(
|
||||
GETFIELD,
|
||||
lambdaBuilder.thisName,
|
||||
"args",
|
||||
ARRAY_OF_STRINGS_TYPE.descriptor
|
||||
)
|
||||
}
|
||||
|
||||
visitVarInsn(ALOAD, 1)
|
||||
val continuationInternalName = state.languageVersionSettings.continuationAsmType().internalName
|
||||
|
||||
visitTypeInsn(
|
||||
CHECKCAST,
|
||||
continuationInternalName
|
||||
)
|
||||
visitMethodInsn(
|
||||
INVOKESTATIC,
|
||||
packagePartClassInternalName,
|
||||
signatureOfRealDeclaration.asmMethod.name,
|
||||
signatureOfRealDeclaration.asmMethod.descriptor,
|
||||
false
|
||||
)
|
||||
visitInsn(ARETURN)
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
writeSyntheticClassMetadata(lambdaBuilder, state)
|
||||
|
||||
lambdaBuilder.done()
|
||||
return lambdaBuilder.thisName
|
||||
}
|
||||
|
||||
@@ -393,12 +393,16 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
public CodegenContext findParentContextWithDescriptor(DeclarationDescriptor descriptor) {
|
||||
CodegenContext c = this;
|
||||
while (c != null) {
|
||||
if (c.getContextDescriptor() == descriptor) break;
|
||||
if (!c.shouldSkipThisContextInHierarchy() && c.getContextDescriptor() == descriptor) break;
|
||||
c = c.getParentContext();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private boolean shouldSkipThisContextInHierarchy() {
|
||||
return getContextKind() == OwnerKind.ERASED_INLINE_CLASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PropertyDescriptor getPropertyAccessor(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@@ -409,7 +413,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return getAccessor(propertyDescriptor, AccessorKind.NORMAL, null, superCallTarget, getterAccessorRequired, setterAccessorRequired);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <D extends CallableMemberDescriptor> D getAccessorForJvmDefaultCompatibility(@NotNull D descriptor) {
|
||||
if (descriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyDescriptor propertyAccessor = getAccessor(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty(),
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.kotlin.codegen.StackValue;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public final class EnclosedValueDescriptor {
|
||||
@@ -29,18 +30,21 @@ public final class EnclosedValueDescriptor {
|
||||
private final StackValue.StackValueWithSimpleReceiver innerValue;
|
||||
private final StackValue instanceValue;
|
||||
private final Type type;
|
||||
private final KotlinType kotlinType;
|
||||
|
||||
public EnclosedValueDescriptor(
|
||||
@NotNull String fieldName,
|
||||
@Nullable DeclarationDescriptor descriptor,
|
||||
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
||||
@NotNull Type type
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType
|
||||
) {
|
||||
this.fieldName = fieldName;
|
||||
this.descriptor = descriptor;
|
||||
this.innerValue = innerValue;
|
||||
this.instanceValue = innerValue;
|
||||
this.type = type;
|
||||
this.kotlinType = kotlinType;
|
||||
}
|
||||
|
||||
public EnclosedValueDescriptor(
|
||||
@@ -48,13 +52,15 @@ public final class EnclosedValueDescriptor {
|
||||
@Nullable DeclarationDescriptor descriptor,
|
||||
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
||||
@NotNull StackValue.Field instanceValue,
|
||||
@NotNull Type type
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType
|
||||
) {
|
||||
this.fieldName = name;
|
||||
this.descriptor = descriptor;
|
||||
this.innerValue = innerValue;
|
||||
this.instanceValue = instanceValue;
|
||||
this.type = type;
|
||||
this.kotlinType = kotlinType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -82,6 +88,11 @@ public final class EnclosedValueDescriptor {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public KotlinType getKotlinType() {
|
||||
return kotlinType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fieldName + " " + type + " -> " + descriptor;
|
||||
|
||||
@@ -63,11 +63,11 @@ public interface LocalLookup {
|
||||
if (sharedVarType != null) {
|
||||
StackValue.Field wrapperValue = StackValue.receiverWithRefWrapper(localType, classType, fieldName, thiz, vd);
|
||||
innerValue = StackValue.fieldForSharedVar(localType, classType, fieldName, wrapperValue, vd);
|
||||
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, wrapperValue, type);
|
||||
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, wrapperValue, type, kotlinType);
|
||||
}
|
||||
else {
|
||||
innerValue = StackValue.field(type, kotlinType, classType, fieldName, false, thiz, vd);
|
||||
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, type);
|
||||
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, type, kotlinType);
|
||||
}
|
||||
|
||||
closure.captureVariable(enclosedValueDescriptor);
|
||||
@@ -118,7 +118,7 @@ public interface LocalLookup {
|
||||
localType, null, classType, fieldName, false, StackValue.LOCAL_0, vd
|
||||
);
|
||||
|
||||
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType));
|
||||
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType, null));
|
||||
|
||||
return innerValue;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -64,8 +65,9 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
public StackValue getReceiverExpression(KotlinTypeMapper typeMapper) {
|
||||
assert getCallableDescriptorWithReceiver() != null;
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
Type asmType = typeMapper.mapType(getCallableDescriptorWithReceiver().getExtensionReceiverParameter().getType());
|
||||
return StackValue.local(AsmUtil.getReceiverIndex(this, getContextDescriptor()), asmType);
|
||||
KotlinType kotlinType = getCallableDescriptorWithReceiver().getExtensionReceiverParameter().getType();
|
||||
Type asmType = typeMapper.mapType(kotlinType);
|
||||
return StackValue.local(AsmUtil.getReceiverIndex(this, getContextDescriptor()), asmType, kotlinType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -77,7 +77,7 @@ class ScriptContext(
|
||||
scriptDescriptor.unsubstitutedPrimaryConstructor.valueParameters[ctorImplicitReceiversParametersStart + index].name.identifier
|
||||
|
||||
fun getImplicitReceiverType(index: Int): Type? {
|
||||
val receivers = script.kotlinScriptDefinition.value.implicitReceivers
|
||||
val receivers = script.kotlinScriptDefinition.implicitReceivers
|
||||
val kClass = receivers.getOrNull(index)?.classifier as? KClass<*>
|
||||
return kClass?.java?.classId?.let(AsmUtil::asmTypeByClassId)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.boxing.isPrimitiveBoxing
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
private val BOXING_CLASS_INTERNAL_NAME =
|
||||
RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName().child(Name.identifier("Boxing")).topLevelClassInternalName()
|
||||
|
||||
object ChangeBoxingMethodTransformer : MethodTransformer() {
|
||||
private val wrapperToInternalBoxing: Map<String, String>
|
||||
|
||||
init {
|
||||
val map = hashMapOf<String, String>()
|
||||
for (primitiveType in JvmPrimitiveType.values()) {
|
||||
val name = primitiveType.wrapperFqName.topLevelClassInternalName()
|
||||
map[name] = "box${primitiveType.javaKeywordName.capitalize()}"
|
||||
}
|
||||
wrapperToInternalBoxing = map
|
||||
}
|
||||
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
for (boxing in methodNode.instructions.asSequence().filter { it.isPrimitiveBoxing() }) {
|
||||
assert(boxing.opcode == Opcodes.INVOKESTATIC) {
|
||||
"boxing shall be INVOKESTATIC wrapper.valueOf"
|
||||
}
|
||||
boxing as MethodInsnNode
|
||||
val methodName = wrapperToInternalBoxing[boxing.owner].sure {
|
||||
"expected primitive wrapper, but got ${boxing.owner}"
|
||||
}
|
||||
methodNode.instructions.set(
|
||||
boxing,
|
||||
MethodInsnNode(boxing.opcode, BOXING_CLASS_INTERNAL_NAME, methodName, boxing.desc, false)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ abstract class AbstractCoroutineCodegen(
|
||||
element: KtElement,
|
||||
closureContext: ClosureContext,
|
||||
classBuilder: ClassBuilder,
|
||||
private val userDataForDoResume: Map<out FunctionDescriptor.UserDataKey<*>, *>? = null
|
||||
private val userDataForDoResume: Map<out CallableDescriptor.UserDataKey<*>, *>? = null
|
||||
) : ClosureCodegen(
|
||||
outerExpressionCodegen.state,
|
||||
element, null, closureContext, null,
|
||||
@@ -347,7 +347,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
// pass captured closure to constructor
|
||||
val constructorParameters = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, owner)
|
||||
for (parameter in constructorParameters) {
|
||||
StackValue.field(parameter, thisInstance).put(parameter.fieldType, this)
|
||||
StackValue.field(parameter, thisInstance).put(parameter.fieldType, parameter.fieldKotlinType, this)
|
||||
}
|
||||
|
||||
// load resultContinuation
|
||||
@@ -377,7 +377,11 @@ class CoroutineCodegenForLambda private constructor(
|
||||
load(1, AsmTypes.OBJECT_TYPE)
|
||||
iconst(index - 1)
|
||||
aload(AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, fieldInfoForCoroutineLambdaParameter.fieldType, this)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
putfield(
|
||||
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldName,
|
||||
@@ -386,7 +390,11 @@ class CoroutineCodegenForLambda private constructor(
|
||||
} else {
|
||||
if (generateErasedCreate) {
|
||||
load(index, AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, fieldInfoForCoroutineLambdaParameter.fieldType, this)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
} else {
|
||||
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
||||
}
|
||||
@@ -434,6 +442,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
FieldInfo.createForHiddenField(
|
||||
typeMapper.mapClass(closureContext.thisDescriptor),
|
||||
typeMapper.mapType(type),
|
||||
type,
|
||||
name
|
||||
)
|
||||
|
||||
@@ -448,7 +457,8 @@ class CoroutineCodegenForLambda private constructor(
|
||||
return CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null,
|
||||
obtainClassBuilderForCoroutineState = { v },
|
||||
lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0,
|
||||
element = element,
|
||||
diagnostics = state.diagnostics,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = v.thisName,
|
||||
isForNamedFunction = false,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import com.intellij.util.containers.Stack
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
@@ -19,7 +20,10 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -56,9 +60,11 @@ class CoroutineTransformerMethodVisitor(
|
||||
obtainClassBuilderForCoroutineState: () -> ClassBuilder,
|
||||
private val isForNamedFunction: Boolean,
|
||||
private val shouldPreserveClassInitialization: Boolean,
|
||||
private val lineNumber: Int,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val sourceFile: String,
|
||||
// These two are needed to report diagnostics about suspension points inside critical section
|
||||
private val element: KtElement,
|
||||
private val diagnostics: DiagnosticSink,
|
||||
// It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls
|
||||
private val needDispatchReceiver: Boolean = false,
|
||||
// May differ from containingClassInternalName in case of DefaultImpls
|
||||
@@ -68,6 +74,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
|
||||
|
||||
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
|
||||
private val lineNumber = element?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0
|
||||
|
||||
private var continuationIndex = if (isForNamedFunction) -1 else 0
|
||||
private var dataIndex = if (isForNamedFunction) -1 else 1
|
||||
@@ -83,14 +90,18 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
FixStackMethodTransformer().transform(containingClassInternalName, methodNode)
|
||||
RedundantLocalsEliminationMethodTransformer(languageVersionSettings).transform(containingClassInternalName, methodNode)
|
||||
if (languageVersionSettings.isReleaseCoroutines()) {
|
||||
ChangeBoxingMethodTransformer.transform(containingClassInternalName, methodNode)
|
||||
}
|
||||
updateMaxStack(methodNode)
|
||||
|
||||
val suspensionPoints = collectSuspensionPoints(methodNode)
|
||||
|
||||
checkForSuspensionPointInsideMonitor(methodNode, suspensionPoints)
|
||||
|
||||
// First instruction in the method node may change in case of named function
|
||||
val actualCoroutineStart = methodNode.instructions.first
|
||||
|
||||
var startLabelNode: LabelNode? = null
|
||||
if (isForNamedFunction) {
|
||||
ReturnUnitMethodTransformer.transform(containingClassInternalName, methodNode)
|
||||
|
||||
@@ -105,7 +116,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
continuationIndex = methodNode.maxLocals++
|
||||
|
||||
startLabelNode = prepareMethodNodePreludeForNamedFunction(methodNode)
|
||||
prepareMethodNodePreludeForNamedFunction(methodNode)
|
||||
} else {
|
||||
ReturnUnitMethodTransformer.cleanUpReturnsUnitMarkers(methodNode, ReturnUnitMethodTransformer.findReturnsUnitMarks(methodNode))
|
||||
}
|
||||
@@ -127,14 +138,16 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
val suspendMarkerVarIndex = methodNode.maxLocals++
|
||||
|
||||
val suspensionPointLabels = suspensionPoints.withIndex().map {
|
||||
val suspensionPointLineNumbers = suspensionPoints.map { findSuspensionPointLineNumber(it) }
|
||||
|
||||
val continuationLabels = suspensionPoints.withIndex().map {
|
||||
transformCallAndReturnContinuationLabel(it.index + 1, it.value, methodNode, suspendMarkerVarIndex)
|
||||
}
|
||||
|
||||
val defaultLabel = LabelNode()
|
||||
val tableSwitchLabel = LabelNode()
|
||||
methodNode.instructions.apply {
|
||||
val startLabel = LabelNode()
|
||||
val tableSwitchLabel = LabelNode()
|
||||
val firstStateLabel = LabelNode()
|
||||
val defaultLabel = LabelNode()
|
||||
|
||||
// tableswitch(this.label)
|
||||
insertBefore(
|
||||
@@ -151,13 +164,13 @@ class CoroutineTransformerMethodVisitor(
|
||||
0,
|
||||
suspensionPoints.size,
|
||||
defaultLabel,
|
||||
startLabel, *suspensionPointLabels.toTypedArray()
|
||||
firstStateLabel, *continuationLabels.toTypedArray()
|
||||
),
|
||||
startLabel
|
||||
firstStateLabel
|
||||
)
|
||||
)
|
||||
|
||||
insert(startLabel, withInstructionAdapter {
|
||||
insert(firstStateLabel, withInstructionAdapter {
|
||||
generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex)
|
||||
})
|
||||
insert(last, defaultLabel)
|
||||
@@ -171,31 +184,90 @@ class CoroutineTransformerMethodVisitor(
|
||||
dropSuspensionMarkers(methodNode, suspensionPoints)
|
||||
methodNode.removeEmptyCatchBlocks()
|
||||
|
||||
if (isForNamedFunction) {
|
||||
addContinuationToLvt(
|
||||
methodNode,
|
||||
startLabelNode.sure { "start label has not been initialized during prelude generation" },
|
||||
defaultLabel
|
||||
)
|
||||
}
|
||||
// The parameters (and 'this') shall live throughout the method, otherwise, d8 emits warning about invalid debug info
|
||||
val startLabel = LabelNode()
|
||||
val endLabel = LabelNode()
|
||||
methodNode.instructions.insertBefore(methodNode.instructions.first, startLabel)
|
||||
methodNode.instructions.insert(methodNode.instructions.last, endLabel)
|
||||
|
||||
fixLvtForParameters(methodNode, startLabel, endLabel)
|
||||
|
||||
if (languageVersionSettings.isReleaseCoroutines() && !isCrossinlineLambda) {
|
||||
val suspensionPointLabelNodes = listOf(tableSwitchLabel) + suspensionPointLabels.map {
|
||||
it.label.info.safeAs<LabelNode>()
|
||||
.sure { "suspensionPointLabel shall have valid info. Check state-machine generation." }
|
||||
writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findSuspensionPointLineNumber(suspensionPoint: SuspensionPoint) =
|
||||
suspensionPoint.suspensionCallBegin.findPreviousOrNull { it is LineNumberNode } as LineNumberNode?
|
||||
|
||||
private fun checkForSuspensionPointInsideMonitor(methodNode: MethodNode, suspensionPoints: List<SuspensionPoint>) {
|
||||
if (methodNode.instructions.asSequence().none { it.opcode == Opcodes.MONITORENTER }) return
|
||||
|
||||
val cfg = ControlFlowGraph.build(methodNode)
|
||||
val monitorDepthMap = hashMapOf<AbstractInsnNode, Int>()
|
||||
fun addMonitorDepthToSuccs(index: Int, depth: Int) {
|
||||
val insn = methodNode.instructions[index]
|
||||
monitorDepthMap[insn] = depth
|
||||
val newDepth = when (insn.opcode) {
|
||||
Opcodes.MONITORENTER -> depth + 1
|
||||
Opcodes.MONITOREXIT -> depth - 1
|
||||
else -> depth
|
||||
}
|
||||
writeDebugMetadata(methodNode, suspensionPointLabelNodes, spilledToVariableMapping)
|
||||
for (succIndex in cfg.getSuccessorsIndices(index)) {
|
||||
if (monitorDepthMap[methodNode.instructions[succIndex]] == null) {
|
||||
addMonitorDepthToSuccs(succIndex, newDepth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addMonitorDepthToSuccs(0, 0)
|
||||
|
||||
for (suspensionPoint in suspensionPoints) {
|
||||
if (monitorDepthMap[suspensionPoint.suspensionCallBegin]?.let { it > 0 } == true) {
|
||||
// TODO: Support crossinline suspend lambdas
|
||||
val stackTraceElement = StackTraceElement(
|
||||
containingClassInternalName,
|
||||
methodNode.name,
|
||||
sourceFile,
|
||||
findSuspensionPointLineNumber(suspensionPoint)?.line ?: -1
|
||||
)
|
||||
diagnostics.report(ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR.on(element, "$stackTraceElement"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fixLvtForParameters(methodNode: MethodNode, startLabel: LabelNode, endLabel: LabelNode) {
|
||||
// We need to skip continuation, since the inliner likes to remap variables there.
|
||||
// But this is not a problem, since we have separate $continuation LVT entry
|
||||
|
||||
val paramsNum =
|
||||
/* this */ (if (internalNameForDispatchReceiver != null) 1 else 0) +
|
||||
/* real params */ Type.getArgumentTypes(methodNode.desc).size -
|
||||
/* no continuation */ if (isForNamedFunction) 1 else 0
|
||||
|
||||
for (i in 0..paramsNum) {
|
||||
fixRangeOfLvtRecord(methodNode, i, startLabel, endLabel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fixRangeOfLvtRecord(methodNode: MethodNode, index: Int, startLabel: LabelNode, endLabel: LabelNode) {
|
||||
val vars = methodNode.localVariables.filter { it.index == index }
|
||||
assert(vars.size <= 1) {
|
||||
"Someone else occupies parameter's slot at $index"
|
||||
}
|
||||
vars.firstOrNull()?.let {
|
||||
it.start = startLabel
|
||||
it.end = endLabel
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeDebugMetadata(
|
||||
methodNode: MethodNode,
|
||||
suspensionPointLabels: List<LabelNode>,
|
||||
suspensionPointLineNumbers: List<LineNumberNode?>,
|
||||
spilledToLocalMapping: List<List<SpilledVariableDescriptor>>
|
||||
) {
|
||||
val lines = suspensionPointLabels.map { label ->
|
||||
label.safeAs<AbstractInsnNode>()?.findNextOrNull { it is LineNumberNode }.safeAs<LineNumberNode>()?.line ?: -1
|
||||
}
|
||||
val lines = suspensionPointLineNumbers.map { it?.line ?: -1 }
|
||||
val metadata = classBuilderForCoroutineState.newAnnotation(DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor, true)
|
||||
metadata.visit(COROUTINES_METADATA_SOURCE_FILE_JVM_NAME, sourceFile)
|
||||
metadata.visit(COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME, lines.toIntArray())
|
||||
@@ -220,7 +292,11 @@ class CoroutineTransformerMethodVisitor(
|
||||
metadata.visitEnd()
|
||||
}
|
||||
|
||||
private fun addContinuationToLvt(methodNode: MethodNode, startLabel: LabelNode, endLabel: LabelNode) {
|
||||
// Warning! This is _continuation_, not _completion_, it can be allocated inside the method, thus, it is incorrect to treat it
|
||||
// as a parameter
|
||||
private fun addContinuationToLvt(methodNode: MethodNode, startLabel: LabelNode) {
|
||||
val endLabel = LabelNode()
|
||||
methodNode.instructions.insert(methodNode.instructions.last, endLabel)
|
||||
methodNode.localVariables.add(
|
||||
LocalVariableNode(
|
||||
"\$continuation",
|
||||
@@ -288,7 +364,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun prepareMethodNodePreludeForNamedFunction(methodNode: MethodNode): LabelNode {
|
||||
private fun prepareMethodNodePreludeForNamedFunction(methodNode: MethodNode) {
|
||||
val objectTypeForState = Type.getObjectType(classBuilderForCoroutineState.thisName)
|
||||
val continuationArgumentIndex = getLastParameterIndex(methodNode.desc, methodNode.access)
|
||||
methodNode.instructions.asSequence().filterIsInstance<VarInsnNode>().forEach {
|
||||
@@ -297,8 +373,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
it.`var` = continuationIndex
|
||||
}
|
||||
|
||||
val startLabel = LabelNode()
|
||||
|
||||
methodNode.instructions.insert(withInstructionAdapter {
|
||||
val createStateInstance = Label()
|
||||
val afterCoroutineStateCreated = Label()
|
||||
@@ -318,7 +392,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
// `doResume` just before calling the suspend function (see kotlin.coroutines.experimental.jvm.internal.CoroutineImplForNamedFunction).
|
||||
// So, if it's set we're in continuation.
|
||||
|
||||
visitLabel(startLabel.label)
|
||||
visitVarInsn(Opcodes.ALOAD, continuationArgumentIndex)
|
||||
instanceOf(objectTypeForState)
|
||||
ifeq(createStateInstance)
|
||||
@@ -360,6 +433,8 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
visitLabel(afterCoroutineStateCreated)
|
||||
|
||||
addContinuationToLvt(methodNode, LabelNode(afterCoroutineStateCreated))
|
||||
|
||||
visitVarInsn(Opcodes.ALOAD, continuationIndex)
|
||||
getfield(classBuilderForCoroutineState.thisName, languageVersionSettings.dataFieldName(), AsmTypes.OBJECT_TYPE.descriptor)
|
||||
visitVarInsn(Opcodes.ASTORE, dataIndex)
|
||||
@@ -370,7 +445,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
visitVarInsn(Opcodes.ASTORE, exceptionIndex)
|
||||
}
|
||||
})
|
||||
return startLabel
|
||||
}
|
||||
|
||||
private fun removeUnreachableSuspensionPointsAndExitPoints(methodNode: MethodNode, suspensionPoints: MutableList<SuspensionPoint>) {
|
||||
@@ -870,17 +944,11 @@ private fun allSuspensionPointsAreTailCalls(
|
||||
}
|
||||
if (insideTryBlock) return@all false
|
||||
|
||||
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
|
||||
sourceFrames[returnIndex].top().sure {
|
||||
"There must be some value on stack to return"
|
||||
}.insns.all { sourceInsn ->
|
||||
sourceInsn?.let(instructions::indexOf) in beginIndex..endIndex
|
||||
}
|
||||
} ?: false
|
||||
safelyReachableReturns[endIndex + 1] != null
|
||||
}
|
||||
}
|
||||
|
||||
internal class IgnoringCopyOperationSourceInterpreter : SourceInterpreter() {
|
||||
internal class IgnoringCopyOperationSourceInterpreter : SourceInterpreter(OPTIMIZATION_ASM_API_VERSION) {
|
||||
override fun copyOperation(insn: AbstractInsnNode?, value: SourceValue?) = value
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ open class SuspendFunctionGenerationStrategy(
|
||||
return CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
|
||||
isForNamedFunction = true,
|
||||
lineNumber = CodegenUtil.getLineNumberForElement(declaration, false) ?: 0,
|
||||
element = declaration,
|
||||
diagnostics = state.diagnostics,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
||||
|
||||
@@ -56,7 +56,7 @@ const val DO_RESUME_METHOD_NAME = "doResume"
|
||||
const val INVOKE_SUSPEND_METHOD_NAME = "invokeSuspend"
|
||||
const val EXCEPTION_FIELD_NAME = "exception"
|
||||
|
||||
private val RELEASE_COROUTINES_VERSION_SETTINGS = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3)
|
||||
val RELEASE_COROUTINES_VERSION_SETTINGS = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3)
|
||||
|
||||
fun LanguageVersionSettings.isResumeImplMethodName(name: String) =
|
||||
if (isReleaseCoroutines())
|
||||
@@ -117,10 +117,10 @@ private val GET_CONTEXT_METHOD_NAME = "getContext"
|
||||
data class ResolvedCallWithRealDescriptor(val resolvedCall: ResolvedCall<*>, val fakeContinuationExpression: KtExpression)
|
||||
|
||||
@JvmField
|
||||
val INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION = object : FunctionDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
val INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION = object : CallableDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
|
||||
@JvmField
|
||||
val INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME = object : FunctionDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
val INITIAL_SUSPEND_DESCRIPTOR_FOR_DO_RESUME = object : CallableDescriptor.UserDataKey<FunctionDescriptor> {}
|
||||
|
||||
// Resolved calls to suspension function contain descriptors as they visible within coroutines:
|
||||
// E.g. `fun <V> await(f: CompletableFuture<V>): V` instead of `fun <V> await(f: CompletableFuture<V>, machine: Continuation<V>): Unit`
|
||||
|
||||
@@ -169,7 +169,7 @@ private fun checkUpdatedExpectedType(was: Type?, new: Type) {
|
||||
}
|
||||
}
|
||||
|
||||
private class MySourceInterpreter : SourceInterpreter() {
|
||||
private class MySourceInterpreter : SourceInterpreter(OPTIMIZATION_ASM_API_VERSION) {
|
||||
override fun copyOperation(insn: AbstractInsnNode, value: SourceValue) =
|
||||
when {
|
||||
insn.isStoreOperation() || insn.isLoadOperation() -> SourceValue(value.size, insn)
|
||||
|
||||
@@ -10,13 +10,12 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getKotlinTypeForComparison
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getKotlinTypeWithPossibleSmartCastToFP
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class TypeAndNullability(@JvmField val type: Type, @JvmField val isNullable: Boolean)
|
||||
@@ -35,60 +34,31 @@ fun calcProperTypeForIeee754ArithmeticIfNeeded(
|
||||
return TypeAndNullability(asmType, isNullable)
|
||||
}
|
||||
|
||||
private fun KotlinType.isFloatingPointOrNullable() =
|
||||
KotlinBuiltIns.isDoubleOrNullableDouble(this) || KotlinBuiltIns.isFloatOrNullableFloat(this)
|
||||
|
||||
private fun KtExpression.getKotlinTypeForComparison(bindingContext: BindingContext): KotlinType? =
|
||||
when {
|
||||
this is KtProperty -> bindingContext[BindingContext.VARIABLE, this]?.type
|
||||
else -> kotlinType(bindingContext)
|
||||
}
|
||||
|
||||
fun legacyCalcTypeForIeee754ArithmeticIfNeeded(
|
||||
expression: KtExpression?,
|
||||
bindingContext: BindingContext,
|
||||
descriptor: DeclarationDescriptor,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): TypeAndNullability? {
|
||||
val ktType = expression?.getKotlinTypeForComparison(bindingContext) ?: return null
|
||||
|
||||
if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) {
|
||||
return TypeAndNullability(
|
||||
Type.DOUBLE_TYPE,
|
||||
TypeUtils.isNullableType(ktType)
|
||||
)
|
||||
}
|
||||
|
||||
if (KotlinBuiltIns.isFloatOrNullableFloat(ktType)) {
|
||||
return TypeAndNullability(
|
||||
Type.FLOAT_TYPE,
|
||||
TypeUtils.isNullableType(ktType)
|
||||
)
|
||||
}
|
||||
|
||||
// NB. Using DataFlowValueFactoryImpl is a hack, but it is ok for 'legacy'
|
||||
val dataFlow = DataFlowValueFactoryImpl(languageVersionSettings).createDataFlowValue(
|
||||
expression,
|
||||
ktType,
|
||||
bindingContext,
|
||||
descriptor
|
||||
val ktType = expression.getKotlinTypeWithPossibleSmartCastToFP(
|
||||
// NB. Using DataFlowValueFactoryImpl is a hack, but it is ok for 'legacy'
|
||||
bindingContext, descriptor, languageVersionSettings, DataFlowValueFactoryImpl(languageVersionSettings)
|
||||
)
|
||||
val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow, languageVersionSettings)
|
||||
return stableTypes.firstNotNullResult {
|
||||
when {
|
||||
KotlinBuiltIns.isDoubleOrNullableDouble(it) -> TypeAndNullability(
|
||||
|
||||
if (ktType != null) {
|
||||
if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) {
|
||||
return TypeAndNullability(
|
||||
Type.DOUBLE_TYPE,
|
||||
TypeUtils.isNullableType(
|
||||
it
|
||||
)
|
||||
TypeUtils.isNullableType(ktType)
|
||||
)
|
||||
KotlinBuiltIns.isFloatOrNullableFloat(it) -> TypeAndNullability(
|
||||
}
|
||||
|
||||
if (KotlinBuiltIns.isFloatOrNullableFloat(ktType)) {
|
||||
return TypeAndNullability(
|
||||
Type.FLOAT_TYPE,
|
||||
TypeUtils.isNullableType(
|
||||
it
|
||||
)
|
||||
TypeUtils.isNullableType(ktType)
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -21,8 +21,10 @@ import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -131,10 +133,9 @@ class AnonymousObjectTransformer(
|
||||
constructor!!, allCapturedParamBuilder, constructorParamBuilder,transformationInfo, parentRemapper
|
||||
)
|
||||
|
||||
val crossinlineSuspendElement = capturedCrossinlineSuspendElement()
|
||||
val capturesCrossinlineSuspend = (!inliningContext.isInliningLambda || inliningContext.isContinuation) &&
|
||||
inliningContext.expressionMap.values.any { lambda ->
|
||||
lambda is PsiExpressionLambda && lambda.isCrossInline && lambda.invokeMethodDescriptor.isSuspend
|
||||
}
|
||||
crossinlineSuspendElement != null
|
||||
|
||||
val deferringMethods = ArrayList<DeferredMethodVisitor>()
|
||||
|
||||
@@ -158,11 +159,18 @@ class AnonymousObjectTransformer(
|
||||
capturesCrossinlineSuspend && !inliningContext.isContinuation && continuationClassName != null
|
||||
|
||||
val deferringVisitor =
|
||||
when {
|
||||
generateStateMachineForLambda -> newStateMachineForLambda(classBuilder, next)
|
||||
generateStateMachineForNamedFunction -> newStateMachineForNamedFunction(classBuilder, next, continuationClassName!!)
|
||||
else -> newMethod(classBuilder, next)
|
||||
}
|
||||
if (crossinlineSuspendElement != null) {
|
||||
when {
|
||||
generateStateMachineForLambda -> newStateMachineForLambda(classBuilder, next, crossinlineSuspendElement)
|
||||
generateStateMachineForNamedFunction -> newStateMachineForNamedFunction(
|
||||
classBuilder,
|
||||
next,
|
||||
continuationClassName!!,
|
||||
crossinlineSuspendElement
|
||||
)
|
||||
else -> newMethod(classBuilder, next)
|
||||
}
|
||||
} else newMethod(classBuilder, next)
|
||||
val funResult = inlineMethodAndUpdateGlobalResult(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false)
|
||||
|
||||
val returnType = Type.getReturnType(next.desc)
|
||||
@@ -227,6 +235,10 @@ class AnonymousObjectTransformer(
|
||||
return transformationResult
|
||||
}
|
||||
|
||||
private fun capturedCrossinlineSuspendElement(): KtExpression? = inliningContext.expressionMap.values.find { lambda ->
|
||||
lambda is PsiExpressionLambda && lambda.isCrossInline && lambda.invokeMethodDescriptor.isSuspend
|
||||
}?.cast<PsiExpressionLambda>()?.functionWithBodyOrCallableReference
|
||||
|
||||
private fun writeTransformedMetadata(header: KotlinClassHeader, classBuilder: ClassBuilder) {
|
||||
writeKotlinMetadata(classBuilder, state, header.kind, header.extraInt) action@ { av ->
|
||||
val (newProto, newStringTable) = transformMetadata(header) ?: run {
|
||||
@@ -435,7 +447,7 @@ class AnonymousObjectTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun newStateMachineForLambda(builder: ClassBuilder, original: MethodNode): DeferredMethodVisitor {
|
||||
private fun newStateMachineForLambda(builder: ClassBuilder, original: MethodNode, element: KtExpression): DeferredMethodVisitor {
|
||||
return DeferredMethodVisitor(
|
||||
MethodNode(
|
||||
original.access, original.name, original.desc, original.signature,
|
||||
@@ -448,7 +460,8 @@ class AnonymousObjectTransformer(
|
||||
ArrayUtil.toStringArray(original.exceptions)
|
||||
), original.access, original.name, original.desc, null, null,
|
||||
obtainClassBuilderForCoroutineState = { builder },
|
||||
lineNumber = 0, // <- TODO
|
||||
element = element,
|
||||
diagnostics = state.diagnostics,
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = builder.thisName,
|
||||
@@ -462,7 +475,8 @@ class AnonymousObjectTransformer(
|
||||
private fun newStateMachineForNamedFunction(
|
||||
builder: ClassBuilder,
|
||||
original: MethodNode,
|
||||
continuationClassName: String
|
||||
continuationClassName: String,
|
||||
element: KtExpression
|
||||
): DeferredMethodVisitor {
|
||||
assert(inliningContext is RegeneratedClassContext)
|
||||
return DeferredMethodVisitor(
|
||||
@@ -477,7 +491,8 @@ class AnonymousObjectTransformer(
|
||||
ArrayUtil.toStringArray(original.exceptions)
|
||||
), original.access, original.name, original.desc, null, null,
|
||||
obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! },
|
||||
lineNumber = 0, // <- TODO
|
||||
element = element,
|
||||
diagnostics = state.diagnostics,
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = builder.thisName,
|
||||
|
||||
@@ -255,25 +255,27 @@ class PsiExpressionLambda(
|
||||
arrayListOf<CapturedParamDesc>().apply {
|
||||
val captureThis = closure.capturedOuterClassDescriptor
|
||||
if (captureThis != null) {
|
||||
val type = typeMapper.mapType(captureThis)
|
||||
val kotlinType = captureThis.defaultType
|
||||
val type = typeMapper.mapType(kotlinType)
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_THIS_FIELD, null,
|
||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
||||
type
|
||||
type, kotlinType
|
||||
)
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
}
|
||||
|
||||
if (closure.capturedReceiverFromOuterContext != null) {
|
||||
val type = typeMapper.mapType(closure.capturedReceiverFromOuterContext!!).let {
|
||||
val capturedReceiver = closure.capturedReceiverFromOuterContext
|
||||
if (capturedReceiver != null) {
|
||||
val type = typeMapper.mapType(capturedReceiver).let {
|
||||
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
||||
}
|
||||
|
||||
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
fieldName, null,
|
||||
StackValue.field(type, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
||||
type
|
||||
StackValue.field(type, capturedReceiver, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
||||
type, capturedReceiver
|
||||
)
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.codegen.inline.FieldRemapper.Companion.foldName
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer
|
||||
import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.ControlFlowGraph
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
@@ -23,7 +24,7 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -640,26 +641,78 @@ class MethodInliner(
|
||||
private fun replaceContinuationAccessesWithFakeContinuationsIfNeeded(processingNode: MethodNode) {
|
||||
val lambdaInfo = inliningContext.lambdaInfo ?: return
|
||||
if (!lambdaInfo.invokeMethodDescriptor.isSuspend) return
|
||||
val sources = analyzeMethodNodeBeforeInline(processingNode)
|
||||
val cfg = ControlFlowGraph.build(processingNode)
|
||||
val aload0s = processingNode.instructions.asSequence().filter { it.opcode == Opcodes.ALOAD && it.safeAs<VarInsnNode>()?.`var` == 0 }
|
||||
// Expected pattern here:
|
||||
// ALOAD 0
|
||||
// ICONST_0
|
||||
// INVOKESTATIC InlineMarker.mark
|
||||
// INVOKE* suspendingFunction(..., Continuation;)Ljava/lang/Object;
|
||||
val continuationAsParameterAload0s =
|
||||
aload0s.filter { it.next?.next?.let(::isBeforeSuspendMarker) == true && isSuspendCall(it.next?.next?.next) }
|
||||
replaceContinuationsWithFakeOnes(continuationAsParameterAload0s, processingNode)
|
||||
|
||||
val visited = hashSetOf<AbstractInsnNode>()
|
||||
fun findMeaningfulSuccs(insn: AbstractInsnNode): Collection<AbstractInsnNode> {
|
||||
if (!visited.add(insn)) return emptySet()
|
||||
val res = hashSetOf<AbstractInsnNode>()
|
||||
for (succIndex in cfg.getSuccessorsIndices(insn)) {
|
||||
val succ = processingNode.instructions[succIndex]
|
||||
if (succ.isMeaningful) res.add(succ)
|
||||
else res.addAll(findMeaningfulSuccs(succ))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// After inlining suspendCoroutineUninterceptedOrReturn there will be suspension point, which is not a MethodInsnNode.
|
||||
// So, it is incorrect to expect MethodInsnNodes only
|
||||
val suspensionPoints = processingNode.instructions.asSequence()
|
||||
.filter { isBeforeSuspendMarker(it) }
|
||||
.flatMap { findMeaningfulSuccs(it).asSequence() }
|
||||
.filter { it is MethodInsnNode }
|
||||
|
||||
val toReplace = hashSetOf<AbstractInsnNode>()
|
||||
for (suspensionPoint in suspensionPoints) {
|
||||
assert(suspensionPoint is MethodInsnNode) {
|
||||
"suspensionPoint shall be MethodInsnNode, but instead $suspensionPoint"
|
||||
}
|
||||
suspensionPoint as MethodInsnNode
|
||||
assert(Type.getReturnType(suspensionPoint.desc) == OBJECT_TYPE) {
|
||||
"suspensionPoint shall return $OBJECT_TYPE, but returns ${Type.getReturnType(suspensionPoint.desc)}"
|
||||
}
|
||||
val frame = sources[processingNode.instructions.indexOf(suspensionPoint)] ?: continue
|
||||
val paramTypes = Type.getArgumentTypes(suspensionPoint.desc)
|
||||
if (suspensionPoint.name.endsWith(JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX)) {
|
||||
// Expected pattern here:
|
||||
// ALOAD 0
|
||||
// (ICONST or other integers creating instruction)
|
||||
// (ACONST_NULL or ALOAD)
|
||||
// ICONST_0
|
||||
// INVOKESTATIC InlineMarker.mark
|
||||
// INVOKE* suspendingFunction$default(..., Continuation;ILjava/lang/Object)Ljava/lang/Object;
|
||||
assert(paramTypes.size >= 3) {
|
||||
"${suspensionPoint.name}${suspensionPoint.desc} shall have 3+ parameters"
|
||||
}
|
||||
} else {
|
||||
// Expected pattern here:
|
||||
// ALOAD 0
|
||||
// ICONST_0
|
||||
// INVOKESTATIC InlineMarker.mark
|
||||
// INVOKE* suspendingFunction(..., Continuation;)Ljava/lang/Object;
|
||||
assert(paramTypes.isNotEmpty()) {
|
||||
"${suspensionPoint.name}${suspensionPoint.desc} shall have 1+ parameters"
|
||||
}
|
||||
}
|
||||
paramTypes.reversed().asSequence().withIndex()
|
||||
.filter { it.value == languageVersionSettings.continuationAsmType() || it.value == OBJECT_TYPE }
|
||||
.flatMap { frame.getStack(frame.stackSize - it.index - 1).insns.asSequence() }
|
||||
.filter { it in aload0s }.let { toReplace.addAll(it) }
|
||||
}
|
||||
|
||||
// Expected pattern here:
|
||||
// ALOAD 0
|
||||
// ASTORE N
|
||||
// This pattern may occur after multiple inlines
|
||||
val continuationToStoreAload0s = aload0s.filter { it.next?.opcode == Opcodes.ASTORE }
|
||||
replaceContinuationsWithFakeOnes(continuationToStoreAload0s, processingNode)
|
||||
// Note, that this is not a suspension point, thus we check it separately
|
||||
toReplace.addAll(aload0s.filter { it.next?.opcode == Opcodes.ASTORE })
|
||||
// Expected pattern here:
|
||||
// ALOAD 0
|
||||
// INVOKEINTERFACE kotlin/jvm/functions/FunctionN.invoke (...,Ljava/lang/Object;)Ljava/lang/Object;
|
||||
val continuationAsLambdaParameterAload0s = aload0s.filter { isLambdaCall(it.next) }
|
||||
replaceContinuationsWithFakeOnes(continuationAsLambdaParameterAload0s, processingNode)
|
||||
toReplace.addAll(aload0s.filter { isLambdaCall(it.next) })
|
||||
replaceContinuationsWithFakeOnes(toReplace, processingNode)
|
||||
}
|
||||
|
||||
private fun isLambdaCall(invoke: AbstractInsnNode?): Boolean {
|
||||
@@ -672,7 +725,7 @@ class MethodInliner(
|
||||
}
|
||||
|
||||
private fun replaceContinuationsWithFakeOnes(
|
||||
continuations: Sequence<AbstractInsnNode>,
|
||||
continuations: Collection<AbstractInsnNode>,
|
||||
node: MethodNode
|
||||
) {
|
||||
for (toReplace in continuations) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.org.objectweb.asm.ClassVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.commons.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.FieldRemapper;
|
||||
|
||||
public class RemappingClassBuilder extends DelegatingClassBuilder {
|
||||
private final ClassBuilder builder;
|
||||
@@ -66,9 +67,8 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
|
||||
@Nullable String signature,
|
||||
@Nullable Object value
|
||||
) {
|
||||
return new RemappingFieldAdapter(
|
||||
builder.newField(origin, access, name, remapper.mapDesc(desc), remapper.mapSignature(signature, true), value),
|
||||
remapper
|
||||
return new FieldRemapper(
|
||||
builder.newField(origin, access, name, remapper.mapDesc(desc), remapper.mapSignature(signature, true), value), remapper
|
||||
);
|
||||
}
|
||||
|
||||
@@ -82,8 +82,7 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
|
||||
@Nullable String signature,
|
||||
@Nullable String[] exceptions
|
||||
) {
|
||||
return new RemappingMethodAdapter(
|
||||
access, desc,
|
||||
return new MethodRemapper(
|
||||
builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), remapper.mapSignature(signature, false), exceptions),
|
||||
remapper
|
||||
);
|
||||
@@ -92,12 +91,12 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
|
||||
@Override
|
||||
@NotNull
|
||||
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
||||
return new RemappingAnnotationAdapter(builder.newAnnotation(remapper.mapDesc(desc), visible), remapper);
|
||||
return new AnnotationRemapper(builder.newAnnotation(remapper.mapDesc(desc), visible), remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ClassVisitor getVisitor() {
|
||||
return new RemappingClassAdapter(builder.getVisitor(), remapper);
|
||||
return new ClassRemapper(builder.getVisitor(), remapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
import gnu.trove.TIntIntHashMap
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.SourceInfo
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.END
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.FILE_SECTION
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.LINE_SECTION
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.STRATA_SECTION
|
||||
import java.util.*
|
||||
|
||||
const val KOTLIN_STRATA_NAME = "Kotlin"
|
||||
@@ -49,9 +53,9 @@ class SMAPBuilder(
|
||||
}
|
||||
|
||||
private fun generateDefaultStrata(realMappings: List<FileMapping>): String {
|
||||
val fileIds = "*F" + realMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
|
||||
val lineMappings = "*L" + realMappings.joinToString("") { it.toSMAPMapping() }
|
||||
return "*S $KOTLIN_STRATA_NAME\n$fileIds\n$lineMappings\n*E\n"
|
||||
val fileIds = FILE_SECTION + realMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
|
||||
val lineMappings = LINE_SECTION + realMappings.joinToString("") { it.toSMAPMapping() }
|
||||
return "$STRATA_SECTION $KOTLIN_STRATA_NAME\n$fileIds\n$lineMappings\n$END\n"
|
||||
}
|
||||
|
||||
private fun generateDebugStrata(realMappings: List<FileMapping>): String {
|
||||
@@ -69,9 +73,9 @@ class SMAPBuilder(
|
||||
if (combinedMapping.lineMappings.isEmpty()) return ""
|
||||
|
||||
val newMappings = listOf(combinedMapping)
|
||||
val fileIds = "*F" + newMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
|
||||
val lineMappings = "*L" + newMappings.joinToString("") { it.toSMAPMapping() }
|
||||
return "*S $KOTLIN_DEBUG_STRATA_NAME\n$fileIds\n$lineMappings\n*E\n"
|
||||
val fileIds = FILE_SECTION + newMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
|
||||
val lineMappings = LINE_SECTION + newMappings.joinToString("") { it.toSMAPMapping() }
|
||||
return "$STRATA_SECTION $KOTLIN_DEBUG_STRATA_NAME\n$fileIds\n$lineMappings\n$END\n"
|
||||
}
|
||||
|
||||
private fun RangeMapping.toSMAP(fileId: Int): String {
|
||||
@@ -271,6 +275,7 @@ class SMAP(val fileMappings: List<FileMapping>) {
|
||||
companion object {
|
||||
const val FILE_SECTION = "*F"
|
||||
const val LINE_SECTION = "*L"
|
||||
const val STRATA_SECTION = "*S"
|
||||
const val END = "*E"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,25 +42,24 @@ object SMAPParser {
|
||||
fun parse(mappingInfo: String): SMAP {
|
||||
val fileMappings = linkedMapOf<Int, FileMapping>()
|
||||
|
||||
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length
|
||||
val lineSectionAnchor = mappingInfo.indexOf(SMAP.LINE_SECTION)
|
||||
val files = mappingInfo.substring(fileSectionStart, lineSectionAnchor)
|
||||
val iterator = mappingInfo.lineSequence().dropWhile { it.trim() != SMAP.FILE_SECTION }.drop(1).iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val fileDeclaration = iterator.next().trim()
|
||||
if (fileDeclaration == SMAP.LINE_SECTION) break
|
||||
|
||||
val fileEntries = files.trim().split('+')
|
||||
if (!fileDeclaration.startsWith('+')) {
|
||||
throw AssertionError("File declaration should be in extended form, but: $fileDeclaration in $mappingInfo")
|
||||
}
|
||||
|
||||
for (fileDeclaration in fileEntries) {
|
||||
if (fileDeclaration == "") continue
|
||||
val fileInternalName = fileDeclaration.trim()
|
||||
|
||||
val indexEnd = fileInternalName.indexOf(' ')
|
||||
val fileIndex = fileInternalName.substring(0, indexEnd).toInt()
|
||||
val newLine = fileInternalName.indexOf('\n')
|
||||
val fileName = fileInternalName.substring(indexEnd + 1, newLine)
|
||||
fileMappings[fileIndex] = FileMapping(fileName, fileInternalName.substring(newLine + 1).trim())
|
||||
val indexAndFileInternalName = fileDeclaration.substringAfter("+ ").trim()
|
||||
val fileIndex = indexAndFileInternalName.substringBefore(' ').toInt()
|
||||
val fileName = indexAndFileInternalName.substringAfter(' ')
|
||||
val path = iterator.next().trim()
|
||||
fileMappings[fileIndex] = FileMapping(fileName, path)
|
||||
}
|
||||
|
||||
val lines = mappingInfo.substring(lineSectionAnchor + SMAP.LINE_SECTION.length, mappingInfo.indexOf(SMAP.END)).trim().split('\n')
|
||||
for (lineMapping in lines) {
|
||||
for (lineMapping in iterator) {
|
||||
if (lineMapping.trim() == SMAP.END) break
|
||||
/*only simple mapping now*/
|
||||
val targetSplit = lineMapping.indexOf(':')
|
||||
val originalPart = lineMapping.substring(0, targetSplit)
|
||||
|
||||
@@ -172,17 +172,20 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
val strategy = when (expression) {
|
||||
is KtCallableReferenceExpression -> {
|
||||
val resolvedCall = expression.callableReference.getResolvedCallWithAssert(state.bindingContext)
|
||||
val receiverType = JvmCodegenUtil.getBoundCallableReferenceReceiver(resolvedCall)?.type?.let(state.typeMapper::mapType)
|
||||
val receiverKotlinType = JvmCodegenUtil.getBoundCallableReferenceReceiver(resolvedCall)?.type
|
||||
val receiverType = receiverKotlinType?.let(state.typeMapper::mapType)
|
||||
val boundReceiverJvmKotlinType = receiverType?.let { JvmKotlinType(receiverType, receiverKotlinType) }
|
||||
|
||||
if (isLambda && lambdaInfo!!.isPropertyReference) {
|
||||
val asmType = state.typeMapper.mapClass(lambdaInfo.classDescriptor)
|
||||
val info = lambdaInfo.propertyReferenceInfo
|
||||
PropertyReferenceCodegen.PropertyReferenceGenerationStrategy(
|
||||
true, info!!.getFunction, info.target, asmType, receiverType,
|
||||
true, info!!.getFunction, info.target, asmType,
|
||||
boundReceiverJvmKotlinType,
|
||||
lambdaInfo.functionWithBodyOrCallableReference, state, true
|
||||
)
|
||||
} else {
|
||||
FunctionReferenceGenerationStrategy(state, descriptor, resolvedCall, receiverType, null, true)
|
||||
FunctionReferenceGenerationStrategy(state, descriptor, resolvedCall, boundReceiverJvmKotlinType, null, true)
|
||||
}
|
||||
}
|
||||
is KtFunctionLiteral -> ClosureGenerationStrategy(state, expression as KtDeclarationWithBody)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.OPTIMIZATION_ASM_API_VERSION
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.debugText
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isLoadOperation
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
@@ -119,7 +120,7 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
throw AssertionError("Incorrect bytecode at ${methodNode.instructions.indexOf(insn)}: ${insn.debugText} $frame")
|
||||
}
|
||||
|
||||
private inner class HazardsTrackingInterpreter : SourceInterpreter() {
|
||||
private inner class HazardsTrackingInterpreter : SourceInterpreter(OPTIMIZATION_ASM_API_VERSION) {
|
||||
override fun naryOperation(insn: AbstractInsnNode, values: MutableList<out SourceValue>): SourceValue {
|
||||
for (value in values) {
|
||||
value.insns.markAsDontTouch()
|
||||
@@ -313,4 +314,4 @@ fun AbstractInsnNode.isUnitInstance() =
|
||||
this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"
|
||||
|
||||
fun AbstractInsnNode.isPrimitiveTypeConversion() =
|
||||
opcode in Opcodes.I2L..Opcodes.I2S
|
||||
opcode in Opcodes.I2L..Opcodes.I2S
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
const val OPTIMIZATION_ASM_API_VERSION = Opcodes.ASM5
|
||||
|
||||
val AbstractInsnNode.isMeaningful: Boolean
|
||||
get() =
|
||||
when (this.type) {
|
||||
@@ -221,4 +223,4 @@ internal inline fun <reified T : AbstractInsnNode> AbstractInsnNode.takeInsnIf(o
|
||||
|
||||
fun InsnList.removeAll(nodes: Collection<AbstractInsnNode>) {
|
||||
for (node in nodes) remove(node)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ 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.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
@@ -31,6 +32,8 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
@@ -138,7 +141,8 @@ class GenerationState private constructor(
|
||||
val deserializationConfiguration: DeserializationConfiguration =
|
||||
CompilerDeserializationConfiguration(configuration.languageVersionSettings)
|
||||
|
||||
val deprecationProvider = DeprecationResolver(LockBasedStorageManager.NO_LOCKS, configuration.languageVersionSettings, CoroutineCompatibilitySupport.ENABLED)
|
||||
val deprecationProvider =
|
||||
DeprecationResolver(LockBasedStorageManager.NO_LOCKS, configuration.languageVersionSettings, CoroutineCompatibilitySupport.ENABLED)
|
||||
|
||||
init {
|
||||
val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
|
||||
@@ -180,6 +184,7 @@ class GenerationState private constructor(
|
||||
filter = if (wantsDiagnostics) BindingTraceFilter.ACCEPT_ALL else BindingTraceFilter.NO_DIAGNOSTICS
|
||||
)
|
||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||
val mainFunctionDetector = MainFunctionDetector(bindingContext, languageVersionSettings)
|
||||
private val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false
|
||||
val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
|
||||
this.bindingContext,
|
||||
@@ -238,7 +243,7 @@ class GenerationState private constructor(
|
||||
JVMConstructorCallNormalizationMode.DISABLE
|
||||
}
|
||||
|
||||
val jvmDefaultMode = languageVersionSettings.getFlag(AnalysisFlag.jvmDefaultMode)
|
||||
val jvmDefaultMode = languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)
|
||||
|
||||
val disableOptimization = configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false)
|
||||
|
||||
@@ -247,7 +252,12 @@ class GenerationState private constructor(
|
||||
init {
|
||||
this.interceptedBuilderFactory = builderFactory
|
||||
.wrapWith(
|
||||
{ OptimizationClassBuilderFactory(it, this) },
|
||||
{
|
||||
if (classBuilderMode.generateBodies)
|
||||
OptimizationClassBuilderFactory(it, this)
|
||||
else
|
||||
it
|
||||
},
|
||||
{
|
||||
BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
it, this.bindingContext, diagnostics, this.moduleName,
|
||||
|
||||
@@ -509,31 +509,35 @@ public class KotlinTypeMapper {
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure this method is called only from back-end
|
||||
// It uses staticTypeMappingConfiguration that throws exception on error types
|
||||
@NotNull
|
||||
public static Type mapInlineClassTypeAsDeclaration(@NotNull KotlinType kotlinType) {
|
||||
return mapInlineClassType(kotlinType, TypeMappingMode.CLASS_DECLARATION);
|
||||
return mapInlineClassType(kotlinType, TypeMappingMode.CLASS_DECLARATION, staticTypeMappingConfiguration);
|
||||
}
|
||||
|
||||
// Make sure this method is called only from back-end
|
||||
// It uses staticTypeMappingConfiguration that throws exception on error types
|
||||
@NotNull
|
||||
public static Type mapUnderlyingTypeOfInlineClassType(@NotNull KotlinType kotlinType) {
|
||||
KotlinType underlyingType = InlineClassesUtilsKt.unsubstitutedUnderlyingType(kotlinType);
|
||||
if (underlyingType == null) {
|
||||
throw new IllegalStateException("There should be underlying type for inline class type: " + kotlinType);
|
||||
}
|
||||
return mapInlineClassType(underlyingType, TypeMappingMode.DEFAULT);
|
||||
return mapInlineClassType(underlyingType, TypeMappingMode.DEFAULT, staticTypeMappingConfiguration);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type mapInlineClassType(@NotNull KotlinType kotlinType) {
|
||||
return mapInlineClassType(kotlinType, TypeMappingMode.DEFAULT);
|
||||
private Type mapInlineClassType(@NotNull KotlinType kotlinType) {
|
||||
return mapInlineClassType(kotlinType, TypeMappingMode.DEFAULT, typeMappingConfiguration);
|
||||
}
|
||||
|
||||
private static Type mapInlineClassType(
|
||||
@NotNull KotlinType kotlinType,
|
||||
@NotNull TypeMappingMode mode
|
||||
@NotNull TypeMappingMode mode,
|
||||
@NotNull TypeMappingConfiguration<Type> configuration
|
||||
) {
|
||||
return TypeSignatureMappingKt.mapType(
|
||||
kotlinType, AsmTypeFactory.INSTANCE, mode, staticTypeMappingConfiguration, null,
|
||||
kotlinType, AsmTypeFactory.INSTANCE, mode, configuration, null,
|
||||
(ktType, asmType, typeMappingMode) -> Unit.INSTANCE,
|
||||
false
|
||||
);
|
||||
@@ -858,6 +862,9 @@ public class KotlinTypeMapper {
|
||||
}
|
||||
else {
|
||||
boolean toInlinedErasedClass = currentOwner.isInline() && !isAccessor(functionDescriptor);
|
||||
if (toInlinedErasedClass) {
|
||||
functionDescriptor = descriptor;
|
||||
}
|
||||
|
||||
boolean isStaticInvocation = (isStaticDeclaration(functionDescriptor) &&
|
||||
!(functionDescriptor instanceof ImportedFromObjectCallableDescriptor)) ||
|
||||
@@ -1040,6 +1047,9 @@ public class KotlinTypeMapper {
|
||||
else if (isInterface(containingDeclaration)) {
|
||||
return OwnerKind.DEFAULT_IMPLS;
|
||||
}
|
||||
else if (InlineClassesUtilsKt.isInlineClass(containingDeclaration)) {
|
||||
return OwnerKind.ERASED_INLINE_CLASS;
|
||||
}
|
||||
return OwnerKind.IMPLEMENTATION;
|
||||
}
|
||||
|
||||
@@ -1361,8 +1371,12 @@ public class KotlinTypeMapper {
|
||||
) {
|
||||
String descriptor = method.getDescriptor();
|
||||
int maskArgumentsCount = (callableDescriptor.getValueParameters().size() + Integer.SIZE - 1) / Integer.SIZE;
|
||||
String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
|
||||
additionalArgs += (isConstructor(method) ? DEFAULT_CONSTRUCTOR_MARKER : OBJECT_TYPE).getDescriptor();
|
||||
Type defaultConstructorMarkerType =
|
||||
isConstructor(method) || isInlineClassConstructor(callableDescriptor)
|
||||
? DEFAULT_CONSTRUCTOR_MARKER
|
||||
: OBJECT_TYPE;
|
||||
String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount)
|
||||
+ defaultConstructorMarkerType.getDescriptor();
|
||||
String result = descriptor.replace(")", additionalArgs + ")");
|
||||
if (dispatchReceiverDescriptor != null && !isConstructor(method)) {
|
||||
return result.replace("(", "(" + dispatchReceiverDescriptor);
|
||||
@@ -1378,6 +1392,11 @@ public class KotlinTypeMapper {
|
||||
return "<init>".equals(method.getName());
|
||||
}
|
||||
|
||||
private static boolean isInlineClassConstructor(@NotNull CallableDescriptor callableDescriptor) {
|
||||
return callableDescriptor instanceof ClassConstructorDescriptor
|
||||
&& InlineClassesUtilsKt.isInlineClass(callableDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind) {
|
||||
Method jvmSignature = mapAsmMethod(functionDescriptor, kind);
|
||||
@@ -1400,7 +1419,7 @@ public class KotlinTypeMapper {
|
||||
* In that case the generated method's return type should be boxed: otherwise it's not possible to use
|
||||
* this class from Java since javac issues errors when loading the class (incompatible return types)
|
||||
*/
|
||||
private static boolean forceBoxedReturnType(@NotNull FunctionDescriptor descriptor) {
|
||||
private boolean forceBoxedReturnType(@NotNull FunctionDescriptor descriptor) {
|
||||
if (isBoxMethodForInlineClass(descriptor)) return true;
|
||||
|
||||
//noinspection ConstantConditions
|
||||
@@ -1414,7 +1433,7 @@ public class KotlinTypeMapper {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isJvmPrimitive(@NotNull KotlinType kotlinType) {
|
||||
private boolean isJvmPrimitive(@NotNull KotlinType kotlinType) {
|
||||
if (KotlinBuiltIns.isPrimitiveType(kotlinType)) return true;
|
||||
|
||||
if (InlineClassesUtilsKt.isInlineClassType(kotlinType) && !KotlinTypeKt.isError(kotlinType)) {
|
||||
|
||||
@@ -91,6 +91,7 @@ abstract class SwitchCodegen(
|
||||
v.mark(endLabel)
|
||||
|
||||
subjectVariableDescriptor?.let {
|
||||
codegen.frameMap.leave(it)
|
||||
v.visitLocalVariable(
|
||||
it.name.asString(), subjectType.descriptor, null,
|
||||
beginLabel, endLabel, subjectLocal
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion
|
||||
@@ -38,7 +38,7 @@ fun writeKotlinMetadata(
|
||||
if (state.languageVersionSettings.isPreRelease()) {
|
||||
flags = flags or JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG
|
||||
}
|
||||
if (state.languageVersionSettings.getFlag(AnalysisFlag.strictMetadataVersionSemantics)) {
|
||||
if (state.languageVersionSettings.getFlag(JvmAnalysisFlags.strictMetadataVersionSemantics)) {
|
||||
flags = flags or JvmAnnotationNames.METADATA_STRICT_VERSION_SEMANTICS_FLAG
|
||||
}
|
||||
if (flags != 0) {
|
||||
|
||||
@@ -67,11 +67,11 @@ dependencies {
|
||||
testRuntime(intellijDep()) // Should come before compiler, because of "progarded" stuff needed for tests
|
||||
|
||||
depDistProjects.forEach {
|
||||
testCompile(projectDist(it))
|
||||
testCompile(project(it))
|
||||
}
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompileOnly(projectDist(":kotlin-test:kotlin-test-jvm"))
|
||||
testCompileOnly(projectDist(":kotlin-test:kotlin-test-junit"))
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-jvm"))
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-junit"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(projectTests(":generators:test-generator"))
|
||||
testCompile(project(":compiler:ir.ir2cfg"))
|
||||
@@ -84,10 +84,10 @@ dependencies {
|
||||
testCompileOnly(project(it))
|
||||
}
|
||||
testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi", "idea", "idea_rt", "util", "asm-all") }
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi", "idea", "idea_rt", "util", "asm-all", rootProject = rootProject) }
|
||||
|
||||
testRuntime(projectDist(":kotlin-reflect"))
|
||||
testRuntime(projectDist(":kotlin-daemon-client"))
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
testRuntime(project(":kotlin-daemon-client"))
|
||||
testRuntime(androidDxJar())
|
||||
testRuntime(files(toolsJar()))
|
||||
|
||||
@@ -117,6 +117,7 @@ projectTest {
|
||||
systemProperty("kotlin.ant.classpath", antLauncherJar.asPath)
|
||||
systemProperty("kotlin.ant.launcher.class", "org.apache.tools.ant.Main")
|
||||
}
|
||||
exclude("org/jetbrains/kotlin/codegen/jdk/JvmTarget*")
|
||||
}
|
||||
|
||||
fun Project.codegenTest(target: Int, jvm: Int,
|
||||
@@ -125,15 +126,8 @@ fun Project.codegenTest(target: Int, jvm: Int,
|
||||
dependsOn(*testDistProjects.map { "$it:dist" }.toTypedArray())
|
||||
workingDir = rootDir
|
||||
|
||||
filter.includeTestsMatching("org.jetbrains.kotlin.codegen.BlackBoxCodegenTestGenerated*")
|
||||
filter.includeTestsMatching("org.jetbrains.kotlin.codegen.BlackBoxInlineCodegenTestGenerated*")
|
||||
filter.includeTestsMatching("org.jetbrains.kotlin.codegen.CompileKotlinAgainstInlineKotlinTestGenerated*")
|
||||
filter.includeTestsMatching("org.jetbrains.kotlin.codegen.CompileKotlinAgainstKotlinTestGenerated*")
|
||||
filter.includeTestsMatching("org.jetbrains.kotlin.codegen.BlackBoxAgainstJavaCodegenTestGenerated*")
|
||||
filter.includeTestsMatching("org.jetbrains.kotlin.codegen.jdk.JvmTarget${target}OnJvm${jvm}")
|
||||
|
||||
if (jdk == "JDK_9") {
|
||||
jvmArgs = listOf("--add-opens", "java.desktop/javax.swing=ALL-UNNAMED", "--add-opens", "java.base/java.io=ALL-UNNAMED")
|
||||
}
|
||||
body()
|
||||
doFirst {
|
||||
val jdkPath = project.findProperty(jdk) ?: error("$jdk is not optional to run this test")
|
||||
@@ -200,6 +194,11 @@ codegenTest(target = 10, jvm = 10) {
|
||||
systemProperty("kotlin.test.substitute.bytecode.1.8.to.10", "true")
|
||||
}
|
||||
|
||||
codegenTest(target = 8, jvm = 11) {
|
||||
systemProperty("kotlin.test.default.jvm.target", "1.8")
|
||||
jvmArgs!!.add( "-XX:-FailOverToOldVerifier")
|
||||
}
|
||||
|
||||
val generateTests by generator("org.jetbrains.kotlin.generators.tests.GenerateCompilerTestsKt")
|
||||
|
||||
testsJar()
|
||||
|
||||
@@ -198,13 +198,13 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
|
||||
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
return HashMap<AnalysisFlag<*>, Any>().apply {
|
||||
put(AnalysisFlag.skipMetadataVersionCheck, skipMetadataVersionCheck)
|
||||
put(AnalysisFlag.multiPlatformDoNotCheckActual, noCheckActual)
|
||||
put(AnalysisFlag.allowKotlinPackage, allowKotlinPackage)
|
||||
put(AnalysisFlag.experimental, experimental?.toList().orEmpty())
|
||||
put(AnalysisFlag.useExperimental, useExperimental?.toList().orEmpty())
|
||||
put(AnalysisFlag.explicitApiVersion, apiVersion != null)
|
||||
put(AnalysisFlag.allowResultReturnType, allowResultReturnType)
|
||||
put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck)
|
||||
put(AnalysisFlags.multiPlatformDoNotCheckActual, noCheckActual)
|
||||
put(AnalysisFlags.allowKotlinPackage, allowKotlinPackage)
|
||||
put(AnalysisFlags.experimental, experimental?.toList().orEmpty())
|
||||
put(AnalysisFlags.useExperimental, useExperimental?.toList().orEmpty())
|
||||
put(AnalysisFlags.explicitApiVersion, apiVersion != null)
|
||||
put(AnalysisFlags.allowResultReturnType, allowResultReturnType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import java.io.Serializable
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
abstract class Freezable {
|
||||
protected open inner class FreezableVar<T>(private var value: T) : ReadWriteProperty<Any, T> {
|
||||
protected open inner class FreezableVar<T>(private var value: T) : ReadWriteProperty<Any, T>, Serializable {
|
||||
override fun getValue(thisRef: Any, property: KProperty<*>) = value
|
||||
|
||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
|
||||
|
||||
@@ -110,7 +110,9 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(
|
||||
value = "-Xnormalize-constructor-calls",
|
||||
valueDescription = "{disable|enable}",
|
||||
description = "Normalize constructor calls (disable: don't normalize; enable: normalize), default is disable"
|
||||
description = "Normalize constructor calls (disable: don't normalize; enable: normalize),\n" +
|
||||
"default is 'disable' in language version 1.2 and below,\n" +
|
||||
"'enable' since language version 1.3"
|
||||
)
|
||||
var constructorCallNormalizationMode: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@@ -259,13 +261,13 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
|
||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
val result = super.configureAnalysisFlags(collector)
|
||||
result.put(AnalysisFlag.strictMetadataVersionSemantics, strictMetadataVersionSemantics)
|
||||
result[AnalysisFlag.jsr305] = Jsr305Parser(collector).parse(
|
||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||
result[JvmAnalysisFlags.jsr305] = Jsr305Parser(collector).parse(
|
||||
jsr305,
|
||||
supportCompatqualCheckerFrameworkAnnotations
|
||||
)
|
||||
result[AnalysisFlag.ignoreDataFlowInAssert] = JVMAssertionsMode.fromString(assertionsMode) != JVMAssertionsMode.LEGACY
|
||||
JvmDefaultMode.fromStringOrNull(jvmDefault)?.let { result[AnalysisFlag.jvmDefaultMode] = it }
|
||||
result[AnalysisFlags.ignoreDataFlowInAssert] = JVMAssertionsMode.fromString(assertionsMode) != JVMAssertionsMode.LEGACY
|
||||
JvmDefaultMode.fromStringOrNull(jvmDefault)?.let { result[JvmAnalysisFlags.jvmDefaultMode] = it }
|
||||
?: collector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"Unknown @JvmDefault mode: $jvmDefault, " +
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user