mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-13 08:31:28 +00:00
Compare commits
889 Commits
push/pdn_b
...
java6-Xint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48a7a55c6 | ||
|
|
30639af5a3 | ||
|
|
3add3f091d | ||
|
|
4583e31991 | ||
|
|
f49fe26632 | ||
|
|
73ec5d27a6 | ||
|
|
ac0dc94800 | ||
|
|
789799ac17 | ||
|
|
1f837134bb | ||
|
|
e6e3c9b236 | ||
|
|
5f65b46dfc | ||
|
|
a36135baf1 | ||
|
|
974779e91b | ||
|
|
84334b087c | ||
|
|
62f7e8f71f | ||
|
|
96bd2c54f0 | ||
|
|
931a637bdd | ||
|
|
2165cc8f0d | ||
|
|
e06a60bda5 | ||
|
|
61d5595790 | ||
|
|
dfea915f92 | ||
|
|
81ce1da352 | ||
|
|
bcf47ddc94 | ||
|
|
e790fa8ac9 | ||
|
|
8b3769b88e | ||
|
|
a3ad03d1ad | ||
|
|
b43e5a5e7d | ||
|
|
6a5cf00d7a | ||
|
|
b61277df97 | ||
|
|
229085f3d1 | ||
|
|
f846dd8ea2 | ||
|
|
b1ab597616 | ||
|
|
3293a888ca | ||
|
|
48ef739525 | ||
|
|
825b77cc82 | ||
|
|
b72aa76415 | ||
|
|
a8186d19d6 | ||
|
|
9091ca7b51 | ||
|
|
be097244d4 | ||
|
|
b0d721c9d0 | ||
|
|
290d424111 | ||
|
|
ee45aa6b08 | ||
|
|
886ce055f5 | ||
|
|
5c2753b5d1 | ||
|
|
84c10079e4 | ||
|
|
1ff6dc1275 | ||
|
|
ecbae02f17 | ||
|
|
c6a2d85c87 | ||
|
|
6121d156a1 | ||
|
|
d934c97bf5 | ||
|
|
0b10f255d7 | ||
|
|
c5e6215d27 | ||
|
|
4c943e7cd1 | ||
|
|
8e1c420c9f | ||
|
|
de5dcfcbd8 | ||
|
|
94a94a557d | ||
|
|
89f8c5a651 | ||
|
|
78e20c1098 | ||
|
|
e927764aaf | ||
|
|
15b6a3c88c | ||
|
|
3e892d3184 | ||
|
|
65972fa64c | ||
|
|
1ba6845b59 | ||
|
|
e7275a7cb0 | ||
|
|
e0cc6d44a7 | ||
|
|
67d48d0150 | ||
|
|
96f0b53761 | ||
|
|
af35892007 | ||
|
|
639b7537da | ||
|
|
f5a53c82c5 | ||
|
|
fefc6f9b53 | ||
|
|
d3b1ee42be | ||
|
|
cc571a876a | ||
|
|
242d79ded6 | ||
|
|
b9018e8888 | ||
|
|
5dcaaf47cb | ||
|
|
91e47f1fd7 | ||
|
|
15e978dbd3 | ||
|
|
1dfcec3a93 | ||
|
|
aaffd73feb | ||
|
|
54b9f39b3a | ||
|
|
f4788b479c | ||
|
|
76c15e4444 | ||
|
|
bd7fb56a24 | ||
|
|
4a767c597e | ||
|
|
e942052eb6 | ||
|
|
758eb8f851 | ||
|
|
be22078bd1 | ||
|
|
d8c68aacdd | ||
|
|
fd5169186e | ||
|
|
31ed1ad5d9 | ||
|
|
84bd580f92 | ||
|
|
472ab09511 | ||
|
|
ac222fdb41 | ||
|
|
c0ad1c9b18 | ||
|
|
26cbb020db | ||
|
|
3ff22b67f7 | ||
|
|
d5be258291 | ||
|
|
9fd1cbd2e7 | ||
|
|
d486f7e188 | ||
|
|
0c427555cf | ||
|
|
0f317b01b4 | ||
|
|
0b37b2be6a | ||
|
|
ecde5414dc | ||
|
|
ee927a15a9 | ||
|
|
afbda75581 | ||
|
|
6356b9d501 | ||
|
|
5a11450d77 | ||
|
|
703a353d2e | ||
|
|
c5faf532f5 | ||
|
|
90066d7e50 | ||
|
|
7da47dcde8 | ||
|
|
ac7b459f2a | ||
|
|
5d0461c722 | ||
|
|
26b8e86fe1 | ||
|
|
af12b2fdf0 | ||
|
|
6a7770573c | ||
|
|
8a856e440e | ||
|
|
720edfa6aa | ||
|
|
ebf6ce133b | ||
|
|
3a22761d02 | ||
|
|
b6f35ac44d | ||
|
|
3387615d4a | ||
|
|
cdb04f9cd7 | ||
|
|
af1f57007a | ||
|
|
0b1884c994 | ||
|
|
166f0a597b | ||
|
|
b5f71bacaf | ||
|
|
9d1a6ebb18 | ||
|
|
d12a24418e | ||
|
|
a778cc673e | ||
|
|
157046153f | ||
|
|
01c14a709a | ||
|
|
1abf3a39d4 | ||
|
|
2d015da1ea | ||
|
|
961ee92c15 | ||
|
|
e0c7cda1cf | ||
|
|
f2a067eda0 | ||
|
|
3709616baa | ||
|
|
34878d17eb | ||
|
|
2f60ce21a0 | ||
|
|
535934dc28 | ||
|
|
5f4be07225 | ||
|
|
c2389a94fa | ||
|
|
b541721a79 | ||
|
|
bed42e9ab2 | ||
|
|
14eca72913 | ||
|
|
0749443f7e | ||
|
|
54994a289f | ||
|
|
8481f4a9d2 | ||
|
|
3e2b8a8898 | ||
|
|
b3bb033fe4 | ||
|
|
b63770bc7b | ||
|
|
89e52cb780 | ||
|
|
8eca31e867 | ||
|
|
d37ceb47be | ||
|
|
16dbafced1 | ||
|
|
f431b4b171 | ||
|
|
29584edcdd | ||
|
|
426ac1281d | ||
|
|
2129a762a5 | ||
|
|
a006f35df3 | ||
|
|
61475c48e2 | ||
|
|
3bd6bf1432 | ||
|
|
e31173ca73 | ||
|
|
33ddeffcfd | ||
|
|
117fad2018 | ||
|
|
d023966054 | ||
|
|
14ed660f4f | ||
|
|
5d9915e133 | ||
|
|
e8bd8a938f | ||
|
|
c62a965180 | ||
|
|
b18d4af37b | ||
|
|
2c18406632 | ||
|
|
23605e08be | ||
|
|
af99ad0736 | ||
|
|
71c5c9f6c5 | ||
|
|
b5994fa3a9 | ||
|
|
ae079d9bdd | ||
|
|
64b45e6d1b | ||
|
|
dce8bd4e62 | ||
|
|
7f2eaab02b | ||
|
|
f9eba6e842 | ||
|
|
d530344eda | ||
|
|
5effbce363 | ||
|
|
8b93727f64 | ||
|
|
0395294933 | ||
|
|
f16f9a13fd | ||
|
|
240f86b109 | ||
|
|
741fdee59e | ||
|
|
15a4649675 | ||
|
|
3c3b5aa4ac | ||
|
|
a54a807dc9 | ||
|
|
dac9d7b17a | ||
|
|
ddbdfafa79 | ||
|
|
2ecba6ac39 | ||
|
|
d4586cefb4 | ||
|
|
858e3584a9 | ||
|
|
4f64431f10 | ||
|
|
1b7425f428 | ||
|
|
924678a00d | ||
|
|
26002a040f | ||
|
|
fe1d540c95 | ||
|
|
accd48de8c | ||
|
|
cf531dbbe6 | ||
|
|
ef53f0e0b3 | ||
|
|
6de97e17fe | ||
|
|
7f591bcfd4 | ||
|
|
2320eb8b44 | ||
|
|
0be5602363 | ||
|
|
9ab764e9fd | ||
|
|
1db09d78b3 | ||
|
|
23faacd21b | ||
|
|
0e7d690923 | ||
|
|
bead0e3412 | ||
|
|
261b42f5c5 | ||
|
|
ba00709e4d | ||
|
|
6ca7b39f6a | ||
|
|
ceec451f3f | ||
|
|
ab6f577964 | ||
|
|
c0977dd638 | ||
|
|
478a512b24 | ||
|
|
669985f853 | ||
|
|
0be542fd33 | ||
|
|
a1ae108ce5 | ||
|
|
09e3629d5d | ||
|
|
a9838131ad | ||
|
|
f3c58a1df7 | ||
|
|
7f18d147c1 | ||
|
|
9825babc23 | ||
|
|
f0c85e0935 | ||
|
|
617d99faac | ||
|
|
a121061df7 | ||
|
|
dc8934ab22 | ||
|
|
573191251e | ||
|
|
73533e4b19 | ||
|
|
792ac6ab63 | ||
|
|
c72b2caf3e | ||
|
|
be4632c2fe | ||
|
|
acda71cc90 | ||
|
|
e1b542314a | ||
|
|
0eaab6d8a2 | ||
|
|
00ffa69cb3 | ||
|
|
9106ae4f5f | ||
|
|
cceb7197a5 | ||
|
|
594fbbb4ef | ||
|
|
d2b8204fdc | ||
|
|
1d9247ae0f | ||
|
|
9e01a608b2 | ||
|
|
efa3bf9c69 | ||
|
|
db82797f58 | ||
|
|
71a8d9c0bb | ||
|
|
85cbea70bf | ||
|
|
c472c9facd | ||
|
|
c0fbdb1535 | ||
|
|
3fc7e0ed03 | ||
|
|
f7aabf03f8 | ||
|
|
d10910e553 | ||
|
|
a801eccf66 | ||
|
|
db500fab94 | ||
|
|
36c9418d55 | ||
|
|
7c05c6420a | ||
|
|
4433dffbd3 | ||
|
|
8f41badf74 | ||
|
|
c3646b11ac | ||
|
|
d3fc22fc6a | ||
|
|
c4862fb124 | ||
|
|
4f08e1550d | ||
|
|
be68dd5c11 | ||
|
|
9265377d51 | ||
|
|
601500fd99 | ||
|
|
e46199d28b | ||
|
|
da3233c47d | ||
|
|
010a0c6cdc | ||
|
|
7c5c744e87 | ||
|
|
00821bbc63 | ||
|
|
dbc0ebd861 | ||
|
|
b94335dd1c | ||
|
|
829f80179c | ||
|
|
faa5e46396 | ||
|
|
c758069d7c | ||
|
|
c46d049394 | ||
|
|
c67ae8a0a3 | ||
|
|
dac5c31993 | ||
|
|
9c7982673b | ||
|
|
91806c0a68 | ||
|
|
2b806e717d | ||
|
|
571c16be52 | ||
|
|
35c754c27c | ||
|
|
d0a0739d10 | ||
|
|
78ec4b5248 | ||
|
|
cd401b5b8a | ||
|
|
42d387925d | ||
|
|
a700fdc312 | ||
|
|
09321e5e41 | ||
|
|
61bf6bc447 | ||
|
|
0fc31bc9c7 | ||
|
|
897dafc7f3 | ||
|
|
ac6c810d25 | ||
|
|
cc34f65392 | ||
|
|
1fa4874426 | ||
|
|
8dec62de2b | ||
|
|
54f7633738 | ||
|
|
6d125e0880 | ||
|
|
cedafedfb0 | ||
|
|
e0b0df01da | ||
|
|
8dee36d420 | ||
|
|
eac3f507b6 | ||
|
|
f40110eb83 | ||
|
|
d65cbdf44d | ||
|
|
b76f5547e4 | ||
|
|
0921235637 | ||
|
|
18cb8a1b9b | ||
|
|
228c6879f5 | ||
|
|
4d7f7fc50f | ||
|
|
eaf25b517d | ||
|
|
0e00186ca1 | ||
|
|
0182c09318 | ||
|
|
6e40c814c8 | ||
|
|
7bd9462ffb | ||
|
|
6633a9edc0 | ||
|
|
8b18818bcc | ||
|
|
984e912f8d | ||
|
|
ff3f3d2f9b | ||
|
|
6e4cc49f1d | ||
|
|
6d38a236c1 | ||
|
|
f0f1e2d945 | ||
|
|
d38effcbbe | ||
|
|
419aa65381 | ||
|
|
07a8ae7e71 | ||
|
|
0a45b3a50b | ||
|
|
cd22255ab7 | ||
|
|
e021e25d6c | ||
|
|
b1c8669b43 | ||
|
|
df14deb5a0 | ||
|
|
f3c9bd16ee | ||
|
|
eac6da62d6 | ||
|
|
6dd41b617a | ||
|
|
6572010eed | ||
|
|
9a13ec9b76 | ||
|
|
2a33a6927c | ||
|
|
95f2c52659 | ||
|
|
7675ea3c23 | ||
|
|
d11092ae3c | ||
|
|
92ab600081 | ||
|
|
4b00a43b22 | ||
|
|
0d6bc7e7b2 | ||
|
|
3663884db2 | ||
|
|
e85d97b894 | ||
|
|
f0ce311fc6 | ||
|
|
b9a4b60b93 | ||
|
|
e82857996f | ||
|
|
2680111125 | ||
|
|
43b91589a1 | ||
|
|
1dd6dcdeef | ||
|
|
8a418161f6 | ||
|
|
e4ecb3745b | ||
|
|
5d36264660 | ||
|
|
f0044516d1 | ||
|
|
b0df70dbfe | ||
|
|
a02cecec20 | ||
|
|
9412fe094b | ||
|
|
7caadd87a2 | ||
|
|
2fe498149e | ||
|
|
6581d222cd | ||
|
|
99cdb86145 | ||
|
|
2ee54c2201 | ||
|
|
b2ef854aa1 | ||
|
|
f1f13b6e97 | ||
|
|
ae1590d3cf | ||
|
|
896929cb21 | ||
|
|
9fe503eeb3 | ||
|
|
41dd6250d4 | ||
|
|
3388ca2536 | ||
|
|
94076300ec | ||
|
|
a3105da32e | ||
|
|
8d474c0e7e | ||
|
|
864ab2cadd | ||
|
|
e08df2c530 | ||
|
|
73a63359df | ||
|
|
06b2efe65f | ||
|
|
47e258ef6e | ||
|
|
df60e7368a | ||
|
|
27f0d938c9 | ||
|
|
6aca0bb374 | ||
|
|
d44782f49f | ||
|
|
7fc23a1647 | ||
|
|
851980e36f | ||
|
|
bfb1a06f3d | ||
|
|
a27d428573 | ||
|
|
38fe917141 | ||
|
|
7d5fa2830d | ||
|
|
dbccd4d459 | ||
|
|
bf7db84451 | ||
|
|
709c127f1b | ||
|
|
60bc0f4baf | ||
|
|
b78c645fb0 | ||
|
|
2239404085 | ||
|
|
cba221c18a | ||
|
|
fd6475c804 | ||
|
|
8602d1fcf0 | ||
|
|
df2c95e444 | ||
|
|
0c4cba549d | ||
|
|
21dada4d2d | ||
|
|
12f6146bdf | ||
|
|
2479655708 | ||
|
|
937e82db46 | ||
|
|
0d6764efc5 | ||
|
|
570d860217 | ||
|
|
3b3318ab06 | ||
|
|
3df45f9651 | ||
|
|
8a3a60caae | ||
|
|
cf00bc8243 | ||
|
|
b6670f5cc8 | ||
|
|
8ddbf542f3 | ||
|
|
091b2129e7 | ||
|
|
ca2051e1d4 | ||
|
|
cc183e96a4 | ||
|
|
f0a6d9f33f | ||
|
|
5a0f113e6d | ||
|
|
b01478746c | ||
|
|
82b7f589ad | ||
|
|
21f2b3fa2b | ||
|
|
7eedcf75f9 | ||
|
|
57c934987c | ||
|
|
34ac232a82 | ||
|
|
c32ccbb39a | ||
|
|
7c168d663a | ||
|
|
493b4e6c27 | ||
|
|
14e1417ea8 | ||
|
|
aae5cc5574 | ||
|
|
73fb851864 | ||
|
|
c3b8f3e859 | ||
|
|
e57108d4e8 | ||
|
|
aa70c952eb | ||
|
|
d365d7c784 | ||
|
|
3a0e3798ec | ||
|
|
80ce3a5cf8 | ||
|
|
55a9f1a910 | ||
|
|
a0cc88ab5a | ||
|
|
b77a822822 | ||
|
|
78c65ab802 | ||
|
|
800e382ba9 | ||
|
|
74d1812461 | ||
|
|
507516e44d | ||
|
|
f0b3ee0e35 | ||
|
|
137532bfa6 | ||
|
|
796d2fd210 | ||
|
|
8cd704b6db | ||
|
|
19dece01f6 | ||
|
|
d34c23914a | ||
|
|
207bad5d5f | ||
|
|
a5f701bac7 | ||
|
|
dedcaf1eab | ||
|
|
3275165619 | ||
|
|
2bfacaaed2 | ||
|
|
c5372be267 | ||
|
|
0569f810cf | ||
|
|
633e03b710 | ||
|
|
445f13d1bf | ||
|
|
cfc0bfd64a | ||
|
|
384b2ad048 | ||
|
|
966743c704 | ||
|
|
37ccab4e23 | ||
|
|
2e7eedd3f2 | ||
|
|
959ff50fa7 | ||
|
|
ae63ad0b6d | ||
|
|
261098a122 | ||
|
|
779a06e86f | ||
|
|
95acb6121b | ||
|
|
38242bee75 | ||
|
|
aaefe94763 | ||
|
|
aa13936cb2 | ||
|
|
8b722cfc47 | ||
|
|
ba6c3c7fe0 | ||
|
|
48a684c024 | ||
|
|
ee6586fe4f | ||
|
|
d1322280dd | ||
|
|
a255f44d6e | ||
|
|
53c1de172f | ||
|
|
dc9d5cdf35 | ||
|
|
7066a5b3dc | ||
|
|
c652a9e7b1 | ||
|
|
194252e5a1 | ||
|
|
43b075d452 | ||
|
|
cf5af0f7ea | ||
|
|
f02a4a6b1f | ||
|
|
0427066558 | ||
|
|
af307bd55d | ||
|
|
28be3a0dbc | ||
|
|
2abed7161b | ||
|
|
28e4721a89 | ||
|
|
02c58b7a8f | ||
|
|
24f1f7b7b2 | ||
|
|
f16194e60d | ||
|
|
57a8642f5a | ||
|
|
92d6b39ffe | ||
|
|
5cfa8694d4 | ||
|
|
a15316de24 | ||
|
|
fa8d8ad503 | ||
|
|
c523379e6a | ||
|
|
e8c4b0e947 | ||
|
|
4ad7a4a2d1 | ||
|
|
e5b7cf23d6 | ||
|
|
d114913cd2 | ||
|
|
24b6c5df56 | ||
|
|
c386b10f04 | ||
|
|
3c4e3e8db6 | ||
|
|
84a7bdffe5 | ||
|
|
8308f5d7d3 | ||
|
|
ec6c25ef7e | ||
|
|
9504488acb | ||
|
|
8991ce53f4 | ||
|
|
b2378620c3 | ||
|
|
cc4c61d2b3 | ||
|
|
e90cc30edb | ||
|
|
26f71c33c0 | ||
|
|
58c7aa9937 | ||
|
|
1a3aa1bff0 | ||
|
|
55104a594c | ||
|
|
0f9f63400e | ||
|
|
db828a6aad | ||
|
|
632a9d66d1 | ||
|
|
6d82aa0bc9 | ||
|
|
d2cbf941db | ||
|
|
243114ef29 | ||
|
|
6618b4ea57 | ||
|
|
1a3b5657c7 | ||
|
|
e3b92fd561 | ||
|
|
b5af93c8b4 | ||
|
|
0a18174165 | ||
|
|
da06faa57e | ||
|
|
54befa769f | ||
|
|
4c7f207309 | ||
|
|
7fb3f48c67 | ||
|
|
6aaff9dfb7 | ||
|
|
5d30576d28 | ||
|
|
e74141ded6 | ||
|
|
07e47140a6 | ||
|
|
9cadd1c8a7 | ||
|
|
238ada04c0 | ||
|
|
13fd2a24ea | ||
|
|
1198b40c11 | ||
|
|
4ef81e93ef | ||
|
|
ca320f2f8d | ||
|
|
47a596c214 | ||
|
|
f8fc43f1e9 | ||
|
|
96117fc1eb | ||
|
|
597d64b81d | ||
|
|
f18bcdb88c | ||
|
|
e5202f44d7 | ||
|
|
8983bde73e | ||
|
|
ae212f36f5 | ||
|
|
e624f2c136 | ||
|
|
49aba39ae8 | ||
|
|
8f399652d7 | ||
|
|
8cfa85df6b | ||
|
|
ca1fd185dc | ||
|
|
81c6f38f79 | ||
|
|
8eff865277 | ||
|
|
a08c267c37 | ||
|
|
98becc9a50 | ||
|
|
36068d0b94 | ||
|
|
1f93eb0841 | ||
|
|
62fe3930ff | ||
|
|
d7a91cb05e | ||
|
|
4adb291a12 | ||
|
|
03a1439cc0 | ||
|
|
22db894076 | ||
|
|
3ad9e4cb5c | ||
|
|
eadd7ac034 | ||
|
|
24642a7c9f | ||
|
|
cc41592969 | ||
|
|
e50d643213 | ||
|
|
598501aaf0 | ||
|
|
52c32d3d85 | ||
|
|
177394f6ef | ||
|
|
77c137df22 | ||
|
|
3191e0b925 | ||
|
|
dc99a673a5 | ||
|
|
5c086e2321 | ||
|
|
1be02e3ac4 | ||
|
|
cb0b80253c | ||
|
|
bab5d16001 | ||
|
|
4608ca15eb | ||
|
|
67d1c35f19 | ||
|
|
3fc2cc410c | ||
|
|
e079fb665e | ||
|
|
f30980806f | ||
|
|
818bbbbb83 | ||
|
|
b41fdd2705 | ||
|
|
2c5a4dcb98 | ||
|
|
ad18d5984b | ||
|
|
18462445b7 | ||
|
|
d7a87a8552 | ||
|
|
9412b7236e | ||
|
|
19393948d7 | ||
|
|
b9fc97b44f | ||
|
|
c23376f040 | ||
|
|
9723d45d27 | ||
|
|
194175d2d0 | ||
|
|
2d3c13f8a2 | ||
|
|
d66d0fd4e4 | ||
|
|
249fb8393c | ||
|
|
c283c76130 | ||
|
|
420bc6cbe8 | ||
|
|
d5d6736e67 | ||
|
|
a37db99841 | ||
|
|
cff74b31d4 | ||
|
|
53bf0b1c42 | ||
|
|
540c69ab89 | ||
|
|
86041096fd | ||
|
|
f82c28bd79 | ||
|
|
a0d35e56a9 | ||
|
|
fa525a8359 | ||
|
|
c4ddf3530d | ||
|
|
e5f3091f2c | ||
|
|
5dc0b52e38 | ||
|
|
03b5c14944 | ||
|
|
302e0fa46b | ||
|
|
8e10b5fdec | ||
|
|
8da183e4f4 | ||
|
|
b9209962cd | ||
|
|
1407af6301 | ||
|
|
2530ae6b3d | ||
|
|
c9cd49d34f | ||
|
|
89f0a790c9 | ||
|
|
468fc86a3f | ||
|
|
57d3f98ece | ||
|
|
c898805ac5 | ||
|
|
f63dac26e6 | ||
|
|
d397efb2bd | ||
|
|
3db5ba98ad | ||
|
|
3532ce7fbc | ||
|
|
c284eab2dd | ||
|
|
eb4bb9554d | ||
|
|
85d9e96632 | ||
|
|
080a832605 | ||
|
|
335c5a03b6 | ||
|
|
dc1ce19db9 | ||
|
|
bee8c0bb90 | ||
|
|
c2a46baa77 | ||
|
|
640d263ae1 | ||
|
|
656c2496a6 | ||
|
|
614d529168 | ||
|
|
47dc524763 | ||
|
|
90798d8857 | ||
|
|
f9087a8ab1 | ||
|
|
accc0e3761 | ||
|
|
0ba6412f96 | ||
|
|
bbe5cf0a70 | ||
|
|
e14848740a | ||
|
|
626c1d3b48 | ||
|
|
7cea639209 | ||
|
|
ac0aaff611 | ||
|
|
bdfc879f00 | ||
|
|
d2f831b635 | ||
|
|
7ac599520e | ||
|
|
6919f3dbb5 | ||
|
|
bf85b110da | ||
|
|
cd7841ceed | ||
|
|
f574f89f78 | ||
|
|
40eeee48b6 | ||
|
|
cbe3c66156 | ||
|
|
209ec68591 | ||
|
|
5ff4d648f4 | ||
|
|
6182228de8 | ||
|
|
c98dba6aea | ||
|
|
cf5e6b242b | ||
|
|
e9af2849ef | ||
|
|
6bc4e124fb | ||
|
|
d70b889004 | ||
|
|
36a25353e9 | ||
|
|
ac9e8f667d | ||
|
|
05872fc6a8 | ||
|
|
df815a64cf | ||
|
|
6a51ddf755 | ||
|
|
b7eded6e48 | ||
|
|
e56a3b3c30 | ||
|
|
686368749a | ||
|
|
7388e60869 | ||
|
|
042ac5555c | ||
|
|
27903b4cd6 | ||
|
|
d306d8a90e | ||
|
|
124bd559de | ||
|
|
f83841a34f | ||
|
|
9273c6326e | ||
|
|
7a745cfe5c | ||
|
|
417c841f77 | ||
|
|
e56b39bbd8 | ||
|
|
d09be811f0 | ||
|
|
0b8b20eda0 | ||
|
|
53aafbd7d9 | ||
|
|
00031c8eb1 | ||
|
|
34387e228f | ||
|
|
06ba143afe | ||
|
|
6e3009b82e | ||
|
|
d60a8f9baa | ||
|
|
a58f29aa06 | ||
|
|
66f39ca185 | ||
|
|
ebbef484ad | ||
|
|
1385a4690e | ||
|
|
7f627ab480 | ||
|
|
939740d26e | ||
|
|
9baa24e626 | ||
|
|
b6fa28ea81 | ||
|
|
1181854bd6 | ||
|
|
a30cfc332d | ||
|
|
9f53d70109 | ||
|
|
776920f77d | ||
|
|
18f617a582 | ||
|
|
87d05bcf83 | ||
|
|
e451ecf000 | ||
|
|
1936a815e2 | ||
|
|
db55a973d4 | ||
|
|
d4717569b9 | ||
|
|
7bb81ef157 | ||
|
|
787c743333 | ||
|
|
1be39cb505 | ||
|
|
e2e173b92c | ||
|
|
4d346d3735 | ||
|
|
0b46ed3cde | ||
|
|
08688670b1 | ||
|
|
c6fc393417 | ||
|
|
afa1b8bfdc | ||
|
|
4994cb3774 | ||
|
|
80181c1091 | ||
|
|
1c0d40055e | ||
|
|
98cc99e36b | ||
|
|
f5caa49c31 | ||
|
|
0882da1788 | ||
|
|
01dd15cc3e | ||
|
|
ad9f6e63b6 | ||
|
|
5eed9a4e6e | ||
|
|
ff27a61252 | ||
|
|
571c9c10d4 | ||
|
|
56cad96718 | ||
|
|
b3d8187df4 | ||
|
|
61e21ef6a2 | ||
|
|
cba21c68a3 | ||
|
|
e2dc21da90 | ||
|
|
19d939c36e | ||
|
|
7ee6597873 | ||
|
|
bb37728e4f | ||
|
|
f94ed1a00c | ||
|
|
291cd842b9 | ||
|
|
dad198cb67 | ||
|
|
03d4cb0dfa | ||
|
|
eac875b5d6 | ||
|
|
f37c722c76 | ||
|
|
40eaabdbb5 | ||
|
|
225e3a747c | ||
|
|
efba90c6f1 | ||
|
|
c14a890e7e | ||
|
|
b389fd6667 | ||
|
|
d9be05fea8 | ||
|
|
c24ad0ba51 | ||
|
|
75d2e415e1 | ||
|
|
5e456ed82b | ||
|
|
41ab97ff1f | ||
|
|
babf079c31 | ||
|
|
9e1bc5680d | ||
|
|
ef5f0e77ec | ||
|
|
aff807e3af | ||
|
|
4942f5eb66 | ||
|
|
fdb091d98e | ||
|
|
09a94f3200 | ||
|
|
3503a54437 | ||
|
|
65ce641b22 | ||
|
|
b771f9eea4 | ||
|
|
0c77565104 | ||
|
|
6095d8a7fa | ||
|
|
6d9f02cfc6 | ||
|
|
0764a0601c | ||
|
|
a1ed81146e | ||
|
|
b48850c993 | ||
|
|
7349ec8f2f | ||
|
|
ec440aecf6 | ||
|
|
9d9e11d6d8 | ||
|
|
0d9e32f963 | ||
|
|
9eaec8d919 | ||
|
|
2a2fa31577 | ||
|
|
624740a80a | ||
|
|
2eda82f178 | ||
|
|
8f97d8a78e | ||
|
|
df225c0c7f | ||
|
|
83e3a702c5 | ||
|
|
ef2c2c2c9e | ||
|
|
3160fc84fa | ||
|
|
a6a7da31c9 | ||
|
|
b6bd4ae8e6 | ||
|
|
84e67da2af | ||
|
|
95d95f9a9b | ||
|
|
8dd307573a | ||
|
|
80a449862e | ||
|
|
84ccf7bbb1 | ||
|
|
5de8401494 | ||
|
|
4fb78fab93 | ||
|
|
c9568c0744 | ||
|
|
7c62e9aecd | ||
|
|
e110b49cab | ||
|
|
287ff3ed55 | ||
|
|
6365164c21 | ||
|
|
13464cce68 | ||
|
|
f330d67740 | ||
|
|
78ffefe107 | ||
|
|
909f0d8bdb | ||
|
|
2e57ff25ee | ||
|
|
072bba109f | ||
|
|
e93133a28f | ||
|
|
b9536a25d6 | ||
|
|
bc5e92033b | ||
|
|
24685ee9d6 | ||
|
|
89270399db | ||
|
|
cdcde634e8 | ||
|
|
757fdb2b32 | ||
|
|
71755b7a5e | ||
|
|
1f0616439c | ||
|
|
6065f0e2d0 | ||
|
|
8f097b14cc | ||
|
|
6f9694174f | ||
|
|
57bd4d3a98 | ||
|
|
49e838781c | ||
|
|
788d3c022a | ||
|
|
9cbcafa8d1 | ||
|
|
72804d2e8c | ||
|
|
f3a935adb9 | ||
|
|
25ebb3fa75 | ||
|
|
274d18a141 | ||
|
|
8dd71ec5c8 | ||
|
|
f9d2ca68ce | ||
|
|
caff279255 | ||
|
|
e4a5775570 | ||
|
|
8afb6d2761 | ||
|
|
b58bea6fa1 | ||
|
|
07daf2165a | ||
|
|
b88f54b31a | ||
|
|
3e883120dd | ||
|
|
7ec709cf46 | ||
|
|
9b39a8abc2 | ||
|
|
887032667d | ||
|
|
5f582ad28a | ||
|
|
61825e9aec | ||
|
|
816e955c61 | ||
|
|
201b6dfa60 | ||
|
|
85456bd6d8 | ||
|
|
007f11e22e | ||
|
|
ddf451739b | ||
|
|
d438d2db40 | ||
|
|
77ae1fa1f2 | ||
|
|
663c0d975d | ||
|
|
602be42b24 | ||
|
|
66683d2952 | ||
|
|
c8a81911c0 | ||
|
|
f0199d7277 | ||
|
|
cb89bd0e13 | ||
|
|
5d296a01c2 | ||
|
|
dbaaf081d7 | ||
|
|
df51856e65 | ||
|
|
8147a88353 | ||
|
|
cc05d91bda | ||
|
|
59b5475350 | ||
|
|
84d78035e4 | ||
|
|
276ffd5a4b | ||
|
|
d10f734594 | ||
|
|
7149d08995 | ||
|
|
cccf9b7d54 | ||
|
|
81a7271009 | ||
|
|
e43835c9f5 | ||
|
|
525cc6df97 | ||
|
|
b8002cb54f | ||
|
|
beba85a848 | ||
|
|
f7fdffefd6 | ||
|
|
b34e2c1474 | ||
|
|
72849a3dc3 | ||
|
|
bdf914e8d5 | ||
|
|
07b15f9de6 | ||
|
|
32c3f85679 | ||
|
|
7e052c1eb1 | ||
|
|
2a08923c51 | ||
|
|
8925b8c922 | ||
|
|
1afb844e1a | ||
|
|
12331cb10c | ||
|
|
d54808e33f | ||
|
|
f2f2df90aa | ||
|
|
660208740e | ||
|
|
704b5a0e13 | ||
|
|
ea2d9f7c0c | ||
|
|
cc4adb798f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,6 +12,7 @@
|
||||
/android-studio/sdk
|
||||
out/
|
||||
/tmp
|
||||
kotlin-ide/
|
||||
workspace.xml
|
||||
*.versionsBackup
|
||||
/idea/testData/debugger/tinyApp/classes*
|
||||
|
||||
672
ChangeLog.md
672
ChangeLog.md
@@ -1,5 +1,677 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 1.5.10
|
||||
|
||||
### Compiler
|
||||
|
||||
#### Fixes
|
||||
|
||||
- [`KT-41078`](https://youtrack.jetbrains.com/issue/KT-41078) Incorrect type substitution in contracts with type parameters
|
||||
- [`KT-44770`](https://youtrack.jetbrains.com/issue/KT-44770) JVM / IR: "IllegalArgumentException: Unrecognized Type: [null]" Jackson doesn't recognize type
|
||||
- [`KT-45084`](https://youtrack.jetbrains.com/issue/KT-45084) JVM IR: "NoSuchElementException: Sequence contains no element matching the predicate" when inline class is passed to lambda with >22 parameters
|
||||
- [`KT-45779`](https://youtrack.jetbrains.com/issue/KT-45779) JVM / IR: java.lang.NoSuchMethodError: 'int java.lang.Integer.plus(int)' caused by function reference
|
||||
- [`KT-45941`](https://youtrack.jetbrains.com/issue/KT-45941) JVM IR: local functions use generic type parameters of the outer class in the bytecode, which breaks Bytebuddy and MockK
|
||||
- [`KT-46149`](https://youtrack.jetbrains.com/issue/KT-46149) Generate synthetic classes for SAM adapters with erased instead of generic supertype
|
||||
- [`KT-46189`](https://youtrack.jetbrains.com/issue/KT-46189) JVM IR: tailrec function with capturing lambda in default parameter value leads to NoSuchMethodError at runtime
|
||||
- [`KT-46214`](https://youtrack.jetbrains.com/issue/KT-46214) JVM / IR: "IllegalStateException: No mapping for symbol: VALUE_PARAMETER INSTANCE_RECEIVER" on a suspend function in an inner class
|
||||
- [`KT-46238`](https://youtrack.jetbrains.com/issue/KT-46238) JVM IR: BootstrapMethodError in JDK 11+ on intersection type passed in arguments of SAM adapter where SAM interface's type parameter has a non-trivial upper bound
|
||||
- [`KT-46259`](https://youtrack.jetbrains.com/issue/KT-46259) JVM IR: local function for adapted function reference is not declared as ACC_SYNTHETIC
|
||||
- [`KT-46284`](https://youtrack.jetbrains.com/issue/KT-46284) JVM IR: "Unbound private symbol IrClassSymbol" on class reference to script class
|
||||
- [`KT-46402`](https://youtrack.jetbrains.com/issue/KT-46402) IllegalAccessError: "CapturedLambdaInterpreter (in unnamed module @0x71b06418) cannot access class jdk.internal.org.objectweb.asm.Type" caused by inline function with a suspend parameter in Maven project
|
||||
- [`KT-46408`](https://youtrack.jetbrains.com/issue/KT-46408) JVM IR: BootstrapMethodError due to missing bridge for subclass of generic Java interface
|
||||
- [`KT-46426`](https://youtrack.jetbrains.com/issue/KT-46426) JVM IR: Corrupted .class file when passing Array constructor reference as (inline) lambda
|
||||
- [`KT-46455`](https://youtrack.jetbrains.com/issue/KT-46455) OOM on parsing invalid code with string interpolation
|
||||
- [`KT-46503`](https://youtrack.jetbrains.com/issue/KT-46503) JVM IR: "AssertionError: Unexpected variance in super type argument: out @1"
|
||||
- [`KT-46505`](https://youtrack.jetbrains.com/issue/KT-46505) JVM IR: NullPointerException caused by a callable reference with nullable inline value class parameter
|
||||
- [`KT-46512`](https://youtrack.jetbrains.com/issue/KT-46512) JVM / IR: NoSuchMethodError on SAM conversion of a function reference
|
||||
- [`KT-46515`](https://youtrack.jetbrains.com/issue/KT-46515) IndexOutOfBoundsException: "Empty list doesn't contain element at index 0." on bad variable name in 1.5.0
|
||||
- [`KT-46516`](https://youtrack.jetbrains.com/issue/KT-46516) JVM IR: "AnalyzerException: Expected I, but found R" on subclassing AbstractMutableList<Int>
|
||||
- [`KT-46524`](https://youtrack.jetbrains.com/issue/KT-46524) Cannot use unsigned literals with api-version < 1.5 even with opt-in
|
||||
- [`KT-46537`](https://youtrack.jetbrains.com/issue/KT-46537) JVM / IR: "IllegalStateException: No noarg super constructor for CLASS" caused by "No-arg" plugin with annotation on child class
|
||||
- [`KT-46540`](https://youtrack.jetbrains.com/issue/KT-46540) JVM / IR: AnalyzerException: Expected an object reference, but found J caused by java.function.Supplier
|
||||
- [`KT-46554`](https://youtrack.jetbrains.com/issue/KT-46554) JVM IR: "IllegalStateException: No mapping for symbol: VAR IR_TEMPORARY_VARIABLE" with value class constructor delegation call
|
||||
- [`KT-46555`](https://youtrack.jetbrains.com/issue/KT-46555) JVM IR: IllegalAccessError when using Java method reference
|
||||
- [`KT-46562`](https://youtrack.jetbrains.com/issue/KT-46562) Kotlin 1.5.0 generates non-serializable lambdas when they should be serializable
|
||||
- [`KT-46568`](https://youtrack.jetbrains.com/issue/KT-46568) JVM IR: "AssertionError: IrCall expected inside JvmStatic wrapper" on compiling protected static function with return type Nothing inside companion object of abstract class
|
||||
- [`KT-46574`](https://youtrack.jetbrains.com/issue/KT-46574) JVM / IR: ClassCastException caused by runBlocking awaiting call while returning Kotlin.Result type.
|
||||
- [`KT-46579`](https://youtrack.jetbrains.com/issue/KT-46579) JVM IR: "IllegalArgumentException: Sequence contains more than one matching element" for Java enum with overloaded values() static method
|
||||
- [`KT-46584`](https://youtrack.jetbrains.com/issue/KT-46584) JVM IR: Intrinsics.needClassReification (UnsupportedOperationException thrown). Property delegate provider crossinline lambda inlining/reification issue
|
||||
- [`KT-46751`](https://youtrack.jetbrains.com/issue/KT-46751) JVM / IR:"ClassCastException: java.lang.String cannot be cast to java.lang.Void" in extension function in Kotlin 1.5
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-45981`](https://youtrack.jetbrains.com/issue/KT-45981) failed to analyze: java.lang.AssertionError: diagnostic callback has been already registered: Code analysis get stuck in AS 2020.3.1.14 & Kotlin v1.5.0-M2
|
||||
- [`KT-46622`](https://youtrack.jetbrains.com/issue/KT-46622) 60+ second freezes with Kotlin plugin 1.5.0: GetModuleInfoKt.findJvmStdlibAcrossDependencies
|
||||
|
||||
### IDE. Gradle Integration
|
||||
|
||||
- [`KT-46417`](https://youtrack.jetbrains.com/issue/KT-46417) [UNRESOLVED_REFERENCE] For project to project dependencies of native platform test source sets
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-46280`](https://youtrack.jetbrains.com/issue/KT-46280) JvmRecord annotation missing constructor in common
|
||||
|
||||
### Middle-end. IR
|
||||
|
||||
- [`KT-44013`](https://youtrack.jetbrains.com/issue/KT-44013) NPE: When calling constructor of a function type while inheriting from it, despite it's an interface
|
||||
|
||||
### Tools. Android Extensions
|
||||
|
||||
- [`KT-46590`](https://youtrack.jetbrains.com/issue/KT-46590) Kotlin Android Extensions 1.5.0 generates bad writeToParcel() method for nullable Array types
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-41142`](https://youtrack.jetbrains.com/issue/KT-41142) Kotlin version conflict when using Kotlin Gradle plugins in pre-compiled script plugin
|
||||
- [`KT-46353`](https://youtrack.jetbrains.com/issue/KT-46353) Optimizations disabled in Gradle 7 for KAPT when generating sources
|
||||
- [`KT-46368`](https://youtrack.jetbrains.com/issue/KT-46368) Memory leak with 1.5.0-RC when building with Gradle
|
||||
- [`KT-46689`](https://youtrack.jetbrains.com/issue/KT-46689) Track -Xuse-old-backend flag usage
|
||||
|
||||
### Tools. Gradle. JS
|
||||
|
||||
- [`KT-46006`](https://youtrack.jetbrains.com/issue/KT-46006) KJS \ Gradle: Task without declaring an explicit or implicit dependency on `jsGenerateExternalsIntegrated` in Gradle 7
|
||||
- [`KT-46162`](https://youtrack.jetbrains.com/issue/KT-46162) KJS: Exported items unavailable on dev server
|
||||
- [`KT-46331`](https://youtrack.jetbrains.com/issue/KT-46331) KJS: With `kotlin.js.webpack.major.version=4` browserXRun tasks fail
|
||||
|
||||
### Tools. Parcelize
|
||||
|
||||
- [`KT-46567`](https://youtrack.jetbrains.com/issue/KT-46567) Kotlin 1.5.0 parcelize compilation fails in new backend when using TypeParceller with nested generics
|
||||
|
||||
### Tools. kapt
|
||||
|
||||
- [`KT-45532`](https://youtrack.jetbrains.com/issue/KT-45532) Do not create Kapt stubs directory during configuration time
|
||||
|
||||
|
||||
## 1.5.0
|
||||
|
||||
### Backend. Native
|
||||
|
||||
- [`KT-42053`](https://youtrack.jetbrains.com/issue/KT-42053) Support compiler caches for linux_x64
|
||||
- [`KT-43690`](https://youtrack.jetbrains.com/issue/KT-43690) Support compiler caches for ios_arm64
|
||||
|
||||
### Backend. IR
|
||||
|
||||
- [`KT-42684`](https://youtrack.jetbrains.com/issue/KT-42684) StackOverflowError on recursive inline arguments in inline fun
|
||||
|
||||
### Compiler
|
||||
|
||||
#### New Features
|
||||
|
||||
- [`KT-28791`](https://youtrack.jetbrains.com/issue/KT-28791) Kotlin serialization with inline classes
|
||||
- [`KT-30222`](https://youtrack.jetbrains.com/issue/KT-30222) Support JVM target version selection in Kotlin bytecode tool window
|
||||
- [`KT-41884`](https://youtrack.jetbrains.com/issue/KT-41884) Support 'file' target for JvmSynthetic annotation
|
||||
- [`KT-43677`](https://youtrack.jetbrains.com/issue/KT-43677) Support for Java records
|
||||
- [`KT-43920`](https://youtrack.jetbrains.com/issue/KT-43920) Support loading binary Java annotations on fields
|
||||
- [`KT-44278`](https://youtrack.jetbrains.com/issue/KT-44278) Generate SAM-converted lambdas and function references using 'invokedynamic' on JDK 1.8+
|
||||
- [`KT-44650`](https://youtrack.jetbrains.com/issue/KT-44650) Deprecate JVM target version 1.6
|
||||
- [`KT-44787`](https://youtrack.jetbrains.com/issue/KT-44787) Suspend functions in fun interfaces
|
||||
- [`KT-44865`](https://youtrack.jetbrains.com/issue/KT-44865) Allow to declare protected constructors in sealed classes
|
||||
- [`KT-44869`](https://youtrack.jetbrains.com/issue/KT-44869) Compiling sealed interface with version less than 1.5: error message from future could be provided
|
||||
|
||||
|
||||
#### Performance Improvements
|
||||
|
||||
- [`KT-6336`](https://youtrack.jetbrains.com/issue/KT-6336) Optimize generation of local functions
|
||||
- [`KT-7307`](https://youtrack.jetbrains.com/issue/KT-7307) Optimize infix call of String.plus
|
||||
- [`KT-18692`](https://youtrack.jetbrains.com/issue/KT-18692) Optimize '<optimizable_range> step x' for-in loop
|
||||
- [`KT-19978`](https://youtrack.jetbrains.com/issue/KT-19978) Inefficient bytecode generated for function references undergoing Java SAM conversion
|
||||
- [`KT-23565`](https://youtrack.jetbrains.com/issue/KT-23565) OperationsMapGenerated.kt generates unreasonable amount of bytecode
|
||||
- [`KT-23825`](https://youtrack.jetbrains.com/issue/KT-23825) Tail suspend call utilizing elvis operator does not take advantage of suspend tail call optimization
|
||||
- [`KT-23826`](https://youtrack.jetbrains.com/issue/KT-23826) A suspend function on the right side of a returned || condition is not tail call optimized
|
||||
- [`KT-25348`](https://youtrack.jetbrains.com/issue/KT-25348) No compile time unsigned integer conversion when using hex literal
|
||||
- [`KT-26060`](https://youtrack.jetbrains.com/issue/KT-26060) Support a compiler mode to compile lambda expressions using `invokedynamic` instruction
|
||||
- [`KT-26590`](https://youtrack.jetbrains.com/issue/KT-26590) Do not generate create method for suspend lambdas if its arity >= 2
|
||||
- [`KT-27427`](https://youtrack.jetbrains.com/issue/KT-27427) Optimize nullable check introduced with 'as' cast
|
||||
- [`KT-28246`](https://youtrack.jetbrains.com/issue/KT-28246) Redundant boxing/unboxing isn't eliminated by the compiler in case of inline classes and javaClass intrinsic
|
||||
- [`KT-30605`](https://youtrack.jetbrains.com/issue/KT-30605) Constant folding doesn't evaluate inv() function
|
||||
- [`KT-36845`](https://youtrack.jetbrains.com/issue/KT-36845) Generate enum-based TABLESWITCH/LOOKUPSWITCH on a value with smart cast to enum in JVM_IR
|
||||
- [`KT-39585`](https://youtrack.jetbrains.com/issue/KT-39585) JVM BE generates redundant accessor calls when accessing static final field lifted from companion
|
||||
- [`KT-40886`](https://youtrack.jetbrains.com/issue/KT-40886) Old JVM BE unspills ACONST_NULL from continuation
|
||||
- [`KT-42621`](https://youtrack.jetbrains.com/issue/KT-42621) Kotlin binary size considerably larger for code extensively using stream API
|
||||
- [`KT-44153`](https://youtrack.jetbrains.com/issue/KT-44153) NI: Low Memory and IntelliJ hangs when quotes in split() are missed
|
||||
- [`KT-45410`](https://youtrack.jetbrains.com/issue/KT-45410) JVM / IR: Extreme performance regression on arithmetic operations inside a loop
|
||||
|
||||
#### Fixes
|
||||
|
||||
- [`KT-6007`](https://youtrack.jetbrains.com/issue/KT-6007) Support changed return type of inlined generic function when lambda returns anonymous object
|
||||
- [`KT-6055`](https://youtrack.jetbrains.com/issue/KT-6055) Failed invoke plus assign on array element accessed via several args through local get/set convention extensions
|
||||
- [`KT-6879`](https://youtrack.jetbrains.com/issue/KT-6879) CompilationException when local classes hierarchy is placed within other local or inner declaration
|
||||
- [`KT-8120`](https://youtrack.jetbrains.com/issue/KT-8120) NoSuchMethodError on local class constructor call inside a local class
|
||||
- [`KT-8199`](https://youtrack.jetbrains.com/issue/KT-8199) "Cannot pop operand off an empty stack" for local class using a captured variable as default value for constructor parameter
|
||||
- [`KT-10835`](https://youtrack.jetbrains.com/issue/KT-10835) "AssertionError: Non-outer parameter incorrectly mapped to outer" when inlining object literal extending inner class
|
||||
- [`KT-12790`](https://youtrack.jetbrains.com/issue/KT-12790) Don't generate synthetic accessors for private inline function/properties
|
||||
- [`KT-13213`](https://youtrack.jetbrains.com/issue/KT-13213) IllegalArgumentException in ByteVector.putUTF8 on attempt to compile file with moderately long string literal
|
||||
- [`KT-14628`](https://youtrack.jetbrains.com/issue/KT-14628) "UnsupportedOperationException: Don't know how to generate outer expression" for nested class inheriting from inner class with a companion object
|
||||
- [`KT-14833`](https://youtrack.jetbrains.com/issue/KT-14833) JVM internal error: Augment assignment and increment are not supported for local delegated properties and inline properties
|
||||
- [`KT-15403`](https://youtrack.jetbrains.com/issue/KT-15403) Suspend operator get wrong code generated by BE (NoSuchMethodError)
|
||||
- [`KT-15404`](https://youtrack.jetbrains.com/issue/KT-15404) Suspend operator set wrong code generated
|
||||
- [`KT-16084`](https://youtrack.jetbrains.com/issue/KT-16084) Proguard can't find enclosing class of let closure inside apply closure
|
||||
- [`KT-16151`](https://youtrack.jetbrains.com/issue/KT-16151) Internal compiler error when using plusAssign operator with mutable map
|
||||
- [`KT-16221`](https://youtrack.jetbrains.com/issue/KT-16221) Support in/!in suspend operators
|
||||
- [`KT-16282`](https://youtrack.jetbrains.com/issue/KT-16282) "Cannot pop operand off an empty stack" for plusAssign with default parameters in setter operator
|
||||
- [`KT-16445`](https://youtrack.jetbrains.com/issue/KT-16445) `java.lang.VerifyError: Bad type on operand stack` when delegating an interface through a private reified function inside an object
|
||||
- [`KT-16520`](https://youtrack.jetbrains.com/issue/KT-16520) Invalid bytecode semantics for set call by convention with default parameters
|
||||
- [`KT-16567`](https://youtrack.jetbrains.com/issue/KT-16567) Inliner creates redundant objects on source inlining
|
||||
- [`KT-16752`](https://youtrack.jetbrains.com/issue/KT-16752) Delegating function interface to function reference does not work
|
||||
- [`KT-17554`](https://youtrack.jetbrains.com/issue/KT-17554) Incorrect cast to Unit generated on annotated when-expression with a single-branch if inside
|
||||
- [`KT-17738`](https://youtrack.jetbrains.com/issue/KT-17738) Java cannot extend class implementing kotlin.collections.Map
|
||||
- [`KT-17753`](https://youtrack.jetbrains.com/issue/KT-17753) Strange behavior of if and return statements
|
||||
- [`KT-18583`](https://youtrack.jetbrains.com/issue/KT-18583) "ISE: Recursive call in a lazy value" for generic sealed class with nested subclass in a `when(this)` with inferred return type
|
||||
- [`KT-19861`](https://youtrack.jetbrains.com/issue/KT-19861) "IllegalStateException: Label wasn't found during iterating through instructions" for `plusAssign` with safe call
|
||||
- [`KT-20306`](https://youtrack.jetbrains.com/issue/KT-20306) Make 'when' over an 'expect' enum class non-exhaustive
|
||||
- [`KT-20869`](https://youtrack.jetbrains.com/issue/KT-20869) kotlin.jvm.internal.DefaultConstructorMarker should be public
|
||||
- [`KT-20996`](https://youtrack.jetbrains.com/issue/KT-20996) IllegalStateException: Cannot get FQ name of local class: class <no name provided> in metadata serialization for common code
|
||||
- [`KT-21014`](https://youtrack.jetbrains.com/issue/KT-21014) Incorrect bytecode generated for 'PrimitiveArray::size'
|
||||
- [`KT-21092`](https://youtrack.jetbrains.com/issue/KT-21092) Reference `javaClass` for generic property: "couldn't transform method node: get()"
|
||||
- [`KT-21778`](https://youtrack.jetbrains.com/issue/KT-21778) "IllegalStateException: Couldn't build context" for inline function inside an anonymous object
|
||||
- [`KT-21900`](https://youtrack.jetbrains.com/issue/KT-21900) VerifyError on equals on generic primitive type
|
||||
- [`KT-22098`](https://youtrack.jetbrains.com/issue/KT-22098) "UnsupportedOperationException: Don't know how to generate outer expression" on extension function call inside lambda in anonymous object super constructor call
|
||||
- [`KT-22488`](https://youtrack.jetbrains.com/issue/KT-22488) Bad line numbers generated for '&&' expression
|
||||
- [`KT-22972`](https://youtrack.jetbrains.com/issue/KT-22972) A compiler bug(?) in Number class descendants
|
||||
- [`KT-23619`](https://youtrack.jetbrains.com/issue/KT-23619) Transform stateless singleton lambda during inline
|
||||
- [`KT-23881`](https://youtrack.jetbrains.com/issue/KT-23881) Declaration of lambda in inlined apply block holds reference to superfluous references causing leak
|
||||
- [`KT-24135`](https://youtrack.jetbrains.com/issue/KT-24135) Calling invoke on crossinline suspend lambda leads to no state-machine
|
||||
- [`KT-24193`](https://youtrack.jetbrains.com/issue/KT-24193) NoClassDefFoundError: java/lang/Cloneable$DefaultImpls on inheritance from Cloneable through an interface
|
||||
- [`KT-24305`](https://youtrack.jetbrains.com/issue/KT-24305) ClassNotFoundException when using Java reflection on local class in an inlined lambda
|
||||
- [`KT-24564`](https://youtrack.jetbrains.com/issue/KT-24564) Custom operator fun set on ByteArray resolves properly but is miscompiled
|
||||
- [`KT-25400`](https://youtrack.jetbrains.com/issue/KT-25400) "NoClassDefFoundError: kotlin/KotlinPackage" with Turkish system locale on macOS
|
||||
- [`KT-26130`](https://youtrack.jetbrains.com/issue/KT-26130) Incorrect method signature for a generic function with inline class as a type parameter upper bound
|
||||
- [`KT-26360`](https://youtrack.jetbrains.com/issue/KT-26360) "Method from super interface has a different signature" for Interface that extends both interfaces with and without @JvmDefault
|
||||
- [`KT-26473`](https://youtrack.jetbrains.com/issue/KT-26473) Error on compiling inline class with calls of super methods equals(), hashCode(), toString()
|
||||
- [`KT-26474`](https://youtrack.jetbrains.com/issue/KT-26474) VE “Bad type on operand stack” at runtime on calling toString() method of inline class with calls of super methods (toString(), equals(), hashCode()) inside
|
||||
- [`KT-26592`](https://youtrack.jetbrains.com/issue/KT-26592) Do not generate private suspend functions as synthetic package-private
|
||||
- [`KT-27449`](https://youtrack.jetbrains.com/issue/KT-27449) NoSuchMethodError for local suspend function with suspend lambda parameter with default value
|
||||
- [`KT-27469`](https://youtrack.jetbrains.com/issue/KT-27469) "Cannot pop operand off an empty stack" for compound assignment (plusAssign) with a `vararg` operator get
|
||||
- [`KT-27825`](https://youtrack.jetbrains.com/issue/KT-27825) Gradually prohibit non-abstract classes containing abstract members invisible from that classes (internal/package-private)
|
||||
- [`KT-27830`](https://youtrack.jetbrains.com/issue/KT-27830) "Incompatible stack heights" with suspend inline function in do while loop that executes suspend lambda
|
||||
- [`KT-28042`](https://youtrack.jetbrains.com/issue/KT-28042) "Cannot pop operand off an empty stack" for a bound callable reference of lambda inside inline function
|
||||
- [`KT-28166`](https://youtrack.jetbrains.com/issue/KT-28166) "Argument 1: expected I, but found R" for generic method with generic parameter or receiver with inline class upper bound
|
||||
- [`KT-28331`](https://youtrack.jetbrains.com/issue/KT-28331) Consider generating accessors for lateinit properties to avoid assertion on each call
|
||||
- [`KT-28573`](https://youtrack.jetbrains.com/issue/KT-28573) Inliner does not update references to transformed object
|
||||
- [`KT-29331`](https://youtrack.jetbrains.com/issue/KT-29331) "AnalyzerException: Argument 1: expected R, but found I" with local generic extension property called on `Int` receiver
|
||||
- [`KT-29595`](https://youtrack.jetbrains.com/issue/KT-29595) NoClassDefFoundError with inline reified function with lambda argument returning anonymous object
|
||||
- [`KT-29802`](https://youtrack.jetbrains.com/issue/KT-29802) Incorrect reification when the same type parameter name is used for different reified types
|
||||
- [`KT-30041`](https://youtrack.jetbrains.com/issue/KT-30041) "AnalyzerException: Expected an object reference, but found ." on nested suspend function calls outer suspend function
|
||||
- [`KT-30066`](https://youtrack.jetbrains.com/issue/KT-30066) Consider adding annotations to ConeKotlinType
|
||||
- [`KT-30280`](https://youtrack.jetbrains.com/issue/KT-30280) Inline class class literal gets unwrapped in annotation arguments
|
||||
- [`KT-30402`](https://youtrack.jetbrains.com/issue/KT-30402) Constant folding works incorrectly with unsigned arithmetics
|
||||
- [`KT-30548`](https://youtrack.jetbrains.com/issue/KT-30548) "java.lang.IndexOutOfBoundsException: Cannot pop operand off an empty stack" while compiling access to a private lateinit companion field
|
||||
- [`KT-30629`](https://youtrack.jetbrains.com/issue/KT-30629) `java.lang.VerifyError: Bad type on operand stack` when using a function reference to a generic property
|
||||
- [`KT-30933`](https://youtrack.jetbrains.com/issue/KT-30933) Inline function produces IllegalAccessError on property reference from different package
|
||||
- [`KT-31136`](https://youtrack.jetbrains.com/issue/KT-31136) "AnalyzerException: Argument 1: expected R, but found I" on x::javaClass when x is inline class object built around primitive type
|
||||
- [`KT-31227`](https://youtrack.jetbrains.com/issue/KT-31227) Prohibit using array based on non-reified type parameters as reified type arguments on JVM
|
||||
- [`KT-31592`](https://youtrack.jetbrains.com/issue/KT-31592) NoSuchMethodException when inlining public function accessing a protected static Java class member
|
||||
- [`KT-31727`](https://youtrack.jetbrains.com/issue/KT-31727) Object expression captures all variables used in constructor
|
||||
- [`KT-32023`](https://youtrack.jetbrains.com/issue/KT-32023) "AnalyzerException: Expected I, but found R" with inline suspend function used with callable reference
|
||||
- [`KT-32115`](https://youtrack.jetbrains.com/issue/KT-32115) NPE during initialization of enum class with delegated property
|
||||
- [`KT-32153`](https://youtrack.jetbrains.com/issue/KT-32153) "AnalyzerException: Expected an object reference, but found ." with recursive suspend local function
|
||||
- [`KT-32351`](https://youtrack.jetbrains.com/issue/KT-32351) ClassNotFoundException for anonymous object implementing interface inside a lambda with data class and inline methods
|
||||
- [`KT-32384`](https://youtrack.jetbrains.com/issue/KT-32384) Safe cast to generic type argument with inline class upper-bound throws NPE instead of ClassCastException
|
||||
- [`KT-32579`](https://youtrack.jetbrains.com/issue/KT-32579) java.lang.VerifyError: Bad type on operand stack on calling inner class of inherited class in super class when casting to inherited class
|
||||
- [`KT-32749`](https://youtrack.jetbrains.com/issue/KT-32749) "VerifyError: Call to wrong <init> method" with inline function and accessing class field from anonymous object
|
||||
- [`KT-32793`](https://youtrack.jetbrains.com/issue/KT-32793) Generated code crashes by ClassCastException with local suspend function and inline class
|
||||
- [`KT-32812`](https://youtrack.jetbrains.com/issue/KT-32812) "AnalyzerException: Argument 1: expected R, but found I" invoking function with default parameter inherited by inline class
|
||||
- [`KT-32821`](https://youtrack.jetbrains.com/issue/KT-32821) Missing unboxing of inline class for complex hierarchy of suspend calls
|
||||
- [`KT-33155`](https://youtrack.jetbrains.com/issue/KT-33155) ClassNotFoundException for qualified this in anonymous object and as a result of inline function call
|
||||
- [`KT-33173`](https://youtrack.jetbrains.com/issue/KT-33173) Internal error: "AnalyzerException: Expected I, but found R" for supercall inside inline lambda from HashSet.remove implementation
|
||||
- [`KT-33577`](https://youtrack.jetbrains.com/issue/KT-33577) NoSuchFieldError with nested anonymous objects accessing outer instance property
|
||||
- [`KT-33836`](https://youtrack.jetbrains.com/issue/KT-33836) Wrong code generated for a local tailrec suspend function.
|
||||
- [`KT-33873`](https://youtrack.jetbrains.com/issue/KT-33873) ClassCastException invoking UByte setter function via reflection
|
||||
- [`KT-34018`](https://youtrack.jetbrains.com/issue/KT-34018) "Cannot pop operand off an empty stack" with inline lambda with callable reference
|
||||
- [`KT-34186`](https://youtrack.jetbrains.com/issue/KT-34186) JDK11: class file contains malformed variable arity method for vararg sealed class constructor
|
||||
- [`KT-34202`](https://youtrack.jetbrains.com/issue/KT-34202) IllegalAccessError on callable reference of function from multifile facade from standard library
|
||||
- [`KT-34255`](https://youtrack.jetbrains.com/issue/KT-34255) @JvmStatic tailrec function: "Cannot pop operand off an empty stack"
|
||||
- [`KT-34507`](https://youtrack.jetbrains.com/issue/KT-34507) Incorrect generated code for mutable collection stub methods in case of presence of functions with similar signature
|
||||
- [`KT-34665`](https://youtrack.jetbrains.com/issue/KT-34665) Possible index overflow in optimized "for" loop over withIndex()
|
||||
- [`KT-34754`](https://youtrack.jetbrains.com/issue/KT-34754) Flow builder: "AnalyzerException: Expected an object reference, but found ." with recursive suspend local function
|
||||
- [`KT-34816`](https://youtrack.jetbrains.com/issue/KT-34816) "AnalyzerException: Expected an object reference, but found I" on "this" in inline class member extension suspend function
|
||||
- [`KT-34841`](https://youtrack.jetbrains.com/issue/KT-34841) ClassNotFoundException when invoke param function inside anonymous object method
|
||||
- [`KT-35008`](https://youtrack.jetbrains.com/issue/KT-35008) "AnalyzerException: Expected an object reference, but found I" in inline class companion calling private constructor
|
||||
- [`KT-35166`](https://youtrack.jetbrains.com/issue/KT-35166) `NoSuchMethodError` at runtime with local property delegate on anonymous object referencing another anonymous object
|
||||
- [`KT-35224`](https://youtrack.jetbrains.com/issue/KT-35224) It's possible to pass non-spread arrays after arguments with SAM-conversion
|
||||
- [`KT-35301`](https://youtrack.jetbrains.com/issue/KT-35301) MethodInliner fails with "AssertionError: <init> call doesn't correspond to object transformation info" for qualified this in SAM constructor used as parameter of anonymous object inside inline lambda
|
||||
- [`KT-35419`](https://youtrack.jetbrains.com/issue/KT-35419) `Failed to generate expression: KtNamedFunction` for local suspend tailrec function with receiver
|
||||
- [`KT-35511`](https://youtrack.jetbrains.com/issue/KT-35511) VerifyError: "Bad type on operand stack" after reification
|
||||
- [`KT-35553`](https://youtrack.jetbrains.com/issue/KT-35553) Kotlin compiler generates methods that always have line number 1 for Inline Classes
|
||||
- [`KT-35725`](https://youtrack.jetbrains.com/issue/KT-35725) "AssertionError: Couldn't find a context for a super-call" for `super` member call in property initializer of companion object
|
||||
- [`KT-36420`](https://youtrack.jetbrains.com/issue/KT-36420) ClassCastException with inline class Foo extending generic Comparable<Foo>
|
||||
- [`KT-36713`](https://youtrack.jetbrains.com/issue/KT-36713) AnalyzerException: "Incompatible stack heights" with suspend and inline suspend functions
|
||||
- [`KT-36794`](https://youtrack.jetbrains.com/issue/KT-36794) Move $assertionsDisabled field to the top-level class
|
||||
- [`KT-36853`](https://youtrack.jetbrains.com/issue/KT-36853) IR: UninitializedPropertyAccessException on tailrec with object expression in default argument
|
||||
- [`KT-36875`](https://youtrack.jetbrains.com/issue/KT-36875) "RuntimeException: Trying to access skipped parameter" on synthetic local variable access from inline function
|
||||
- [`KT-36916`](https://youtrack.jetbrains.com/issue/KT-36916) AnalyzerException: Argument 1: expected I, but found R when using inline class with rxjava
|
||||
- [`KT-36957`](https://youtrack.jetbrains.com/issue/KT-36957) Exception during codegen: cannot pop operand off an empty stack (Nothing variable in string interpolation)
|
||||
- [`KT-36984`](https://youtrack.jetbrains.com/issue/KT-36984) SAM adapter classes should be generated as anonymous inner classes in JVM_IR
|
||||
- [`KT-37704`](https://youtrack.jetbrains.com/issue/KT-37704) Incorrect SMAP syntax
|
||||
- [`KT-37716`](https://youtrack.jetbrains.com/issue/KT-37716) "AssertionError: <init> call doesn't correspond to object transformation info" with inline reified type parameter, anonymous object and lambda in constructor call
|
||||
- [`KT-37972`](https://youtrack.jetbrains.com/issue/KT-37972) IllegalAccessError on initializing property reference for a property declared in JvmMultifileClass with -Xmultifile-parts-inherit
|
||||
- [`KT-38100`](https://youtrack.jetbrains.com/issue/KT-38100) Support local delegated properties (not inlined) in new JVM default modes
|
||||
- [`KT-38833`](https://youtrack.jetbrains.com/issue/KT-38833) JVM: java.lang.ClassCastException when loop variable is nullable in for loop over unsigned progression
|
||||
- [`KT-38849`](https://youtrack.jetbrains.com/issue/KT-38849) Read-only variable initialized in non-inline lambda using contract callsInPlace EXACTLY_ONCE is not captured correctly in nested lambdas
|
||||
- [`KT-38869`](https://youtrack.jetbrains.com/issue/KT-38869) JVM BE produces invalid bytecode when inheriting from AbstractList and declaring methods that look like MutableList implementors (but they aren't)
|
||||
- [`KT-38965`](https://youtrack.jetbrains.com/issue/KT-38965) "UnsupportedOperationException: Don't know how to generate outer expression: Closure" with reference to local variable in block argument of anonymous object `by` delegation
|
||||
- [`KT-39289`](https://youtrack.jetbrains.com/issue/KT-39289) CCE in if-else inside annotated 'if' statement
|
||||
- [`KT-39425`](https://youtrack.jetbrains.com/issue/KT-39425) AbstractMethodError: "Receiver class does not define or inherit an implementation of the resolved method" using classes with complex Java and Kotlin inheritance hierarchies.
|
||||
- [`KT-39434`](https://youtrack.jetbrains.com/issue/KT-39434) IllegalAccessError with local delegated property in lambda in inlined function
|
||||
- [`KT-39687`](https://youtrack.jetbrains.com/issue/KT-39687) "Couldn't find captured this" when more than 3 inline functions are nested
|
||||
- [`KT-39784`](https://youtrack.jetbrains.com/issue/KT-39784) "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by JvmOverloads annotation inside an inline class
|
||||
- [`KT-40165`](https://youtrack.jetbrains.com/issue/KT-40165) ClassCastException caused by SAM conversion used on a functional interface with suspended function
|
||||
- [`KT-40179`](https://youtrack.jetbrains.com/issue/KT-40179) "VerifyError: Bad type on operand stack" with parent class `get` extension function and child class `set` extension function which used inside child class `plusAssign` extension function
|
||||
- [`KT-40277`](https://youtrack.jetbrains.com/issue/KT-40277) Fix generic types in special bridge methods
|
||||
- [`KT-40308`](https://youtrack.jetbrains.com/issue/KT-40308) NoSuchFieldError for multiple delegated extension properties with the same name in a companion object
|
||||
- [`KT-40338`](https://youtrack.jetbrains.com/issue/KT-40338) NoSuchFieldError on property without backing field that is called as function reference
|
||||
- [`KT-40392`](https://youtrack.jetbrains.com/issue/KT-40392) Deprecate JvmDefault annotation and old -Xjvm-default modes
|
||||
- [`KT-40396`](https://youtrack.jetbrains.com/issue/KT-40396) NI: Exceptions when ambiguous type argument and generic invoke
|
||||
- [`KT-40510`](https://youtrack.jetbrains.com/issue/KT-40510) "AssertionError: DELEGATION slice must override something" for ByteBuffer delegation
|
||||
- [`KT-40601`](https://youtrack.jetbrains.com/issue/KT-40601) VerifyError: "interface method reference is in an indirect superinterface" when calling @JvmDefault suspend method
|
||||
- [`KT-40809`](https://youtrack.jetbrains.com/issue/KT-40809) "Couldn't find captured field" compiler error with local function with recursive call through method reference
|
||||
- [`KT-41056`](https://youtrack.jetbrains.com/issue/KT-41056) Increase stub version due to new "contract" keyword
|
||||
- [`KT-41105`](https://youtrack.jetbrains.com/issue/KT-41105) IllegalStateException: 'Couldn't find declaration file <class name>' with inline delegate declared in another file
|
||||
- [`KT-41165`](https://youtrack.jetbrains.com/issue/KT-41165) "IllegalStateException: Concrete fake override public final fun" when an enum class inherits an interface with a variable 'name' or 'ordinal'
|
||||
- [`KT-41222`](https://youtrack.jetbrains.com/issue/KT-41222) "IllegalStateException: Concrete fake override public final fun" when a class property is inherited as merged 'var' from 'val' and 'var' from parent abstract class and interface properties
|
||||
- [`KT-41255`](https://youtrack.jetbrains.com/issue/KT-41255) JDK 11: "VerifyError: Bad type on operand stack" with long function body with annotated `when` expression
|
||||
- [`KT-41427`](https://youtrack.jetbrains.com/issue/KT-41427) NoSuchMethodError caused by implementation by delegation to function reference
|
||||
- [`KT-41508`](https://youtrack.jetbrains.com/issue/KT-41508) ClassNotFoundException caused by object with overridden function inside a lambda with safe cast receiver
|
||||
- [`KT-41750`](https://youtrack.jetbrains.com/issue/KT-41750) Inline classes: ClassCastExceptionError when calling .withIndex() on Iterator over Array
|
||||
- [`KT-41758`](https://youtrack.jetbrains.com/issue/KT-41758) Deprecate kotlin.Metadata.bytecodeVersion and avoid using it in the compiler
|
||||
- [`KT-41770`](https://youtrack.jetbrains.com/issue/KT-41770) AssertionError: "Asm parameter types should be the same length as Kotlin parameter types" cause by fun interface
|
||||
- [`KT-41874`](https://youtrack.jetbrains.com/issue/KT-41874) "IllegalStateException: Couldn't obtain compiled function body" on extension delegated property with inline operator getValue in a different file
|
||||
- [`KT-41917`](https://youtrack.jetbrains.com/issue/KT-41917) [FIR] Incorrect calculating property type for override from intersection scope
|
||||
- [`KT-42012`](https://youtrack.jetbrains.com/issue/KT-42012) IllegalAccess to protected field instead of getter
|
||||
- [`KT-42017`](https://youtrack.jetbrains.com/issue/KT-42017) "AssertionError: Unsigned type expected: UInt?" during codegen when a variable of nullable unsigned type is checking for presence in the range
|
||||
- [`KT-42032`](https://youtrack.jetbrains.com/issue/KT-42032) "AnalyzerException: Expected I, but found R" while using Flow.reduce() with suspend function reference
|
||||
- [`KT-42034`](https://youtrack.jetbrains.com/issue/KT-42034) ArrayIndexOutOfBoundsException in PopBackwardPropagationTransformer on external override of function in inline class
|
||||
- [`KT-42064`](https://youtrack.jetbrains.com/issue/KT-42064) "Parameter specified as non-null is null" with default value of the parameter in operator fun
|
||||
- [`KT-42069`](https://youtrack.jetbrains.com/issue/KT-42069) JVM IR: -Xreport-output-files doesn't report any source files for META-INF/*.kotlin_module files
|
||||
- [`KT-42083`](https://youtrack.jetbrains.com/issue/KT-42083) AbstractMethodError when 'remove' with irrelevant generic parameter but matching JVM signature is present in Kotlin collection class
|
||||
- [`KT-42092`](https://youtrack.jetbrains.com/issue/KT-42092) JVM / IR: "AnalyzerException: Argument 1: expected R, but found J" when trying to add to ArrayList the result of a function applied to int
|
||||
- [`KT-42175`](https://youtrack.jetbrains.com/issue/KT-42175) Psi2ir: "AssertionError: Undefined parameter referenced: <this>" on augmented assignment on this in a BuilderInference lambda
|
||||
- [`KT-42179`](https://youtrack.jetbrains.com/issue/KT-42179) Platform declaration clash when extending abstract Java class implementing 'java.util.Collection' by abstract Kotlin class implementing Kotlin Set or List
|
||||
- [`KT-42321`](https://youtrack.jetbrains.com/issue/KT-42321) JVM IR: do not cast integer value based on the type of a literal receiver of an operator call
|
||||
- [`KT-42337`](https://youtrack.jetbrains.com/issue/KT-42337) NoSuchMethodError in JVM backend with inheritance of private functions in the interface
|
||||
- [`KT-42404`](https://youtrack.jetbrains.com/issue/KT-42404) "Supertypes of the following classes cannot be resolved" in Rider project
|
||||
- [`KT-42472`](https://youtrack.jetbrains.com/issue/KT-42472) No TYPE_INFERENCE_UPPER_BOUND_VIOLATED for Delegated Properties do not check types (in Kotlin 1.4.10)
|
||||
- [`KT-42487`](https://youtrack.jetbrains.com/issue/KT-42487) "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by USELESS_IS_CHECK of Double type
|
||||
- [`KT-42533`](https://youtrack.jetbrains.com/issue/KT-42533) `(N until MIN_VALUE).reversed()` should be an empty progression in for loops
|
||||
- [`KT-42588`](https://youtrack.jetbrains.com/issue/KT-42588) "IllegalStateException: Concrete fake override public open fun" caused by `val` override with `var` with delegation.
|
||||
- [`KT-42634`](https://youtrack.jetbrains.com/issue/KT-42634) Different bridges and abstract stubs behavior in abstract class implementing Map<K, String> in JVM and JVM_IR
|
||||
- [`KT-42635`](https://youtrack.jetbrains.com/issue/KT-42635) ClassCastException with inline class in for loop
|
||||
- [`KT-42662`](https://youtrack.jetbrains.com/issue/KT-42662) AbstractMethodError when using partially specialized generic Map class
|
||||
- [`KT-42694`](https://youtrack.jetbrains.com/issue/KT-42694) @get:Synchronized causes the JVM getter method not to be generated
|
||||
- [`KT-42753`](https://youtrack.jetbrains.com/issue/KT-42753) "VerifyError: Bad invokespecial instruction: interface method reference is in an indirect superinterface" with `jvm-default=all`
|
||||
- [`KT-42879`](https://youtrack.jetbrains.com/issue/KT-42879) JVM: Declaration clash in fun interface implementation returning an inline class
|
||||
- [`KT-42900`](https://youtrack.jetbrains.com/issue/KT-42900) "VerifyError: Bad return type" incorrect bytecode when a property and an extension property in inline class have the same names
|
||||
- [`KT-42946`](https://youtrack.jetbrains.com/issue/KT-42946) FIR2IR: Fix super-calls to Java overrides of special built-in
|
||||
- [`KT-42971`](https://youtrack.jetbrains.com/issue/KT-42971) JVM: "AssertionError: Unsigned type expected: T" with UInt loop range
|
||||
- [`KT-42990`](https://youtrack.jetbrains.com/issue/KT-42990) "AssertionError: Next value after NEW should be one generated by DUP" caused by extension properties with accessors annotataed as @JvmStatic
|
||||
- [`KT-43034`](https://youtrack.jetbrains.com/issue/KT-43034) AssertionError: Compiler fails with complicated tailrec + inline case
|
||||
- [`KT-43048`](https://youtrack.jetbrains.com/issue/KT-43048) JVM_IR: Implement coroutines state clearing
|
||||
- [`KT-43050`](https://youtrack.jetbrains.com/issue/KT-43050) JVM IR: incorrect mangling for method with type parameter with inline class bound in the signature
|
||||
- [`KT-43059`](https://youtrack.jetbrains.com/issue/KT-43059) Different bridges behavior in class implementing Map<String, String> in JVM and JVM_IR
|
||||
- [`KT-43063`](https://youtrack.jetbrains.com/issue/KT-43063) Redundant DefaultImpls delegate is generated in old JVM backend on explicit "duplicate" inheritance from interface
|
||||
- [`KT-43069`](https://youtrack.jetbrains.com/issue/KT-43069) JVM: incorrect generic signature for method with implicit return type Nothing overriding a method from Collection
|
||||
- [`KT-43099`](https://youtrack.jetbrains.com/issue/KT-43099) Tailrec call in not tail-call position leads to internal compiler error
|
||||
- [`KT-43106`](https://youtrack.jetbrains.com/issue/KT-43106) JVM: custom `remove` in Iterator subclass results in a synthetic bridge
|
||||
- [`KT-43120`](https://youtrack.jetbrains.com/issue/KT-43120) JVM: "Expected an object reference, but found ." caused by function which is passed as reference to suspend parameter
|
||||
- [`KT-43167`](https://youtrack.jetbrains.com/issue/KT-43167) JVM IR, serialization: "No mapping for symbol: VALUE_PARAMETER INSTANCE_RECEIVER" with data class containing property defined in body
|
||||
- [`KT-43255`](https://youtrack.jetbrains.com/issue/KT-43255) Verify error when inheriting from an abstract class implementing Collection with stub-like method in superclass
|
||||
- [`KT-43303`](https://youtrack.jetbrains.com/issue/KT-43303) NI: False negative TYPE_INFERENCE_UPPER_BOUND_VIOLATED when inferred type argument is not a subtype of type parameter upper bound
|
||||
- [`KT-43333`](https://youtrack.jetbrains.com/issue/KT-43333) AbstractMethodError when calling 'toArray' from Java on a Kotlin Collection with custom internal 'toArray'
|
||||
- [`KT-43334`](https://youtrack.jetbrains.com/issue/KT-43334) AbstractMethodError when calling 'remove' from Java on a Kotlin Collection with custom internal 'remove'
|
||||
- [`KT-43342`](https://youtrack.jetbrains.com/issue/KT-43342) [FIR2IR] No getter or backing field found for delegated member call
|
||||
- [`KT-43347`](https://youtrack.jetbrains.com/issue/KT-43347) [FIR] Synthetic setter with unmatched parameter type isn't found
|
||||
- [`KT-43401`](https://youtrack.jetbrains.com/issue/KT-43401) JVM_IR. Additional `synchronized` flag on JvmOverloads-generated adapter for Synchronized function
|
||||
- [`KT-43405`](https://youtrack.jetbrains.com/issue/KT-43405) Turkish locale, Linux Mint: "NoSuchMethodError: 'int[] kotlin.jvm.internal.Intrinsics$Kotlin.intArrayOf(int[])'" with `intArrayOf` function call
|
||||
- [`KT-43460`](https://youtrack.jetbrains.com/issue/KT-43460) JVM: redundant private setter is generated in case of multifile facade
|
||||
- [`KT-43473`](https://youtrack.jetbrains.com/issue/KT-43473) "VerifyError: Bad type on operand stack" caused by operator `get` with optional argument in superclass when called via square brackets on subclass
|
||||
- [`KT-43518`](https://youtrack.jetbrains.com/issue/KT-43518) JVM_IR. Additional `strictfp` flag on JvmOverloads-generated adapter for Strictfp function
|
||||
- [`KT-43569`](https://youtrack.jetbrains.com/issue/KT-43569) FIR: inapplicable candidate(s): kotlin/collections/set
|
||||
- [`KT-43616`](https://youtrack.jetbrains.com/issue/KT-43616) [FIR] Nullable type parameter-based type after merge in if
|
||||
- [`KT-43669`](https://youtrack.jetbrains.com/issue/KT-43669) FIR: No real overrides for FUN IR_EXTERNAL_DECLARATION_STUB
|
||||
- [`KT-43682`](https://youtrack.jetbrains.com/issue/KT-43682) Inline extension method of a multifile library inline class not found
|
||||
- [`KT-43687`](https://youtrack.jetbrains.com/issue/KT-43687) FIR: UnusedChecker does not take annotation arguments into account
|
||||
- [`KT-43688`](https://youtrack.jetbrains.com/issue/KT-43688) FIR: unused checker doesn't handle invokes properly
|
||||
- [`KT-43749`](https://youtrack.jetbrains.com/issue/KT-43749) "UnsupportedOperationException: Don't know how to generate outer expression: Closure" caused by Flow and collect method with function reference as a parameter
|
||||
- [`KT-43812`](https://youtrack.jetbrains.com/issue/KT-43812) JVM IR: SAM wrapper class with generic supertype mentions missing type parameter in the signature
|
||||
- [`KT-43832`](https://youtrack.jetbrains.com/issue/KT-43832) JVM IR: missing bridges for inheritance of class from interface in a complex generic diamond hierarchy
|
||||
- [`KT-43851`](https://youtrack.jetbrains.com/issue/KT-43851) JVM IR: function call returning object instance is removed during constant propagation
|
||||
- [`KT-43864`](https://youtrack.jetbrains.com/issue/KT-43864) JVM: "Assertion error after mandatory stack transformations: incorrect bytecode" with lateinit property of type T, which has a primitive type upperbound
|
||||
- [`KT-43887`](https://youtrack.jetbrains.com/issue/KT-43887) Problem with FunctionReferenceLowering$FunctionReferenceBuilder in kotlin native
|
||||
- [`KT-43912`](https://youtrack.jetbrains.com/issue/KT-43912) JVM internal error: Augment assignment and increment are not supported for local delegated properties and inline properties
|
||||
- [`KT-43915`](https://youtrack.jetbrains.com/issue/KT-43915) Back-end (JVM) Internal error: wrong bytecode generated for default method
|
||||
- [`KT-43938`](https://youtrack.jetbrains.com/issue/KT-43938) NSME when calling 'kotlin.Number' methods on instance of Java class extending Kolin abstract class extending 'kotlin.Number'
|
||||
- [`KT-43942`](https://youtrack.jetbrains.com/issue/KT-43942) org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Failed to generate function
|
||||
- [`KT-43949`](https://youtrack.jetbrains.com/issue/KT-43949) FIR: unresolved callable reference as lambda return
|
||||
- [`KT-43983`](https://youtrack.jetbrains.com/issue/KT-43983) IllegalStateException: "Couldn't obtain compiled function body for public final suspend inline fun" after moving inline extension function to library
|
||||
- [`KT-43984`](https://youtrack.jetbrains.com/issue/KT-43984) FIR: recursion in overridden symbols
|
||||
- [`KT-43984`](https://youtrack.jetbrains.com/issue/KT-43984) FIR: recursion in overridden symbols
|
||||
- [`KT-44010`](https://youtrack.jetbrains.com/issue/KT-44010) FIR: Inapplicable constructor due to an unresolved reference
|
||||
- [`KT-44030`](https://youtrack.jetbrains.com/issue/KT-44030) FIR2IR: uncached type parameters in delegated property
|
||||
- [`KT-44032`](https://youtrack.jetbrains.com/issue/KT-44032) FIR2IR: uncached type parameters in Java field
|
||||
- [`KT-44050`](https://youtrack.jetbrains.com/issue/KT-44050) FIR: anonymous object as IR parent
|
||||
- [`KT-44054`](https://youtrack.jetbrains.com/issue/KT-44054) FIR2IR: incorrect IR origin for substituted override function
|
||||
- [`KT-44058`](https://youtrack.jetbrains.com/issue/KT-44058) CompilationException: open suspend fun with @JvmStatic in open class companion
|
||||
- [`KT-44069`](https://youtrack.jetbrains.com/issue/KT-44069) please remove deprecated usages
|
||||
- [`KT-44066`](https://youtrack.jetbrains.com/issue/KT-44066) FIR Java: override ambiguity with vararg value type
|
||||
- [`KT-44114`](https://youtrack.jetbrains.com/issue/KT-44114) CompilationException when inlining a extension suspend function declared in interface companion with 'this' reference to extension receiver
|
||||
- [`KT-44131`](https://youtrack.jetbrains.com/issue/KT-44131) "UnsupportedOperationException: Don't know how to generate outer expression: Closure" when using suspend lambda and a function reference
|
||||
- [`KT-44140`](https://youtrack.jetbrains.com/issue/KT-44140) JVM IR: compilation of kotlin.Result crashes with IOOBE while generating toString-impl
|
||||
- [`KT-44141`](https://youtrack.jetbrains.com/issue/KT-44141) JVM IR: "ISE: There should be underlying type for inline class type" on usage of type parameter with Result upper bound inside a lambda
|
||||
- [`KT-44192`](https://youtrack.jetbrains.com/issue/KT-44192) Allow a greater number of constants in an enum class
|
||||
- [`KT-44202`](https://youtrack.jetbrains.com/issue/KT-44202) "ClassCastException" when getting delegated property with inline class and Any/Any? type
|
||||
- [`KT-44210`](https://youtrack.jetbrains.com/issue/KT-44210) KJS / IR: "AssertionError: Undefined parameter referenced: <this> defined" caused by plus assign operators in build blocks
|
||||
- [`KT-44233`](https://youtrack.jetbrains.com/issue/KT-44233) [IR] Collection Stub generation not correctly considering java.util Collection iterators
|
||||
- [`KT-44234`](https://youtrack.jetbrains.com/issue/KT-44234) Private companion property with explicit setter generates invalid bytecode
|
||||
- [`KT-44269`](https://youtrack.jetbrains.com/issue/KT-44269) "[TAILREC_ON_VIRTUAL_MEMBER_ERROR] Tailrec is not allowed on open members" with Spring annotation and private tailrec function
|
||||
- [`KT-44284`](https://youtrack.jetbrains.com/issue/KT-44284) Make Kotlin binaries publicly unavailable (set KotlinCompilerVersion.IS_PRE_RELEASE = true)
|
||||
- [`KT-44316`](https://youtrack.jetbrains.com/issue/KT-44316) ReenteringLazyValueComputationException when analyzing complex lazy delegate
|
||||
- [`KT-44347`](https://youtrack.jetbrains.com/issue/KT-44347) Back-end (JVM) Internal error: Couldn't transform method node for suspend function with wrong local for Continuation
|
||||
- [`KT-44368`](https://youtrack.jetbrains.com/issue/KT-44368) "IllegalStateException: Error type encountered" when inlining 'invoke' operator without enough information on type variable
|
||||
- [`KT-44412`](https://youtrack.jetbrains.com/issue/KT-44412) JVM IR backend fails to compile break in condition of do while
|
||||
- [`KT-44420`](https://youtrack.jetbrains.com/issue/KT-44420) False NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATION with 1.4.30-RC
|
||||
- [`KT-44429`](https://youtrack.jetbrains.com/issue/KT-44429) JVM IR: unnecessary integer unboxing leads to NPE when using mockito-kotlin
|
||||
- [`KT-44439`](https://youtrack.jetbrains.com/issue/KT-44439) Type inference of generic types failing java interop
|
||||
- [`KT-44440`](https://youtrack.jetbrains.com/issue/KT-44440) Too many Nothings in inferred type
|
||||
- [`KT-44471`](https://youtrack.jetbrains.com/issue/KT-44471) Fix failing script tests after switching to 1.5
|
||||
- [`KT-44474`](https://youtrack.jetbrains.com/issue/KT-44474) Compiler expects sealed type inheritors from platform specific source-sets in when expression in common source-set
|
||||
- [`KT-44483`](https://youtrack.jetbrains.com/issue/KT-44483) JVM IR: CCE on calling generic vararg function reference with Array expected type
|
||||
- [`KT-44527`](https://youtrack.jetbrains.com/issue/KT-44527) Suspend function with kotlin.Result: ClassCastException class kotlin.Result cannot be cast to class ...
|
||||
- [`KT-44529`](https://youtrack.jetbrains.com/issue/KT-44529) Inline class calls wrong iterator method in for loop
|
||||
- [`KT-44533`](https://youtrack.jetbrains.com/issue/KT-44533) JVM IR: ClassFormatError on synthetic $suspendImpl method generated in interface for a @JvmDefault function
|
||||
- [`KT-44540`](https://youtrack.jetbrains.com/issue/KT-44540) Regression in 1.4.30 in intellij-community: type mismatch for generic function call with generic Java class
|
||||
- [`KT-44546`](https://youtrack.jetbrains.com/issue/KT-44546) NI: changed variable fixation order (that can lead to changed resolution)
|
||||
- [`KT-44550`](https://youtrack.jetbrains.com/issue/KT-44550) KotlinBinaryClassCache leaks Kotlin plugin classloader on plugin unload
|
||||
- [`KT-44563`](https://youtrack.jetbrains.com/issue/KT-44563) Type Inference loosing type annotations in lambda type expectation for function calls with block parameters
|
||||
- [`KT-44583`](https://youtrack.jetbrains.com/issue/KT-44583) "Supertypes of the following classes cannot be resolved" error message gives no context
|
||||
- [`KT-44627`](https://youtrack.jetbrains.com/issue/KT-44627) JVM IR: ACCIDENTAL_OVERRIDE when overriding a generic field where the type parameter has a primitive bound
|
||||
- [`KT-44631`](https://youtrack.jetbrains.com/issue/KT-44631) "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by a default param in inner class constructor which uses method or field from receiver
|
||||
- [`KT-44647`](https://youtrack.jetbrains.com/issue/KT-44647) "IllegalAccessError: class TestKt tried to access private method" with String Builder `get` and `inc` operator
|
||||
- [`KT-44651`](https://youtrack.jetbrains.com/issue/KT-44651) JVM / IR: "IllegalStateException: Illegal type substitutor" with if-else inside class constructor argument inside another if-else
|
||||
- [`KT-44660`](https://youtrack.jetbrains.com/issue/KT-44660) Internal inline functions in companion object with inline class return type fails compilation
|
||||
- [`KT-44671`](https://youtrack.jetbrains.com/issue/KT-44671) JVM_IR: ClassCastException: Result$Failure cannot be cast to Result with multithreaded coroutines
|
||||
- [`KT-44703`](https://youtrack.jetbrains.com/issue/KT-44703) JVM / IR: "IllegalStateException: Unhandled special name in mangledNameFor" caused by a reference to inline class inside interface's companion with lazy initialization
|
||||
- [`KT-44712`](https://youtrack.jetbrains.com/issue/KT-44712) JVM / IR: Behavior change after enabling with Mockito
|
||||
- [`KT-44714`](https://youtrack.jetbrains.com/issue/KT-44714) Debugger / Coroutines: Local variables are trimmed out too aggressively
|
||||
- [`KT-44722`](https://youtrack.jetbrains.com/issue/KT-44722) JVM IR: ClassCastException with inline class, let and bound function reference
|
||||
- [`KT-44726`](https://youtrack.jetbrains.com/issue/KT-44726) JVM IR: Incorrect KType nullability for platform type reified as non-null
|
||||
- [`KT-44781`](https://youtrack.jetbrains.com/issue/KT-44781) JVM IR: java.lang.NoSuchFieldError: $noName_0 when calling a crossinline lambda within a suspending lambda
|
||||
- [`KT-44798`](https://youtrack.jetbrains.com/issue/KT-44798) JVM IR: Inherited platform declarations clash for class implementing both List and Set
|
||||
- [`KT-44801`](https://youtrack.jetbrains.com/issue/KT-44801) 1.4.30 JVM IR: Unbound symbols not allowed with anonymous object
|
||||
- [`KT-44803`](https://youtrack.jetbrains.com/issue/KT-44803) FIR bootstrap: incorrect nullability is set for type alias-based type
|
||||
- [`KT-44827`](https://youtrack.jetbrains.com/issue/KT-44827) Non-existing outer class is written in anonymous class for SAM wrapper in inline lambda with capture
|
||||
- [`KT-44837`](https://youtrack.jetbrains.com/issue/KT-44837) JVM / IR: ClassCastException with Result object when it is used by a generic method in a suspend call
|
||||
- [`KT-44875`](https://youtrack.jetbrains.com/issue/KT-44875) JVM_IR. `hashCode` call is generated on interface target in fun interface equality
|
||||
- [`KT-44878`](https://youtrack.jetbrains.com/issue/KT-44878) JVM_IR: "IllegalStateException: Unexpected types" when checking non-nullable variable is `in` range between nullable ones with smart-cast
|
||||
- [`KT-44926`](https://youtrack.jetbrains.com/issue/KT-44926) MPP: Actual typealias to compiled inline class incompatible with expect inline class
|
||||
- [`KT-44947`](https://youtrack.jetbrains.com/issue/KT-44947) Sealed interfaces: Sealed fun interface leads to "NoWhenBranchMatchedException"
|
||||
- [`KT-44993`](https://youtrack.jetbrains.com/issue/KT-44993) JVM IR: VerifyError on getfield with Kotlin generic field and elvis operator
|
||||
- [`KT-45008`](https://youtrack.jetbrains.com/issue/KT-45008) JVM IR: hashCode is generated as invokeinterface if smart cast to interface is present
|
||||
- [`KT-45011`](https://youtrack.jetbrains.com/issue/KT-45011) JVM / IR: "AssertionError: Unbound symbols not allowed"
|
||||
- [`KT-45022`](https://youtrack.jetbrains.com/issue/KT-45022) IR: "AssertionError: Undefined variable referenced" from psi2ir caused by plusAssign operator of object
|
||||
- [`KT-45064`](https://youtrack.jetbrains.com/issue/KT-45064) JVM IR: "java.lang.AssertionError: SyntheticAccessorLowering should not attempt to modify other files!" with member reference to property in another file with private setter
|
||||
- [`KT-45067`](https://youtrack.jetbrains.com/issue/KT-45067) "IllegalArgumentException: Wildcard mast have a bound for annotation of WILDCARD_BOUND position" with BEAM SDK 2.27
|
||||
- [`KT-45069`](https://youtrack.jetbrains.com/issue/KT-45069) JVM / IR: New SAM conversions mode fails when converting from Unit to Any
|
||||
- [`KT-45131`](https://youtrack.jetbrains.com/issue/KT-45131) JVM / IR: "RuntimeException: Lambda, SAM or anonymous object should have only one constructor" caused by inline class that type cast to reified type parameter inside lambda in inline function
|
||||
- [`KT-45139`](https://youtrack.jetbrains.com/issue/KT-45139) Inline class: AssertionError: Expected top level inline class
|
||||
- [`KT-45166`](https://youtrack.jetbrains.com/issue/KT-45166) JVM / IR: "AbstractMethodError: Receiver class does not define or inherit an implementation of the resolved method of interface" caused by interface with suspend function
|
||||
- [`KT-45187`](https://youtrack.jetbrains.com/issue/KT-45187) JVM / IR: ClassCastException caused by substituting generic type of vararg parameter with java.lang.Void
|
||||
- [`KT-45195`](https://youtrack.jetbrains.com/issue/KT-45195) JVM IR: annotation methods are generated as default interface methods if `allopen` is used
|
||||
- [`KT-45243`](https://youtrack.jetbrains.com/issue/KT-45243) "IllegalStateException: Lambdas shouldn't be visited by ESExpressionVisitor" caused by lambda inside `kotlin.test.assertNotNull`
|
||||
- [`KT-45259`](https://youtrack.jetbrains.com/issue/KT-45259) JVM: ClassCastException caused by Result as lambda parameter type
|
||||
- [`KT-45292`](https://youtrack.jetbrains.com/issue/KT-45292) AssertionError with recursive inline extension property
|
||||
- [`KT-45300`](https://youtrack.jetbrains.com/issue/KT-45300) Deprecate super calls in public-api inline functions
|
||||
- [`KT-45409`](https://youtrack.jetbrains.com/issue/KT-45409) Rename jspecify annotations’ package and default not null annotation
|
||||
- [`KT-45446`](https://youtrack.jetbrains.com/issue/KT-45446) JVM / IR: NullPointerException caused by unreachable code and comparison
|
||||
- [`KT-45721`](https://youtrack.jetbrains.com/issue/KT-45721) JVM / IR: "Unbound symbols not allowed" caused by class reference in sequence lambda
|
||||
- [`KT-45853`](https://youtrack.jetbrains.com/issue/KT-45853) JVM / IR: "Accidental override" caused by inheriting Throwable.getCause from Java interface
|
||||
- [`KT-45861`](https://youtrack.jetbrains.com/issue/KT-45861) Turning warnings into errors for calls with type parameters annotated by @OnlyInputTypes
|
||||
- [`KT-45865`](https://youtrack.jetbrains.com/issue/KT-45865) JVM IR: "VerifyError: Bad type on operand stack" with `enumValueOf` on a value from a list of strings
|
||||
- [`KT-45868`](https://youtrack.jetbrains.com/issue/KT-45868) JVM IR: ClassCastException with SAM function in init block when SAM is generated via invokedynamic
|
||||
- [`KT-45920`](https://youtrack.jetbrains.com/issue/KT-45920) JVM IR: "Accidental override" on redefining `get()` in custom Map class
|
||||
- [`KT-45934`](https://youtrack.jetbrains.com/issue/KT-45934) JVM IR: "java.lang.IllegalStateException: Function has no body" for class implementing interface by delegation
|
||||
- [`KT-45945`](https://youtrack.jetbrains.com/issue/KT-45945) JVM / IR: "AssertionError: Unexpected variance in super type argument" with contravariance and intersection types
|
||||
- [`KT-45963`](https://youtrack.jetbrains.com/issue/KT-45963) JVM / IR: "AbstractMethodError: Receiver class does not define or inherit an implementation of the resolved method" in Dokka tests
|
||||
- [`KT-45967`](https://youtrack.jetbrains.com/issue/KT-45967) JVM IR: "IllegalAccessError" with invokedynamic to Java SAM over callable reference to private function
|
||||
- [`KT-45982`](https://youtrack.jetbrains.com/issue/KT-45982) Wrong subtyping result on captured types with postponed type variables
|
||||
- [`KT-46007`](https://youtrack.jetbrains.com/issue/KT-46007) JVM / IR: "ClassCastException: kotlin.Unit cannot be cast to java.lang.String" caused by default suspend function in interface
|
||||
- [`KT-46060`](https://youtrack.jetbrains.com/issue/KT-46060) JVM IR: NullPointerException from RangeContainsLowering when `contains` is a @JvmStatic function in object
|
||||
- [`KT-46069`](https://youtrack.jetbrains.com/issue/KT-46069) JVM IR: unbound type parameter on generic bound adapted function reference
|
||||
- [`KT-46092`](https://youtrack.jetbrains.com/issue/KT-46092) JVM IR: AssertionError "Array type expected: @[FlexibleNullability] kotlin.CharArray?" on super call to Java constructor with primitive vararg
|
||||
- [`KT-46104`](https://youtrack.jetbrains.com/issue/KT-46104) The message on inline -> value class migration should not say that inline classes are deprecated
|
||||
- [`KT-46131`](https://youtrack.jetbrains.com/issue/KT-46131) Kotlin 1.5.0-RC errors when reading class file
|
||||
- [`KT-46160`](https://youtrack.jetbrains.com/issue/KT-46160) JVM IR: IllegalAccessException at runtime for member reference to JvmMultifileClass member from stdlib
|
||||
- [`KT-46186`](https://youtrack.jetbrains.com/issue/KT-46186) Type inference regression in Kotlin 1.5 with constrained generic return types
|
||||
|
||||
### Docs & Examples
|
||||
|
||||
- [`KT-45884`](https://youtrack.jetbrains.com/issue/KT-45884) Incorrect description for JVM `toUpperCase` method
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-33233`](https://youtrack.jetbrains.com/issue/KT-33233) Use dependency of library to build built-ins in IDE, instead of loading them from the current classloader
|
||||
- [`KT-34023`](https://youtrack.jetbrains.com/issue/KT-34023) kotlin.KotlinNullPointerException at org.jetbrains.kotlin.backend.common.FunctionsFromAnyGenerator.getPrimaryConstructorProperties(FunctionsFromAnyGenerator.kt:66)
|
||||
- [`KT-35947`](https://youtrack.jetbrains.com/issue/KT-35947) KFunctionN.call is unresolved in IDE in Kotlin/JVM project
|
||||
- [`KT-37702`](https://youtrack.jetbrains.com/issue/KT-37702) Code analysis speed: on-the-fly analysis diagnostics reporting
|
||||
- [`KT-41048`](https://youtrack.jetbrains.com/issue/KT-41048) [FIR-IDE] Properly implement methods in KtFirPackageScope
|
||||
- [`KT-41671`](https://youtrack.jetbrains.com/issue/KT-41671) Missing nullability information in properties using type inference from get()
|
||||
- [`KT-43824`](https://youtrack.jetbrains.com/issue/KT-43824) KtLightClassForSourceDeclaration#isInheritor works in a different way than java implementation
|
||||
- [`KT-44128`](https://youtrack.jetbrains.com/issue/KT-44128) IDE: Kotlin JVM record has incorrect property accessors as seen from Java
|
||||
- [`KT-44487`](https://youtrack.jetbrains.com/issue/KT-44487) MPP, IDE: No error in IDE when sealed class inheritor from common source-set is not used in exhaustive when expression in platform source-set
|
||||
- [`KT-45254`](https://youtrack.jetbrains.com/issue/KT-45254) Highlighting for files with certain errors appears only on second opening
|
||||
- [`KT-46097`](https://youtrack.jetbrains.com/issue/KT-46097) Light classes: Incomplete nullability information for a getter method of a kotlin property defined in private constructor
|
||||
|
||||
### IDE. Decompiler, Indexing, Stubs
|
||||
|
||||
- [`KT-43699`](https://youtrack.jetbrains.com/issue/KT-43699) IDE: Unresolved extension method from Java code for simple class with typealias and generics (IllegalStateException: Unknown type parameter)
|
||||
- [`KT-44756`](https://youtrack.jetbrains.com/issue/KT-44756) Infinite "UpToDateStubIndexMismatch: PSI and index do not match." with IDEA 2021.1 EAP upon attempt to open "org.gradle.configurationcache" even they seem to be the same
|
||||
|
||||
### IDE. Gradle Integration
|
||||
|
||||
- [`KT-37127`](https://youtrack.jetbrains.com/issue/KT-37127) Implement precise importing of platforms of root source sets (commonMain/commonTest) when hierarchical multiplatform support is enabled
|
||||
- [`KT-42048`](https://youtrack.jetbrains.com/issue/KT-42048) KJS / Gradle integration: Could not determine the dependencies of task ':webApp:testPackageJson' in Android Studio 4.2 Canary 11
|
||||
|
||||
### IDE. Gradle. Script
|
||||
|
||||
- [`KT-46215`](https://youtrack.jetbrains.com/issue/KT-46215) Dead lock on closing project during the import in IJ211 through ScriptDefinitionsManager
|
||||
|
||||
### IDE. Inspections and Intentions
|
||||
|
||||
- [`KT-23824`](https://youtrack.jetbrains.com/issue/KT-23824) Return lifted out of if condition causes suspend tail call optimization to no longer apply
|
||||
- [`KT-38155`](https://youtrack.jetbrains.com/issue/KT-38155) Lift assignment out of 'if' produces type mismatch without manually adding a semicolon
|
||||
- [`KT-44821`](https://youtrack.jetbrains.com/issue/KT-44821) IDE: False positive NO_ELSE_IN_WHEN caused by sealed class and when in another module
|
||||
- [`KT-46088`](https://youtrack.jetbrains.com/issue/KT-46088) [IDEA] Incorrect behavior of replace inline class with value class intention
|
||||
|
||||
### IDE. Misc
|
||||
|
||||
- [`KT-44675`](https://youtrack.jetbrains.com/issue/KT-44675) Incorrect reference to resource into 202 plugin
|
||||
|
||||
### IDE. Refactorings
|
||||
|
||||
- [`KT-44079`](https://youtrack.jetbrains.com/issue/KT-44079) Sealed Interfaces: Move refactoring should warn about violation of hierarchy restrictions
|
||||
- [`KT-44839`](https://youtrack.jetbrains.com/issue/KT-44839) Sealed interfaces: move refactoring warnings works with "more freedom for sealed classes" rules for language level < 1.5
|
||||
|
||||
### IDE. Script
|
||||
|
||||
- [`KT-43288`](https://youtrack.jetbrains.com/issue/KT-43288) Allow push notifications about script configuration /dependencies changes via the `ScriptDefinitionsProvider` EP
|
||||
|
||||
### JavaScript
|
||||
|
||||
- [`KT-39272`](https://youtrack.jetbrains.com/issue/KT-39272) KJS / IR: Can't use javascript keywords as JsName
|
||||
- [`KT-41650`](https://youtrack.jetbrains.com/issue/KT-41650) JS IR BE: `default` should be a reserved identifier
|
||||
- [`KT-42176`](https://youtrack.jetbrains.com/issue/KT-42176) KJS / IR: Interface default method in sub-interface not resolved correctly from extension on super-interface
|
||||
- [`KT-44103`](https://youtrack.jetbrains.com/issue/KT-44103) [JSIR] TypeError when bumping from 1.4.20 to 1.4.30-M1
|
||||
- [`KT-44180`](https://youtrack.jetbrains.com/issue/KT-44180) KJS / IR: NPE in ConstTransformer of compileDevelopmentExecutableKotlinJs/compileProductionExecutableKotlinJs tasks
|
||||
- [`KT-44415`](https://youtrack.jetbrains.com/issue/KT-44415) Kotlin/JS with IR and kotlin-react: "too much recursion" error in runtime in browser
|
||||
- [`KT-44433`](https://youtrack.jetbrains.com/issue/KT-44433) KJS IR: support function interfaces with suspend member
|
||||
- [`KT-44469`](https://youtrack.jetbrains.com/issue/KT-44469) KJS / IR: Incorrect export functions with bridges
|
||||
- [`KT-44718`](https://youtrack.jetbrains.com/issue/KT-44718) MPP/ KJS: "IllegalStateException: Unsupported operation" with serialization plugin and incremental compilation
|
||||
- [`KT-44796`](https://youtrack.jetbrains.com/issue/KT-44796) KJS / IR: default parameter of function with @JsName leads to "RangeError: Maximum call stack size exceeded"
|
||||
- [`KT-45059`](https://youtrack.jetbrains.com/issue/KT-45059) KJS / IR: Add possibility for runtime diagnostics of DCE result
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-12109`](https://youtrack.jetbrains.com/issue/KT-12109) Add stdlib method that combines mapNotNull() and first/firstOrNull()
|
||||
- [`KT-25571`](https://youtrack.jetbrains.com/issue/KT-25571) Make random implementations serializable
|
||||
- [`KT-26234`](https://youtrack.jetbrains.com/issue/KT-26234) Floored division and remainder function for numeric types
|
||||
- [`KT-32996`](https://youtrack.jetbrains.com/issue/KT-32996) kotlin.test: add assertContentEquals for comparing content of arrays, iterables, sequences
|
||||
- [`KT-39177`](https://youtrack.jetbrains.com/issue/KT-39177) Make CharCategory available in common multiplatform code
|
||||
- [`KT-40225`](https://youtrack.jetbrains.com/issue/KT-40225) Support adding kotlin-test as a single dependency, as it should be with a multiplatform library
|
||||
- [`KT-42071`](https://youtrack.jetbrains.com/issue/KT-42071) Strict version of String.toBoolean()
|
||||
- [`KT-42720`](https://youtrack.jetbrains.com/issue/KT-42720) Kotlin ArrayDeque on JVM: provide optimized toArray method
|
||||
- [`KT-42840`](https://youtrack.jetbrains.com/issue/KT-42840) Commonize and generalize String.contentEquals that is currently JVM-only
|
||||
- [`KT-43772`](https://youtrack.jetbrains.com/issue/KT-43772) Kotlin/Native unfinished workers detected.
|
||||
- [`KT-44168`](https://youtrack.jetbrains.com/issue/KT-44168) Prevent storing NaN and negative zero in kotlin.time.Duration
|
||||
- [`KT-44369`](https://youtrack.jetbrains.com/issue/KT-44369) Commonize Char.titlecaseChar() and Char.titlecase() that are currently JVM-only
|
||||
- [`KT-44783`](https://youtrack.jetbrains.com/issue/KT-44783) Add IS_VALUE flag for value classes to kotlinx-metadata-jvm
|
||||
- [`KT-44815`](https://youtrack.jetbrains.com/issue/KT-44815) Remove kotlin-annotations-android and JVM compiler support for @ParameterName/@DefaultValue/@DefaultNull
|
||||
- [`KT-45213`](https://youtrack.jetbrains.com/issue/KT-45213) Update Unicode version used in K/N for Char and String case conversion functions
|
||||
|
||||
### Middle-end. IR
|
||||
|
||||
- [`KT-43831`](https://youtrack.jetbrains.com/issue/KT-43831) Compilation failed, IrSimpleFunctionPublicSymbolImpl is already bound
|
||||
- [`KT-44100`](https://youtrack.jetbrains.com/issue/KT-44100) KJS / IR: Top level declarations added in IR plugin are not referenceable from other modules
|
||||
- [`KT-45170`](https://youtrack.jetbrains.com/issue/KT-45170) IR: "AssertionError: Single expression value for GET_OBJECT" caused by inc operator of field inside scope function inside object
|
||||
|
||||
### Native
|
||||
|
||||
- [`KT-42446`](https://youtrack.jetbrains.com/issue/KT-42446) Native: SIGSEGV in Kotlin_Array_get on linuxArm64
|
||||
- [`KT-43502`](https://youtrack.jetbrains.com/issue/KT-43502) [K/N] relocation R_X86_64_PC32 cannot be used against symbol __environ; recompile with -fPIC
|
||||
- [`KT-44295`](https://youtrack.jetbrains.com/issue/KT-44295) 1.4.21 Kotlin native ndk compiler crash
|
||||
- [`KT-44774`](https://youtrack.jetbrains.com/issue/KT-44774) ld fails with CALL16 reloc at 0x48f00 not against global symbol (Linux MIPS)
|
||||
- [`KT-44746`](https://youtrack.jetbrains.com/issue/KT-44746) Different hashCode() results for Kotlin/Native stdlib
|
||||
|
||||
### Native. C and ObjC Import
|
||||
|
||||
- [`KT-44824`](https://youtrack.jetbrains.com/issue/KT-44824) cinterop tool no longer appends .klib to produced klibs
|
||||
|
||||
### Native. C Export
|
||||
|
||||
- [`KT-36639`](https://youtrack.jetbrains.com/issue/KT-36639) MPP: Build ios "staticLib" or "sharedLib" binary failed if interface contains member extension function
|
||||
- [`KT-41725`](https://youtrack.jetbrains.com/issue/KT-41725) Dynamic library doesn't load on raspberrypi
|
||||
|
||||
### Native. ObjC Export
|
||||
|
||||
- [`KT-44549`](https://youtrack.jetbrains.com/issue/KT-44549) In the Xcode debug session, call stack is missing a frame when the iOS app fails
|
||||
|
||||
### Native. Platforms
|
||||
|
||||
- [`KT-45094`](https://youtrack.jetbrains.com/issue/KT-45094) Fail to compile Kotlin Native sources under Oracle Linux 7
|
||||
|
||||
### Reflection
|
||||
|
||||
- [`KT-44594`](https://youtrack.jetbrains.com/issue/KT-44594) Avoid using unnecessary array types reflection in kotlin-reflect
|
||||
- [`KT-44782`](https://youtrack.jetbrains.com/issue/KT-44782) Add KClass.isValue to kotlin-reflect
|
||||
|
||||
### Tools. Ant
|
||||
|
||||
- [`KT-16227`](https://youtrack.jetbrains.com/issue/KT-16227) Ant task: do not include runtime by default if destination is a jar
|
||||
- [`KT-44293`](https://youtrack.jetbrains.com/issue/KT-44293) Support fork mode in kotlinc Ant task
|
||||
|
||||
### Tools. CLI
|
||||
|
||||
- [`KT-17344`](https://youtrack.jetbrains.com/issue/KT-17344) Include kotlin-reflect to resulting jar if "-include-runtime" is specified
|
||||
- [`KT-43220`](https://youtrack.jetbrains.com/issue/KT-43220) -include-runtime should add .kotlin_builtins to the output
|
||||
- [`KT-43704`](https://youtrack.jetbrains.com/issue/KT-43704) Illegal reflective access by com.intellij.util.ReflectionUtil to method java.util.ResourceBundle.setParent(java.util.ResourceBundle)
|
||||
- [`KT-44078`](https://youtrack.jetbrains.com/issue/KT-44078) Do not include module-info.class of kotlin-stdlib.jar to the resulting jar with -include-runtime
|
||||
- [`KT-44232`](https://youtrack.jetbrains.com/issue/KT-44232) CLI: do not pass -noverify to java process starting from JDK 13
|
||||
- [`KT-45566`](https://youtrack.jetbrains.com/issue/KT-45566) JDK 16 - e: java.lang.NoClassDefFoundError: Could not initialize class org.jetbrains.kotlin.com.intellij.pom.java.LanguageLevel
|
||||
|
||||
### Tools. CLI. Native
|
||||
|
||||
- [`KT-43874`](https://youtrack.jetbrains.com/issue/KT-43874) Native / CLI: provide a way to show difference between Jvm and Native compilers
|
||||
|
||||
### Tools. Compiler Plugins
|
||||
|
||||
- [`KT-45783`](https://youtrack.jetbrains.com/issue/KT-45783) Serialization: "AnalyzerException: Expected an object reference, but found I" caused by `JvmInline` and `Serializable` annotations
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-31027`](https://youtrack.jetbrains.com/issue/KT-31027) java.lang.NoSuchMethodError: No static method hashCode(Z)I in class Ljava/lang/Boolean; or its super classes (declaration of 'java.lang.Boolean' appears in /system/framework/core-libart.jar)
|
||||
- [`KT-43605`](https://youtrack.jetbrains.com/issue/KT-43605) Kotlin Gradle Plugin 1.4.20 undeclared system property reads cause problems with Gradle configuration cache enabled
|
||||
- [`KT-44204`](https://youtrack.jetbrains.com/issue/KT-44204) Kotlin Gradle Plugin 1.4.21 makes impossible to use ANTLR in other plugins
|
||||
- [`KT-44361`](https://youtrack.jetbrains.com/issue/KT-44361) Gradle: deprecate options includeRuntime, noStdlib, noReflect
|
||||
- [`KT-44462`](https://youtrack.jetbrains.com/issue/KT-44462) Kotlin Gradle plugin creates `compile` configuration with Gradle 7.0
|
||||
- [`KT-44834`](https://youtrack.jetbrains.com/issue/KT-44834) Gradle Kotlin DSL: Add `languageSettings` configuration lambda without `apply` call
|
||||
- [`KT-44949`](https://youtrack.jetbrains.com/issue/KT-44949) Compatibility with Gradle 7.0
|
||||
- [`KT-44957`](https://youtrack.jetbrains.com/issue/KT-44957) gradle - target.compilations seems to be deprecated
|
||||
- [`KT-45340`](https://youtrack.jetbrains.com/issue/KT-45340) Update minimal supported version of Kotlin Gradle Plugin to 6.1
|
||||
|
||||
### Tools. Gradle. JS
|
||||
|
||||
- [`KT-43237`](https://youtrack.jetbrains.com/issue/KT-43237) KJS: `-jsLegacy` Naming Convention is incompatible with NPM
|
||||
- [`KT-43869`](https://youtrack.jetbrains.com/issue/KT-43869) Error in webpack configuration not displayed
|
||||
- [`KT-44614`](https://youtrack.jetbrains.com/issue/KT-44614) Update Node.JS and Yarn versions
|
||||
- [`KT-44616`](https://youtrack.jetbrains.com/issue/KT-44616) Kotlin/JS: IR backend with React: "Uncaught TypeError: _this__0 is undefined" runtime error in browser
|
||||
- [`KT-45574`](https://youtrack.jetbrains.com/issue/KT-45574) Sync Kotlin/JS compile tasks into one folder (build/js/packages/<package>/kotlin)
|
||||
|
||||
### Tools. Gradle. Multiplatform
|
||||
|
||||
- [`KT-42098`](https://youtrack.jetbrains.com/issue/KT-42098) Commonizer is re-launched for every included Gradle build
|
||||
- [`KT-43116`](https://youtrack.jetbrains.com/issue/KT-43116) Merge together MultiplatformHighlightingTest and MultiplatformAnalysisTest
|
||||
- [`KT-44322`](https://youtrack.jetbrains.com/issue/KT-44322) KotlinTargetComponent maintenance for -sources.jar
|
||||
- [`KT-44900`](https://youtrack.jetbrains.com/issue/KT-44900) Support gradle configuration cache with kotlin.multiplatform plugin
|
||||
|
||||
### Tools. Gradle. Native
|
||||
|
||||
- [`KT-46122`](https://youtrack.jetbrains.com/issue/KT-46122) kotlinx-serialization and kotlinx-datetime can't be built with 1.5.0-RC
|
||||
|
||||
### Tools. JPS
|
||||
|
||||
- [`KT-13631`](https://youtrack.jetbrains.com/issue/KT-13631) Compilation fails on Turkish locale because of locale-sensitive uppercasing
|
||||
- [`KT-44644`](https://youtrack.jetbrains.com/issue/KT-44644) Mark all `@JvmMultifileClass` parts compiled in the previous round as dirty in the JPS plugin, similarly to how it’s done in the Gradle plugin
|
||||
|
||||
### Tools. Scripts
|
||||
|
||||
- [`KT-45194`](https://youtrack.jetbrains.com/issue/KT-45194) KT: Generate Kotlin Entities script: it doesn't work
|
||||
- [`KT-44580`](https://youtrack.jetbrains.com/issue/KT-44580) Scripts: Unable to set new file annotation hooks after first snippet compilation
|
||||
|
||||
### Tools. kapt
|
||||
|
||||
- [`KT-43686`](https://youtrack.jetbrains.com/issue/KT-43686) KaptWithoutKotlincTask should use `@CompileClasspath` for `kotlinStdlibClasspath` for cache relocateability.
|
||||
- [`KT-44130`](https://youtrack.jetbrains.com/issue/KT-44130) KAPT changes field order in 1.4.30-M1
|
||||
- [`KT-44909`](https://youtrack.jetbrains.com/issue/KT-44909) Kapt: ReenteringLazyValueComputationException without stacktrace caused by `when` expression with sealed class function without explicit return type
|
||||
- [`KT-45168`](https://youtrack.jetbrains.com/issue/KT-45168) KAPT: Java stubs generated for Kotlin files generated by annotation processors
|
||||
|
||||
|
||||
## 1.4.32
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-43824`](https://youtrack.jetbrains.com/issue/KT-43824) KtLightClassForSourceDeclaration#isInheritor works in a different way than java implementation
|
||||
- [`KT-45287`](https://youtrack.jetbrains.com/issue/KT-45287) LightClasses: `KtLightSimpleModifierList` is no more a parent of `KtLightAnnotationForSourceEntry`
|
||||
- [`KT-45291`](https://youtrack.jetbrains.com/issue/KT-45291) LightClasses: can't get annotations for constructor val-parameter
|
||||
- [`KT-45417`](https://youtrack.jetbrains.com/issue/KT-45417) ULC leakage of primitive type annotations
|
||||
|
||||
### Tools. CLI
|
||||
|
||||
- [`KT-44758`](https://youtrack.jetbrains.com/issue/KT-44758) kotlin-compiler-embeddable dependency includes unshaded `fastutil` package
|
||||
- [`KT-45007`](https://youtrack.jetbrains.com/issue/KT-45007) Concurrent Kotlin script compilation/execution results in NullPointerException in KeyedExtensionCollector.getPoint()
|
||||
|
||||
## 1.4.31
|
||||
|
||||
### Compiler
|
||||
|
||||
- [`KT-39776`](https://youtrack.jetbrains.com/issue/KT-39776) 2020.3+: Unresolved reference to Kotlin stdlib function
|
||||
|
||||
### IDE. Gradle Integration
|
||||
|
||||
- [`KT-44845`](https://youtrack.jetbrains.com/issue/KT-44845) After update to Kotlin 1.4.30 all external dependencies is unresolved in IDE with kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
|
||||
### IDE. Gradle. Script
|
||||
|
||||
- [`KTIJ-11137`](https://youtrack.jetbrains.com/issue/KTIJ-1137) build.gradle.kts: Fatal error during save/load standalone scripts settings
|
||||
- [`KTIJ-898`](https://youtrack.jetbrains.com/issue/KTIJ-898) Unable to import with Kotlin DSL buildscript - NullPointerException in KotlinDslScriptModelProcessorKt.toListOfScriptModels
|
||||
|
||||
### IDE. Multiplatform
|
||||
|
||||
- [`KTIJ-1200`](https://youtrack.jetbrains.com/issue/KTIJ-1200) KotlinIconProviderKt.addExpectActualMarker takes up to 180+ seconds
|
||||
|
||||
### IDE
|
||||
|
||||
#### Fixes
|
||||
|
||||
- [`KT-44697`](https://youtrack.jetbrains.com/issue/KT-44697) New JVM IR backend notification - narrow its triggering to Kotlin projects
|
||||
- [`KT-44523`](https://youtrack.jetbrains.com/issue/KT-44523) IDE notification for trying new JVM backend
|
||||
- [`KTIJ-696`](https://youtrack.jetbrains.com/issue/KTIJ-696) Freeze during startup of IDEA with intellij project with Kotlin (211-1.4.10-release-IJ1440)
|
||||
|
||||
## 1.4.30
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import kotlinx.benchmark.gradle.benchmark
|
||||
|
||||
val benchmarks_version = "0.3.0"
|
||||
val benchmarks_version = "0.3.1"
|
||||
|
||||
plugins {
|
||||
java
|
||||
kotlin("jvm")
|
||||
id("org.jetbrains.kotlinx.benchmark") version "0.3.0"
|
||||
id("org.jetbrains.kotlinx.benchmark") version "0.3.1"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
@@ -147,6 +148,7 @@ abstract class AbstractSimpleFileBenchmark {
|
||||
bh.consume(result.shouldGenerateCode)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
private fun analyzeGreenFileIr(bh: Blackhole) {
|
||||
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
|
||||
|
||||
@@ -39,4 +39,4 @@ class GeneratedJvmClass(
|
||||
}
|
||||
}
|
||||
|
||||
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"
|
||||
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import org.jetbrains.kotlin.build.GeneratedFile
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
|
||||
import org.jetbrains.kotlin.incremental.js.IrTranslationResultValue
|
||||
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
||||
@@ -48,6 +49,7 @@ open class IncrementalJsCache(
|
||||
private const val INLINE_FUNCTIONS = "inline-functions"
|
||||
private const val HEADER_FILE_NAME = "header.meta"
|
||||
private const val PACKAGE_META_FILE = "packages-meta"
|
||||
private const val SOURCE_TO_JS_OUTPUT = "source-to-js-output"
|
||||
|
||||
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
|
||||
}
|
||||
@@ -60,6 +62,7 @@ open class IncrementalJsCache(
|
||||
private val irTranslationResults = registerMap(IrTranslationResultMap(IR_TRANSLATION_RESULT_MAP.storageFile, pathConverter))
|
||||
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter))
|
||||
private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile))
|
||||
private val sourceToJsOutputsMap = registerMap(SourceToJsOutputMap(SOURCE_TO_JS_OUTPUT.storageFile, pathConverter))
|
||||
|
||||
private val dirtySources = hashSetOf<File>()
|
||||
|
||||
@@ -75,6 +78,7 @@ open class IncrementalJsCache(
|
||||
|
||||
override fun markDirty(removedAndCompiledSources: Collection<File>) {
|
||||
removedAndCompiledSources.forEach { sourceFile ->
|
||||
sourceToJsOutputsMap.remove(sourceFile)
|
||||
// The common prefix of all FQN parents has to be the file package
|
||||
sourceToClassesMap[sourceFile].map { it.parentOrNull()?.asString() ?: "" }.minByOrNull { it.length }?.let {
|
||||
packageMetadata.remove(it)
|
||||
@@ -95,6 +99,10 @@ open class IncrementalJsCache(
|
||||
}
|
||||
}
|
||||
|
||||
fun getOutputsBySource(sourceFile: File): Collection<File> {
|
||||
return sourceToJsOutputsMap.get(sourceFile)
|
||||
}
|
||||
|
||||
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
|
||||
val translatedFiles = incrementalResults.packageParts
|
||||
|
||||
@@ -175,6 +183,17 @@ open class IncrementalJsCache(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSourceToOutputMap(
|
||||
generatedFiles: Iterable<GeneratedFile>,
|
||||
) {
|
||||
for (generatedFile in generatedFiles) {
|
||||
for (source in generatedFile.sourceFiles) {
|
||||
if (dirtySources.contains(source))
|
||||
sourceToJsOutputsMap.add(source, generatedFile.outputFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
|
||||
@@ -215,17 +234,20 @@ private class TranslationResultMap(
|
||||
override fun dumpValue(value: TranslationResultValue): String =
|
||||
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
|
||||
|
||||
@Synchronized
|
||||
fun put(sourceFile: File, newMetadata: ByteArray, newBinaryAst: ByteArray, newInlineData: ByteArray) {
|
||||
storage[pathConverter.toPath(sourceFile)] =
|
||||
TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst, inlineData = newInlineData)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
operator fun get(sourceFile: File): TranslationResultValue? =
|
||||
storage[pathConverter.toPath(sourceFile)]
|
||||
|
||||
fun keys(): Collection<File> =
|
||||
storage.keys.map { pathConverter.toFile(it) }
|
||||
|
||||
@Synchronized
|
||||
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
|
||||
val path = pathConverter.toPath(sourceFile)
|
||||
val protoBytes = storage[path]!!.metadata
|
||||
@@ -359,6 +381,7 @@ private class InlineFunctionsMap(
|
||||
storageFile: File,
|
||||
private val pathConverter: FileToPathConverter
|
||||
) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
|
||||
@Synchronized
|
||||
fun process(srcFile: File, newMap: Map<String, Long>, changesCollector: ChangesCollector) {
|
||||
val key = pathConverter.toPath(srcFile)
|
||||
val oldMap = storage[key] ?: emptyMap()
|
||||
@@ -376,6 +399,7 @@ private class InlineFunctionsMap(
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun remove(sourceFile: File) {
|
||||
storage.remove(pathConverter.toPath(sourceFile))
|
||||
}
|
||||
|
||||
@@ -47,10 +47,16 @@ abstract class BasicMap<K : Comparable<K>, V>(
|
||||
storage.flush(memoryCachesOnly)
|
||||
}
|
||||
|
||||
// avoid unsynchronized close
|
||||
fun close() {
|
||||
storage.close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun closeForTest() {
|
||||
close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun dump(): String {
|
||||
return with(StringBuilder()) {
|
||||
|
||||
@@ -34,7 +34,6 @@ class CachingLazyStorage<K, V>(
|
||||
) : LazyStorage<K, V> {
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
@@ -46,32 +45,36 @@ class CachingLazyStorage<K, V>(
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
@Synchronized
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
@Synchronized
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
@Synchronized
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
@Synchronized
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key, { valueExternalizer.save(it, value) })
|
||||
}
|
||||
@@ -103,7 +106,11 @@ class CachingLazyStorage<K, V>(
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
try {
|
||||
storage?.close()
|
||||
} finally {
|
||||
storage = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> = PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
@@ -28,6 +28,7 @@ internal open class ClassOneToManyMap(storageFile: File) : BasicStringMap<Collec
|
||||
storage.append(key.asString(), listOf(value.asString()))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
operator fun get(key: FqName): Collection<FqName> =
|
||||
storage[key.asString()]?.map(::FqName) ?: setOf()
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ class NonCachingLazyStorage<K, V>(
|
||||
) : LazyStorage<K, V> {
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
@@ -43,7 +42,6 @@ class NonCachingLazyStorage<K, V>(
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
@@ -53,22 +51,28 @@ class NonCachingLazyStorage<K, V>(
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
@Synchronized
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
@Synchronized
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
@Synchronized
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
@Synchronized
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
|
||||
}
|
||||
@@ -100,7 +104,11 @@ class NonCachingLazyStorage<K, V>(
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
try {
|
||||
storage?.close()
|
||||
} finally {
|
||||
storage = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import java.io.File
|
||||
|
||||
class SourceToJsOutputMap(storageFile: File, private val pathConverter: FileToPathConverter) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
|
||||
@Synchronized
|
||||
fun add(key: File, value: File) {
|
||||
storage.append(pathConverter.toPath(key), listOf(pathConverter.toPath(value)))
|
||||
}
|
||||
|
||||
operator fun get(sourceFile: File): Collection<File> =
|
||||
storage[pathConverter.toPath(sourceFile)]?.map { pathConverter.toFile(it) } ?: setOf()
|
||||
|
||||
|
||||
@Synchronized
|
||||
operator fun set(key: File, values: Collection<File>) {
|
||||
if (values.isEmpty()) {
|
||||
remove(key)
|
||||
return
|
||||
}
|
||||
|
||||
storage[pathConverter.toPath(key)] = values.map { pathConverter.toPath(it) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun remove(key: File) {
|
||||
storage.remove(pathConverter.toPath(key))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun removeValues(key: File, removed: Set<File>) {
|
||||
val notRemoved = this[key].filter { it !in removed }
|
||||
this[key] = notRemoved
|
||||
}
|
||||
}
|
||||
150
build.gradle.kts
150
build.gradle.kts
@@ -14,8 +14,11 @@ buildscript {
|
||||
|
||||
if (cacheRedirectorEnabled) {
|
||||
maven("https://cache-redirector.jetbrains.com/plugins.gradle.org/m2")
|
||||
maven("https://cache-redirector.jetbrains.com/repo.maven.apache.org/maven2")
|
||||
|
||||
} else {
|
||||
maven("https://plugins.gradle.org/m2")
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +30,7 @@ buildscript {
|
||||
dependencies {
|
||||
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
|
||||
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.29")
|
||||
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
|
||||
classpath(kotlin("serialization", bootstrapKotlinVersion))
|
||||
classpath("org.jetbrains.dokka:dokka-gradle-plugin:0.9.17")
|
||||
@@ -35,10 +38,6 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
if (kotlinBuildProperties.buildScanServer != null) {
|
||||
apply(from = "gradle/buildScanUserData.gradle")
|
||||
}
|
||||
|
||||
plugins {
|
||||
base
|
||||
idea
|
||||
@@ -183,7 +182,7 @@ extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.completion-ranking-kotlin"] = "0.1.3"
|
||||
extra["versions.r8"] = "2.1.96"
|
||||
extra["versions.r8"] = "2.2.64"
|
||||
val immutablesVersion = "0.3.1"
|
||||
extra["versions.kotlinx-collections-immutable"] = immutablesVersion
|
||||
extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
||||
@@ -298,6 +297,7 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:fir:java",
|
||||
":compiler:fir:jvm",
|
||||
":compiler:fir:checkers",
|
||||
":compiler:fir:checkers:checkers.jvm",
|
||||
":compiler:fir:entrypoint",
|
||||
":compiler:fir:analysis-tests",
|
||||
":compiler:fir:analysis-tests:legacy-fir-tests",
|
||||
@@ -317,7 +317,6 @@ extra["compilerModulesForJps"] = listOf(
|
||||
":core:compiler.common.jvm",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":idea:idea-jps-common",
|
||||
":kotlin-preloader",
|
||||
":compiler:util",
|
||||
":compiler:config",
|
||||
@@ -327,13 +326,47 @@ extra["compilerModulesForJps"] = listOf(
|
||||
":compiler:compiler.version"
|
||||
)
|
||||
|
||||
extra["compilerArtifactsForIde"] = listOf(
|
||||
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide",
|
||||
":prepare:ide-plugin-dependencies:js-ir-runtime-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-cli-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:compiler-components-for-jps",
|
||||
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:lombok-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-tests-for-ide",
|
||||
":kotlin-script-runtime",
|
||||
":kotlin-script-util",
|
||||
":kotlin-scripting-common",
|
||||
":kotlin-scripting-jvm",
|
||||
":kotlin-scripting-compiler",
|
||||
":kotlin-scripting-compiler-impl",
|
||||
":kotlin-android-extensions-runtime",
|
||||
":kotlin-stdlib-common",
|
||||
":kotlin-stdlib",
|
||||
":kotlin-stdlib-jdk7",
|
||||
":kotlin-stdlib-jdk8",
|
||||
":kotlin-reflect",
|
||||
":kotlin-main-kts"
|
||||
)
|
||||
|
||||
// TODO: fix remaining warnings and remove this property.
|
||||
extra["tasksWithWarnings"] = listOf(
|
||||
":kotlin-stdlib:compileTestKotlin",
|
||||
":kotlin-stdlib-jdk7:compileTestKotlin",
|
||||
":kotlin-stdlib-jdk8:compileTestKotlin",
|
||||
":plugins:uast-kotlin-base:compileKotlin",
|
||||
":plugins:uast-kotlin:compileKotlin",
|
||||
":plugins:uast-kotlin:compileTestKotlin"
|
||||
":plugins:uast-kotlin:compileTestKotlin",
|
||||
":plugins:uast-kotlin-fir:compileKotlin",
|
||||
":plugins:uast-kotlin-fir:compileTestKotlin"
|
||||
)
|
||||
|
||||
val tasksWithWarnings: List<String> by extra
|
||||
@@ -378,7 +411,7 @@ apply {
|
||||
}
|
||||
|
||||
apply {
|
||||
if (extra["isSonatypeRelease"] as? Boolean == true) {
|
||||
if (extra["isDeployStagingRepoGenerationRequired"] as? Boolean == true) {
|
||||
logger.info("Applying configuration for sonatype release")
|
||||
from("libraries/prepareSonatypeStaging.gradle")
|
||||
}
|
||||
@@ -397,6 +430,29 @@ val defaultJavaHome = jdkPath(if (Platform[203].orHigher()) "11" else defaultJvm
|
||||
val ignoreTestFailures by extra(project.kotlinBuildProperties.ignoreTestFailures)
|
||||
|
||||
allprojects {
|
||||
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
|
||||
|
||||
repositories {
|
||||
kotlinBuildLocalRepo(project)
|
||||
mirrorRepo?.let(::maven)
|
||||
|
||||
internalBootstrapRepo?.let(::maven)
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
maven(protobufRepo)
|
||||
|
||||
maven(intellijRepo)
|
||||
|
||||
mavenCentral()
|
||||
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
|
||||
maven("https://dl.google.com/dl/android/maven2")
|
||||
maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies")
|
||||
|
||||
jcenter()
|
||||
}
|
||||
|
||||
if (path.startsWith(":kotlin-ide.")) {
|
||||
return@allprojects
|
||||
}
|
||||
|
||||
configurations.maybeCreate("embedded").apply {
|
||||
isCanBeConsumed = false
|
||||
@@ -425,25 +481,6 @@ allprojects {
|
||||
// therefore it is disabled by default
|
||||
// buildDir = File(commonBuildDir, project.name)
|
||||
|
||||
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
|
||||
|
||||
repositories {
|
||||
kotlinBuildLocalRepo(project)
|
||||
mirrorRepo?.let(::maven)
|
||||
|
||||
internalBootstrapRepo?.let(::maven)
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
maven(protobufRepo)
|
||||
|
||||
maven(intellijRepo)
|
||||
|
||||
mavenCentral()
|
||||
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies")
|
||||
maven("https://dl.google.com/dl/android/maven2")
|
||||
maven("https://packages.jetbrains.team/maven/p/ij/intellij-dependencies")
|
||||
|
||||
jcenter()
|
||||
}
|
||||
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
|
||||
@@ -519,12 +556,16 @@ allprojects {
|
||||
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KTI-112") { true }
|
||||
}
|
||||
|
||||
normalization {
|
||||
runtimeClasspath {
|
||||
ignore("META-INF/MANIFEST.MF")
|
||||
ignore("META-INF/compiler.version")
|
||||
ignore("META-INF/plugin.xml")
|
||||
ignore("kotlin/KotlinVersionCurrentValue.class")
|
||||
if (isConfigurationCacheDisabled) {
|
||||
// Custom input normolization isn't supported by configuration cache at the moment
|
||||
// See https://github.com/gradle/gradle/issues/13706
|
||||
normalization {
|
||||
runtimeClasspath {
|
||||
ignore("META-INF/MANIFEST.MF")
|
||||
ignore("META-INF/compiler.version")
|
||||
ignore("META-INF/plugin.xml")
|
||||
ignore("kotlin/KotlinVersionCurrentValue.class")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,11 +885,12 @@ tasks {
|
||||
":idea:idea-fir:test",
|
||||
":idea:idea-frontend-api:test",
|
||||
":idea:idea-frontend-fir:test",
|
||||
":idea:idea-frontend-fir:idea-fir-low-level-api:test"
|
||||
":idea:idea-frontend-fir:idea-fir-low-level-api:test",
|
||||
":plugins:uast-kotlin-fir:test",
|
||||
":idea:idea-fir-fe10-binding:test"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
register("android-ide-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
@@ -894,7 +936,6 @@ tasks {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
register("kaptIdeTest") {
|
||||
dependsOn(":kotlin-annotation-processing:test")
|
||||
dependsOn(":kotlin-annotation-processing-base:test")
|
||||
@@ -950,32 +991,13 @@ tasks {
|
||||
|
||||
register("publishIdeArtifacts") {
|
||||
idePluginDependency {
|
||||
dependsOn(
|
||||
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:compiler-components-for-jps:publish",
|
||||
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide:publish",
|
||||
":kotlin-script-runtime:publish",
|
||||
":kotlin-script-util:publish",
|
||||
":kotlin-scripting-common:publish",
|
||||
":kotlin-scripting-jvm:publish",
|
||||
":kotlin-scripting-compiler:publish",
|
||||
":kotlin-scripting-compiler-impl:publish",
|
||||
":kotlin-android-extensions-runtime:publish",
|
||||
":kotlin-stdlib-common:publish",
|
||||
":kotlin-stdlib:publish",
|
||||
":kotlin-stdlib-jdk7:publish",
|
||||
":kotlin-stdlib-jdk8:publish",
|
||||
":kotlin-reflect:publish",
|
||||
":kotlin-main-kts:publish"
|
||||
)
|
||||
dependsOn((rootProject.extra["compilerArtifactsForIde"] as List<String>).map { "$it:publish" })
|
||||
}
|
||||
}
|
||||
|
||||
register("installIdeArtifacts") {
|
||||
idePluginDependency {
|
||||
dependsOn((rootProject.extra["compilerArtifactsForIde"] as List<String>).map { "$it:install" })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1113,7 +1135,7 @@ fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jdkHome = javaHome
|
||||
kotlinOptions.jdkHome = javaHome.takeUnless { kotlinBuildProperties.suppressJdkHomeWarning }
|
||||
kotlinOptions.jvmTarget = javaVersion
|
||||
kotlinOptions.freeCompilerArgs += "-Xjvm-default=compatibility"
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.29")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
|
||||
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
|
||||
}
|
||||
@@ -144,7 +144,7 @@ java {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib", embeddedKotlinVersion))
|
||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.29")
|
||||
implementation("com.gradle.publish:plugin-publish-plugin:0.14.0")
|
||||
|
||||
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
|
||||
|
||||
@@ -18,6 +18,7 @@ plugins {
|
||||
val intellijUltimateEnabled: Boolean by rootProject.extra
|
||||
val intellijReleaseType: String by rootProject.extra
|
||||
val intellijVersion = rootProject.extra["versions.intellijSdk"] as String
|
||||
val intellijVersionForIde = rootProject.intellijSdkVersionForIde()
|
||||
val asmVersion = rootProject.findProperty("versions.jar.asm-all") as String?
|
||||
val androidStudioRelease = rootProject.findProperty("versions.androidStudioRelease") as String?
|
||||
val androidStudioBuild = rootProject.findProperty("versions.androidStudioBuild") as String?
|
||||
@@ -25,15 +26,18 @@ val intellijSeparateSdks: Boolean by rootProject.extra
|
||||
val installIntellijCommunity = !intellijUltimateEnabled || intellijSeparateSdks
|
||||
val installIntellijUltimate = intellijUltimateEnabled && androidStudioRelease == null
|
||||
|
||||
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
|
||||
if (intellijVersionDelimiterIndex == -1) {
|
||||
error("Invalid IDEA version $intellijVersion")
|
||||
fun checkIntellijVersion(intellijVersion: String) {
|
||||
val intellijVersionDelimiterIndex = intellijVersion.indexOfAny(charArrayOf('.', '-'))
|
||||
if (intellijVersionDelimiterIndex == -1) {
|
||||
error("Invalid IDEA version $intellijVersion")
|
||||
}
|
||||
}
|
||||
|
||||
val platformBaseVersion = intellijVersion.substring(0, intellijVersionDelimiterIndex)
|
||||
checkIntellijVersion(intellijVersion)
|
||||
intellijVersionForIde?.let { checkIntellijVersion(it) }
|
||||
|
||||
logger.info("intellijUltimateEnabled: $intellijUltimateEnabled")
|
||||
logger.info("intellijVersion: $intellijVersion")
|
||||
logger.info("intellijVersionForIde: $intellijVersionForIde")
|
||||
logger.info("androidStudioRelease: $androidStudioRelease")
|
||||
logger.info("androidStudioBuild: $androidStudioBuild")
|
||||
logger.info("intellijSeparateSdks: $intellijSeparateSdks")
|
||||
@@ -73,11 +77,16 @@ repositories {
|
||||
}
|
||||
|
||||
val intellij by configurations.creating
|
||||
val intellijForIde by configurations.creating
|
||||
val intellijUltimate by configurations.creating
|
||||
val intellijUltimateForIde by configurations.creating
|
||||
val androidStudio by configurations.creating
|
||||
val sources by configurations.creating
|
||||
val sourcesForIde by configurations.creating
|
||||
val jpsStandalone by configurations.creating
|
||||
val jpsStandaloneForIde by configurations.creating
|
||||
val intellijCore by configurations.creating
|
||||
val intellijCoreForIde by configurations.creating
|
||||
val nodeJSPlugin by configurations.creating
|
||||
|
||||
/**
|
||||
@@ -93,7 +102,6 @@ val dependenciesDir = (findProperty("kotlin.build.dependencies.dir") as String?)
|
||||
val customDepsRepoDir = dependenciesDir.resolve("repo")
|
||||
|
||||
val customDepsOrg: String by rootProject.extra
|
||||
val customDepsRevision = intellijVersion
|
||||
val repoDir = File(customDepsRepoDir, customDepsOrg)
|
||||
|
||||
dependencies {
|
||||
@@ -107,9 +115,11 @@ dependencies {
|
||||
} else {
|
||||
if (installIntellijCommunity) {
|
||||
intellij("com.jetbrains.intellij.idea:ideaIC:$intellijVersion")
|
||||
intellijVersionForIde?.let { intellijForIde("com.jetbrains.intellij.idea:ideaIC:$it") }
|
||||
}
|
||||
if (installIntellijUltimate) {
|
||||
intellijUltimate("com.jetbrains.intellij.idea:ideaIU:$intellijVersion")
|
||||
intellijVersionForIde.let { intellijUltimateForIde("com.jetbrains.intellij.idea:ideaIU:$it") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,102 +128,111 @@ dependencies {
|
||||
}
|
||||
|
||||
sources("com.jetbrains.intellij.idea:ideaIC:$intellijVersion:sources@jar")
|
||||
intellijVersionForIde?.let { sourcesForIde("com.jetbrains.intellij.idea:ideaIC:$it:sources@jar") }
|
||||
jpsStandalone("com.jetbrains.intellij.idea:jps-standalone:$intellijVersion")
|
||||
intellijVersionForIde?.let { jpsStandaloneForIde("com.jetbrains.intellij.idea:jps-standalone:$it") }
|
||||
intellijCore("com.jetbrains.intellij.idea:intellij-core:$intellijVersion")
|
||||
intellijVersionForIde?.let { intellijCoreForIde("com.jetbrains.intellij.idea:intellij-core:$it") }
|
||||
if (intellijUltimateEnabled) {
|
||||
nodeJSPlugin("com.jetbrains.plugins:NodeJS:${rootProject.extra["versions.idea.NodeJS"]}@zip")
|
||||
}
|
||||
}
|
||||
|
||||
val makeIntellijCore = buildIvyRepositoryTask(intellijCore, customDepsOrg, customDepsRepoDir)
|
||||
fun prepareDeps(intellij: Configuration, intellijCore: Configuration, sources: Configuration, intellijUltimate: Configuration, jpsStandalone: Configuration, intellijVersion: String) {
|
||||
val makeIntellijCore = buildIvyRepositoryTask(intellijCore, customDepsOrg, customDepsRepoDir)
|
||||
|
||||
val makeIntellijAnnotations by tasks.registering(Copy::class) {
|
||||
dependsOn(makeIntellijCore)
|
||||
val makeIntellijAnnotations = tasks.register("makeIntellijAnnotations${intellij.name.capitalize()}", Copy::class) {
|
||||
dependsOn(makeIntellijCore)
|
||||
|
||||
val intellijCoreRepo = CleanableStore[repoDir.resolve("intellij-core").absolutePath][intellijVersion].use()
|
||||
from(intellijCoreRepo.resolve("artifacts/annotations.jar"))
|
||||
val intellijCoreRepo = CleanableStore[repoDir.resolve("intellij-core").absolutePath][intellijVersion].use()
|
||||
from(intellijCoreRepo.resolve("artifacts/annotations.jar"))
|
||||
|
||||
val annotationsStore = CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath]
|
||||
val targetDir = annotationsStore[intellijVersion].use()
|
||||
into(targetDir)
|
||||
val annotationsStore = CleanableStore[repoDir.resolve(intellijRuntimeAnnotations).absolutePath]
|
||||
val targetDir = annotationsStore[intellijVersion].use()
|
||||
into(targetDir)
|
||||
|
||||
val ivyFile = File(targetDir, "$intellijRuntimeAnnotations.ivy.xml")
|
||||
outputs.files(ivyFile)
|
||||
val ivyFile = File(targetDir, "$intellijRuntimeAnnotations.ivy.xml")
|
||||
outputs.files(ivyFile)
|
||||
|
||||
doFirst {
|
||||
annotationsStore.cleanStore()
|
||||
doFirst {
|
||||
annotationsStore.cleanStore()
|
||||
}
|
||||
|
||||
doLast {
|
||||
writeIvyXml(
|
||||
customDepsOrg,
|
||||
intellijRuntimeAnnotations,
|
||||
intellijVersion,
|
||||
intellijRuntimeAnnotations,
|
||||
targetDir,
|
||||
targetDir,
|
||||
targetDir,
|
||||
allowAnnotations = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
doLast {
|
||||
writeIvyXml(
|
||||
val mergeSources = tasks.create("mergeSources${intellij.name.capitalize()}", Jar::class.java) {
|
||||
dependsOn(sources)
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
isZip64 = true
|
||||
if (!kotlinBuildProperties.isTeamcityBuild) {
|
||||
from(provider { sources.map(::zipTree) })
|
||||
}
|
||||
destinationDirectory.set(File(repoDir, sources.name))
|
||||
archiveBaseName.set("intellij")
|
||||
archiveClassifier.set("sources")
|
||||
archiveVersion.set(intellijVersion)
|
||||
}
|
||||
|
||||
val sourcesFile = mergeSources.outputs.files.singleFile
|
||||
|
||||
val makeIde = if (androidStudioBuild != null) {
|
||||
buildIvyRepositoryTask(
|
||||
androidStudio,
|
||||
customDepsOrg,
|
||||
intellijRuntimeAnnotations,
|
||||
intellijVersion,
|
||||
intellijRuntimeAnnotations,
|
||||
targetDir,
|
||||
targetDir,
|
||||
targetDir,
|
||||
allowAnnotations = true
|
||||
customDepsRepoDir,
|
||||
if (androidStudioOs == "mac")
|
||||
::skipContentsDirectory
|
||||
else
|
||||
::skipToplevelDirectory
|
||||
)
|
||||
} else {
|
||||
val task = if (installIntellijUltimate) {
|
||||
buildIvyRepositoryTask(intellijUltimate, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
} else {
|
||||
buildIvyRepositoryTask(intellij, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
}
|
||||
|
||||
task.configure {
|
||||
dependsOn(mergeSources)
|
||||
}
|
||||
|
||||
task
|
||||
}
|
||||
|
||||
val buildJpsStandalone = buildIvyRepositoryTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
|
||||
tasks.named("build") {
|
||||
dependsOn(
|
||||
makeIntellijCore,
|
||||
makeIde,
|
||||
buildJpsStandalone,
|
||||
makeIntellijAnnotations
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val mergeSources by tasks.creating(Jar::class.java) {
|
||||
dependsOn(sources)
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
isZip64 = true
|
||||
if (!kotlinBuildProperties.isTeamcityBuild) {
|
||||
from(provider { sources.map(::zipTree) })
|
||||
if (installIntellijUltimate) {
|
||||
val buildNodeJsPlugin =
|
||||
buildIvyRepositoryTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
|
||||
tasks.named("build") { dependsOn(buildNodeJsPlugin) }
|
||||
}
|
||||
destinationDirectory.set(File(repoDir, sources.name))
|
||||
archiveBaseName.set("intellij")
|
||||
archiveClassifier.set("sources")
|
||||
archiveVersion.set(intellijVersion)
|
||||
}
|
||||
|
||||
val sourcesFile = mergeSources.outputs.files.singleFile
|
||||
|
||||
val makeIde = if (androidStudioBuild != null) {
|
||||
buildIvyRepositoryTask(
|
||||
androidStudio,
|
||||
customDepsOrg,
|
||||
customDepsRepoDir,
|
||||
if (androidStudioOs == "mac")
|
||||
::skipContentsDirectory
|
||||
else
|
||||
::skipToplevelDirectory
|
||||
)
|
||||
} else {
|
||||
val task = if (installIntellijUltimate) {
|
||||
buildIvyRepositoryTask(intellijUltimate, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
} else {
|
||||
buildIvyRepositoryTask(intellij, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
}
|
||||
|
||||
task.configure {
|
||||
dependsOn(mergeSources)
|
||||
}
|
||||
|
||||
task
|
||||
}
|
||||
|
||||
val buildJpsStandalone = buildIvyRepositoryTask(jpsStandalone, customDepsOrg, customDepsRepoDir, null, sourcesFile)
|
||||
|
||||
tasks.named("build") {
|
||||
dependsOn(
|
||||
makeIntellijCore,
|
||||
makeIde,
|
||||
buildJpsStandalone,
|
||||
makeIntellijAnnotations
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
if (installIntellijUltimate) {
|
||||
val buildNodeJsPlugin =
|
||||
buildIvyRepositoryTask(nodeJSPlugin, customDepsOrg, customDepsRepoDir, ::skipToplevelDirectory, sourcesFile)
|
||||
tasks.named("build") { dependsOn(buildNodeJsPlugin) }
|
||||
prepareDeps(intellij, intellijCore, sources, intellijUltimate, jpsStandalone, intellijVersion)
|
||||
if (intellijVersionForIde != null) {
|
||||
prepareDeps(intellijForIde, intellijCoreForIde, sourcesForIde, intellijUltimateForIde, jpsStandaloneForIde, intellijVersionForIde)
|
||||
}
|
||||
|
||||
tasks.named<Delete>("clean") {
|
||||
@@ -400,6 +419,11 @@ fun skipToplevelDirectory(path: String) = path.substringAfter('/')
|
||||
|
||||
fun skipContentsDirectory(path: String) = path.substringAfter("Contents/")
|
||||
|
||||
fun Project.intellijSdkVersionForIde(): String? {
|
||||
val majorVersion = kotlinBuildProperties.getOrNull("attachedIntellijVersion") as? String ?: return null
|
||||
return rootProject.findProperty("versions.intellijSdk.forIde.$majorVersion") as? String
|
||||
}
|
||||
|
||||
class XMLWriter(private val outputStreamWriter: OutputStreamWriter) : Closeable {
|
||||
|
||||
private val xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(outputStreamWriter)
|
||||
|
||||
@@ -18,9 +18,10 @@ buildscript {
|
||||
} else {
|
||||
maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-dependencies" }
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.26")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.29")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,3 +20,5 @@ val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.bui
|
||||
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
|
||||
|
||||
val KotlinBuildProperties.disableWerror: Boolean get() = getBoolean("kotlin.build.disable.werror", false)
|
||||
|
||||
val KotlinBuildProperties.suppressJdkHomeWarning: Boolean get() = getBoolean("kotlin.suppress.jdkHome.warning", false)
|
||||
|
||||
@@ -81,3 +81,9 @@ fun Task.singleOutputFile(): File = when (this) {
|
||||
is ProGuardTask -> project.file(outJarFiles.single()!!)
|
||||
else -> outputs.files.singleFile
|
||||
}
|
||||
|
||||
val Project.isConfigurationCacheDisabled
|
||||
get() = (gradle.startParameter as? org.gradle.api.internal.StartParameterInternal)?.isConfigurationCache != true
|
||||
|
||||
val Project.isIdeaActive
|
||||
get() = providers.systemProperty("idea.active").forUseAtConfigurationTime().isPresent
|
||||
@@ -229,23 +229,6 @@ fun Project.publish(moduleMetadata: Boolean = false, configure: MavenPublication
|
||||
publication.configure()
|
||||
}
|
||||
|
||||
fun Project.publishWithLegacyMavenPlugin(body: Upload.() -> Unit = {}): Upload {
|
||||
apply<plugins.PublishedKotlinModule>()
|
||||
|
||||
if (artifactsRemovedDiagnosticFlag) {
|
||||
error("`publish()` should be called before removing artifacts typically done in `noDefaultJar()` or `runtimeJar()` call")
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
if (configurations.findByName("classes-dirs") != null)
|
||||
throw GradleException("classesDirsArtifact() is incompatible with publish(), see sources comments for details")
|
||||
}
|
||||
|
||||
return (tasks.getByName("uploadArchives") as Upload).apply {
|
||||
body()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.idePluginDependency(block: () -> Unit) {
|
||||
val shouldActivate = rootProject.findProperty("publish.ide.plugin.dependencies")?.toString()?.toBoolean() == true
|
||||
if (shouldActivate) {
|
||||
@@ -253,6 +236,31 @@ fun Project.idePluginDependency(block: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.publishJarsForIde(projects: List<String>, libraryDependencies: List<String> = emptyList()) {
|
||||
idePluginDependency {
|
||||
publishProjectJars(projects, libraryDependencies)
|
||||
}
|
||||
dependencies {
|
||||
projects.forEach {
|
||||
jpsLikeJarDependency(project(it), JpsDepScope.COMPILE, { isTransitive = false }, exported = true)
|
||||
}
|
||||
libraryDependencies.forEach {
|
||||
jpsLikeJarDependency(it, JpsDepScope.COMPILE, exported = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.publishTestJarsForIde(projectNames: List<String>) {
|
||||
idePluginDependency {
|
||||
publishTestJar(projectNames)
|
||||
}
|
||||
dependencies {
|
||||
for (projectName in projectNames) {
|
||||
jpsLikeJarDependency(projectTests(projectName), JpsDepScope.COMPILE, exported = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.publishProjectJars(projects: List<String>, libraryDependencies: List<String> = emptyList()) {
|
||||
apply<JavaPlugin>()
|
||||
|
||||
@@ -291,13 +299,15 @@ fun Project.publishProjectJars(projects: List<String>, libraryDependencies: List
|
||||
javadocJar()
|
||||
}
|
||||
|
||||
fun Project.publishTestJar(projectName: String) {
|
||||
fun Project.publishTestJar(projects: List<String>) {
|
||||
apply<JavaPlugin>()
|
||||
|
||||
val fatJarContents by configurations.creating
|
||||
|
||||
dependencies {
|
||||
fatJarContents(project(projectName, configuration = "tests-jar")) { isTransitive = false }
|
||||
for (projectName in projects) {
|
||||
fatJarContents(project(projectName, configuration = "tests-jar")) { isTransitive = false }
|
||||
}
|
||||
}
|
||||
|
||||
publish()
|
||||
@@ -314,7 +324,7 @@ fun Project.publishTestJar(projectName: String) {
|
||||
|
||||
sourcesJar {
|
||||
from {
|
||||
project(projectName).testSourceSet.allSource
|
||||
projects.map { project(it).testSourceSet.allSource }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@ import org.gradle.api.GradleException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.artifacts.ProjectDependency
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.kotlin.dsl.accessors.runtime.addDependencyTo
|
||||
import org.gradle.kotlin.dsl.closureOf
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
import org.gradle.kotlin.dsl.project
|
||||
import java.io.File
|
||||
@@ -115,6 +117,87 @@ fun DependencyHandler.projectTests(name: String): ProjectDependency = project(na
|
||||
fun DependencyHandler.projectRuntimeJar(name: String): ProjectDependency = project(name, configuration = "runtimeJar")
|
||||
fun DependencyHandler.projectArchives(name: String): ProjectDependency = project(name, configuration = "archives")
|
||||
|
||||
enum class JpsDepScope {
|
||||
COMPILE, TEST, RUNTIME, PROVIDED
|
||||
}
|
||||
|
||||
fun DependencyHandler.add(configurationName: String, dependencyNotation: Any, configure: (ModuleDependency.() -> Unit)?) {
|
||||
// Avoid `dependencyNotation` to `ModuleDependency` class cast exception if possible
|
||||
if (configure != null) {
|
||||
add(configurationName, dependencyNotation, closureOf(configure))
|
||||
} else {
|
||||
add(configurationName, dependencyNotation)
|
||||
}
|
||||
}
|
||||
|
||||
fun DependencyHandler.jpsLikeJarDependency(
|
||||
dependencyNotation: Any,
|
||||
scope: JpsDepScope,
|
||||
dependencyConfiguration: (ModuleDependency.() -> Unit)? = null,
|
||||
exported: Boolean = false
|
||||
) {
|
||||
when (scope) {
|
||||
JpsDepScope.COMPILE -> {
|
||||
if (exported) {
|
||||
add("api", dependencyNotation, dependencyConfiguration)
|
||||
add("testCompile", dependencyNotation, dependencyConfiguration)
|
||||
} else {
|
||||
add("implementation", dependencyNotation, dependencyConfiguration)
|
||||
}
|
||||
}
|
||||
JpsDepScope.TEST -> {
|
||||
if (exported) {
|
||||
add("testCompile", dependencyNotation, dependencyConfiguration)
|
||||
} else {
|
||||
add("testImplementation", dependencyNotation, dependencyConfiguration)
|
||||
}
|
||||
}
|
||||
JpsDepScope.RUNTIME -> {
|
||||
add("testRuntimeOnly", dependencyNotation, dependencyConfiguration)
|
||||
}
|
||||
JpsDepScope.PROVIDED -> {
|
||||
if (exported) {
|
||||
add("compileOnlyApi", dependencyNotation, dependencyConfiguration)
|
||||
add("testCompile", dependencyNotation, dependencyConfiguration)
|
||||
} else {
|
||||
add("compileOnly", dependencyNotation, dependencyConfiguration)
|
||||
add("testImplementation", dependencyNotation, dependencyConfiguration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun DependencyHandler.jpsLikeModuleDependency(moduleName: String, scope: JpsDepScope, exported: Boolean = false) {
|
||||
jpsLikeJarDependency(project(moduleName), scope, exported = exported)
|
||||
when (scope) {
|
||||
JpsDepScope.COMPILE -> {
|
||||
if (exported) {
|
||||
add("testCompile", projectTests(moduleName))
|
||||
} else {
|
||||
add("testImplementation", projectTests(moduleName))
|
||||
}
|
||||
}
|
||||
JpsDepScope.TEST -> {
|
||||
if (exported) {
|
||||
add("testCompile", projectTests(moduleName))
|
||||
} else {
|
||||
add("testImplementation", projectTests(moduleName))
|
||||
}
|
||||
}
|
||||
JpsDepScope.RUNTIME -> {
|
||||
add("runtimeOnly", projectTests(moduleName))
|
||||
}
|
||||
JpsDepScope.PROVIDED -> {
|
||||
if (exported) {
|
||||
add("testCompile", projectTests(moduleName))
|
||||
} else {
|
||||
add("testImplementation", projectTests(moduleName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Project.testApiJUnit5(
|
||||
vintageEngine: Boolean = false,
|
||||
runner: Boolean = false,
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
publish()
|
||||
standardPublicJars()
|
||||
|
||||
extensions.extraProperties["kotlin.stdlib.default.dependency"] = "false"
|
||||
|
||||
dependencies {
|
||||
compileOnly(kotlinStdlib())
|
||||
compileOnly(gradleApi())
|
||||
}
|
||||
|
||||
// These dependencies will be provided by Gradle and we should prevent version conflict
|
||||
fun Configuration.excludeGradleCommonDependencies() {
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk7")
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-jdk8")
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib-common")
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-reflect")
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-script-runtime")
|
||||
}
|
||||
configurations {
|
||||
"implementation" {
|
||||
excludeGradleCommonDependencies()
|
||||
}
|
||||
"api" {
|
||||
excludeGradleCommonDependencies()
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.languageVersion = "1.3"
|
||||
kotlinOptions.apiVersion = "1.3"
|
||||
kotlinOptions.freeCompilerArgs += listOf(
|
||||
"-Xskip-prerelease-check",
|
||||
"-Xskip-runtime-version-check",
|
||||
"-Xsuppress-version-warnings"
|
||||
)
|
||||
}
|
||||
|
||||
tasks.named<Jar>("jar") {
|
||||
callGroovy("manifestAttributes", manifest, project)
|
||||
}
|
||||
@@ -42,9 +42,21 @@ private fun Project.ideModuleName() = when (IdeVersionConfigurator.currentIde.ki
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.ideModuleVersion() = when (IdeVersionConfigurator.currentIde.kind) {
|
||||
private fun Project.ideModuleVersion(forIde: Boolean) = when (IdeVersionConfigurator.currentIde.kind) {
|
||||
Ide.Kind.AndroidStudio -> rootProject.findProperty("versions.androidStudioBuild")
|
||||
Ide.Kind.IntelliJ -> rootProject.findProperty("versions.intellijSdk")
|
||||
Ide.Kind.IntelliJ -> {
|
||||
if (forIde) {
|
||||
intellijSdkVersionForIde()
|
||||
?: error("Please specify 'attachedIntellijVersion' in your local.properties")
|
||||
} else {
|
||||
rootProject.findProperty("versions.intellijSdk")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.intellijSdkVersionForIde(): String? {
|
||||
val majorVersion = kotlinBuildProperties.getOrNull("attachedIntellijVersion") as? String ?: return null
|
||||
return rootProject.findProperty("versions.intellijSdk.forIde.$majorVersion") as? String
|
||||
}
|
||||
|
||||
fun RepositoryHandler.kotlinBuildLocalRepo(project: Project): IvyArtifactRepository = ivy {
|
||||
@@ -58,6 +70,7 @@ fun RepositoryHandler.kotlinBuildLocalRepo(project: Project): IvyArtifactReposit
|
||||
|
||||
artifact("[organisation]/[module]/[revision]/artifacts/lib/[artifact](-[classifier]).[ext]")
|
||||
artifact("[organisation]/[module]/[revision]/artifacts/[artifact](-[classifier]).[ext]")
|
||||
artifact("[organisation]/intellij-core/[revision]/artifacts/[artifact](-[classifier]).[ext]")
|
||||
artifact("[organisation]/${project.ideModuleName()}/[revision]/artifacts/plugins/[module]/lib/[artifact](-[classifier]).[ext]") // bundled plugins
|
||||
artifact("[organisation]/sources/[artifact]-[revision](-[classifier]).[ext]")
|
||||
artifact("[organisation]/[module]/[revision]/[artifact](-[classifier]).[ext]")
|
||||
@@ -68,7 +81,9 @@ fun RepositoryHandler.kotlinBuildLocalRepo(project: Project): IvyArtifactReposit
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.intellijDep(module: String? = null) = "kotlin.build:${module ?: ideModuleName()}:${ideModuleVersion()}"
|
||||
@JvmOverloads
|
||||
fun Project.intellijDep(module: String? = null, forIde: Boolean = false) =
|
||||
"kotlin.build:${module ?: ideModuleName()}:${ideModuleVersion(forIde)}"
|
||||
|
||||
fun Project.intellijCoreDep() = "kotlin.build:intellij-core:${rootProject.extra["versions.intellijSdk"]}"
|
||||
|
||||
@@ -93,7 +108,7 @@ fun Project.kotlinxCollectionsImmutable() = "org.jetbrains.kotlinx:kotlinx-colle
|
||||
*/
|
||||
fun Project.intellijRuntimeAnnotations() = "kotlin.build:intellij-runtime-annotations:${rootProject.extra["versions.intellijSdk"]}"
|
||||
|
||||
fun Project.intellijPluginDep(plugin: String) = intellijDep(plugin)
|
||||
fun Project.intellijPluginDep(plugin: String, forIde: Boolean = false) = intellijDep(plugin, forIde)
|
||||
|
||||
fun Project.intellijUltimateDep() = intellijDep("ideaIU")
|
||||
|
||||
@@ -125,7 +140,7 @@ object IntellijRootUtils {
|
||||
fun getIntellijRootDir(project: Project): File = with(project.rootProject) {
|
||||
return File(
|
||||
getRepositoryRootDir(this),
|
||||
"${ideModuleName()}/${ideModuleVersion()}/artifacts"
|
||||
"${ideModuleName()}/${ideModuleVersion(forIde = false)}/artifacts"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,17 @@ fun Project.configureDefaultPublishing() {
|
||||
private fun Project.configureSigning() {
|
||||
configure<SigningExtension> {
|
||||
sign(extensions.getByType<PublishingExtension>().publications) // all publications
|
||||
useGpgCmd()
|
||||
|
||||
val signKeyId = project.findProperty("signKeyId") as? String
|
||||
if (!signKeyId.isNullOrBlank()) {
|
||||
val signKeyPrivate = project.findProperty("signKeyPrivate") as? String
|
||||
?: error("Parameter `signKeyPrivate` not found")
|
||||
val signKeyPassphrase = project.findProperty("signKeyPassphrase") as? String
|
||||
?: error("Parameter `signKeyPassphrase` not found")
|
||||
useInMemoryPgpKeys(signKeyId, signKeyPrivate, signKeyPassphrase)
|
||||
} else {
|
||||
useGpgCmd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
package plugins
|
||||
|
||||
import org.codehaus.groovy.runtime.InvokerHelper
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.maven.Conf2ScopeMappingContainer
|
||||
import org.gradle.api.artifacts.maven.MavenDeployment
|
||||
import org.gradle.api.artifacts.maven.MavenResolver
|
||||
import org.gradle.api.plugins.MavenPluginConvention
|
||||
import org.gradle.api.plugins.MavenRepositoryHandlerConvention
|
||||
import org.gradle.api.publication.maven.internal.deployer.MavenRemoteRepository
|
||||
import org.gradle.api.tasks.Upload
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.plugins.signing.Sign
|
||||
import org.gradle.plugins.signing.SigningExtension
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
* Configures a Kotlin module for publication.
|
||||
*/
|
||||
open class PublishedKotlinModule : Plugin<Project> {
|
||||
|
||||
private fun String.toBooleanOrNull() = listOf(true, false).firstOrNull { it.toString().equals(this, ignoreCase = true) }
|
||||
|
||||
override fun apply(project: Project) {
|
||||
|
||||
project.run {
|
||||
|
||||
plugins.apply("maven")
|
||||
|
||||
configurations.maybeCreate("publishedRuntime").apply {
|
||||
the<MavenPluginConvention>()
|
||||
.conf2ScopeMappings
|
||||
.addMapping(0, this, Conf2ScopeMappingContainer.RUNTIME)
|
||||
}
|
||||
|
||||
configurations.maybeCreate("publishedCompile").apply {
|
||||
the<MavenPluginConvention>()
|
||||
.conf2ScopeMappings
|
||||
.addMapping(0, this, Conf2ScopeMappingContainer.COMPILE)
|
||||
}
|
||||
|
||||
if (!project.hasProperty("prebuiltJar")) {
|
||||
plugins.apply("signing")
|
||||
|
||||
val signingRequired = project.findProperty("signingRequired")?.toString()?.toBooleanOrNull()
|
||||
?: project.property("isSonatypeRelease") as Boolean
|
||||
|
||||
configure<SigningExtension> {
|
||||
isRequired = signingRequired
|
||||
sign(configurations["archives"])
|
||||
useGpgCmd()
|
||||
}
|
||||
|
||||
tasks.named<Sign>("signArchives").configure {
|
||||
enabled = signingRequired
|
||||
}
|
||||
}
|
||||
|
||||
fun MavenResolver.configurePom() {
|
||||
pom.project {
|
||||
withGroovyBuilder {
|
||||
"licenses" {
|
||||
"license" {
|
||||
"name"("The Apache Software License, Version 2.0")
|
||||
"url"("http://www.apache.org/licenses/LICENSE-2.0.txt")
|
||||
"distribution"("repo")
|
||||
}
|
||||
}
|
||||
"name"("${project.group}:${project.name}")
|
||||
"packaging"("jar")
|
||||
// optionally artifactId can be defined here
|
||||
"description"(project.description)
|
||||
"url"("https://kotlinlang.org/")
|
||||
"licenses" {
|
||||
"license" {
|
||||
"name"("The Apache License, Version 2.0")
|
||||
"url"("http://www.apache.org/licenses/LICENSE-2.0.txt")
|
||||
}
|
||||
}
|
||||
"scm" {
|
||||
"url"("https://github.com/JetBrains/kotlin")
|
||||
"connection"("scm:git:https://github.com/JetBrains/kotlin.git")
|
||||
"developerConnection"("scm:git:https://github.com/JetBrains/kotlin.git")
|
||||
}
|
||||
"developers" {
|
||||
"developer" {
|
||||
"name"("Kotlin Team")
|
||||
setProperty("organization", "JetBrains")
|
||||
"organizationUrl"("https://www.jetbrains.com")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pom.whenConfigured {
|
||||
dependencies.removeIf {
|
||||
InvokerHelper.getMetaClass(it).getProperty(it, "scope") == "test"
|
||||
}
|
||||
|
||||
dependencies
|
||||
.find {
|
||||
InvokerHelper.getMetaClass(it).getProperty(it, "groupId") == "org.jetbrains.kotlin"
|
||||
&& InvokerHelper.getMetaClass(it).getProperty(it, "artifactId") == "kotlin-stdlib"
|
||||
}
|
||||
?.also {
|
||||
InvokerHelper.getMetaClass(it).setProperty(it, "exclusions", emptyList<Any>())
|
||||
logger.warn("WARNING! Removed exclusions from kotlin-stdlib dependency of ${this.artifactId} artifact's maven metadata, check kotlin-stdlib dependency of ${project.path} project")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<Upload>("uploadArchives").configure {
|
||||
|
||||
val preparePublication = project.rootProject.tasks.named("preparePublication").get()
|
||||
|
||||
dependsOn(preparePublication)
|
||||
|
||||
val username: String? by preparePublication.extra
|
||||
val password: String? by preparePublication.extra
|
||||
val repoUrl: String by preparePublication.extra
|
||||
|
||||
var repository by Delegates.notNull<MavenRemoteRepository>()
|
||||
|
||||
repositories {
|
||||
withConvention(MavenRepositoryHandlerConvention::class) {
|
||||
|
||||
mavenDeployer {
|
||||
withGroovyBuilder {
|
||||
"beforeDeployment" {
|
||||
val signing = project.the<SigningExtension>()
|
||||
if (signing.isRequired)
|
||||
signing.signPom(delegate as MavenDeployment)
|
||||
}
|
||||
|
||||
"repository"("url" to repoUrl)!!.also { repository = it as MavenRemoteRepository }.withGroovyBuilder {
|
||||
if (username != null && password != null) {
|
||||
"authentication"("userName" to username, "password" to password)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurePom()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doFirst {
|
||||
repository.url = repoUrl
|
||||
}
|
||||
}
|
||||
|
||||
val install = if (tasks.names.contains("install")) tasks.getByName("install") as Upload
|
||||
else tasks.create("install", Upload::class.java)
|
||||
install.apply {
|
||||
configuration = project.configurations.getByName(Dependency.ARCHIVES_CONFIGURATION)
|
||||
description = "Installs the 'archives' artifacts into the local Maven repository."
|
||||
repositories {
|
||||
withConvention(MavenRepositoryHandlerConvention::class) {
|
||||
mavenInstaller {
|
||||
configurePom()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("publish") {
|
||||
dependsOn(tasks.named("uploadArchives"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,8 +354,8 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
extractor.provideConfigurationKeys()
|
||||
extractor.configure(keyConfiguration, module.directives)
|
||||
}
|
||||
val kind = configuratorForFlags.extractConfigurationKind(module.directives)
|
||||
val jdkKind = configuratorForFlags.extractJdkKind(module.directives)
|
||||
val kind = JvmEnvironmentConfigurator.extractConfigurationKind(module.directives)
|
||||
val jdkKind = JvmEnvironmentConfigurator.extractJdkKind(module.directives)
|
||||
|
||||
keyConfiguration.languageVersionSettings = module.languageVersionSettings
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ interface TypeMappingContext<Writer : JvmDescriptorTypeWriter<Type>> {
|
||||
val typeContext: TypeSystemCommonBackendContextForTypeMapping
|
||||
|
||||
fun getClassInternalName(typeConstructor: TypeConstructorMarker): String
|
||||
fun getScriptInternalName(typeConstructor: TypeConstructorMarker): String
|
||||
fun Writer.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode)
|
||||
}
|
||||
|
||||
@@ -117,9 +118,7 @@ object AbstractTypeMapper {
|
||||
}
|
||||
|
||||
typeConstructor.isScript() -> {
|
||||
val asmType = AsmTypes.JAVA_CLASS_TYPE
|
||||
with(context) { sw?.writeGenericType(type, asmType, mode) }
|
||||
return asmType
|
||||
return Type.getObjectType(context.getScriptInternalName(typeConstructor))
|
||||
}
|
||||
|
||||
typeConstructor.isTypeParameter() -> {
|
||||
|
||||
@@ -34,10 +34,10 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil;
|
||||
import org.jetbrains.kotlin.types.FlexibleType;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypesKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
@@ -376,7 +376,7 @@ public abstract class AnnotationCodegen {
|
||||
// We do not generate annotations whose classes are optional (annotated with `@OptionalExpectation`) because if an annotation entry
|
||||
// is resolved to the expected declaration, this means that annotation has no actual class, and thus should not be generated.
|
||||
// (Otherwise we would've resolved the entry to the actual annotation class.)
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(classDescriptor)) {
|
||||
if (OptionalAnnotationUtil.isOptionalAnnotationClass(classDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import kotlin.Unit;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.ClosureContext;
|
||||
@@ -31,7 +32,6 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -376,10 +376,12 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
value = StackValue.local(slot, type, bridgeParameterKotlinTypes.get(i));
|
||||
slot += type.getSize();
|
||||
}
|
||||
if (InlineClassesCodegenUtilKt.isInlineClassWithUnderlyingTypeAnyOrAnyN(parameterType) &&
|
||||
functionReferenceCall == null
|
||||
) {
|
||||
parameterType = InlineClassesUtilsKt.unsubstitutedUnderlyingParameter(parameterType).getType();
|
||||
if (InlineClassesCodegenUtilKt.isInlineClassWithUnderlyingTypeAnyOrAnyN(parameterType) && functionReferenceCall == null) {
|
||||
ClassDescriptor descriptor = TypeUtils.getClassDescriptor(parameterType);
|
||||
InlineClassRepresentation<SimpleType> representation =
|
||||
descriptor != null ? descriptor.getInlineClassRepresentation() : null;
|
||||
assert representation != null : "Not an inline class type: " + parameterType;
|
||||
parameterType = representation.getUnderlyingType();
|
||||
}
|
||||
value.put(typeMapper.mapType(calleeParameter), parameterType, iv);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ class ErasedInlineClassBodyCodegen(
|
||||
}
|
||||
|
||||
private fun generateUnboxMethod() {
|
||||
val boxMethodDescriptor = InlineClassDescriptorResolver.createBoxFunctionDescriptor(descriptor) ?: return
|
||||
val boxMethodDescriptor = InlineClassDescriptorResolver.createBoxFunctionDescriptor(descriptor)
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
Synthetic(null, boxMethodDescriptor), boxMethodDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@@ -103,7 +103,7 @@ class ErasedInlineClassBodyCodegen(
|
||||
}
|
||||
|
||||
private fun generateSpecializedEqualsStub() {
|
||||
val specializedEqualsDescriptor = InlineClassDescriptorResolver.createSpecializedEqualsDescriptor(descriptor) ?: return
|
||||
val specializedEqualsDescriptor = InlineClassDescriptorResolver.createSpecializedEqualsDescriptor(descriptor)
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
Synthetic(null, specializedEqualsDescriptor), specializedEqualsDescriptor, object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
@@ -92,7 +93,6 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker;
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker;
|
||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
@@ -265,13 +265,23 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
);
|
||||
}
|
||||
|
||||
private static void addReifiedParametersFromSignature(@NotNull MemberCodegen member, @NotNull ClassDescriptor descriptor) {
|
||||
private static void addReifiedParametersFromSignature(@NotNull MemberCodegen<?> member, @NotNull ClassDescriptor descriptor) {
|
||||
for (KotlinType type : descriptor.getTypeConstructor().getSupertypes()) {
|
||||
for (TypeProjection supertypeArgument : type.getArguments()) {
|
||||
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(supertypeArgument.getType());
|
||||
if (parameterDescriptor != null && parameterDescriptor.isReified()) {
|
||||
processTypeArguments(member, type);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processTypeArguments(@NotNull MemberCodegen<?> member, KotlinType type) {
|
||||
for (TypeProjection supertypeArgument : type.getArguments()) {
|
||||
if (supertypeArgument.isStarProjection()) continue;
|
||||
|
||||
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(supertypeArgument.getType());
|
||||
if (parameterDescriptor != null) {
|
||||
if (parameterDescriptor.isReified()) {
|
||||
member.getReifiedTypeParametersUsages().addUsedReifiedParameter(parameterDescriptor.getName().asString());
|
||||
}
|
||||
} else {
|
||||
processTypeArguments(member, supertypeArgument.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2014,10 +2024,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
// Do not unbox parameters of suspend lambda, they are unboxed in `invoke` method
|
||||
!CoroutineCodegenUtilKt.isInvokeSuspendOfLambda(context.getFunctionDescriptor())
|
||||
) {
|
||||
KotlinType underlyingType = InlineClassesUtilsKt.underlyingRepresentation(
|
||||
(ClassDescriptor) inlineClassType.getConstructor().getDeclarationDescriptor()).getType();
|
||||
return StackValue.underlyingValueOfInlineClass(
|
||||
typeMapper.mapType(underlyingType), underlyingType, localOrCaptured);
|
||||
ClassDescriptor inlineClass = (ClassDescriptor) inlineClassType.getConstructor().getDeclarationDescriptor();
|
||||
InlineClassRepresentation<SimpleType> representation =
|
||||
inlineClass != null ? inlineClass.getInlineClassRepresentation() : null;
|
||||
assert representation != null : "Not an inline class: " + inlineClassType;
|
||||
KotlinType underlyingType = representation.getUnderlyingType();
|
||||
return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(underlyingType), underlyingType, localOrCaptured);
|
||||
}
|
||||
}
|
||||
return localOrCaptured;
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -369,23 +370,22 @@ public class FunctionCodegen {
|
||||
public static void generateMethodInsideInlineClassWrapper(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull ClassDescriptor containingDeclaration,
|
||||
@NotNull ClassDescriptor inlineClass,
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
) {
|
||||
mv.visitCode();
|
||||
|
||||
Type fieldOwnerType = typeMapper.mapClass(containingDeclaration);
|
||||
Type fieldOwnerType = typeMapper.mapClass(inlineClass);
|
||||
Method erasedMethodImpl = typeMapper.mapAsmMethod(functionDescriptor.getOriginal(), OwnerKind.ERASED_INLINE_CLASS);
|
||||
|
||||
ValueParameterDescriptor valueRepresentation = InlineClassesUtilsKt.underlyingRepresentation(containingDeclaration);
|
||||
if (valueRepresentation == null) return;
|
||||
|
||||
Type fieldType = typeMapper.mapType(valueRepresentation);
|
||||
InlineClassRepresentation<SimpleType> representation = inlineClass.getInlineClassRepresentation();
|
||||
assert representation != null : "Not an inline class: " + inlineClass;
|
||||
|
||||
generateDelegateToStaticErasedVersion(
|
||||
mv, erasedMethodImpl,
|
||||
fieldOwnerType, valueRepresentation.getName().asString(), fieldType
|
||||
mv, erasedMethodImpl, fieldOwnerType,
|
||||
representation.getUnderlyingPropertyName().asString(),
|
||||
typeMapper.mapType(representation.getUnderlyingType())
|
||||
);
|
||||
|
||||
endVisit(mv, null, origin.getElement());
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -274,26 +275,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
protected void generateUnboxMethodForInlineClass() {
|
||||
if (!(myClass instanceof KtClass)) return;
|
||||
if (!InlineClassesUtilsKt.isInlineClass(descriptor)) return;
|
||||
InlineClassRepresentation<SimpleType> inlineClassRepresentation = descriptor.getInlineClassRepresentation();
|
||||
if (inlineClassRepresentation == null) return;
|
||||
|
||||
Type ownerType = typeMapper.mapClass(descriptor);
|
||||
ValueParameterDescriptor inlinedValue = InlineClassesUtilsKt.underlyingRepresentation(this.descriptor);
|
||||
if (inlinedValue == null) return;
|
||||
|
||||
Type valueType = typeMapper.mapType(inlinedValue.getType());
|
||||
Type valueType = typeMapper.mapType(inlineClassRepresentation.getUnderlyingType());
|
||||
SimpleFunctionDescriptor functionDescriptor = InlineClassDescriptorResolver.createUnboxFunctionDescriptor(this.descriptor);
|
||||
assert functionDescriptor != null : "FunctionDescriptor for unbox method should be not null during codegen";
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
JvmDeclarationOriginKt.UnboxMethodOfInlineClass(functionDescriptor), functionDescriptor,
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
public void doGenerateBody(
|
||||
@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature
|
||||
) {
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
InstructionAdapter iv = codegen.v;
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
iv.getfield(ownerType.getInternalName(), inlinedValue.getName().asString(), valueType.getDescriptor());
|
||||
iv.getfield(
|
||||
ownerType.getInternalName(),
|
||||
inlineClassRepresentation.getUnderlyingPropertyName().asString(),
|
||||
valueType.getDescriptor()
|
||||
);
|
||||
iv.areturn(valueType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.PackageDescriptorUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil;
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -91,8 +91,8 @@ public class PackageCodegenImpl implements PackageCodegen {
|
||||
if (declaration instanceof KtClassOrObject) {
|
||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, declaration);
|
||||
if (PsiUtilsKt.hasExpectModifier(declaration)) {
|
||||
if (descriptor != null && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(descriptor)) {
|
||||
assert ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor) :
|
||||
if (descriptor != null && OptionalAnnotationUtil.shouldGenerateExpectClass(descriptor)) {
|
||||
assert OptionalAnnotationUtil.isOptionalAnnotationClass(descriptor) :
|
||||
"Expect class should be generated only if it's an optional annotation: " + descriptor;
|
||||
state.getFactory().getPackagePartRegistry().getOptionalAnnotations().add(descriptor);
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE
|
||||
@@ -601,21 +599,6 @@ class CoroutineCodegenForLambda private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun isCapturedSuspendLambda(closure: CalculatedClosure, name: String, bindingContext: BindingContext): Boolean {
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param !is ValueParameterDescriptor) continue
|
||||
if (value.fieldName != name) continue
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
val classDescriptor = closure.capturedOuterClassDescriptor ?: return false
|
||||
return isCapturedSuspendLambda(classDescriptor, name, bindingContext)
|
||||
}
|
||||
|
||||
fun isCapturedSuspendLambda(classDescriptor: ClassDescriptor, name: String, bindingContext: BindingContext): Boolean {
|
||||
val closure = bindingContext[CLOSURE, classDescriptor] ?: return false
|
||||
return isCapturedSuspendLambda(closure, name, bindingContext)
|
||||
}
|
||||
|
||||
private class AddEndLabelMethodVisitor(
|
||||
delegate: MethodVisitor,
|
||||
access: Int,
|
||||
|
||||
@@ -650,7 +650,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
val livenessFrames = analyzeLiveness(methodNode)
|
||||
|
||||
// References shall be cleaned up after uspill (during spill in next suspension point) to prevent memory leaks,
|
||||
// References shall be cleaned up after unspill (during spill in next suspension point) to prevent memory leaks,
|
||||
val referencesToSpillBySuspensionPointIndex = arrayListOf<List<ReferenceToSpill>>()
|
||||
// while primitives shall not
|
||||
val primitivesToSpillBySuspensionPointIndex = arrayListOf<List<PrimitiveToSpill>>()
|
||||
@@ -759,6 +759,35 @@ class CoroutineTransformerMethodVisitor(
|
||||
referencesToCleanBySuspensionPointIndex += currentSpilledReferencesCount to predSpilledReferencesCount
|
||||
}
|
||||
|
||||
// Calculate debug metadata mapping before modifying method node to make it easier to locate
|
||||
// locals alive across suspension points.
|
||||
|
||||
fun calculateSpilledVariableAndField(
|
||||
suspension: SuspensionPoint,
|
||||
slot: Int,
|
||||
spillableVariable: SpillableVariable?
|
||||
): SpilledVariableAndField? {
|
||||
if (spillableVariable == null) return null
|
||||
val name = localVariableName(methodNode, slot, suspension.suspensionCallBegin.index()) ?: return null
|
||||
return SpilledVariableAndField(spillableVariable.fieldName, name)
|
||||
}
|
||||
|
||||
val spilledToVariableMapping = arrayListOf<List<SpilledVariableAndField>>()
|
||||
for (suspensionPointIndex in suspensionPoints.indices) {
|
||||
val suspension = suspensionPoints[suspensionPointIndex]
|
||||
|
||||
val spilledToVariable = arrayListOf<SpilledVariableAndField>()
|
||||
|
||||
referencesToSpillBySuspensionPointIndex[suspensionPointIndex].mapNotNullTo(spilledToVariable) { (slot, spillableVariable) ->
|
||||
calculateSpilledVariableAndField(suspension, slot, spillableVariable)
|
||||
}
|
||||
primitivesToSpillBySuspensionPointIndex[suspensionPointIndex].mapNotNullTo(spilledToVariable) { (slot, spillableVariable) ->
|
||||
calculateSpilledVariableAndField(suspension, slot, spillableVariable)
|
||||
}
|
||||
|
||||
spilledToVariableMapping += spilledToVariable
|
||||
}
|
||||
|
||||
// Mutate method node
|
||||
|
||||
fun generateSpillAndUnspill(suspension: SuspensionPoint, slot: Int, spillableVariable: SpillableVariable?) {
|
||||
@@ -772,6 +801,22 @@ class CoroutineTransformerMethodVisitor(
|
||||
return
|
||||
}
|
||||
|
||||
// Find and remove the local variable node, if any, in the local variable table corresponding to the slot that is spilled.
|
||||
var local: LocalVariableNode? = null
|
||||
val localRestart = LabelNode().linkWithLabel()
|
||||
val iterator = methodNode.localVariables.listIterator()
|
||||
while (iterator.hasNext()) {
|
||||
val node = iterator.next()
|
||||
if (node.index == slot &&
|
||||
methodNode.instructions.indexOf(node.start) <= methodNode.instructions.indexOf(suspension.suspensionCallBegin) &&
|
||||
methodNode.instructions.indexOf(node.end) > methodNode.instructions.indexOf(suspension.tryCatchBlockEndLabelAfterSuspensionCall)
|
||||
) {
|
||||
local = node
|
||||
iterator.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
with(instructions) {
|
||||
// store variable before suspension call
|
||||
insertBefore(suspension.suspensionCallBegin, withInstructionAdapter {
|
||||
@@ -795,8 +840,31 @@ class CoroutineTransformerMethodVisitor(
|
||||
)
|
||||
StackValue.coerce(spillableVariable.normalizedType, spillableVariable.type, this)
|
||||
store(slot, spillableVariable.type)
|
||||
if (local != null) {
|
||||
visitLabel(localRestart.label)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Split the local variable range for the local so that it is visible until the next state label, but is
|
||||
// not visible until it has been unspilled from the continuation on the reentry path.
|
||||
if (local != null) {
|
||||
val previousEnd = local.end
|
||||
local.end = suspension.stateLabel
|
||||
// Add the local back, but end it at the next state label.
|
||||
methodNode.localVariables.add(local)
|
||||
// Add a new entry that starts after the local variable is restored from the continuation.
|
||||
methodNode.localVariables.add(
|
||||
LocalVariableNode(
|
||||
local.name,
|
||||
local.desc,
|
||||
local.signature,
|
||||
localRestart,
|
||||
previousEnd,
|
||||
local.index
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun cleanUpField(suspension: SuspensionPoint, fieldIndex: Int) {
|
||||
@@ -839,33 +907,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate debug metadata mapping
|
||||
|
||||
fun calculateSpilledVariableAndField(
|
||||
suspension: SuspensionPoint,
|
||||
slot: Int,
|
||||
spillableVariable: SpillableVariable?
|
||||
): SpilledVariableAndField? {
|
||||
if (spillableVariable == null) return null
|
||||
val name = localVariableName(methodNode, slot, suspension.suspensionCallEnd.next.index()) ?: return null
|
||||
return SpilledVariableAndField(spillableVariable.fieldName, name)
|
||||
}
|
||||
|
||||
val spilledToVariableMapping = arrayListOf<List<SpilledVariableAndField>>()
|
||||
for (suspensionPointIndex in suspensionPoints.indices) {
|
||||
val suspension = suspensionPoints[suspensionPointIndex]
|
||||
|
||||
val spilledToVariable = arrayListOf<SpilledVariableAndField>()
|
||||
|
||||
referencesToSpillBySuspensionPointIndex[suspensionPointIndex].mapNotNullTo(spilledToVariable) { (slot, spillableVariable) ->
|
||||
calculateSpilledVariableAndField(suspension, slot, spillableVariable)
|
||||
}
|
||||
primitivesToSpillBySuspensionPointIndex[suspensionPointIndex].mapNotNullTo(spilledToVariable) { (slot, spillableVariable) ->
|
||||
calculateSpilledVariableAndField(suspension, slot, spillableVariable)
|
||||
}
|
||||
|
||||
spilledToVariableMapping += spilledToVariable
|
||||
}
|
||||
return spilledToVariableMapping
|
||||
}
|
||||
|
||||
@@ -901,7 +942,6 @@ class CoroutineTransformerMethodVisitor(
|
||||
suspendMarkerVarIndex: Int,
|
||||
suspendPointLineNumber: LineNumberNode?
|
||||
): LabelNode {
|
||||
val stateLabel = LabelNode().linkWithLabel()
|
||||
val continuationLabelAfterLoadedResult = LabelNode()
|
||||
val suspendElementLineNumber = lineNumber
|
||||
var nextLineNumberNode = nextDefinitelyHitLineNumber(suspension)
|
||||
@@ -929,7 +969,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
load(suspendMarkerVarIndex, AsmTypes.OBJECT_TYPE)
|
||||
areturn(AsmTypes.OBJECT_TYPE)
|
||||
// Mark place for continuation
|
||||
visitLabel(stateLabel.label)
|
||||
visitLabel(suspension.stateLabel.label)
|
||||
})
|
||||
|
||||
// After suspension point there is always three nodes: L1, NOP, L2
|
||||
@@ -985,7 +1025,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
return stateLabel
|
||||
return suspension.stateLabel
|
||||
}
|
||||
|
||||
// Find the next line number instruction that is defintely hit. That is, a line number
|
||||
@@ -1154,6 +1194,7 @@ internal class SuspensionPoint(
|
||||
) {
|
||||
lateinit var tryCatchBlocksContinuationLabel: LabelNode
|
||||
|
||||
val stateLabel = LabelNode().linkWithLabel()
|
||||
val unboxInlineClassInstructions: List<AbstractInsnNode> = findUnboxInlineClassInstructions()
|
||||
|
||||
private fun findUnboxInlineClassInstructions(): List<AbstractInsnNode> {
|
||||
@@ -1235,16 +1276,13 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
fun isAlive(insnIndex: Int, variableIndex: Int): Boolean =
|
||||
liveness[insnIndex].isAlive(variableIndex)
|
||||
|
||||
fun nextSuspensionPointEndLabel(insn: AbstractInsnNode): LabelNode {
|
||||
val suspensionPoint =
|
||||
InsnSequence(insn, method.instructions.last).firstOrNull { isAfterSuspendMarker(it) } ?: method.instructions.last
|
||||
return suspensionPoint as? LabelNode ?: suspensionPoint.findNextOrNull { it is LabelNode } as LabelNode
|
||||
}
|
||||
|
||||
fun nextSuspensionPointStartLabel(insn: AbstractInsnNode): LabelNode {
|
||||
val suspensionPoint =
|
||||
InsnSequence(insn, method.instructions.last).firstOrNull { isBeforeSuspendMarker(it) } ?: method.instructions.last
|
||||
return suspensionPoint as? LabelNode ?: suspensionPoint.findPreviousOrNull { it is LabelNode } as LabelNode
|
||||
fun nextLabel(node: AbstractInsnNode?): LabelNode? {
|
||||
var current = node
|
||||
while (current != null) {
|
||||
if (current is LabelNode) return current
|
||||
current = current.next
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun min(a: LabelNode, b: LabelNode): LabelNode =
|
||||
@@ -1253,9 +1291,6 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
fun max(a: LabelNode, b: LabelNode): LabelNode =
|
||||
if (method.instructions.indexOf(a) < method.instructions.indexOf(b)) b else a
|
||||
|
||||
fun containsSuspensionPoint(a: LabelNode, b: LabelNode): Boolean =
|
||||
InsnSequence(min(a, b), max(a, b)).none { isBeforeSuspendMarker(it) }
|
||||
|
||||
val oldLvt = arrayListOf<LocalVariableNode>()
|
||||
for (record in method.localVariables) {
|
||||
oldLvt += record
|
||||
@@ -1276,35 +1311,40 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
// No variable in LVT -> do not add one
|
||||
val lvtRecord = oldLvt.findRecord(insnIndex, variableIndex) ?: continue
|
||||
if (lvtRecord.name == CONTINUATION_VARIABLE_NAME) continue
|
||||
// Extend lvt record to the next suspension point
|
||||
val endLabel = min(lvtRecord.end, nextSuspensionPointEndLabel(insn))
|
||||
// End the local when it is no longer live. Since it is not live, we will not spill and unspill it across
|
||||
// suspension points. It is tempting to keep it alive until the next suspension point to leave it visible in
|
||||
// the debugger for as long as possible. However, in the case of loops, the resumption after suspension can
|
||||
// have a backwards edge targeting instruction between the point of death and the next suspension point.
|
||||
//
|
||||
// For example, code such as the following:
|
||||
//
|
||||
// listOf<String>.forEach {
|
||||
// yield(it)
|
||||
// }
|
||||
//
|
||||
// Generates code of this form with a back edge after resumption that will lead to invalid locals tables
|
||||
// if the local range is extended to the next suspension point.
|
||||
//
|
||||
// iterator = iterable.iterator()
|
||||
// L1: (iterable dies here)
|
||||
// load iterator.next if there
|
||||
// yield suspension point
|
||||
//
|
||||
// L2: (resumption point)
|
||||
// restore live variables (not including iterable)
|
||||
// goto L1 (iterator not restored here, so we cannot not have iterator live at L1)
|
||||
val endLabel = nextLabel(insn.next)?.let { min(lvtRecord.end, it) } ?: lvtRecord.end
|
||||
// startLabel can be null in case of parameters
|
||||
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
|
||||
// Attempt to extend existing local variable node corresponding to the record in
|
||||
// the original local variable table.
|
||||
val recordToExtend: LocalVariableNode? = oldLvtNodeToLatestNewLvtNode[lvtRecord]
|
||||
if (recordToExtend != null && containsSuspensionPoint(recordToExtend.end, startLabel)) {
|
||||
recordToExtend.end = endLabel
|
||||
} else {
|
||||
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||
if (lvtRecord !in oldLvtNodeToLatestNewLvtNode) {
|
||||
method.localVariables.add(node)
|
||||
}
|
||||
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
|
||||
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||
if (lvtRecord !in oldLvtNodeToLatestNewLvtNode) {
|
||||
method.localVariables.add(node)
|
||||
}
|
||||
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val deadVariables = arrayListOf<Int>()
|
||||
outer@for (variableIndex in start until method.maxLocals) {
|
||||
if (oldLvt.none { it.index == variableIndex }) continue
|
||||
for (insnIndex in 0 until (method.instructions.size() - 1)) {
|
||||
if (isAlive(insnIndex, variableIndex)) continue@outer
|
||||
}
|
||||
deadVariables += variableIndex
|
||||
}
|
||||
|
||||
for (variable in oldLvt) {
|
||||
// $continuation and $result are dead, but they are used by debugger, as well as fake inliner variables
|
||||
// For example, $continuation is used to create async stack trace
|
||||
@@ -1320,19 +1360,5 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
method.localVariables.add(variable)
|
||||
continue
|
||||
}
|
||||
|
||||
// Shrink LVT records of dead variables to the next suspension point
|
||||
if (variable.index in deadVariables) {
|
||||
method.localVariables.add(
|
||||
LocalVariableNode(
|
||||
variable.name,
|
||||
variable.desc,
|
||||
variable.signature,
|
||||
variable.start,
|
||||
min(variable.end, nextSuspensionPointStartLabel(variable.start)),
|
||||
variable.index
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
|
||||
}.toMap()
|
||||
|
||||
newCall.setResultingSubstitutor(
|
||||
newCall.setSubstitutor(
|
||||
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
|
||||
)
|
||||
|
||||
|
||||
@@ -547,7 +547,7 @@ class AnonymousObjectTransformer(
|
||||
capturedParamBuilder.addCapturedParam(desc, desc.fieldName, !capturedOuterThisTypes.add(desc.type.className))
|
||||
else
|
||||
capturedParamBuilder.addCapturedParam(desc, addUniqueField(desc.fieldName + INLINE_TRANSFORMATION_SUFFIX), false)
|
||||
if (info is ExpressionLambda && info.isCapturedSuspend(desc)) {
|
||||
if (desc.isSuspend) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
}
|
||||
val composed = StackValue.field(
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class CapturedParamDesc(private val containingLambdaType: Type, val fieldName: String, val type: Type) {
|
||||
|
||||
val containingLambdaName: String
|
||||
get() = containingLambdaType.internalName
|
||||
class CapturedParamDesc(containingLambdaType: Type, val fieldName: String, val type: Type, val isSuspend: Boolean = false) {
|
||||
val containingLambdaName: String = containingLambdaType.internalName
|
||||
}
|
||||
|
||||
@@ -320,8 +320,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
|
||||
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
|
||||
processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
|
||||
|
||||
//processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy);
|
||||
processor.localVarsMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true);
|
||||
|
||||
mark.dropTo()
|
||||
}
|
||||
@@ -330,8 +329,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
}
|
||||
|
||||
processor.substituteTryBlockNodes(intoNode)
|
||||
|
||||
//processor.substituteLocalVarTable(intoNode);
|
||||
processor.substituteLocalVarTable(intoNode);
|
||||
}
|
||||
|
||||
protected abstract fun generateAssertFieldIfNeeded(info: RootInliningContext)
|
||||
|
||||
@@ -5,32 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil
|
||||
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.*
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
import kotlin.properties.Delegates
|
||||
@@ -47,7 +28,9 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
|
||||
abstract val invokeMethod: Method
|
||||
|
||||
abstract val invokeMethodDescriptor: FunctionDescriptor
|
||||
abstract val invokeMethodParameters: List<KotlinType?>
|
||||
|
||||
abstract val invokeMethodReturnType: KotlinType?
|
||||
|
||||
abstract val capturedVars: List<CapturedParamDesc>
|
||||
|
||||
@@ -56,6 +39,8 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
|
||||
lateinit var node: SMAPAndMethodNode
|
||||
|
||||
val reifiedTypeParametersUsages = ReifiedTypeParametersUsages()
|
||||
|
||||
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>)
|
||||
|
||||
open val hasDispatchReceiver = true
|
||||
@@ -67,7 +52,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
val field = remapper.findField(FieldInsnNode(0, info.containingLambdaName, info.fieldName, ""))
|
||||
?: error("Captured field not found: " + info.containingLambdaName + "." + info.fieldName)
|
||||
val recapturedParamInfo = builder.addCapturedParam(field, info.fieldName)
|
||||
if (this is ExpressionLambda && isCapturedSuspend(info)) {
|
||||
if (info.isSuspend) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
}
|
||||
}
|
||||
@@ -75,14 +60,9 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
return builder.buildParameters()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun LambdaInfo.getCapturedParamInfo(descriptor: EnclosedValueDescriptor): CapturedParamDesc {
|
||||
return capturedParamDesc(descriptor.fieldName, descriptor.type)
|
||||
}
|
||||
|
||||
fun LambdaInfo.capturedParamDesc(fieldName: String, fieldType: Type): CapturedParamDesc {
|
||||
return CapturedParamDesc(lambdaClassType, fieldName, fieldType)
|
||||
fun LambdaInfo.capturedParamDesc(fieldName: String, fieldType: Type, isSuspend: Boolean): CapturedParamDesc {
|
||||
return CapturedParamDesc(lambdaClassType, fieldName, fieldType, isSuspend)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,31 +70,19 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
object NonInlineableArgumentForInlineableParameterCalledInSuspend : FunctionalArgument
|
||||
object NonInlineableArgumentForInlineableSuspendParameter : FunctionalArgument
|
||||
|
||||
|
||||
class PsiDefaultLambda(
|
||||
lambdaClassType: Type,
|
||||
capturedArgs: Array<Type>,
|
||||
parameterDescriptor: ValueParameterDescriptor,
|
||||
offset: Int,
|
||||
needReification: Boolean
|
||||
) : DefaultLambda(lambdaClassType, capturedArgs, parameterDescriptor, offset, needReification) {
|
||||
override fun mapAsmSignature(sourceCompiler: SourceCompilerForInline): Method {
|
||||
return sourceCompiler.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod
|
||||
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||
node = sourceCompiler.generateLambdaBody(this, reifiedTypeParametersUsages)
|
||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||
}
|
||||
|
||||
override fun findInvokeMethodDescriptor(): FunctionDescriptor =
|
||||
parameterDescriptor.type.memberScope
|
||||
.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND)
|
||||
.single()
|
||||
}
|
||||
|
||||
abstract class DefaultLambda(
|
||||
override val lambdaClassType: Type,
|
||||
private val capturedArgs: Array<Type>,
|
||||
val parameterDescriptor: ValueParameterDescriptor,
|
||||
isCrossinline: Boolean,
|
||||
val offset: Int,
|
||||
val needReification: Boolean
|
||||
) : LambdaInfo(parameterDescriptor.isCrossinline) {
|
||||
) : LambdaInfo(isCrossinline) {
|
||||
|
||||
final override var isBoundCallableReference by Delegates.notNull<Boolean>()
|
||||
private set
|
||||
@@ -124,80 +92,52 @@ abstract class DefaultLambda(
|
||||
final override lateinit var invokeMethod: Method
|
||||
private set
|
||||
|
||||
override lateinit var invokeMethodDescriptor: FunctionDescriptor
|
||||
|
||||
final override lateinit var capturedVars: List<CapturedParamDesc>
|
||||
private set
|
||||
|
||||
var originalBoundReceiverType: Type? = null
|
||||
private set
|
||||
|
||||
override val isSuspend = parameterDescriptor.isSuspendLambda
|
||||
override val isSuspend = false // TODO: it should probably be true sometimes, but it never was
|
||||
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||
val classBytes = loadClassBytesByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
||||
val classReader = ClassReader(classBytes)
|
||||
var isPropertyReference = false
|
||||
var isFunctionReference = false
|
||||
classReader.accept(object : ClassVisitor(Opcodes.API_VERSION) {
|
||||
override fun visit(
|
||||
version: Int,
|
||||
access: Int,
|
||||
name: String,
|
||||
signature: String?,
|
||||
superName: String?,
|
||||
interfaces: Array<out String>?
|
||||
) {
|
||||
isPropertyReference = superName in PROPERTY_REFERENCE_SUPER_CLASSES
|
||||
isFunctionReference = superName == FUNCTION_REFERENCE.internalName || superName == FUNCTION_REFERENCE_IMPL.internalName
|
||||
|
||||
super.visit(version, access, name, signature, superName, interfaces)
|
||||
}
|
||||
}, ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES or ClassReader.SKIP_DEBUG)
|
||||
|
||||
invokeMethodDescriptor = findInvokeMethodDescriptor().let {
|
||||
//property reference generates erased 'get' method
|
||||
if (isPropertyReference) it.original else it
|
||||
}
|
||||
|
||||
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
||||
val constructor = getMethodNode(classBytes, "<init>", descriptor, lambdaClassType)?.node
|
||||
val superName = ClassReader(classBytes).superName
|
||||
val isPropertyReference = superName in PROPERTY_REFERENCE_SUPER_CLASSES
|
||||
val isFunctionReference = superName == FUNCTION_REFERENCE.internalName || superName == FUNCTION_REFERENCE_IMPL.internalName
|
||||
|
||||
val constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
||||
val constructor = getMethodNode(classBytes, "<init>", constructorDescriptor, lambdaClassType)?.node
|
||||
assert(constructor != null || capturedArgs.isEmpty()) {
|
||||
"Can't find non-default constructor <init>$descriptor for default lambda $lambdaClassType"
|
||||
"Can't find non-default constructor <init>$constructorDescriptor for default lambda $lambdaClassType"
|
||||
}
|
||||
|
||||
capturedVars =
|
||||
if (isFunctionReference || isPropertyReference)
|
||||
constructor?.desc?.let { Type.getArgumentTypes(it) }?.singleOrNull()?.let {
|
||||
originalBoundReceiverType = it
|
||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, it.boxReceiverForBoundReference()))
|
||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, AsmUtil.boxType(it), isSuspend = false))
|
||||
} ?: emptyList()
|
||||
else
|
||||
constructor?.findCapturedFieldAssignmentInstructions()?.map { fieldNode ->
|
||||
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc))
|
||||
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc), isSuspend = false)
|
||||
}?.toList() ?: emptyList()
|
||||
|
||||
isBoundCallableReference = (isFunctionReference || isPropertyReference) && capturedVars.isNotEmpty()
|
||||
|
||||
val methodName = (if (isPropertyReference) OperatorNameConventions.GET else OperatorNameConventions.INVOKE).asString()
|
||||
|
||||
val signature = mapAsmSignature(sourceCompiler)
|
||||
|
||||
node = getMethodNode(classBytes, methodName, signature.descriptor, lambdaClassType, signatureAmbiguity = true)
|
||||
?: error("Can't find method '$methodName$signature' in '${classReader.className}'")
|
||||
|
||||
invokeMethod = Method(node.node.name, node.node.desc)
|
||||
|
||||
val invokeNameFallback = (if (isPropertyReference) OperatorNameConventions.GET else OperatorNameConventions.INVOKE).asString()
|
||||
val invokeMethod = mapAsmMethod(sourceCompiler, isPropertyReference)
|
||||
// TODO: `signatureAmbiguity = true` ignores the argument types from `invokeDescriptor` and only looks at the count.
|
||||
// This effectively masks incorrect results from `mapAsmDescriptor`, which hopefully won't manifest in another way.
|
||||
node = getMethodNode(classBytes, invokeMethod.name, invokeMethod.descriptor, lambdaClassType, signatureAmbiguity = true)
|
||||
?: getMethodNode(classBytes, invokeNameFallback, invokeMethod.descriptor, lambdaClassType, signatureAmbiguity = true)
|
||||
?: error("Can't find method '$invokeMethod' in '${lambdaClassType.internalName}'")
|
||||
this.invokeMethod = Method(node.node.name, node.node.desc)
|
||||
if (needReification) {
|
||||
//nested classes could also require reification
|
||||
reifiedTypeInliner.reifyInstructions(node.node)
|
||||
reifiedTypeParametersUsages.mergeAll(reifiedTypeInliner.reifyInstructions(node.node))
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun mapAsmSignature(sourceCompiler: SourceCompilerForInline): Method
|
||||
|
||||
protected abstract fun findInvokeMethodDescriptor(): FunctionDescriptor
|
||||
protected abstract fun mapAsmMethod(sourceCompiler: SourceCompilerForInline, isPropertyReference: Boolean): Method
|
||||
|
||||
private companion object {
|
||||
val PROPERTY_REFERENCE_SUPER_CLASSES =
|
||||
@@ -208,131 +148,3 @@ abstract class DefaultLambda(
|
||||
.mapTo(HashSet(), Type::getInternalName)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Type.boxReceiverForBoundReference() =
|
||||
AsmUtil.boxType(this)
|
||||
|
||||
internal fun Type.boxReceiverForBoundReference(kotlinType: KotlinType, typeMapper: KotlinTypeMapper) =
|
||||
DescriptorAsmUtil.boxType(this, kotlinType, typeMapper)
|
||||
|
||||
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||
node = sourceCompiler.generateLambdaBody(this)
|
||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||
}
|
||||
|
||||
abstract fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor
|
||||
abstract fun isCapturedSuspend(desc: CapturedParamDesc): Boolean
|
||||
}
|
||||
|
||||
class PsiExpressionLambda(
|
||||
expression: KtExpression,
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
isCrossInline: Boolean,
|
||||
override val isBoundCallableReference: Boolean
|
||||
) : ExpressionLambda(isCrossInline) {
|
||||
|
||||
override val lambdaClassType: Type
|
||||
|
||||
override val invokeMethod: Method
|
||||
|
||||
override val invokeMethodDescriptor: FunctionDescriptor
|
||||
|
||||
val classDescriptor: ClassDescriptor
|
||||
|
||||
val propertyReferenceInfo: PropertyReferenceInfo?
|
||||
|
||||
val functionWithBodyOrCallableReference: KtExpression = (expression as? KtLambdaExpression)?.functionLiteral ?: expression
|
||||
|
||||
override val returnLabels: Map<String, Label?>
|
||||
|
||||
override val isSuspend: Boolean
|
||||
|
||||
var closure: CalculatedClosure
|
||||
private set
|
||||
|
||||
init {
|
||||
val bindingContext = typeMapper.bindingContext
|
||||
val function =
|
||||
bindingContext.get<PsiElement, SimpleFunctionDescriptor>(BindingContext.FUNCTION, functionWithBodyOrCallableReference)
|
||||
if (function == null && expression is KtCallableReferenceExpression) {
|
||||
val variableDescriptor =
|
||||
bindingContext.get(BindingContext.VARIABLE, functionWithBodyOrCallableReference) as? VariableDescriptorWithAccessors
|
||||
?: throw AssertionError("Reference expression not resolved to variable descriptor with accessors: ${expression.getText()}")
|
||||
classDescriptor = bindingContext.get(CLASS_FOR_CALLABLE, variableDescriptor)
|
||||
?: throw IllegalStateException("Class for callable not found: $variableDescriptor\n${expression.text}")
|
||||
lambdaClassType = typeMapper.mapClass(classDescriptor)
|
||||
val getFunction = PropertyReferenceCodegen.findGetFunction(variableDescriptor)
|
||||
invokeMethodDescriptor = PropertyReferenceCodegen.createFakeOpenDescriptor(getFunction, classDescriptor)
|
||||
val resolvedCall = expression.callableReference.getResolvedCallWithAssert(bindingContext)
|
||||
propertyReferenceInfo = PropertyReferenceInfo(
|
||||
resolvedCall.resultingDescriptor as VariableDescriptor, getFunction
|
||||
)
|
||||
} else {
|
||||
propertyReferenceInfo = null
|
||||
invokeMethodDescriptor = function ?: throw AssertionError("Function is not resolved to descriptor: " + expression.text)
|
||||
classDescriptor = bindingContext.get(CLASS_FOR_CALLABLE, invokeMethodDescriptor)
|
||||
?: throw IllegalStateException("Class for invoke method not found: $invokeMethodDescriptor\n${expression.text}")
|
||||
lambdaClassType = asmTypeForAnonymousClass(bindingContext, invokeMethodDescriptor)
|
||||
}
|
||||
|
||||
bindingContext.get<ClassDescriptor, MutableClosure>(CLOSURE, classDescriptor).let {
|
||||
assert(it != null) { "Closure for lambda should be not null " + expression.text }
|
||||
closure = it!!
|
||||
}
|
||||
|
||||
returnLabels = InlineCodegen.getDeclarationLabels(expression, invokeMethodDescriptor).associateWith { null }
|
||||
invokeMethod = typeMapper.mapAsmMethod(invokeMethodDescriptor)
|
||||
isSuspend = invokeMethodDescriptor.isSuspend
|
||||
}
|
||||
|
||||
override val capturedVars: List<CapturedParamDesc> by lazy {
|
||||
arrayListOf<CapturedParamDesc>().apply {
|
||||
val captureThis = closure.capturedOuterClassDescriptor
|
||||
if (captureThis != null) {
|
||||
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, kotlinType
|
||||
)
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
}
|
||||
|
||||
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, capturedReceiver, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
||||
type, capturedReceiver
|
||||
)
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
}
|
||||
|
||||
closure.captureVariables.values.forEach { descriptor ->
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val isPropertyReference: Boolean
|
||||
get() = propertyReferenceInfo != null
|
||||
|
||||
override fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor {
|
||||
return getOrCreateJvmSuspendFunctionView(
|
||||
invokeMethodDescriptor,
|
||||
languageVersionSettings.isReleaseCoroutines(),
|
||||
typeMapper.bindingContext
|
||||
)
|
||||
}
|
||||
|
||||
override fun isCapturedSuspend(desc: CapturedParamDesc): Boolean =
|
||||
isCapturedSuspendLambda(closure, desc.fieldName, typeMapper.bindingContext)
|
||||
}
|
||||
|
||||
@@ -23,13 +23,10 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -233,52 +230,34 @@ class MethodInliner(
|
||||
return
|
||||
}
|
||||
|
||||
// in case of inlining suspend lambda reference as ordinary parameter of inline function:
|
||||
// suspend fun foo (...) ...
|
||||
// inline fun inlineMe(c: (...) -> ...) ...
|
||||
// builder {
|
||||
// inlineMe(::foo)
|
||||
// }
|
||||
// we should create additional parameter for continuation.
|
||||
var coroutineDesc = desc
|
||||
val actualInvokeDescriptor: FunctionDescriptor
|
||||
if (info.isSuspend) {
|
||||
actualInvokeDescriptor = (info as ExpressionLambda).getInlineSuspendLambdaViewDescriptor()
|
||||
val parametersSize = actualInvokeDescriptor.valueParameters.size +
|
||||
(if (actualInvokeDescriptor.extensionReceiverParameter != null) 1 else 0)
|
||||
// And here we expect invoke(...Ljava/lang/Object;) be replaced with invoke(...Lkotlin/coroutines/Continuation;)
|
||||
// if this does not happen, insert fake continuation, since we could not have one yet.
|
||||
val argumentTypes = Type.getArgumentTypes(desc)
|
||||
if (argumentTypes.size != parametersSize &&
|
||||
// But do not add it in IR. In IR we already have lowered lambdas with additional parameter, while in Old BE we don't.
|
||||
!inliningContext.root.state.isIrBackend
|
||||
) {
|
||||
val nullableAnyType = inliningContext.root.sourceCompilerForInline.compilationContextDescriptor.builtIns.nullableAnyType
|
||||
val expectedParameters = info.invokeMethod.argumentTypes
|
||||
val expectedKotlinParameters = info.invokeMethodParameters
|
||||
val argumentCount = Type.getArgumentTypes(desc).size.let {
|
||||
if (!inliningContext.root.state.isIrBackend && info.isSuspend && it < expectedParameters.size) {
|
||||
// Inlining suspend lambda into a function that takes a non-suspend lambda.
|
||||
// In the IR backend, this cannot happen as inline lambdas are not lowered.
|
||||
addFakeContinuationMarker(this)
|
||||
coroutineDesc = Type.getMethodDescriptor(Type.getReturnType(desc), *argumentTypes, AsmTypes.OBJECT_TYPE)
|
||||
}
|
||||
} else {
|
||||
actualInvokeDescriptor = info.invokeMethodDescriptor
|
||||
it + 1
|
||||
} else it
|
||||
}
|
||||
assert(argumentCount == expectedParameters.size && argumentCount == expectedKotlinParameters.size) {
|
||||
"inconsistent lambda arguments: $argumentCount on stack, ${expectedParameters.size} expected, " +
|
||||
"${expectedKotlinParameters.size} Kotlin types"
|
||||
}
|
||||
|
||||
val valueParameters =
|
||||
listOfNotNull(actualInvokeDescriptor.extensionReceiverParameter) + actualInvokeDescriptor.valueParameters
|
||||
|
||||
val erasedInvokeFunction = ClosureCodegen.getErasedInvokeFunction(actualInvokeDescriptor)
|
||||
val invokeParameters = erasedInvokeFunction.valueParameters
|
||||
|
||||
val valueParamShift = max(nextLocalIndex, markerShift)//NB: don't inline cause it changes
|
||||
val parameterTypesFromDesc = info.invokeMethod.argumentTypes
|
||||
putStackValuesIntoLocalsForLambdaOnInvoke(
|
||||
listOf(*parameterTypesFromDesc), valueParameters, invokeParameters, valueParamShift, this, coroutineDesc
|
||||
)
|
||||
|
||||
if (parameterTypesFromDesc.isEmpty()) {
|
||||
// There won't be no parameters processing and line call can be left without actual instructions.
|
||||
// Note: if function is called on the line with other instructions like 1 + foo(), 'nop' will still be generated.
|
||||
visitInsn(Opcodes.NOP)
|
||||
var valueParamShift = max(nextLocalIndex, markerShift) + expectedParameters.sumOf { it.size }
|
||||
for (index in argumentCount - 1 downTo 0) {
|
||||
val type = expectedParameters[index]
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, nullableAnyType, type, expectedKotlinParameters[index], this)
|
||||
valueParamShift -= type.size
|
||||
store(valueParamShift, type)
|
||||
}
|
||||
if (expectedParameters.isEmpty()) {
|
||||
nop() // add something for a line number to bind onto
|
||||
}
|
||||
|
||||
inlineOnlySmapSkipper?.onInlineLambdaStart(remappingMethodAdapter, info, sourceMapper.parent)
|
||||
inlineOnlySmapSkipper?.onInlineLambdaStart(remappingMethodAdapter, info.node.node, sourceMapper.parent)
|
||||
addInlineMarker(this, true)
|
||||
val lambdaParameters = info.addAllParameters(nodeRemapper)
|
||||
|
||||
@@ -303,10 +282,9 @@ class MethodInliner(
|
||||
val lambdaResult = inliner.doInline(localVariablesSorter, varRemapper, true, info.returnLabels, invokeCall.finallyDepthShift)
|
||||
result.mergeWithNotChangeInfo(lambdaResult)
|
||||
result.reifiedTypeParametersUsages.mergeAll(lambdaResult.reifiedTypeParametersUsages)
|
||||
result.reifiedTypeParametersUsages.mergeAll(info.reifiedTypeParametersUsages)
|
||||
|
||||
StackValue
|
||||
.onStack(info.invokeMethod.returnType, info.invokeMethodDescriptor.returnType)
|
||||
.put(OBJECT_TYPE, erasedInvokeFunction.returnType, this)
|
||||
StackValue.coerce(info.invokeMethod.returnType, info.invokeMethodReturnType, OBJECT_TYPE, nullableAnyType, this)
|
||||
setLambdaInlining(false)
|
||||
addInlineMarker(this, false)
|
||||
inlineOnlySmapSkipper?.onInlineLambdaEnd(remappingMethodAdapter)
|
||||
@@ -1073,46 +1051,6 @@ class MethodInliner(
|
||||
}
|
||||
}
|
||||
|
||||
private fun putStackValuesIntoLocalsForLambdaOnInvoke(
|
||||
directOrder: List<Type>,
|
||||
directOrderOfArguments: List<ParameterDescriptor>,
|
||||
directOrderOfInvokeParameters: List<ValueParameterDescriptor>,
|
||||
shift: Int,
|
||||
iv: InstructionAdapter,
|
||||
descriptor: String
|
||||
) {
|
||||
val actualParams = Type.getArgumentTypes(descriptor)
|
||||
assert(actualParams.size == directOrder.size) {
|
||||
"Number of expected and actual parameters should be equal, but ${actualParams.size} != ${directOrder.size}!"
|
||||
}
|
||||
|
||||
var currentShift = shift + directOrder.sumOf { it.size }
|
||||
|
||||
val safeToUseArgumentKotlinType =
|
||||
directOrder.size == directOrderOfArguments.size && directOrderOfArguments.size == directOrderOfInvokeParameters.size
|
||||
|
||||
for (index in directOrder.lastIndex downTo 0) {
|
||||
val type = directOrder[index]
|
||||
currentShift -= type.size
|
||||
val typeOnStack = actualParams[index]
|
||||
|
||||
val argumentKotlinType: KotlinType?
|
||||
val invokeParameterKotlinType: KotlinType?
|
||||
if (safeToUseArgumentKotlinType) {
|
||||
argumentKotlinType = directOrderOfArguments[index].type
|
||||
invokeParameterKotlinType = directOrderOfInvokeParameters[index].type
|
||||
} else {
|
||||
argumentKotlinType = null
|
||||
invokeParameterKotlinType = null
|
||||
}
|
||||
|
||||
if (typeOnStack != type || invokeParameterKotlinType != argumentKotlinType) {
|
||||
StackValue.onStack(typeOnStack, invokeParameterKotlinType).put(type, argumentKotlinType, iv)
|
||||
}
|
||||
iv.store(currentShift, type)
|
||||
}
|
||||
}
|
||||
|
||||
//process local and global returns (local substituted with goto end-label global kept unchanged)
|
||||
@JvmStatic
|
||||
fun processReturns(
|
||||
|
||||
@@ -5,20 +5,23 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
@@ -28,8 +31,11 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
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.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
class PsiInlineCodegen(
|
||||
@@ -140,9 +146,9 @@ class PsiInlineCodegen(
|
||||
val receiverKotlinType = receiver.kotlinType
|
||||
val boxedReceiver =
|
||||
if (receiverKotlinType != null)
|
||||
receiver.type.boxReceiverForBoundReference(receiverKotlinType, state.typeMapper)
|
||||
DescriptorAsmUtil.boxType(receiver.type, receiverKotlinType, state.typeMapper)
|
||||
else
|
||||
receiver.type.boxReceiverForBoundReference()
|
||||
AsmUtil.boxType(receiver.type)
|
||||
|
||||
putClosureParametersOnStack(
|
||||
lambdaInfo,
|
||||
@@ -214,3 +220,139 @@ class PsiInlineCodegen(
|
||||
override fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean =
|
||||
memberDescriptor is DescriptorWithContainerSource
|
||||
}
|
||||
|
||||
private val FunctionDescriptor.explicitParameters
|
||||
get() = listOfNotNull(extensionReceiverParameter) + valueParameters
|
||||
|
||||
class PsiExpressionLambda(
|
||||
expression: KtExpression,
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
isCrossInline: Boolean,
|
||||
override val isBoundCallableReference: Boolean
|
||||
) : ExpressionLambda(isCrossInline) {
|
||||
|
||||
override val lambdaClassType: Type
|
||||
|
||||
override val invokeMethod: Method
|
||||
|
||||
val invokeMethodDescriptor: FunctionDescriptor
|
||||
|
||||
override val invokeMethodParameters: List<KotlinType?>
|
||||
get() {
|
||||
val actualInvokeDescriptor = if (isSuspend)
|
||||
getOrCreateJvmSuspendFunctionView(
|
||||
invokeMethodDescriptor, languageVersionSettings.isReleaseCoroutines(), typeMapper.bindingContext
|
||||
)
|
||||
else
|
||||
invokeMethodDescriptor
|
||||
return actualInvokeDescriptor.explicitParameters.map { it.returnType }
|
||||
}
|
||||
|
||||
override val invokeMethodReturnType: KotlinType?
|
||||
get() = invokeMethodDescriptor.returnType
|
||||
|
||||
val classDescriptor: ClassDescriptor
|
||||
|
||||
val propertyReferenceInfo: PropertyReferenceInfo?
|
||||
|
||||
val functionWithBodyOrCallableReference: KtExpression = (expression as? KtLambdaExpression)?.functionLiteral ?: expression
|
||||
|
||||
override val returnLabels: Map<String, Label?>
|
||||
|
||||
override val isSuspend: Boolean
|
||||
|
||||
val closure: CalculatedClosure
|
||||
|
||||
init {
|
||||
val bindingContext = typeMapper.bindingContext
|
||||
val function = bindingContext.get(BindingContext.FUNCTION, functionWithBodyOrCallableReference)
|
||||
if (function == null && expression is KtCallableReferenceExpression) {
|
||||
val variableDescriptor =
|
||||
bindingContext.get(BindingContext.VARIABLE, functionWithBodyOrCallableReference) as? VariableDescriptorWithAccessors
|
||||
?: throw AssertionError("Reference expression not resolved to variable descriptor with accessors: ${expression.getText()}")
|
||||
classDescriptor = bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, variableDescriptor)
|
||||
?: throw IllegalStateException("Class for callable not found: $variableDescriptor\n${expression.text}")
|
||||
lambdaClassType = typeMapper.mapClass(classDescriptor)
|
||||
val getFunction = PropertyReferenceCodegen.findGetFunction(variableDescriptor)
|
||||
invokeMethodDescriptor = PropertyReferenceCodegen.createFakeOpenDescriptor(getFunction, classDescriptor)
|
||||
val resolvedCall = expression.callableReference.getResolvedCallWithAssert(bindingContext)
|
||||
propertyReferenceInfo = PropertyReferenceInfo(resolvedCall.resultingDescriptor as VariableDescriptor, getFunction)
|
||||
} else {
|
||||
propertyReferenceInfo = null
|
||||
invokeMethodDescriptor = function ?: throw AssertionError("Function is not resolved to descriptor: " + expression.text)
|
||||
classDescriptor = bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, invokeMethodDescriptor)
|
||||
?: throw IllegalStateException("Class for invoke method not found: $invokeMethodDescriptor\n${expression.text}")
|
||||
lambdaClassType = CodegenBinding.asmTypeForAnonymousClass(bindingContext, invokeMethodDescriptor)
|
||||
}
|
||||
|
||||
closure = bindingContext.get(CodegenBinding.CLOSURE, classDescriptor)
|
||||
?: throw AssertionError("null closure for lambda ${expression.text}")
|
||||
returnLabels = InlineCodegen.getDeclarationLabels(expression, invokeMethodDescriptor).associateWith { null }
|
||||
invokeMethod = typeMapper.mapAsmMethod(invokeMethodDescriptor)
|
||||
isSuspend = invokeMethodDescriptor.isSuspend
|
||||
}
|
||||
|
||||
override val capturedVars: List<CapturedParamDesc> by lazy {
|
||||
arrayListOf<CapturedParamDesc>().apply {
|
||||
val captureThis = closure.capturedOuterClassDescriptor
|
||||
if (captureThis != null) {
|
||||
add(capturedParamDesc(AsmUtil.CAPTURED_THIS_FIELD, typeMapper.mapType(captureThis.defaultType), isSuspend = false))
|
||||
}
|
||||
|
||||
val capturedReceiver = closure.capturedReceiverFromOuterContext
|
||||
if (capturedReceiver != null) {
|
||||
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
||||
val type = typeMapper.mapType(capturedReceiver).let {
|
||||
if (isBoundCallableReference) AsmUtil.boxType(it) else it
|
||||
}
|
||||
add(capturedParamDesc(fieldName, type, isSuspend = false))
|
||||
}
|
||||
|
||||
closure.captureVariables.forEach { (parameter, value) ->
|
||||
val isSuspend = parameter is ValueParameterDescriptor && parameter.type.isSuspendFunctionTypeOrSubtype
|
||||
add(capturedParamDesc(value.fieldName, value.type, isSuspend))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val isPropertyReference: Boolean
|
||||
get() = propertyReferenceInfo != null
|
||||
}
|
||||
|
||||
class PsiDefaultLambda(
|
||||
override val lambdaClassType: Type,
|
||||
capturedArgs: Array<Type>,
|
||||
private val parameterDescriptor: ValueParameterDescriptor,
|
||||
offset: Int,
|
||||
needReification: Boolean
|
||||
) : DefaultLambda(capturedArgs, parameterDescriptor.isCrossinline, offset, needReification) {
|
||||
private lateinit var invokeMethodDescriptor: FunctionDescriptor
|
||||
|
||||
override val invokeMethodParameters: List<KotlinType?>
|
||||
get() = invokeMethodDescriptor.explicitParameters.map { it.returnType }
|
||||
|
||||
override val invokeMethodReturnType: KotlinType?
|
||||
get() = invokeMethodDescriptor.returnType
|
||||
|
||||
override fun mapAsmMethod(sourceCompiler: SourceCompilerForInline, isPropertyReference: Boolean): Method {
|
||||
val substitutedDescriptor = parameterDescriptor.type.memberScope
|
||||
.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND)
|
||||
.single()
|
||||
invokeMethodDescriptor = when {
|
||||
// Property references: `(A) -> B` => `get(Any?): Any?`
|
||||
isPropertyReference -> substitutedDescriptor.original
|
||||
// Suspend function references: `suspend (A) -> B` => `invoke(A, Continuation<B>): Any?`
|
||||
// TODO: default suspend lambdas are currently uninlinable
|
||||
parameterDescriptor.type.isSuspendFunctionType ->
|
||||
getOrCreateJvmSuspendFunctionView(
|
||||
substitutedDescriptor,
|
||||
sourceCompiler.state.languageVersionSettings.isReleaseCoroutines(),
|
||||
sourceCompiler.state.bindingContext
|
||||
)
|
||||
// Non-suspend function references and lambdas: `(A) -> B` => `invoke(A): B`
|
||||
else -> substitutedDescriptor
|
||||
}
|
||||
return sourceCompiler.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ interface SourceCompilerForInline {
|
||||
|
||||
val lazySourceMapper: SourceMapper
|
||||
|
||||
fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode
|
||||
fun generateLambdaBody(lambdaInfo: ExpressionLambda, reifiedTypeParameters: ReifiedTypeParametersUsages): SMAPAndMethodNode
|
||||
|
||||
fun doCreateMethodNodeFromSource(
|
||||
callableDescriptor: FunctionDescriptor,
|
||||
@@ -130,7 +130,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
override val lazySourceMapper
|
||||
get() = codegen.parentCodegen.orCreateSourceMapper
|
||||
|
||||
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode {
|
||||
override fun generateLambdaBody(lambdaInfo: ExpressionLambda, reifiedTypeParameters: ReifiedTypeParametersUsages): SMAPAndMethodNode {
|
||||
lambdaInfo as? PsiExpressionLambda ?: error("TODO")
|
||||
val invokeMethodDescriptor = lambdaInfo.invokeMethodDescriptor
|
||||
val jvmMethodSignature = state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE")
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import jdk.internal.org.objectweb.asm.Type
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
@@ -16,10 +17,12 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||
@@ -250,7 +253,18 @@ fun FieldInsnNode.isSuspendLambdaCapturedByOuterObjectOrLambda(inliningContext:
|
||||
while (container !is ClassDescriptor) {
|
||||
container = container.containingDeclaration ?: return false
|
||||
}
|
||||
return isCapturedSuspendLambda(container, name, inliningContext.state.bindingContext)
|
||||
val bindingContext = inliningContext.state.bindingContext
|
||||
var classDescriptor: ClassDescriptor? = container
|
||||
while (classDescriptor != null) {
|
||||
val closure = bindingContext[CodegenBinding.CLOSURE, classDescriptor] ?: return false
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param is ValueParameterDescriptor && value.fieldName == name) {
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
}
|
||||
classDescriptor = closure.capturedOuterClassDescriptor
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Interpreter, that keeps track of captured functional arguments
|
||||
@@ -287,4 +301,4 @@ private class CapturedLambdaInterpreter : BasicInterpreter(Opcodes.API_VERSION)
|
||||
|
||||
override fun merge(v: BasicValue?, w: BasicValue?): BasicValue? =
|
||||
if (v is PossibleLambdaLoad && w is PossibleLambdaLoad && v.insn == w.insn) v else super.merge(v, w)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,8 +579,8 @@ class InlineOnlySmapSkipper(codegen: BaseExpressionCodegen) {
|
||||
const val LOCAL_VARIABLE_INLINE_ARGUMENT_SYNTHETIC_LINE_NUMBER = 1
|
||||
}
|
||||
|
||||
fun onInlineLambdaStart(mv: MethodVisitor, info: LambdaInfo, smap: SourceMapper) {
|
||||
val firstLine = info.node.node.instructions.asSequence().mapNotNull { it as? LineNumberNode }.firstOrNull()?.line ?: -1
|
||||
fun onInlineLambdaStart(mv: MethodVisitor, lambda: MethodNode, smap: SourceMapper) {
|
||||
val firstLine = lambda.instructions.asSequence().mapNotNull { it as? LineNumberNode }.firstOrNull()?.line ?: -1
|
||||
if (callLineNumber >= 0 && firstLine == callLineNumber) {
|
||||
// We want the debugger to be able to break both on the inline call itself, plus on each
|
||||
// invocation of the inline lambda passed to it. For that to happen there needs to be at least
|
||||
|
||||
@@ -12,8 +12,6 @@ import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.resolve.underlyingRepresentation
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -26,9 +24,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
fun KotlinType.isInlineClassWithUnderlyingTypeAnyOrAnyN(): Boolean {
|
||||
if (!isInlineClassType()) return false
|
||||
val classDescriptor = constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
||||
return classDescriptor.underlyingRepresentation()?.type?.isAnyOrNullableAny() == true
|
||||
val classDescriptor = constructor.declarationDescriptor
|
||||
return classDescriptor is ClassDescriptor && classDescriptor.inlineClassRepresentation?.underlyingType?.isAnyOrNullableAny() == true
|
||||
}
|
||||
|
||||
fun CallableDescriptor.isGenericParameter(): Boolean {
|
||||
@@ -79,4 +76,4 @@ fun classFileContainsMethod(classId: ClassId, state: GenerationState, method: Me
|
||||
}
|
||||
}, ClassReader.SKIP_FRAMES)
|
||||
return found
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,16 @@ package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.coroutines.RELEASE_COROUTINES_VERSION_SETTINGS
|
||||
import org.jetbrains.kotlin.codegen.coroutines.coroutinesJvmInternalPackageFqName
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.topLevelClassInternalName
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
@@ -174,7 +178,7 @@ fun AbstractInsnNode.isUnboxing(state: GenerationState) =
|
||||
isPrimitiveUnboxing() || isJavaLangClassUnboxing() || isInlineClassUnboxing(state)
|
||||
|
||||
fun AbstractInsnNode.isBoxing(state: GenerationState) =
|
||||
isPrimitiveBoxing() || isJavaLangClassBoxing() || isInlineClassBoxing(state)
|
||||
isPrimitiveBoxing() || isJavaLangClassBoxing() || isInlineClassBoxing(state) || isCoroutinePrimitiveBoxing()
|
||||
|
||||
fun AbstractInsnNode.isPrimitiveUnboxing() =
|
||||
isMethodInsnWith(Opcodes.INVOKEVIRTUAL) {
|
||||
@@ -211,6 +215,19 @@ fun AbstractInsnNode.isPrimitiveBoxing() =
|
||||
isBoxingMethodDescriptor()
|
||||
}
|
||||
|
||||
private val BOXING_CLASS_INTERNAL_NAME =
|
||||
RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName().child(Name.identifier("Boxing")).topLevelClassInternalName()
|
||||
|
||||
private fun isJvmPrimitiveName(name: String) = JvmPrimitiveType.values().any { it.javaKeywordName == name }
|
||||
|
||||
fun AbstractInsnNode.isCoroutinePrimitiveBoxing(): Boolean {
|
||||
return isMethodInsnWith(Opcodes.INVOKESTATIC) {
|
||||
owner == BOXING_CLASS_INTERNAL_NAME &&
|
||||
name.startsWith("box") &&
|
||||
isJvmPrimitiveName(name.substring(3).lowercase())
|
||||
}
|
||||
}
|
||||
|
||||
private fun MethodInsnNode.isBoxingMethodDescriptor(): Boolean {
|
||||
val ownerType = Type.getObjectType(owner)
|
||||
return desc == Type.getMethodDescriptor(ownerType, AsmUtil.unboxType(ownerType))
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.debugText
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isLoadOperation
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.peekWords
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.removeNodeGetNext
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -32,91 +29,66 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
|
||||
import java.util.*
|
||||
|
||||
private typealias Transformation = (AbstractInsnNode) -> Unit
|
||||
|
||||
class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
if (!OptimizationMethodVisitor.canBeOptimizedUsingSourceInterpreter(methodNode)) return
|
||||
Transformer(methodNode).transform()
|
||||
if (methodNode.instructions.any { it.isPop() || it.isPurePush() }) {
|
||||
Transformer(methodNode).transform()
|
||||
}
|
||||
}
|
||||
|
||||
private class Transformer(val methodNode: MethodNode) {
|
||||
private interface Transformation {
|
||||
fun apply(insn: AbstractInsnNode)
|
||||
}
|
||||
|
||||
private inline fun Transformation(crossinline body: (AbstractInsnNode) -> Unit): Transformation =
|
||||
object : Transformation {
|
||||
override fun apply(insn: AbstractInsnNode) {
|
||||
body(insn)
|
||||
}
|
||||
}
|
||||
|
||||
private val REPLACE_WITH_NOP = Transformation { insnList.set(it, createRemovableNopInsn()) }
|
||||
private val REPLACE_WITH_POP1 = Transformation { insnList.set(it, InsnNode(Opcodes.POP)) }
|
||||
private val REPLACE_WITH_POP2 = Transformation { insnList.set(it, InsnNode(Opcodes.POP2)) }
|
||||
private val INSERT_POP1_AFTER = Transformation { insnList.insert(it, InsnNode(Opcodes.POP)) }
|
||||
private val INSERT_POP2_AFTER = Transformation { insnList.insert(it, InsnNode(Opcodes.POP2)) }
|
||||
private val REPLACE_WITH_NOP: Transformation = { insnList.set(it, InsnNode(Opcodes.NOP)) }
|
||||
private val REPLACE_WITH_POP1: Transformation = { insnList.set(it, InsnNode(Opcodes.POP)) }
|
||||
private val REPLACE_WITH_POP2: Transformation = { insnList.set(it, InsnNode(Opcodes.POP2)) }
|
||||
private val INSERT_POP1_AFTER: Transformation = { insnList.insert(it, InsnNode(Opcodes.POP)) }
|
||||
private val INSERT_POP2_AFTER: Transformation = { insnList.insert(it, InsnNode(Opcodes.POP2)) }
|
||||
|
||||
private val insnList = methodNode.instructions
|
||||
|
||||
private val insns = insnList.toArray()
|
||||
|
||||
private val dontTouchInsnIndices = BitSet(insns.size)
|
||||
private val transformations = hashMapOf<AbstractInsnNode, Transformation>()
|
||||
private val removableNops = hashSetOf<InsnNode>()
|
||||
|
||||
private val frames by lazy { analyzeMethodBody() }
|
||||
|
||||
fun transform() {
|
||||
if (insns.none { it.isPop() || it.isPurePush() }) return
|
||||
|
||||
computeTransformations()
|
||||
for ((insn, transformation) in transformations.entries) {
|
||||
transformation.apply(insn)
|
||||
}
|
||||
postprocessNops()
|
||||
}
|
||||
|
||||
private fun analyzeMethodBody(): Array<out Frame<SourceValue>?> {
|
||||
val frames = Analyzer<SourceValue>(HazardsTrackingInterpreter()).analyze("fake", methodNode)
|
||||
|
||||
postprocessStackHazards(frames)
|
||||
|
||||
return frames
|
||||
}
|
||||
|
||||
private fun postprocessStackHazards(frames: Array<out Frame<SourceValue>?>) {
|
||||
val insns = methodNode.instructions.toArray()
|
||||
for (i in frames.indices) {
|
||||
val frames = Analyzer(HazardsTrackingInterpreter()).analyze("fake", methodNode)
|
||||
for ((i, insn) in insns.withIndex()) {
|
||||
val frame = frames[i] ?: continue
|
||||
val insn = insns[i]
|
||||
|
||||
when (insn.opcode) {
|
||||
Opcodes.POP2 -> {
|
||||
val top2 = frame.peekWords(2) ?: throwIncorrectBytecode(insn, frame)
|
||||
top2.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP_X1 -> {
|
||||
val top2 = frame.peekWords(1, 1) ?: throwIncorrectBytecode(insn, frame)
|
||||
top2.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP2_X1 -> {
|
||||
val top3 = frame.peekWords(2, 1) ?: throwIncorrectBytecode(insn, frame)
|
||||
top3.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP_X2 -> {
|
||||
val top3 = frame.peekWords(1, 2) ?: throwIncorrectBytecode(insn, frame)
|
||||
top3.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP2_X2 -> {
|
||||
val top4 = frame.peekWords(2, 2) ?: throwIncorrectBytecode(insn, frame)
|
||||
top4.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.POP ->
|
||||
frame.top()?.let { input ->
|
||||
// If this POP won't be removed, other POPs that touch the same values have to stay as well.
|
||||
if (input.insns.any { it.shouldKeep() } || input.longerWhenFusedWithPop()) {
|
||||
input.insns.markAsDontTouch()
|
||||
}
|
||||
}
|
||||
Opcodes.POP2 -> frame.peekWords(2)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP_X1 -> frame.peekWords(1, 1)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP2_X1 -> frame.peekWords(2, 1)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP_X2 -> frame.peekWords(1, 2)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP2_X2 -> frame.peekWords(2, 2)?.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
}
|
||||
|
||||
val transformations = hashMapOf<AbstractInsnNode, Transformation>()
|
||||
for ((i, insn) in insns.withIndex()) {
|
||||
val frame = frames[i] ?: continue
|
||||
if (insn.opcode == Opcodes.POP) {
|
||||
val input = frame.top() ?: continue
|
||||
if (input.insns.none { it.shouldKeep() }) {
|
||||
transformations[insn] = REPLACE_WITH_NOP
|
||||
input.insns.forEach {
|
||||
if (it !in transformations) {
|
||||
transformations[it] = it.combineWithPop(frames, input.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun throwIncorrectBytecode(insn: AbstractInsnNode?, frame: Frame<SourceValue>): Nothing {
|
||||
throw AssertionError("Incorrect bytecode at ${methodNode.instructions.indexOf(insn)}: ${insn.debugText} $frame")
|
||||
for ((insn, transformation) in transformations.entries) {
|
||||
transformation(insn)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class HazardsTrackingInterpreter : SourceInterpreter(Opcodes.API_VERSION) {
|
||||
@@ -133,9 +105,7 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
}
|
||||
|
||||
override fun unaryOperation(insn: AbstractInsnNode, value: SourceValue): SourceValue {
|
||||
if (insn.opcode != Opcodes.CHECKCAST && !insn.isPrimitiveTypeConversion()) {
|
||||
value.insns.markAsDontTouch()
|
||||
}
|
||||
value.insns.markAsDontTouch()
|
||||
return super.unaryOperation(insn, value)
|
||||
}
|
||||
|
||||
@@ -164,153 +134,48 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun computeTransformations() {
|
||||
transformations.clear()
|
||||
|
||||
for (i in insns.indices) {
|
||||
if (frames[i] == null) continue
|
||||
val insn = insns[i]
|
||||
|
||||
if (insn.opcode == Opcodes.POP) {
|
||||
propagatePopBackwards(insn, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun propagatePopBackwards(insn: AbstractInsnNode, poppedValueSize: Int) {
|
||||
if (transformations.containsKey(insn)) return
|
||||
|
||||
private fun SourceValue.longerWhenFusedWithPop() = insns.fold(0) { x, insn ->
|
||||
when {
|
||||
insn.opcode == Opcodes.POP -> {
|
||||
val inputTop = getInputTop(insn)
|
||||
val sources = inputTop.insns
|
||||
if (sources.all { !isDontTouch(it) } && sources.any { isTransformablePopOperand(it) }) {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
sources.forEach { propagatePopBackwards(it, inputTop.size) }
|
||||
insn.isPurePush() -> x - 1
|
||||
insn.isPrimitiveBoxing() || insn.isPrimitiveTypeConversion() -> x
|
||||
else -> x + 1
|
||||
}
|
||||
} > 0
|
||||
|
||||
private fun AbstractInsnNode.combineWithPop(frames: Array<out Frame<SourceValue>?>, resultSize: Int): Transformation =
|
||||
when {
|
||||
isPurePush() -> REPLACE_WITH_NOP
|
||||
isPrimitiveBoxing() || isPrimitiveTypeConversion() -> {
|
||||
val index = insnList.indexOf(this)
|
||||
val frame = frames[index] ?: throw AssertionError("dead instruction #$index used by non-dead instruction")
|
||||
val input = frame.top() ?: throw AssertionError("coercion instruction at #$index has no input")
|
||||
when (input.size) {
|
||||
1 -> REPLACE_WITH_POP1
|
||||
2 -> REPLACE_WITH_POP2
|
||||
else -> throw AssertionError("Unexpected pop value size: ${input.size}")
|
||||
}
|
||||
}
|
||||
|
||||
insn.opcode == Opcodes.CHECKCAST -> {
|
||||
val inputTop = getInputTop(insn)
|
||||
val sources = inputTop.insns
|
||||
val resultType = (insn as TypeInsnNode).desc
|
||||
if (sources.all { !isDontTouch(it) } && sources.any { isTransformableCheckcastOperand(it, resultType) }) {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
sources.forEach { propagatePopBackwards(it, inputTop.size) }
|
||||
} else {
|
||||
transformations[insn] = insertPopAfterTransformation(poppedValueSize)
|
||||
else ->
|
||||
when (resultSize) {
|
||||
1 -> INSERT_POP1_AFTER
|
||||
2 -> INSERT_POP2_AFTER
|
||||
else -> throw AssertionError("Unexpected pop value size: $resultSize")
|
||||
}
|
||||
}
|
||||
|
||||
insn.isPrimitiveBoxing() -> {
|
||||
val boxedValueSize = getInputTop(insn).size
|
||||
transformations[insn] = replaceWithPopTransformation(boxedValueSize)
|
||||
}
|
||||
|
||||
insn.isPurePush() -> {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
}
|
||||
|
||||
insn.isPrimitiveTypeConversion() -> {
|
||||
val inputTop = getInputTop(insn)
|
||||
val sources = inputTop.insns
|
||||
if (sources.all { !isDontTouch(it) }) {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
sources.forEach { propagatePopBackwards(it, inputTop.size) }
|
||||
} else {
|
||||
transformations[insn] = replaceWithPopTransformation(poppedValueSize)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
transformations[insn] = insertPopAfterTransformation(poppedValueSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun postprocessNops() {
|
||||
var node: AbstractInsnNode? = insnList.first
|
||||
var hasRemovableNops = false
|
||||
while (node != null) {
|
||||
node = node.next
|
||||
val begin = node ?: break
|
||||
while (node != null && node !is LabelNode) {
|
||||
if (node in removableNops) {
|
||||
hasRemovableNops = true
|
||||
}
|
||||
node = node.next
|
||||
}
|
||||
val end = node
|
||||
if (hasRemovableNops) {
|
||||
removeUnneededNopsInRange(begin, end)
|
||||
}
|
||||
hasRemovableNops = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeUnneededNopsInRange(begin: AbstractInsnNode, end: AbstractInsnNode?) {
|
||||
var node: AbstractInsnNode? = begin
|
||||
var keepNop = true
|
||||
while (node != null && node != end) {
|
||||
if (node in removableNops && !keepNop) {
|
||||
node = insnList.removeNodeGetNext(node)
|
||||
} else {
|
||||
if (node.isMeaningful) keepNop = false
|
||||
node = node.next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun replaceWithPopTransformation(size: Int): Transformation =
|
||||
when (size) {
|
||||
1 -> REPLACE_WITH_POP1
|
||||
2 -> REPLACE_WITH_POP2
|
||||
else -> throw AssertionError("Unexpected pop value size: $size")
|
||||
}
|
||||
|
||||
private fun insertPopAfterTransformation(size: Int): Transformation =
|
||||
when (size) {
|
||||
1 -> INSERT_POP1_AFTER
|
||||
2 -> INSERT_POP2_AFTER
|
||||
else -> throw AssertionError("Unexpected pop value size: $size")
|
||||
}
|
||||
|
||||
private fun replaceWithNopTransformation(): Transformation =
|
||||
REPLACE_WITH_NOP
|
||||
|
||||
private fun createRemovableNopInsn() =
|
||||
InsnNode(Opcodes.NOP).apply { removableNops.add(this) }
|
||||
|
||||
private fun getInputTop(insn: AbstractInsnNode): SourceValue {
|
||||
val i = insnList.indexOf(insn)
|
||||
val frame = frames[i] ?: throw AssertionError("Unexpected dead instruction #$i")
|
||||
return frame.top() ?: throw AssertionError("Instruction #$i has empty stack on input")
|
||||
}
|
||||
|
||||
private fun isTransformableCheckcastOperand(it: AbstractInsnNode, resultType: String) =
|
||||
it.isPrimitiveBoxing() && (it as MethodInsnNode).owner == resultType
|
||||
|
||||
private fun isTransformablePopOperand(insn: AbstractInsnNode) =
|
||||
insn.opcode == Opcodes.CHECKCAST || insn.isPrimitiveBoxing() || insn.isPurePush()
|
||||
|
||||
private fun isDontTouch(insn: AbstractInsnNode) =
|
||||
dontTouchInsnIndices[insnList.indexOf(insn)]
|
||||
private fun AbstractInsnNode.shouldKeep() =
|
||||
dontTouchInsnIndices[insnList.indexOf(this)]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun AbstractInsnNode.isPurePush() =
|
||||
isLoadOperation() ||
|
||||
opcode in Opcodes.ACONST_NULL..Opcodes.LDC + 2 ||
|
||||
isUnitInstance()
|
||||
isLoadOperation() || opcode in Opcodes.ACONST_NULL..Opcodes.LDC + 2 || isUnitInstance()
|
||||
|
||||
fun AbstractInsnNode.isPop() =
|
||||
opcode == Opcodes.POP || opcode == Opcodes.POP2
|
||||
|
||||
fun AbstractInsnNode.isUnitInstance() =
|
||||
opcode == Opcodes.GETSTATIC &&
|
||||
this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"
|
||||
opcode == Opcodes.GETSTATIC && this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"
|
||||
|
||||
fun AbstractInsnNode.isPrimitiveTypeConversion() =
|
||||
opcode in Opcodes.I2L..Opcodes.I2S
|
||||
|
||||
@@ -39,7 +39,7 @@ class RedundantBoxingMethodTransformer(private val generationState: GenerationSt
|
||||
|
||||
override fun transform(internalClassName: String, node: MethodNode) {
|
||||
val interpreter = RedundantBoxingInterpreter(node.instructions, generationState)
|
||||
val frames = MethodTransformer.analyze(internalClassName, node, interpreter)
|
||||
val frames = analyze(internalClassName, node, interpreter)
|
||||
|
||||
interpretPopInstructionsForBoxedValues(interpreter, node, frames)
|
||||
|
||||
@@ -168,7 +168,8 @@ class RedundantBoxingMethodTransformer(private val generationState: GenerationSt
|
||||
val frame = frames[i] ?: continue
|
||||
val insn = insnList[i]
|
||||
if ((insn.opcode == Opcodes.ASTORE || insn.opcode == Opcodes.ALOAD) &&
|
||||
(insn as VarInsnNode).`var` == localVariableNode.index) {
|
||||
(insn as VarInsnNode).`var` == localVariableNode.index
|
||||
) {
|
||||
if (insn.getOpcode() == Opcodes.ASTORE) {
|
||||
values.add(frame.top()!!)
|
||||
} else {
|
||||
|
||||
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
class StackPeepholeOptimizationsTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
while (transformOnce(methodNode)) {
|
||||
while (true) {
|
||||
if (!transformOnce(methodNode)) break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,20 +113,26 @@ class StackPeepholeOptimizationsTransformer : MethodTransformer() {
|
||||
opcode == Opcodes.DUP
|
||||
|
||||
private fun AbstractInsnNode.isPurePushOfSize1(): Boolean =
|
||||
opcode in Opcodes.ACONST_NULL..Opcodes.FCONST_2 ||
|
||||
opcode in Opcodes.BIPUSH..Opcodes.ILOAD ||
|
||||
opcode == Opcodes.FLOAD ||
|
||||
opcode == Opcodes.ALOAD ||
|
||||
isUnitInstance()
|
||||
!isLdcOfSize2() && (
|
||||
opcode in Opcodes.ACONST_NULL..Opcodes.FCONST_2 ||
|
||||
opcode in Opcodes.BIPUSH..Opcodes.ILOAD ||
|
||||
opcode == Opcodes.FLOAD ||
|
||||
opcode == Opcodes.ALOAD ||
|
||||
isUnitInstance()
|
||||
)
|
||||
|
||||
private fun AbstractInsnNode.isEliminatedByPop2() =
|
||||
isPurePushOfSize2() ||
|
||||
opcode == Opcodes.DUP2
|
||||
|
||||
private fun AbstractInsnNode.isPurePushOfSize2(): Boolean =
|
||||
opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1 ||
|
||||
isLdcOfSize2() ||
|
||||
opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1 ||
|
||||
opcode == Opcodes.DCONST_0 || opcode == Opcodes.DCONST_1 ||
|
||||
opcode == Opcodes.LLOAD ||
|
||||
opcode == Opcodes.DLOAD
|
||||
|
||||
private fun AbstractInsnNode.isLdcOfSize2(): Boolean =
|
||||
opcode == Opcodes.LDC && this is LdcInsnNode && (this.cst is Double || this.cst is Long)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,4 +29,7 @@ class JvmCodegenStringTable @JvmOverloads constructor(
|
||||
ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), true)
|
||||
}
|
||||
}
|
||||
|
||||
override val isLocalClassIdReplacementKeptGeneric: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ dependencies {
|
||||
compile(project(":compiler:fir:fir2ir"))
|
||||
compile(project(":compiler:fir:fir2ir:jvm-backend"))
|
||||
compile(project(":compiler:fir:checkers"))
|
||||
compile(project(":compiler:fir:checkers:checkers.jvm"))
|
||||
compile(project(":kotlin-util-klib"))
|
||||
compile(project(":kotlin-util-io"))
|
||||
|
||||
|
||||
@@ -151,9 +151,18 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var irModuleName: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xir-legacy-property-access", description = "Force property access via JS properties (requires -Xir-export-all)")
|
||||
var irLegacyPropertyAccess: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xir-base-class-in-metadata", description = "Write base class into metadata")
|
||||
var irBaseClassInMetadata: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xir-per-module", description = "Splits generated .js per-module")
|
||||
var irPerModule: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xir-per-module-output-name", description = "Adds a custom output name to the splitted js files")
|
||||
var irPerModuleOutputName: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xinclude",
|
||||
valueDescription = "<path>",
|
||||
@@ -161,6 +170,16 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var includes: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xcache-directories",
|
||||
valueDescription = "<path>",
|
||||
description = "A path to cache directories"
|
||||
)
|
||||
var cacheDirectories: String? by NullableStringFreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xir-build-cache", description = "Use compiler to build cache")
|
||||
var irBuildCache: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xgenerate-dts",
|
||||
description = "Generate TypeScript declarations .d.ts file alongside JS file. Available in IR backend only."
|
||||
@@ -212,7 +231,7 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
}
|
||||
|
||||
fun K2JSCompilerArguments.isPreIrBackendDisabled(): Boolean =
|
||||
irOnly || irProduceJs || irProduceKlibFile
|
||||
irOnly || irProduceJs || irProduceKlibFile || irBuildCache
|
||||
|
||||
fun K2JSCompilerArguments.isIrBackendEnabled(): Boolean =
|
||||
irProduceKlibDir || irProduceJs || irProduceKlibFile || wasm
|
||||
irProduceKlibDir || irProduceJs || irProduceKlibFile || wasm || irBuildCache
|
||||
@@ -30,6 +30,11 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-include-runtime", description = "Include Kotlin runtime into the resulting JAR")
|
||||
var includeRuntime: Boolean by FreezableVar(false)
|
||||
|
||||
@DeprecatedOption(
|
||||
message = "This option is not working well with Gradle caching and will be removed in the future.",
|
||||
removeAfter = "1.7",
|
||||
level = DeprecationLevel.WARNING
|
||||
)
|
||||
@GradleOption(DefaultValues.StringNullDefault::class)
|
||||
@Argument(
|
||||
value = "-jdk-home",
|
||||
|
||||
@@ -161,9 +161,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
|
||||
val outputFile = File(outputFilePath)
|
||||
|
||||
val moduleName = arguments.irModuleName ?: FileUtil.getNameWithoutExtension(outputFile)
|
||||
configurationJs.put(
|
||||
CommonConfigurationKeys.MODULE_NAME,
|
||||
arguments.irModuleName ?: FileUtil.getNameWithoutExtension(outputFile)
|
||||
moduleName
|
||||
)
|
||||
|
||||
// TODO: in this method at least 3 different compiler configurations are used (original, env.configuration, jsConfig.configuration)
|
||||
@@ -205,7 +206,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
friendDependencies = friendDependencies,
|
||||
irFactory = PersistentIrFactory(), // TODO IrFactoryImpl?
|
||||
outputKlibPath = outputFile.path,
|
||||
nopack = arguments.irProduceKlibDir
|
||||
nopack = arguments.irProduceKlibDir,
|
||||
jsOutputName = arguments.irPerModuleOutputName,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -273,9 +275,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
multiModule = arguments.irPerModule,
|
||||
relativeRequirePath = true,
|
||||
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||
legacyPropertyAccess = arguments.irLegacyPropertyAccess,
|
||||
baseClassIntoMetadata = arguments.irBaseClassInMetadata,
|
||||
)
|
||||
|
||||
|
||||
val jsCode = if (arguments.irDce && !arguments.irDceDriven) compiledModule.dceJsCode!! else compiledModule.jsCode!!
|
||||
outputFile.writeText(jsCode.mainModule)
|
||||
jsCode.dependencies.forEach { (name, content) ->
|
||||
|
||||
@@ -53,6 +53,7 @@ public class Usage {
|
||||
appendln(sb, "Advanced options are non-standard and may be changed or removed without any notice.");
|
||||
}
|
||||
else {
|
||||
renderOptionJUsage(sb);
|
||||
renderArgfileUsage(sb);
|
||||
}
|
||||
|
||||
@@ -103,6 +104,15 @@ public class Usage {
|
||||
appendln(sb, argument.description().replace("\n", "\n" + StringsKt.repeat(" ", OPTION_NAME_PADDING_WIDTH)));
|
||||
}
|
||||
|
||||
private static void renderOptionJUsage(@NotNull StringBuilder sb) {
|
||||
int descriptionStart = sb.length() + OPTION_NAME_PADDING_WIDTH;
|
||||
sb.append(" -J<option>");
|
||||
while (sb.length() < descriptionStart) {
|
||||
sb.append(" ");
|
||||
}
|
||||
appendln(sb, "Pass an option directly to JVM");
|
||||
}
|
||||
|
||||
private static void renderArgfileUsage(@NotNull StringBuilder sb) {
|
||||
int descriptionStart = sb.length() + OPTION_NAME_PADDING_WIDTH;
|
||||
sb.append(" ");
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.light.LightJavaModule
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.cli.common.config.ContentRoot
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.isValidJavaFqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
|
||||
@@ -52,10 +54,13 @@ class ClasspathRootsResolver(
|
||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
||||
private val javaModuleFinder: CliJavaModuleFinder,
|
||||
private val requireStdlibModule: Boolean,
|
||||
private val outputDirectory: VirtualFile?
|
||||
private val outputDirectory: VirtualFile?,
|
||||
private val javaFileManager: KotlinCliJavaFileManager
|
||||
) {
|
||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||
|
||||
private val searchScope = GlobalSearchScope.allScope(psiManager.project)
|
||||
|
||||
data class RootsAndModules(val roots: List<JavaRoot>, val modules: List<JavaModule>)
|
||||
|
||||
private data class RootWithPrefix(val root: VirtualFile, val packagePrefix: String?)
|
||||
@@ -160,7 +165,7 @@ class ClasspathRootsResolver(
|
||||
}
|
||||
|
||||
if (moduleInfoFile != null) {
|
||||
val moduleInfo = JavaModuleInfo.read(moduleInfoFile) ?: return null
|
||||
val moduleInfo = JavaModuleInfo.read(moduleInfoFile, javaFileManager, searchScope) ?: return null
|
||||
return JavaModule.Explicit(moduleInfo, listOf(JavaModule.Root(root, isBinary = true)), moduleInfoFile)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class CliKotlinAsJavaSupport(
|
||||
return findFacadeFilesInPackage(packageFqName, scope)
|
||||
.groupBy { it.javaFileFacadeFqName }
|
||||
.mapNotNull { (facadeClassFqName, _) ->
|
||||
KtLightClassForFacade.createForFacade(psiManager, facadeClassFqName, scope)
|
||||
KtLightClassForFacadeImpl.createForFacade(psiManager, facadeClassFqName, scope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class CliKotlinAsJavaSupport(
|
||||
.orEmpty()
|
||||
|
||||
override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
return listOfNotNull(KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope))
|
||||
return listOfNotNull(KtLightClassForFacadeImpl.createForFacade(psiManager, facadeFqName, scope))
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
|
||||
@@ -35,6 +35,10 @@ class CliVirtualFileFinder(
|
||||
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
|
||||
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
|
||||
|
||||
override fun findSourceOrBinaryVirtualFile(classId: ClassId) =
|
||||
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
|
||||
?: findSourceClass(classId, classId.relativeClassName.asString() + ".java")
|
||||
|
||||
override fun findMetadata(classId: ClassId): InputStream? {
|
||||
assert(!classId.isNestedClass) { "Nested classes are not supported here: $classId" }
|
||||
|
||||
@@ -61,8 +65,11 @@ class CliVirtualFileFinder(
|
||||
return findBinaryClass(classId, BuiltInSerializerProtocol.getBuiltInsFileName(packageFqName))?.inputStream
|
||||
}
|
||||
|
||||
private fun findBinaryClass(classId: ClassId, fileName: String): VirtualFile? =
|
||||
index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, _ ->
|
||||
private fun findClass(classId: ClassId, fileName: String, rootType: Set<JavaRoot.RootType>) =
|
||||
index.findClass(classId, acceptedRootTypes = rootType) { dir, _ ->
|
||||
dir.findChild(fileName)?.takeIf(VirtualFile::isValid)
|
||||
}?.takeIf { it in scope }
|
||||
|
||||
private fun findBinaryClass(classId: ClassId, fileName: String) = findClass(classId, fileName, JavaRoot.OnlyBinary)
|
||||
private fun findSourceClass(classId: ClassId, fileName: String) = findClass(classId, fileName, JavaRoot.OnlySource)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||
import org.jetbrains.kotlin.backend.jvm.jvmPhases
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.container.get
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory.createSessionWithDependencies
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleGenericDiagnostics
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||
import java.io.File
|
||||
|
||||
object FirKotlinToJvmBytecodeCompiler {
|
||||
fun compileModulesUsingFrontendIR(
|
||||
environment: KotlinCoreEnvironment,
|
||||
buildFile: File?,
|
||||
chunk: List<Module>,
|
||||
extendedAnalysisMode: Boolean
|
||||
): Boolean {
|
||||
val project = environment.project
|
||||
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
|
||||
|
||||
environment.messageCollector.report(
|
||||
STRONG_WARNING,
|
||||
"ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir"
|
||||
)
|
||||
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
|
||||
val projectConfiguration = environment.configuration
|
||||
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
||||
val outputs = newLinkedHashMapWithExpectedSize<Module, GenerationState>(chunk.size)
|
||||
val targetIds = environment.configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
|
||||
val incrementalComponents = environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
|
||||
for (module in chunk) {
|
||||
performanceManager?.notifyAnalysisStarted()
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
val ktFiles = module.getSourceFiles(environment, localFileSystem, chunk.size > 1, buildFile)
|
||||
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
|
||||
|
||||
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
|
||||
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, environment.messageCollector).isHasErrors or errorsFound
|
||||
}
|
||||
|
||||
val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
|
||||
|
||||
val sourceScope = GlobalSearchScope.filesWithoutLibrariesScope(project, ktFiles.map { it.virtualFile })
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
|
||||
|
||||
var librariesScope = ProjectScope.getLibrariesScope(project)
|
||||
|
||||
val providerAndScopeForIncrementalCompilation = run {
|
||||
if (targetIds == null || incrementalComponents == null) return@run null
|
||||
val fileSystem = environment.projectEnvironment.environment.localFileSystem
|
||||
val directoryWithIncrementalPartsFromPreviousCompilation =
|
||||
moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY]
|
||||
?: return@run null
|
||||
val previouslyCompiledFiles = directoryWithIncrementalPartsFromPreviousCompilation.walk()
|
||||
.filter { it.extension == "class" }
|
||||
.mapNotNull { fileSystem.findFileByIoFile(it) }
|
||||
.toList()
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?: return@run null
|
||||
val packagePartProvider = IncrementalPackagePartProvider(
|
||||
environment.createPackagePartProvider(sourceScope),
|
||||
targetIds.map(incrementalComponents::getIncrementalCache)
|
||||
)
|
||||
val incrementalCompilationScope = GlobalSearchScope.filesWithoutLibrariesScope(
|
||||
project,
|
||||
previouslyCompiledFiles
|
||||
)
|
||||
librariesScope = librariesScope.intersectWith(GlobalSearchScope.notScope(incrementalCompilationScope))
|
||||
FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope)
|
||||
}
|
||||
|
||||
val languageVersionSettings = moduleConfiguration.languageVersionSettings
|
||||
val session = createSessionWithDependencies(
|
||||
Name.identifier(module.getModuleName()),
|
||||
JvmPlatforms.unspecifiedJvmPlatform,
|
||||
JvmPlatformAnalyzerServices,
|
||||
externalSessionProvider = null,
|
||||
project,
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
||||
providerAndScopeForIncrementalCompilation,
|
||||
getPackagePartProvider = { environment.createPackagePartProvider(it) },
|
||||
dependenciesConfigurator = {
|
||||
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
|
||||
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
|
||||
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||
},
|
||||
sessionConfigurator = {
|
||||
if (extendedAnalysisMode) {
|
||||
registerExtendedCommonCheckers()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles)
|
||||
|
||||
firAnalyzerFacade.runResolution()
|
||||
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||
SimpleGenericDiagnostics(firDiagnostics),
|
||||
environment.messageCollector
|
||||
)
|
||||
performanceManager?.notifyAnalysisFinished()
|
||||
|
||||
if (syntaxErrors || firDiagnostics.any { it.severity == Severity.ERROR }) {
|
||||
return false
|
||||
}
|
||||
|
||||
performanceManager?.notifyGenerationStarted()
|
||||
|
||||
performanceManager?.notifyIRTranslationStarted()
|
||||
val extensions = JvmGeneratorExtensionsImpl()
|
||||
val (moduleFragment, symbolTable, components) = firAnalyzerFacade.convertToIr(extensions)
|
||||
|
||||
performanceManager?.notifyIRTranslationFinished()
|
||||
|
||||
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
|
||||
|
||||
val codegenFactory = JvmIrCodegenFactory(moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
|
||||
|
||||
// Create and initialize the module and its dependencies
|
||||
val container = TopDownAnalyzerFacadeForJVM.createContainer(
|
||||
project, ktFiles, NoScopeRecordCliBindingTrace(), environment.configuration, environment::createPackagePartProvider,
|
||||
::FileBasedDeclarationProviderFactory, CompilerEnvironment,
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles), emptyList()
|
||||
)
|
||||
|
||||
val generationState = GenerationState.Builder(
|
||||
environment.project, ClassBuilderFactories.BINARIES,
|
||||
container.get(), dummyBindingContext, ktFiles,
|
||||
moduleConfiguration
|
||||
).codegenFactory(
|
||||
codegenFactory
|
||||
).withModule(
|
||||
module
|
||||
).onIndependentPartCompilationEnd(
|
||||
createOutputFilesFlushingCallbackIfPossible(moduleConfiguration)
|
||||
).isIrBackend(
|
||||
true
|
||||
).jvmBackendClassResolver(
|
||||
FirJvmBackendClassResolver(components)
|
||||
).build()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
performanceManager?.notifyIRLoweringStarted()
|
||||
generationState.beforeCompile()
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components)
|
||||
) {
|
||||
performanceManager?.notifyIRLoweringFinished()
|
||||
performanceManager?.notifyIRGenerationStarted()
|
||||
}
|
||||
CodegenFactory.doCheckCancelled(generationState)
|
||||
generationState.factory.done()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||
FilteredJvmDiagnostics(
|
||||
generationState.collectedExtraJvmDiagnostics,
|
||||
dummyBindingContext.diagnostics
|
||||
),
|
||||
environment.messageCollector
|
||||
)
|
||||
|
||||
performanceManager?.notifyIRGenerationFinished()
|
||||
performanceManager?.notifyGenerationFinished()
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
outputs[module] = generationState
|
||||
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
Disposer.dispose(environment.project)
|
||||
}
|
||||
|
||||
val mainClassFqName: FqName? =
|
||||
if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null)
|
||||
TODO(".jar output is not yet supported for -Xuse-fir: KT-42868")
|
||||
else null
|
||||
|
||||
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
||||
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
||||
private val signatureParsingComponent = BinaryClassSignatureParser()
|
||||
|
||||
fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? = findClass(JavaClassFinder.Request(classId), searchScope)
|
||||
fun findClass(classId: ClassId, searchScope: GlobalSearchScope) = findClass(JavaClassFinder.Request(classId), searchScope)
|
||||
|
||||
override fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? {
|
||||
val (classId, classFileContentFromRequest, outerClassFromRequest) = request
|
||||
|
||||
@@ -190,11 +190,17 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
|
||||
|
||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
|
||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||
})
|
||||
val javaModuleFinder = CliJavaModuleFinder(
|
||||
jdkHome?.path?.let { path ->
|
||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||
},
|
||||
javaFileManager,
|
||||
project
|
||||
)
|
||||
|
||||
val outputDirectory =
|
||||
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||
@@ -207,7 +213,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
this::contentRootToVirtualFile,
|
||||
javaModuleFinder,
|
||||
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||
outputDirectory?.let(this::findLocalFile)
|
||||
outputDirectory?.let(this::findLocalFile),
|
||||
javaFileManager
|
||||
)
|
||||
|
||||
val (initialRoots, javaModules) =
|
||||
@@ -231,7 +238,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
updateClasspathFromRootsIndex(this)
|
||||
}
|
||||
|
||||
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
||||
javaFileManager.initialize(
|
||||
rootsIndex,
|
||||
packagePartProviders,
|
||||
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||
@@ -240,7 +247,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
project.registerService(
|
||||
JavaModuleResolver::class.java,
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project)
|
||||
)
|
||||
|
||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||
|
||||
@@ -78,10 +78,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.extensions.*
|
||||
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
|
||||
@@ -193,11 +190,16 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
|
||||
|
||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
|
||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||
})
|
||||
val javaModuleFinder = CliJavaModuleFinder(
|
||||
jdkHome?.path?.let { path ->
|
||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||
},
|
||||
javaFileManager
|
||||
)
|
||||
|
||||
val outputDirectory =
|
||||
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||
@@ -210,7 +212,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
this::contentRootToVirtualFile,
|
||||
javaModuleFinder,
|
||||
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||
outputDirectory?.let(this::findLocalFile)
|
||||
outputDirectory?.let(this::findLocalFile),
|
||||
javaFileManager
|
||||
)
|
||||
|
||||
val (initialRoots, javaModules) =
|
||||
@@ -234,7 +237,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
updateClasspathFromRootsIndex(this)
|
||||
}
|
||||
|
||||
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
||||
javaFileManager.initialize(
|
||||
rootsIndex,
|
||||
packagePartProviders,
|
||||
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||
@@ -243,7 +246,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
project.registerService(
|
||||
JavaModuleResolver::class.java,
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project)
|
||||
)
|
||||
|
||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||
|
||||
@@ -17,140 +17,42 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||
import org.jetbrains.kotlin.backend.jvm.jvmPhases
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
|
||||
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
import org.jetbrains.kotlin.cli.common.output.writeAll
|
||||
import org.jetbrains.kotlin.cli.common.toLogger
|
||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||
import org.jetbrains.kotlin.codegen.DefaultCodegenFactory
|
||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.container.get
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.createSessionWithDependencies
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleGenericDiagnostics
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||
import java.io.File
|
||||
import kotlin.collections.set
|
||||
|
||||
object KotlinToJVMBytecodeCompiler {
|
||||
private fun writeOutput(
|
||||
configuration: CompilerConfiguration,
|
||||
outputFiles: OutputFileCollection,
|
||||
mainClassFqName: FqName?
|
||||
) {
|
||||
val reportOutputFiles = configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)
|
||||
val jarPath = configuration.get(JVMConfigurationKeys.OUTPUT_JAR)
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
||||
if (jarPath != null) {
|
||||
val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false)
|
||||
val noReflect = configuration.get(JVMConfigurationKeys.NO_REFLECT, false)
|
||||
val resetJarTimestamps = !configuration.get(JVMConfigurationKeys.NO_RESET_JAR_TIMESTAMPS, false)
|
||||
CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, noReflect, resetJarTimestamps, mainClassFqName, outputFiles, messageCollector)
|
||||
if (reportOutputFiles) {
|
||||
val message = OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath)
|
||||
messageCollector.report(OUTPUT, message)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val outputDir = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) ?: File(".")
|
||||
outputFiles.writeAll(outputDir, messageCollector, reportOutputFiles)
|
||||
}
|
||||
|
||||
private fun createOutputFilesFlushingCallbackIfPossible(configuration: CompilerConfiguration): GenerationStateEventCallback {
|
||||
if (configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) == null) {
|
||||
return GenerationStateEventCallback.DO_NOTHING
|
||||
}
|
||||
return GenerationStateEventCallback { state ->
|
||||
val currentOutput = SimpleOutputFileCollection(state.factory.currentOutput)
|
||||
writeOutput(configuration, currentOutput, null)
|
||||
if (!configuration.get(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, false)) {
|
||||
state.factory.releaseGeneratedOutput()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Module.getSourceFiles(
|
||||
environment: KotlinCoreEnvironment,
|
||||
localFileSystem: VirtualFileSystem,
|
||||
multiModuleChunk: Boolean,
|
||||
buildFile: File?
|
||||
): List<KtFile> {
|
||||
return if (multiModuleChunk) {
|
||||
// filter out source files from other modules
|
||||
assert(buildFile != null) { "Compiling multiple modules, but build file is null" }
|
||||
val (moduleSourceDirs, moduleSourceFiles) =
|
||||
getBuildFilePaths(buildFile, getSourceFiles())
|
||||
.mapNotNull(localFileSystem::findFileByPath)
|
||||
.partition(VirtualFile::isDirectory)
|
||||
|
||||
environment.getSourceFiles().filter { file ->
|
||||
val virtualFile = file.virtualFile
|
||||
virtualFile in moduleSourceFiles || moduleSourceDirs.any { dir ->
|
||||
VfsUtilCore.isAncestor(dir, virtualFile, true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
environment.getSourceFiles()
|
||||
}
|
||||
}
|
||||
|
||||
private fun CompilerConfiguration.applyModuleProperties(module: Module, buildFile: File?): CompilerConfiguration {
|
||||
return copy().apply {
|
||||
if (buildFile != null) {
|
||||
fun checkKeyIsNull(key: CompilerConfigurationKey<*>, name: String) {
|
||||
assert(get(key) == null) { "$name should be null, when buildFile is used" }
|
||||
}
|
||||
|
||||
checkKeyIsNull(JVMConfigurationKeys.OUTPUT_DIRECTORY, "OUTPUT_DIRECTORY")
|
||||
checkKeyIsNull(JVMConfigurationKeys.OUTPUT_JAR, "OUTPUT_JAR")
|
||||
put(JVMConfigurationKeys.OUTPUT_DIRECTORY, File(module.getOutputDirectory()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun compileModules(
|
||||
environment: KotlinCoreEnvironment,
|
||||
buildFile: File?,
|
||||
@@ -182,7 +84,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
val projectConfiguration = environment.configuration
|
||||
if (projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR)) {
|
||||
val extendedAnalysisMode = projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
||||
return compileModulesUsingFrontendIR(environment, buildFile, chunk, extendedAnalysisMode)
|
||||
return FirKotlinToJvmBytecodeCompiler.compileModulesUsingFrontendIR(environment, buildFile, chunk, extendedAnalysisMode)
|
||||
}
|
||||
|
||||
val result = repeatAnalysisIfNeeded(analyze(environment), environment)
|
||||
@@ -214,40 +116,6 @@ object KotlinToJVMBytecodeCompiler {
|
||||
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
|
||||
}
|
||||
|
||||
private fun writeOutputs(
|
||||
environment: KotlinCoreEnvironment,
|
||||
projectConfiguration: CompilerConfiguration,
|
||||
chunk: List<Module>,
|
||||
outputs: Map<Module, GenerationState>,
|
||||
mainClassFqName: FqName?
|
||||
): Boolean {
|
||||
try {
|
||||
for ((_, state) in outputs) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
writeOutput(state.configuration, state.factory, mainClassFqName)
|
||||
}
|
||||
} finally {
|
||||
outputs.values.forEach(GenerationState::destroy)
|
||||
}
|
||||
|
||||
if (projectConfiguration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)) {
|
||||
val singleModule = chunk.singleOrNull()
|
||||
if (singleModule != null) {
|
||||
return JavacWrapper.getInstance(environment.project).use {
|
||||
it.compile(File(singleModule.getOutputDirectory()))
|
||||
}
|
||||
} else {
|
||||
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
|
||||
WARNING,
|
||||
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). " +
|
||||
"-Xuse-javac option couldn't be used to compile java files"
|
||||
)
|
||||
JavacWrapper.getInstance(environment.project).close()
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
internal fun configureSourceRoots(configuration: CompilerConfiguration, chunk: List<Module>, buildFile: File? = null) {
|
||||
for (module in chunk) {
|
||||
@@ -295,162 +163,6 @@ object KotlinToJVMBytecodeCompiler {
|
||||
configuration.addAll(JVMConfigurationKeys.MODULES, chunk)
|
||||
}
|
||||
|
||||
private fun compileModulesUsingFrontendIR(
|
||||
environment: KotlinCoreEnvironment,
|
||||
buildFile: File?,
|
||||
chunk: List<Module>,
|
||||
extendedAnalysisMode: Boolean
|
||||
): Boolean {
|
||||
val project = environment.project
|
||||
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
|
||||
|
||||
environment.messageCollector.report(
|
||||
STRONG_WARNING,
|
||||
"ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir"
|
||||
)
|
||||
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
|
||||
val projectConfiguration = environment.configuration
|
||||
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
|
||||
val outputs = newLinkedHashMapWithExpectedSize<Module, GenerationState>(chunk.size)
|
||||
val targetIds = environment.configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
|
||||
val incrementalComponents = environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
|
||||
for (module in chunk) {
|
||||
performanceManager?.notifyAnalysisStarted()
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
val ktFiles = module.getSourceFiles(environment, localFileSystem, chunk.size > 1, buildFile)
|
||||
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
|
||||
|
||||
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
|
||||
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, environment.messageCollector).isHasErrors or errorsFound
|
||||
}
|
||||
|
||||
val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
|
||||
|
||||
val sourceScope = GlobalSearchScope.filesScope(project, ktFiles.map { it.virtualFile })
|
||||
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
|
||||
|
||||
val librariesScope = ProjectScope.getLibrariesScope(project)
|
||||
|
||||
val languageVersionSettings = moduleConfiguration.languageVersionSettings
|
||||
val session = createSessionWithDependencies(
|
||||
module,
|
||||
project,
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
||||
getPackagePartProvider = { environment.createPackagePartProvider(it) },
|
||||
getAdditionalModulePackagePartProvider = {
|
||||
if (targetIds == null || incrementalComponents == null) null
|
||||
else IncrementalPackagePartProvider(
|
||||
environment.createPackagePartProvider(it),
|
||||
targetIds.map(incrementalComponents::getIncrementalCache)
|
||||
)
|
||||
}
|
||||
) {
|
||||
if (extendedAnalysisMode) {
|
||||
registerExtendedCommonCheckers()
|
||||
}
|
||||
}
|
||||
|
||||
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles)
|
||||
|
||||
firAnalyzerFacade.runResolution()
|
||||
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||
SimpleGenericDiagnostics(firDiagnostics),
|
||||
environment.messageCollector
|
||||
)
|
||||
performanceManager?.notifyAnalysisFinished()
|
||||
|
||||
if (syntaxErrors || firDiagnostics.any { it.severity == Severity.ERROR }) {
|
||||
return false
|
||||
}
|
||||
|
||||
performanceManager?.notifyGenerationStarted()
|
||||
|
||||
performanceManager?.notifyIRTranslationStarted()
|
||||
val extensions = JvmGeneratorExtensionsImpl()
|
||||
val (moduleFragment, symbolTable, components) = firAnalyzerFacade.convertToIr(extensions)
|
||||
|
||||
performanceManager?.notifyIRTranslationFinished()
|
||||
|
||||
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
|
||||
|
||||
val codegenFactory = JvmIrCodegenFactory(moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
|
||||
|
||||
// Create and initialize the module and its dependencies
|
||||
val container = TopDownAnalyzerFacadeForJVM.createContainer(
|
||||
project, ktFiles, NoScopeRecordCliBindingTrace(), environment.configuration, environment::createPackagePartProvider,
|
||||
::FileBasedDeclarationProviderFactory, CompilerEnvironment,
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles), emptyList()
|
||||
)
|
||||
|
||||
val generationState = GenerationState.Builder(
|
||||
environment.project, ClassBuilderFactories.BINARIES,
|
||||
container.get<ModuleDescriptor>(), dummyBindingContext, ktFiles,
|
||||
moduleConfiguration
|
||||
).codegenFactory(
|
||||
codegenFactory
|
||||
).withModule(
|
||||
module
|
||||
).onIndependentPartCompilationEnd(
|
||||
createOutputFilesFlushingCallbackIfPossible(moduleConfiguration)
|
||||
).isIrBackend(
|
||||
true
|
||||
).jvmBackendClassResolver(
|
||||
FirJvmBackendClassResolver(components)
|
||||
).build()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
performanceManager?.notifyIRLoweringStarted()
|
||||
generationState.beforeCompile()
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components)
|
||||
) {
|
||||
performanceManager?.notifyIRLoweringFinished()
|
||||
performanceManager?.notifyIRGenerationStarted()
|
||||
}
|
||||
CodegenFactory.doCheckCancelled(generationState)
|
||||
generationState.factory.done()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||
FilteredJvmDiagnostics(
|
||||
generationState.collectedExtraJvmDiagnostics,
|
||||
dummyBindingContext.diagnostics
|
||||
),
|
||||
environment.messageCollector
|
||||
)
|
||||
|
||||
performanceManager?.notifyIRGenerationFinished()
|
||||
performanceManager?.notifyGenerationFinished()
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
outputs[module] = generationState
|
||||
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
Disposer.dispose(environment.project)
|
||||
}
|
||||
|
||||
val mainClassFqName: FqName? =
|
||||
if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null)
|
||||
TODO(".jar output is not yet supported for -Xuse-fir: KT-42868")
|
||||
else null
|
||||
|
||||
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
|
||||
}
|
||||
|
||||
private fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
|
||||
if (buildFile == null) sourceFilePaths
|
||||
else sourceFilePaths.map { path ->
|
||||
(File(path).takeIf(File::isAbsolute) ?: buildFile.resolveSibling(path)).absolutePath
|
||||
}
|
||||
|
||||
fun compileBunchOfSources(environment: KotlinCoreEnvironment): Boolean {
|
||||
val moduleVisibilityManager = ModuleVisibilityManager.SERVICE.getInstance(environment.project)
|
||||
|
||||
@@ -577,15 +289,6 @@ object KotlinToJVMBytecodeCompiler {
|
||||
override fun toString() = "All files under: $directories"
|
||||
}
|
||||
|
||||
private fun GenerationState.Builder.withModule(module: Module?) =
|
||||
apply {
|
||||
if (module != null) {
|
||||
targetId(TargetId(module))
|
||||
moduleName(module.getModuleName())
|
||||
outDirectory(File(module.getOutputDirectory()))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generate(
|
||||
environment: KotlinCoreEnvironment,
|
||||
configuration: CompilerConfiguration,
|
||||
@@ -632,7 +335,4 @@ object KotlinToJVMBytecodeCompiler {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
return generationState
|
||||
}
|
||||
|
||||
private val KotlinCoreEnvironment.messageCollector: MessageCollector
|
||||
get() = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
import org.jetbrains.kotlin.cli.common.output.writeAll
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
|
||||
fun Module.getSourceFiles(
|
||||
environment: KotlinCoreEnvironment,
|
||||
localFileSystem: VirtualFileSystem,
|
||||
multiModuleChunk: Boolean,
|
||||
buildFile: File?
|
||||
): List<KtFile> {
|
||||
return if (multiModuleChunk) {
|
||||
// filter out source files from other modules
|
||||
assert(buildFile != null) { "Compiling multiple modules, but build file is null" }
|
||||
val (moduleSourceDirs, moduleSourceFiles) =
|
||||
getBuildFilePaths(buildFile, getSourceFiles())
|
||||
.mapNotNull(localFileSystem::findFileByPath)
|
||||
.partition(VirtualFile::isDirectory)
|
||||
|
||||
environment.getSourceFiles().filter { file ->
|
||||
val virtualFile = file.virtualFile
|
||||
virtualFile in moduleSourceFiles || moduleSourceDirs.any { dir ->
|
||||
VfsUtilCore.isAncestor(dir, virtualFile, true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
environment.getSourceFiles()
|
||||
}
|
||||
}
|
||||
|
||||
fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
|
||||
if (buildFile == null) sourceFilePaths
|
||||
else sourceFilePaths.map { path ->
|
||||
(File(path).takeIf(File::isAbsolute) ?: buildFile.resolveSibling(path)).absolutePath
|
||||
}
|
||||
|
||||
fun GenerationState.Builder.withModule(module: Module?) =
|
||||
apply {
|
||||
if (module != null) {
|
||||
targetId(TargetId(module))
|
||||
moduleName(module.getModuleName())
|
||||
outDirectory(File(module.getOutputDirectory()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun createOutputFilesFlushingCallbackIfPossible(configuration: CompilerConfiguration): GenerationStateEventCallback {
|
||||
if (configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) == null) {
|
||||
return GenerationStateEventCallback.DO_NOTHING
|
||||
}
|
||||
return GenerationStateEventCallback { state ->
|
||||
val currentOutput = SimpleOutputFileCollection(state.factory.currentOutput)
|
||||
writeOutput(configuration, currentOutput, null)
|
||||
if (!configuration.get(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, false)) {
|
||||
state.factory.releaseGeneratedOutput()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun writeOutput(
|
||||
configuration: CompilerConfiguration,
|
||||
outputFiles: OutputFileCollection,
|
||||
mainClassFqName: FqName?
|
||||
) {
|
||||
val reportOutputFiles = configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)
|
||||
val jarPath = configuration.get(JVMConfigurationKeys.OUTPUT_JAR)
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
|
||||
if (jarPath != null) {
|
||||
val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false)
|
||||
val noReflect = configuration.get(JVMConfigurationKeys.NO_REFLECT, false)
|
||||
val resetJarTimestamps = !configuration.get(JVMConfigurationKeys.NO_RESET_JAR_TIMESTAMPS, false)
|
||||
CompileEnvironmentUtil.writeToJar(
|
||||
jarPath,
|
||||
includeRuntime,
|
||||
noReflect,
|
||||
resetJarTimestamps,
|
||||
mainClassFqName,
|
||||
outputFiles,
|
||||
messageCollector
|
||||
)
|
||||
if (reportOutputFiles) {
|
||||
val message = OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath)
|
||||
messageCollector.report(CompilerMessageSeverity.OUTPUT, message)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val outputDir = configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY) ?: File(".")
|
||||
outputFiles.writeAll(outputDir, messageCollector, reportOutputFiles)
|
||||
}
|
||||
|
||||
fun writeOutputs(
|
||||
environment: KotlinCoreEnvironment,
|
||||
projectConfiguration: CompilerConfiguration,
|
||||
chunk: List<Module>,
|
||||
outputs: Map<Module, GenerationState>,
|
||||
mainClassFqName: FqName?
|
||||
): Boolean {
|
||||
try {
|
||||
for ((_, state) in outputs) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
writeOutput(state.configuration, state.factory, mainClassFqName)
|
||||
}
|
||||
} finally {
|
||||
outputs.values.forEach(GenerationState::destroy)
|
||||
}
|
||||
|
||||
if (projectConfiguration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)) {
|
||||
val singleModule = chunk.singleOrNull()
|
||||
if (singleModule != null) {
|
||||
return JavacWrapper.getInstance(environment.project).use {
|
||||
it.compile(File(singleModule.getOutputDirectory()))
|
||||
}
|
||||
} else {
|
||||
projectConfiguration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
|
||||
CompilerMessageSeverity.WARNING,
|
||||
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). " +
|
||||
"-Xuse-javac option couldn't be used to compile java files"
|
||||
)
|
||||
JavacWrapper.getInstance(environment.project).close()
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -15,10 +15,13 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.extensions.PreprocessedFileCreator
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||
import java.io.File
|
||||
@@ -79,4 +82,22 @@ fun createSourceFilesFromSourceRoots(
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
val KotlinCoreEnvironment.messageCollector: MessageCollector
|
||||
get() = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
fun CompilerConfiguration.applyModuleProperties(module: Module, buildFile: File?): CompilerConfiguration {
|
||||
return copy().apply {
|
||||
if (buildFile != null) {
|
||||
fun checkKeyIsNull(key: CompilerConfigurationKey<*>, name: String) {
|
||||
assert(get(key) == null) { "$name should be null, when buildFile is used" }
|
||||
}
|
||||
|
||||
checkKeyIsNull(JVMConfigurationKeys.OUTPUT_DIRECTORY, "OUTPUT_DIRECTORY")
|
||||
checkKeyIsNull(JVMConfigurationKeys.OUTPUT_JAR, "OUTPUT_JAR")
|
||||
put(JVMConfigurationKeys.OUTPUT_DIRECTORY, File(module.getOutputDirectory()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ fun CompilerConfiguration.addJvmSdkRoots(files: List<File>) {
|
||||
val CompilerConfiguration.jvmClasspathRoots: List<File>
|
||||
get() = getList(CLIConfigurationKeys.CONTENT_ROOTS).filterIsInstance<JvmClasspathRoot>().map(JvmContentRoot::file)
|
||||
|
||||
val CompilerConfiguration.jvmModularRoots: List<File>
|
||||
get() = getList(CLIConfigurationKeys.CONTENT_ROOTS).filterIsInstance<JvmModulePathRoot>().map(JvmContentRoot::file)
|
||||
|
||||
@JvmOverloads
|
||||
fun CompilerConfiguration.addJavaSourceRoot(file: File, packagePrefix: String? = null) {
|
||||
add(CLIConfigurationKeys.CONTENT_ROOTS, JavaSourceRoot(file, packagePrefix))
|
||||
|
||||
@@ -45,6 +45,7 @@ data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName:
|
||||
|
||||
companion object RootTypes {
|
||||
val OnlyBinary: Set<RootType> = EnumSet.of(RootType.BINARY)
|
||||
val OnlySource: Set<RootType> = EnumSet.of(RootType.SOURCE)
|
||||
val SourceAndBinary: Set<RootType> = EnumSet.of(RootType.BINARY, RootType.SOURCE)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,16 +16,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.modules
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleFinder
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
||||
|
||||
class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
|
||||
class CliJavaModuleFinder(
|
||||
jrtFileSystemRoot: VirtualFile?,
|
||||
private val javaFileManager: KotlinCliJavaFileManager,
|
||||
project: Project
|
||||
) : JavaModuleFinder {
|
||||
private val modulesRoot = jrtFileSystemRoot?.findChild("modules")
|
||||
private val userModules = linkedMapOf<String, JavaModule>()
|
||||
|
||||
private val allScope = GlobalSearchScope.allScope(project)
|
||||
|
||||
fun addUserModule(module: JavaModule) {
|
||||
userModules.putIfAbsent(module.name, module)
|
||||
}
|
||||
@@ -41,7 +50,7 @@ class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
|
||||
|
||||
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
||||
val file = moduleRoot.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) ?: return null
|
||||
val moduleInfo = JavaModuleInfo.read(file) ?: return null
|
||||
val moduleInfo = JavaModuleInfo.read(file, javaFileManager, allScope) ?: return null
|
||||
return JavaModule.Explicit(moduleInfo, listOf(JavaModule.Root(moduleRoot, isBinary = true)), file)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,18 +18,24 @@ package org.jetbrains.kotlin.cli.jvm.modules
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class CliJavaModuleResolver(
|
||||
private val moduleGraph: JavaModuleGraph,
|
||||
private val userModules: List<JavaModule>,
|
||||
private val systemModules: List<JavaModule.Explicit>
|
||||
private val systemModules: List<JavaModule.Explicit>,
|
||||
private val project: Project
|
||||
) : JavaModuleResolver {
|
||||
init {
|
||||
assert(userModules.count(JavaModule::isSourceModule) <= 1) {
|
||||
@@ -37,6 +43,14 @@ class CliJavaModuleResolver(
|
||||
}
|
||||
}
|
||||
|
||||
private val virtualFileFinder by lazy { VirtualFileFinder.getInstance(project) }
|
||||
|
||||
override fun getAnnotationsForModuleOwnerOfClass(classId: ClassId): List<JavaAnnotation>? {
|
||||
val virtualFile = virtualFileFinder.findSourceOrBinaryVirtualFile(classId) ?: return null
|
||||
|
||||
return (findJavaModule(virtualFile) as? JavaModule.Explicit)?.moduleInfo?.annotations
|
||||
}
|
||||
|
||||
private val sourceModule: JavaModule? = userModules.firstOrNull(JavaModule::isSourceModule)
|
||||
|
||||
private fun findJavaModule(file: VirtualFile): JavaModule? {
|
||||
@@ -77,4 +91,8 @@ class CliJavaModuleResolver(
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MODULE_ANNOTATIONS_CACHE_SIZE = 10000
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,11 @@ object KotlinCompilerClient {
|
||||
fun CompileService.leaseImpl(): CompileServiceSession? {
|
||||
// the newJVMOptions could be checked here for additional parameters, if needed
|
||||
registerClient(clientAliveFlagFile.absolutePath)
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "connected to the daemon")
|
||||
val javaExecutablePath = compilerId.javaExecutable?.absolutePath ?: "'user jvm'"
|
||||
reportingTargets.report(
|
||||
DaemonReportCategory.DEBUG,
|
||||
"connected to the daemon. Daemon is using following 'java' executable to run itself: $javaExecutablePath"
|
||||
)
|
||||
|
||||
if (!leaseSession) return CompileServiceSession(this, CompileService.NO_SESSION)
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ plugins {
|
||||
dependencies {
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) }
|
||||
|
||||
testApi(intellijDep())
|
||||
testApi(projectTests(":compiler:test-infrastructure"))
|
||||
testApi(projectTests(":compiler:test-infrastructure-utils"))
|
||||
testApi(projectTests(":compiler:tests-compiler-utils"))
|
||||
testApi(projectTests(":compiler:tests-common-new"))
|
||||
testApi(project(":compiler:cli"))
|
||||
testApi(project(":compiler:fir:checkers"))
|
||||
testApi(project(":compiler:fir:checkers:checkers.jvm"))
|
||||
testApi(project(":compiler:fir:fir-serialization"))
|
||||
testApi(project(":compiler:fir:entrypoint"))
|
||||
testApi(project(":compiler:frontend"))
|
||||
|
||||
@@ -20,6 +20,7 @@ dependencies {
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-junit"))
|
||||
testApi(projectTests(":compiler:tests-common"))
|
||||
testApi(project(":compiler:fir:checkers"))
|
||||
testApi(project(":compiler:fir:checkers:checkers.jvm"))
|
||||
testApi(project(":compiler:fir:entrypoint"))
|
||||
testApi(project(":compiler:frontend"))
|
||||
|
||||
|
||||
@@ -561,6 +561,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/integerLiteralTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("integerOverloads.kt")
|
||||
public void testIntegerOverloads() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/integerOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invoke.kt")
|
||||
public void testInvoke() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/invoke.kt");
|
||||
@@ -970,6 +975,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
public void testConstValWithGetterOrDelegate() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValWithGetterOrDelegate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constValWithTypealiasType.kt")
|
||||
public void testConstValWithTypealiasType() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/constVal/constValWithTypealiasType.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/constructors")
|
||||
@@ -2406,6 +2416,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/definitelyNotNullIntersectionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("elvisAndUnit.kt")
|
||||
public void testElvisAndUnit() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/elvisAndUnit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionCallableReferences.kt")
|
||||
public void testExtensionCallableReferences() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.kt");
|
||||
@@ -2475,6 +2490,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
public void testTypeDepthForTypeAlias() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/typeDepthForTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitUpperBound.kt")
|
||||
public void testUnitUpperBound() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/unitUpperBound.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/inlineClasses")
|
||||
@@ -2789,6 +2809,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/secondaryConstructorCfg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("symbolsAndDescriptors.kt")
|
||||
public void testSymbolsAndDescriptors() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/symbolsAndDescriptors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("transform.kt")
|
||||
public void testTransform() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/problems/transform.kt");
|
||||
@@ -3440,6 +3465,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
public void testCastToBareType() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/types/castToBareType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasInArguments.kt")
|
||||
public void testTypeAliasInArguments() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/types/typeAliasInArguments.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/visibility")
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -30,6 +31,7 @@ abstract class AbstractFirLoadCompiledKotlin : AbstractFirLoadBinariesTest() {
|
||||
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_NO_RUNTIME)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
fun doTest(path: String) {
|
||||
val moduleDescriptor = compileKtFileToTmpDir(path)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.serialization.builtins.BuiltinsTestUtils
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
@@ -16,6 +17,7 @@ class BuiltInsDeserializationForFirTestCase : AbstractFirLoadBinariesTest() {
|
||||
return createEnvironmentWithJdk(ConfigurationKind.ALL, TestJdkKind.FULL_JDK)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
fun testBuiltInPackagesContent() {
|
||||
val moduleDescriptor = BuiltinsTestUtils.compileBuiltinsModule(environment)
|
||||
val session = createSessionForTests(environment, GlobalSearchScope.allScope(project))
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.intellij.psi.PsiPackageStatement
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
@@ -82,6 +83,7 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
fun doTest(path: String) {
|
||||
val javaFile = File(path)
|
||||
val javaLines = javaFile.readLines()
|
||||
|
||||
@@ -81,7 +81,7 @@ public final class CharRange : R|kotlin/ranges/CharProgression|, R|kotlin/ranges
|
||||
|
||||
}
|
||||
|
||||
public abstract interface ClosedRange<T> : R|kotlin/Any| {
|
||||
public abstract interface ClosedRange<T : R|kotlin/Comparable<T>|> : R|kotlin/Any| {
|
||||
public open operator fun contains(value: R|T|): R|kotlin/Boolean|
|
||||
|
||||
public open fun isEmpty(): R|kotlin/Boolean|
|
||||
|
||||
@@ -12,9 +12,9 @@ public final fun doubleArrayOf(vararg elements: R|kotlin/DoubleArray|): R|kotlin
|
||||
|
||||
public final inline fun <reified T> emptyArray(): R|kotlin/Array<T>|
|
||||
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T> enumValueOf(name: R|kotlin/String|): R|T|
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T : R|kotlin/Enum<T>|> enumValueOf(name: R|kotlin/String|): R|T|
|
||||
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T> enumValues(): R|kotlin/Array<T>|
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T : R|kotlin/Enum<T>|> enumValues(): R|kotlin/Array<T>|
|
||||
|
||||
public final fun floatArrayOf(vararg elements: R|kotlin/FloatArray|): R|kotlin/FloatArray|
|
||||
|
||||
@@ -529,7 +529,7 @@ public final class DoubleArray : R|kotlin/Any|, R|kotlin/Cloneable|, R|java/io/S
|
||||
|
||||
}
|
||||
|
||||
public abstract class Enum<E> : R|kotlin/Comparable<E>|, R|java/io/Serializable| {
|
||||
public abstract class Enum<E : R|kotlin/Enum<E>|> : R|kotlin/Comparable<E>|, R|java/io/Serializable| {
|
||||
public final companion object Companion : R|kotlin/Any| {
|
||||
private constructor(): R|kotlin/Enum.Companion|
|
||||
|
||||
@@ -551,7 +551,7 @@ public abstract class Enum<E> : R|kotlin/Comparable<E>|, R|java/io/Serializable|
|
||||
public final val ordinal: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public constructor<E>(name: R|kotlin/String| = STUB, ordinal: R|kotlin/Int| = STUB): R|kotlin/Enum<E>|
|
||||
public constructor<E : R|kotlin/Enum<E>|>(name: R|kotlin/String| = STUB, ordinal: R|kotlin/Int| = STUB): R|kotlin/Enum<E>|
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
FILE: annotationUsedAsAnnotationArgument.kt
|
||||
public final annotation class Ann : R|kotlin/Annotation| {
|
||||
@R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) public final annotation class Ann : R|kotlin/Annotation| {
|
||||
public constructor(): R|Ann| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final annotation class Ann2 : R|kotlin/Annotation| {
|
||||
@R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) public final annotation class Ann2 : R|kotlin/Annotation| {
|
||||
public constructor(): R|Ann2| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final annotation class Ann3 : R|kotlin/Annotation| {
|
||||
@R|kotlin/annotation/Target|(vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.EXPRESSION|)) @R|kotlin/annotation/Retention|(Q|kotlin/annotation/AnnotationRetention|.R|kotlin/annotation/AnnotationRetention.SOURCE|) public final annotation class Ann3 : R|kotlin/Annotation| {
|
||||
public constructor(arg: R|kotlin/Int|, s: R|kotlin/String|): R|Ann3| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
@Target(AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Ann
|
||||
|
||||
@Target(AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Ann2
|
||||
|
||||
@Target(AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class Ann3(val arg: Int, val s: String)
|
||||
|
||||
@Ann3(
|
||||
<!WRONG_ANNOTATION_TARGET!>@Ann3(
|
||||
<!ANNOTATION_USED_AS_ANNOTATION_ARGUMENT!>@Ann3(
|
||||
<!ANNOTATION_USED_AS_ANNOTATION_ARGUMENT!>@Ann<!> 5, ""
|
||||
)<!> <!ANNOTATION_USED_AS_ANNOTATION_ARGUMENT!>@Ann2<!> 1, ""
|
||||
) val a = 0
|
||||
)<!> val a = 0
|
||||
|
||||
@@ -37,8 +37,8 @@ FILE: destructuring.kt
|
||||
}
|
||||
)
|
||||
R|/foo1|(<L> = foo1@fun <anonymous>(<destruct>: R|C|): R|kotlin/Unit| <inline=NoInline> {
|
||||
lval x: R|kotlin/String| = R|<local>/<destruct>|.R|/C.component1|()
|
||||
lval y: R|kotlin/Int| = R|<local>/<destruct>|.R|/C.component2|()
|
||||
lval x: R|kotlin/String| = R|<local>/<destruct>|.<CS errors: /C.component1>#()
|
||||
lval y: R|kotlin/Int| = R|<local>/<destruct>|.<CS errors: /C.component2>#()
|
||||
<Inapplicable(INAPPLICABLE): /C.C>#(R|<local>/x|, R|<local>/y|)
|
||||
}
|
||||
)
|
||||
@@ -59,10 +59,10 @@ FILE: destructuring.kt
|
||||
}
|
||||
)
|
||||
R|/foo2|(<L> = foo2@fun <anonymous>(<destruct>: R|C|, <destruct>: R|C|): R|kotlin/Unit| <inline=NoInline> {
|
||||
lval x: R|kotlin/String| = R|<local>/<destruct>|.R|/C.component1|()
|
||||
lval y: R|kotlin/Int| = R|<local>/<destruct>|.R|/C.component2|()
|
||||
lval z: R|kotlin/String| = R|<local>/<destruct>|.R|/C.component1|()
|
||||
lval w: R|kotlin/Int| = R|<local>/<destruct>|.R|/C.component2|()
|
||||
lval x: R|kotlin/String| = R|<local>/<destruct>|.<CS errors: /C.component1>#()
|
||||
lval y: R|kotlin/Int| = R|<local>/<destruct>|.<CS errors: /C.component2>#()
|
||||
lval z: R|kotlin/String| = R|<local>/<destruct>|.<CS errors: /C.component1>#()
|
||||
lval w: R|kotlin/Int| = R|<local>/<destruct>|.<CS errors: /C.component2>#()
|
||||
<Inapplicable(INAPPLICABLE): /C.C>#(R|<local>/x|.R|kotlin/String.plus|(R|<local>/z|), R|<local>/y|.R|kotlin/Int.plus|(R|<local>/w|))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun test(
|
||||
val f: String.() -> Int = { length }
|
||||
f: String.() -> Int = { length }
|
||||
): Int {
|
||||
return "".f()
|
||||
}
|
||||
|
||||
21
compiler/fir/analysis-tests/testData/resolve/arguments/integerOverloads.fir.txt
vendored
Normal file
21
compiler/fir/analysis-tests/testData/resolve/arguments/integerOverloads.fir.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
FILE: x.kt
|
||||
public final fun f(x: R|kotlin/Byte|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun f(x: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun f(x: R|kotlin/Long|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun g(x: R|kotlin/Byte?|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun g(x: R|kotlin/Int?|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun g(x: R|kotlin/Long?|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
Q|J|.R|/J.f|(Int(123))
|
||||
Q|J|.R|/J.f|(Long(123123123123))
|
||||
R|/f|(Int(123))
|
||||
R|/f|(Long(123123123123))
|
||||
R|/g|(Int(123))
|
||||
R|/g|(Long(123123123123))
|
||||
}
|
||||
24
compiler/fir/analysis-tests/testData/resolve/arguments/integerOverloads.kt
vendored
Normal file
24
compiler/fir/analysis-tests/testData/resolve/arguments/integerOverloads.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// FILE: J.java
|
||||
public class J {
|
||||
public static fun f(Byte x) {}
|
||||
public static fun f(Integer x) {}
|
||||
public static fun f(Long x) {}
|
||||
}
|
||||
|
||||
// FILE: x.kt
|
||||
fun f(x: Byte) {}
|
||||
fun f(x: Int) {}
|
||||
fun f(x: Long) {}
|
||||
|
||||
fun g(x: Byte?) {}
|
||||
fun g(x: Int?) {}
|
||||
fun g(x: Long?) {}
|
||||
|
||||
fun main() {
|
||||
J.f(123)
|
||||
J.f(123123123123)
|
||||
f(123)
|
||||
f(123123123123)
|
||||
g(123)
|
||||
g(123123123123)
|
||||
}
|
||||
@@ -7,7 +7,7 @@ FILE: main.kt
|
||||
public abstract interface PsiClass : R|kotlin/Any| {
|
||||
}
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval processor: R|AdapterProcessor<ft<PsiMethod, PsiMethod?>, ft<PsiClass, PsiClass?>>| = R|/AdapterProcessor.AdapterProcessor|<R|ft<PsiMethod, PsiMethod?>|, R|ft<PsiClass, PsiClass?>|>(R|/Function|<R|ft<PsiMethod, PsiMethod?>|, R|PsiClass?|>(<L> = Function@fun <anonymous>(method: R|PsiMethod?|): R|PsiClass?| <inline=NoInline> {
|
||||
lval processor: R|AdapterProcessor<ft<PsiMethod, PsiMethod?>, ft<PsiClass, PsiClass?>>| = R|/AdapterProcessor.AdapterProcessor|<R|ft<PsiMethod, PsiMethod?>|, R|ft<PsiClass, PsiClass?>|>(R|/Function|<R|ft<PsiMethod, PsiMethod?>|, R|ft<PsiClass, PsiClass?>|>(<L> = Function@fun <anonymous>(method: R|PsiMethod?|): R|ft<PsiClass, PsiClass?>| <inline=NoInline> {
|
||||
^ R|<local>/method|?.{ $subj$.R|/PsiMethod.containingClass| }
|
||||
}
|
||||
))
|
||||
|
||||
@@ -10,7 +10,7 @@ FILE: A.kt
|
||||
}
|
||||
FILE: main.kt
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval a: R|ERROR CLASS: Unresolved name: A| = <Unresolved name: A>#()
|
||||
lval a: <ERROR TYPE REF: Unresolved name: A> = <Unresolved name: A>#()
|
||||
lval b: R|foo/A| = R|foo/A.A|()
|
||||
lval c: R|foo/A| = <Unresolved name: A>#()
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ FILE: cast.kt
|
||||
}
|
||||
|
||||
public get(): R|(kotlin/String) -> kotlin/Boolean|
|
||||
public final val hError: R|(ERROR CLASS: No type for parameter) -> kotlin/Boolean| = fun <anonymous>(_: R|ERROR CLASS: No type for parameter|): R|kotlin/Boolean| <inline=Unknown> {
|
||||
public final val hError: R|(ERROR CLASS: No type for parameter) -> kotlin/Boolean| = fun <anonymous>(_: <ERROR TYPE REF: No type for parameter>): R|kotlin/Boolean| <inline=Unknown> {
|
||||
^ Boolean(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ fun <T : Throwable> test() {
|
||||
|
||||
try {} catch (<!TYPE_PARAMETER_IN_CATCH_CLAUSE!>e: T<!>) {}
|
||||
|
||||
try {} catch (<!TYPE_MISMATCH!>e: () -> Int<!>) {}
|
||||
try {} catch (<!THROWABLE_TYPE_MISMATCH!>e: () -> Int<!>) {}
|
||||
|
||||
try {} catch (<!TYPE_MISMATCH!>e: StringType<!>) {}
|
||||
try {} catch (<!THROWABLE_TYPE_MISMATCH!>e: StringType<!>) {}
|
||||
|
||||
try {} catch (<!CATCH_PARAMETER_WITH_DEFAULT_VALUE, TYPE_MISMATCH!>e: Int = 5<!>) {}
|
||||
try {} catch (<!CATCH_PARAMETER_WITH_DEFAULT_VALUE, THROWABLE_TYPE_MISMATCH!>e: Int = 5<!>) {}
|
||||
|
||||
try {} catch (e: Throwable) {}
|
||||
}
|
||||
|
||||
inline fun <reified T> anotherTest() {
|
||||
try {} catch (<!REIFIED_TYPE_IN_CATCH_CLAUSE, TYPE_MISMATCH!>e: T<!>) {}
|
||||
try {} catch (<!REIFIED_TYPE_IN_CATCH_CLAUSE, THROWABLE_TYPE_MISMATCH!>e: T<!>) {}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,6 @@ interface B
|
||||
|
||||
fun test_2(x: Any?) {
|
||||
if (x is A && x is B) {
|
||||
x is A
|
||||
<!USELESS_IS_CHECK!>x is A<!>
|
||||
}
|
||||
}
|
||||
|
||||
4
compiler/fir/analysis-tests/testData/resolve/constVal/constValWithTypealiasType.fir.txt
vendored
Normal file
4
compiler/fir/analysis-tests/testData/resolve/constVal/constValWithTypealiasType.fir.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
FILE: constValWithTypealiasType.kt
|
||||
public final typealias Foo = R|kotlin/Int|
|
||||
public final const val x: R|Foo| = Int(10)
|
||||
public get(): R|Foo|
|
||||
3
compiler/fir/analysis-tests/testData/resolve/constVal/constValWithTypealiasType.kt
vendored
Normal file
3
compiler/fir/analysis-tests/testData/resolve/constVal/constValWithTypealiasType.kt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
typealias Foo = Int
|
||||
|
||||
const val x: Foo = 10
|
||||
@@ -26,7 +26,7 @@ FILE: kt41982.kt
|
||||
super<R|DelegateProvider<kotlin/Any>|>()
|
||||
}
|
||||
|
||||
public final var start: R|kotlin/Long|by this@R|/Test|.R|/long|<R|Test?|, R|Test?|>(<L> = long@fun <anonymous>(): R|kotlin/Long?| <inline=NoInline> {
|
||||
public final var start: R|kotlin/Long|by this@R|/Test|.R|/long|<R|Test|, R|Test|>(<L> = long@fun <anonymous>(): R|kotlin/Long?| <inline=NoInline> {
|
||||
^ Long(0)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FILE: classInSupertypeForEnum.kt
|
||||
public final class A : R|kotlin/Any| {
|
||||
public open class A : R|kotlin/Any| {
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class A
|
||||
open class A
|
||||
|
||||
interface C
|
||||
|
||||
enum class B : C, <!CLASS_IN_SUPERTYPE_FOR_ENUM!>A<!>(), Any()
|
||||
enum class B : C, <!CLASS_IN_SUPERTYPE_FOR_ENUM!>A<!>(), <!MANY_CLASSES_IN_SUPERTYPE_LIST!>Any<!>()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// FIR_IDE_IGNORE
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun test(x: Int)<!> {}
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun test(y: Int)<!> {}
|
||||
@@ -16,7 +18,7 @@ fun test(z: Int, c: Char) {}
|
||||
|
||||
}<!>
|
||||
|
||||
<!REDECLARATION!>class B : <!SUPERTYPE_NOT_INITIALIZED!>A<!> {
|
||||
<!REDECLARATION!>class B : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
|
||||
<!CONFLICTING_OVERLOADS!>override fun rest(s: String)<!> {}
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {}
|
||||
|
||||
@@ -3,5 +3,5 @@ interface <!CONSTRUCTOR_IN_INTERFACE!>A(val s: String)<!>
|
||||
interface <!CONSTRUCTOR_IN_INTERFACE!>B constructor(val s: String)<!>
|
||||
|
||||
interface C {
|
||||
<!CONSTRUCTOR_IN_INTERFACE!>constructor(val s: String)<!> {}
|
||||
<!CONSTRUCTOR_IN_INTERFACE!>constructor(s: String)<!> {}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ FILE: cyclicConstructorDelegationCall.kt
|
||||
}
|
||||
|
||||
}
|
||||
public final class M : R|kotlin/Any| {
|
||||
public open class M : R|kotlin/Any| {
|
||||
public constructor(m: R|kotlin/Int|): R|M| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class K(x: Int) {
|
||||
constructor() : <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>() {}
|
||||
}
|
||||
|
||||
class M {
|
||||
open class M {
|
||||
constructor(m: Int)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FILE: delegationInInterface.kt
|
||||
public final class A : R|kotlin/Any| {
|
||||
public open class A : R|kotlin/Any| {
|
||||
public constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class A
|
||||
open class A
|
||||
|
||||
interface B : <!DELEGATION_IN_INTERFACE, INTERFACE_WITH_SUPERCLASS!>A<!> by <!UNRESOLVED_REFERENCE!>a<!> {
|
||||
val a: A
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user