mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-20 15:51:32 +00:00
Compare commits
583 Commits
script_run
...
new_infere
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6081fd9dd | ||
|
|
a5222b0558 | ||
|
|
e07a135ee8 | ||
|
|
d872621edc | ||
|
|
a67e578a28 | ||
|
|
ba3a1d5d83 | ||
|
|
4b0890d9f8 | ||
|
|
2d8a56dbd9 | ||
|
|
ba61919795 | ||
|
|
b4149b0b5b | ||
|
|
4a367f3b56 | ||
|
|
04636a5497 | ||
|
|
d1af799f97 | ||
|
|
c6aeb954c8 | ||
|
|
fc3479405a | ||
|
|
8a085f8219 | ||
|
|
f51f5576c8 | ||
|
|
5c0833fb47 | ||
|
|
7d8820fc82 | ||
|
|
ab5088c4b2 | ||
|
|
b9be1b306b | ||
|
|
e245b7edf0 | ||
|
|
5f4ca7a341 | ||
|
|
b4e79424f6 | ||
|
|
6839efe48e | ||
|
|
61992aeefd | ||
|
|
f0f6a252a5 | ||
|
|
0adf1d210f | ||
|
|
0fd5c6f1ca | ||
|
|
9dc5354f24 | ||
|
|
3623f581b8 | ||
|
|
82fc221470 | ||
|
|
0efdcb59fa | ||
|
|
2b90a67bc1 | ||
|
|
806aa7d4c1 | ||
|
|
8af7a25f8e | ||
|
|
39599fc7c9 | ||
|
|
99a402ee30 | ||
|
|
4d2fbf1801 | ||
|
|
97d46e76f5 | ||
|
|
905b8cc4e9 | ||
|
|
79ecc7fd5c | ||
|
|
1b2e28d467 | ||
|
|
f7a1c71b54 | ||
|
|
770441c212 | ||
|
|
8db736e2b4 | ||
|
|
7601666ec0 | ||
|
|
a24c9a987f | ||
|
|
be664e26f7 | ||
|
|
4092d754c6 | ||
|
|
12eb4ef37a | ||
|
|
a2a018eadb | ||
|
|
f7c17d6a64 | ||
|
|
6a5d8dcc82 | ||
|
|
070e35bc15 | ||
|
|
a641838368 | ||
|
|
226ffb6c7e | ||
|
|
6a4ea8b669 | ||
|
|
a12877e51c | ||
|
|
a086863561 | ||
|
|
b2d931fb1f | ||
|
|
9be5cf89b4 | ||
|
|
80b6aaa802 | ||
|
|
5bd04a6d22 | ||
|
|
787bbe9a4c | ||
|
|
1215b2864b | ||
|
|
2f556e1bea | ||
|
|
537c1fd063 | ||
|
|
f80fcc7146 | ||
|
|
d3a9d122e6 | ||
|
|
cd5c382179 | ||
|
|
4dbde03c3b | ||
|
|
f5c7db8270 | ||
|
|
7f9110b4e6 | ||
|
|
0b44386800 | ||
|
|
8439e15c6e | ||
|
|
e4f70a3568 | ||
|
|
62ca3bab31 | ||
|
|
f455f06a9e | ||
|
|
386b1fc002 | ||
|
|
98eb990f30 | ||
|
|
e3963fccf4 | ||
|
|
57d209f599 | ||
|
|
e5e5b56af0 | ||
|
|
04464024fe | ||
|
|
9bb7ed5e02 | ||
|
|
34681b1459 | ||
|
|
1fe3f84071 | ||
|
|
5b72159967 | ||
|
|
e315249624 | ||
|
|
5501cdf049 | ||
|
|
746de612ad | ||
|
|
5fd8f93b0e | ||
|
|
71bf649b1e | ||
|
|
bf98e26bc2 | ||
|
|
718ee01a48 | ||
|
|
830b543879 | ||
|
|
165707c46c | ||
|
|
88bc74551b | ||
|
|
7986250dbe | ||
|
|
192d569e54 | ||
|
|
4cf2bf6ca5 | ||
|
|
3d6622ae1b | ||
|
|
0226d15d29 | ||
|
|
cd40968b72 | ||
|
|
6cd409d379 | ||
|
|
80131d8359 | ||
|
|
4b2b5dec75 | ||
|
|
f8de17b039 | ||
|
|
a8c82b64a1 | ||
|
|
ce37ab81ba | ||
|
|
9962fc88ca | ||
|
|
8898455352 | ||
|
|
8948023a26 | ||
|
|
964f60d0a4 | ||
|
|
f8f0c0b6d7 | ||
|
|
a82e313d14 | ||
|
|
6d66fb35d6 | ||
|
|
10bf49118a | ||
|
|
46bbf55acd | ||
|
|
eeede71d9d | ||
|
|
2cf4da8564 | ||
|
|
d8c20ed9c0 | ||
|
|
0d6cf19896 | ||
|
|
c2b54c3e8a | ||
|
|
bb7521a142 | ||
|
|
99439620d4 | ||
|
|
2954c41848 | ||
|
|
f94569c995 | ||
|
|
4e868c5232 | ||
|
|
62dc3c8da4 | ||
|
|
384ae8d8b5 | ||
|
|
532560ef43 | ||
|
|
ca19ea8205 | ||
|
|
ce77751349 | ||
|
|
6ae247ba61 | ||
|
|
13349086ac | ||
|
|
a36cbad7cd | ||
|
|
4a15870e59 | ||
|
|
e56f9f6040 | ||
|
|
85ecde6ec9 | ||
|
|
4d72f0ef66 | ||
|
|
11086192bc | ||
|
|
08673bfb0c | ||
|
|
0694f2d0c5 | ||
|
|
548e86285c | ||
|
|
20d0d49cc3 | ||
|
|
48d4f5f5c2 | ||
|
|
c1cfd70ae7 | ||
|
|
b825a8db43 | ||
|
|
23e606d179 | ||
|
|
cf4d0fb977 | ||
|
|
83a8395287 | ||
|
|
282da4cab5 | ||
|
|
298d29a962 | ||
|
|
62e583903e | ||
|
|
c675824c0a | ||
|
|
6336c4ee98 | ||
|
|
be1022db2b | ||
|
|
a142c2f8fa | ||
|
|
c07096c9d7 | ||
|
|
768305adc8 | ||
|
|
e8d2782089 | ||
|
|
b50d5fb998 | ||
|
|
7fffb7b553 | ||
|
|
b938206234 | ||
|
|
84e1e9f8aa | ||
|
|
239943867b | ||
|
|
0d3b882852 | ||
|
|
6354d9d54f | ||
|
|
856276328e | ||
|
|
e0ef08cf18 | ||
|
|
642c5414a3 | ||
|
|
46a3a59b81 | ||
|
|
7e7fcd352c | ||
|
|
82c977f2d2 | ||
|
|
6cfd090b20 | ||
|
|
e2190ea956 | ||
|
|
f3f7ca4b95 | ||
|
|
ab90221a93 | ||
|
|
485e2345a9 | ||
|
|
bb2fab5b5d | ||
|
|
a4c7dbd693 | ||
|
|
61b3c1c429 | ||
|
|
c601890151 | ||
|
|
1cce1ef1f6 | ||
|
|
ed5b6e07aa | ||
|
|
23afaeec2f | ||
|
|
f5e77c740d | ||
|
|
8ffd141d17 | ||
|
|
1921950a1b | ||
|
|
cc24b9f4ad | ||
|
|
5dd4e4cdd4 | ||
|
|
9ab7c92b4b | ||
|
|
8fbab94c5c | ||
|
|
6ca06265cf | ||
|
|
a41e5fff6b | ||
|
|
674d30cd76 | ||
|
|
c180de563f | ||
|
|
223acbcfeb | ||
|
|
e35b262827 | ||
|
|
4e190248cd | ||
|
|
3fd6dd3572 | ||
|
|
022430cb59 | ||
|
|
974dad571c | ||
|
|
2ac7b6a534 | ||
|
|
915f47133b | ||
|
|
f24488915a | ||
|
|
adfc481c7a | ||
|
|
4405021f85 | ||
|
|
73a4da6c56 | ||
|
|
a7bbf3d1f8 | ||
|
|
3415853cac | ||
|
|
ac96c31a7d | ||
|
|
0b45d25bb1 | ||
|
|
bdbe134b60 | ||
|
|
07794c8188 | ||
|
|
dde1f4b8f3 | ||
|
|
36cabf1bfc | ||
|
|
d6a9a49968 | ||
|
|
aafe7e6f1b | ||
|
|
fcc067435e | ||
|
|
194deccd09 | ||
|
|
3debca09ea | ||
|
|
cfbc559a97 | ||
|
|
4a74ca568c | ||
|
|
053b02e0df | ||
|
|
20e105c274 | ||
|
|
82c3637d91 | ||
|
|
46d0ea3eed | ||
|
|
cf3615d279 | ||
|
|
e52c3b4c81 | ||
|
|
998814b1a1 | ||
|
|
9361cd895c | ||
|
|
48246e5f34 | ||
|
|
b6e195128c | ||
|
|
5486f4e612 | ||
|
|
64b722d4f6 | ||
|
|
9c37d0a007 | ||
|
|
60e330b6f3 | ||
|
|
ff0736f09e | ||
|
|
45d5f6a950 | ||
|
|
3ae084b1b3 | ||
|
|
49612063dc | ||
|
|
07c5702861 | ||
|
|
6e4b02a94b | ||
|
|
6305abdf9f | ||
|
|
ca418c727e | ||
|
|
8a17e6c1c9 | ||
|
|
e53b1a1e92 | ||
|
|
5904b7f257 | ||
|
|
15f401a473 | ||
|
|
11ba805181 | ||
|
|
5ecdf2af9e | ||
|
|
fca1500d48 | ||
|
|
e2dcf47b3b | ||
|
|
52f923c5ff | ||
|
|
ae3497c6ce | ||
|
|
8f8143d3ed | ||
|
|
4d4c39939f | ||
|
|
216ab1c6d1 | ||
|
|
7ba073206d | ||
|
|
7693f64dee | ||
|
|
9e018fa094 | ||
|
|
07a4496054 | ||
|
|
a13442b12b | ||
|
|
dc83e5ca3a | ||
|
|
3fb865e07c | ||
|
|
fb72726f08 | ||
|
|
6680f01cfe | ||
|
|
e7cd615450 | ||
|
|
cf75afba66 | ||
|
|
ac507e721c | ||
|
|
21c5187c9e | ||
|
|
0d464f06d1 | ||
|
|
39349abd39 | ||
|
|
5ec8d4920f | ||
|
|
c0d6eff97c | ||
|
|
0bf81aeec0 | ||
|
|
258a5aea28 | ||
|
|
ab2f99542a | ||
|
|
b344865c15 | ||
|
|
93d80c252f | ||
|
|
ef93088a42 | ||
|
|
9378bff65c | ||
|
|
3450340d7f | ||
|
|
1bc68e073d | ||
|
|
4848f8e3da | ||
|
|
85e34163bb | ||
|
|
455c43afa8 | ||
|
|
f1144c9f01 | ||
|
|
c752e1580e | ||
|
|
a5dffafacd | ||
|
|
7802492b08 | ||
|
|
6be726854f | ||
|
|
76d013a33f | ||
|
|
4963580f90 | ||
|
|
17cdbcca03 | ||
|
|
915ac32bfb | ||
|
|
91241a34d1 | ||
|
|
d58c6e245f | ||
|
|
e74a02eb94 | ||
|
|
ffc130f5fb | ||
|
|
5f2cc75718 | ||
|
|
e4b73fcdbd | ||
|
|
756f7d6e9c | ||
|
|
d4e8a30dcf | ||
|
|
e5c87fdad7 | ||
|
|
b336919db3 | ||
|
|
397e04f382 | ||
|
|
5b2e66f0ca | ||
|
|
dc453e6d8b | ||
|
|
ba068c2d65 | ||
|
|
def0816095 | ||
|
|
38d9123a57 | ||
|
|
18961cc5a9 | ||
|
|
8599763cb9 | ||
|
|
fbad16567b | ||
|
|
1ae4278cfd | ||
|
|
bc2a8555a3 | ||
|
|
c0c94910e2 | ||
|
|
9fa3bce73a | ||
|
|
26cc08be65 | ||
|
|
6facdcb7ea | ||
|
|
badbf777df | ||
|
|
5eb56dca60 | ||
|
|
d1263c5dc3 | ||
|
|
cf55674109 | ||
|
|
f578d07b00 | ||
|
|
f637ebe9ff | ||
|
|
b7c894a6d3 | ||
|
|
b6bb171b67 | ||
|
|
8670d2abba | ||
|
|
72d14bfe0d | ||
|
|
a303888e66 | ||
|
|
0136be3500 | ||
|
|
0634025229 | ||
|
|
c6fcbf6172 | ||
|
|
e12eb66572 | ||
|
|
de17604fe7 | ||
|
|
42438bd363 | ||
|
|
85248676d2 | ||
|
|
b9e9243e9d | ||
|
|
af138e7403 | ||
|
|
5bb61d2d02 | ||
|
|
7eabdeffb3 | ||
|
|
b3be21146c | ||
|
|
0f0d834c23 | ||
|
|
55181541af | ||
|
|
58f73bd82a | ||
|
|
30f7396803 | ||
|
|
89ac3bd5cf | ||
|
|
3a25405088 | ||
|
|
ff6a28b64c | ||
|
|
acc6e48172 | ||
|
|
29e2a26ad6 | ||
|
|
ee16a79612 | ||
|
|
55dc2c11f7 | ||
|
|
02f4558683 | ||
|
|
36ea9484a9 | ||
|
|
0b358fb693 | ||
|
|
b24c1bf06c | ||
|
|
d624ed4aff | ||
|
|
a4551fb0fb | ||
|
|
71878b2218 | ||
|
|
13a2de1816 | ||
|
|
0cfac71efe | ||
|
|
94036b7cac | ||
|
|
999db0bc80 | ||
|
|
8fd508566a | ||
|
|
64eeb479aa | ||
|
|
1264ed7c86 | ||
|
|
666c241479 | ||
|
|
2536615e0e | ||
|
|
4c00119f08 | ||
|
|
7d66af6583 | ||
|
|
8d226594ff | ||
|
|
8de6017e53 | ||
|
|
ae6f38e252 | ||
|
|
6194bc10f8 | ||
|
|
656f8bb5cf | ||
|
|
435cfeea0a | ||
|
|
c5772e5549 | ||
|
|
2ed5a5e368 | ||
|
|
20cd748377 | ||
|
|
dbaec43e4d | ||
|
|
0a9e0ddba9 | ||
|
|
97a3d343f7 | ||
|
|
d30461afc6 | ||
|
|
78117b3e7b | ||
|
|
3b4891279e | ||
|
|
d738633981 | ||
|
|
563472e676 | ||
|
|
db9f925bb1 | ||
|
|
aed9d3899e | ||
|
|
41e5840298 | ||
|
|
9ac1a0140c | ||
|
|
61b10ac330 | ||
|
|
1ef5362edc | ||
|
|
3ea4a7fb47 | ||
|
|
0e4089ef8e | ||
|
|
d10fa8f891 | ||
|
|
e38cf54dac | ||
|
|
f0becd0040 | ||
|
|
82c62b4d8e | ||
|
|
88420311cb | ||
|
|
b423d58a14 | ||
|
|
4ca8d3d6cf | ||
|
|
8d5e69b06c | ||
|
|
b56f5593ab | ||
|
|
53d12e6cf7 | ||
|
|
10941ae732 | ||
|
|
0c2ea5d799 | ||
|
|
e6f1a3ccf3 | ||
|
|
3c0a4a0abf | ||
|
|
c5613888eb | ||
|
|
05eee9c173 | ||
|
|
3d7d1b20ab | ||
|
|
9a40e9b96d | ||
|
|
3770786075 | ||
|
|
13868f89e8 | ||
|
|
45681ed9eb | ||
|
|
6002281874 | ||
|
|
3bb7febeb8 | ||
|
|
5ff014f89d | ||
|
|
448fa8495a | ||
|
|
c1600c9841 | ||
|
|
9a5a003d0a | ||
|
|
53e193d130 | ||
|
|
4dddb00aca | ||
|
|
bf2bc1fdc7 | ||
|
|
9e9c4f79f5 | ||
|
|
65ea9290ea | ||
|
|
2ba89b9e68 | ||
|
|
45ec0e364a | ||
|
|
40163868af | ||
|
|
2984a5a19f | ||
|
|
50599c933f | ||
|
|
2e49971989 | ||
|
|
2d8f7419eb | ||
|
|
87cdc7635a | ||
|
|
c5a81691fb | ||
|
|
42f8a3e65b | ||
|
|
4dbb82a789 | ||
|
|
df56ef5e3f | ||
|
|
27365dc4be | ||
|
|
5fcefa28a7 | ||
|
|
c2617e89c9 | ||
|
|
1ed1751b63 | ||
|
|
29dba9edb3 | ||
|
|
b9788bbafd | ||
|
|
050744627d | ||
|
|
69b4d213b7 | ||
|
|
514635e965 | ||
|
|
5ce3a436c7 | ||
|
|
7cccba3b9a | ||
|
|
3f471d1ac6 | ||
|
|
e602903567 | ||
|
|
534db2d45b | ||
|
|
a4a0335b20 | ||
|
|
62fdd91947 | ||
|
|
aea5293288 | ||
|
|
8143ca158b | ||
|
|
e7afb073d9 | ||
|
|
5af9d29cbe | ||
|
|
2bd7d12312 | ||
|
|
50091bfac8 | ||
|
|
840f688bbf | ||
|
|
2e82bb5632 | ||
|
|
4923589b38 | ||
|
|
23ea1a1a60 | ||
|
|
f42808af94 | ||
|
|
e0aca97f9f | ||
|
|
88fa7c2952 | ||
|
|
be0b01a1e6 | ||
|
|
05ea99441f | ||
|
|
b0b2c046b2 | ||
|
|
d7e62937b2 | ||
|
|
9a004ceda2 | ||
|
|
5e032139cb | ||
|
|
4e77897bfd | ||
|
|
ca06d38c5b | ||
|
|
d59a72ea75 | ||
|
|
9e34437447 | ||
|
|
82502e1a8b | ||
|
|
527ccaff16 | ||
|
|
9e6b706a03 | ||
|
|
05919244bd | ||
|
|
7906ac9348 | ||
|
|
c1fd8fc318 | ||
|
|
e115c8b373 | ||
|
|
99555fa843 | ||
|
|
8b149db0ec | ||
|
|
b988582531 | ||
|
|
1e6850f198 | ||
|
|
eb673d6ed3 | ||
|
|
4b42f9e071 | ||
|
|
46a01ec131 | ||
|
|
3beb6a86f7 | ||
|
|
67336653e0 | ||
|
|
c8bc2d9d16 | ||
|
|
5df461c7e0 | ||
|
|
24865ba26a | ||
|
|
53373b66b9 | ||
|
|
1b93e2030f | ||
|
|
142a64e039 | ||
|
|
fabcd6b73c | ||
|
|
e9e81d96a5 | ||
|
|
79921b0206 | ||
|
|
ee7eb3186d | ||
|
|
6ba96b1103 | ||
|
|
7f467f0fdd | ||
|
|
d3ea7c3a14 | ||
|
|
996292264b | ||
|
|
0346b31628 | ||
|
|
44dafc38e5 | ||
|
|
3ff5c95419 | ||
|
|
c41c5f1916 | ||
|
|
68659f5a32 | ||
|
|
b81ca31aae | ||
|
|
c9ad290ad5 | ||
|
|
b867c46f72 | ||
|
|
7450899b87 | ||
|
|
ca8bf395c3 | ||
|
|
ff676c050f | ||
|
|
7da6ff78c1 | ||
|
|
ea1068a822 | ||
|
|
f29cf07fa4 | ||
|
|
92558ad183 | ||
|
|
826672ea1b | ||
|
|
725f51056f | ||
|
|
53fda33499 | ||
|
|
c2be771486 | ||
|
|
5a1a4bd8bd | ||
|
|
84eff43b49 | ||
|
|
98a2506eb0 | ||
|
|
8cdcfc5e67 | ||
|
|
38449caaed | ||
|
|
d0e4b236a7 | ||
|
|
cf607a0f14 | ||
|
|
4200629347 | ||
|
|
19eb30b3ae | ||
|
|
3062e72282 | ||
|
|
aa5f9ee3ec | ||
|
|
96c9bcd820 | ||
|
|
4197380621 | ||
|
|
c23bca6afe | ||
|
|
edd8a0a64e | ||
|
|
5290553184 | ||
|
|
a82f66cf45 | ||
|
|
dc88e1e16c | ||
|
|
c3988ef184 | ||
|
|
9781d1fcdf | ||
|
|
a08f55cf99 | ||
|
|
e6872c52a3 | ||
|
|
7fb78a0372 | ||
|
|
732d1129ab | ||
|
|
5df2698f77 | ||
|
|
224df7a1ea | ||
|
|
2f99f6ad34 | ||
|
|
845de7aa4d | ||
|
|
593f98190d | ||
|
|
0391c24ab2 | ||
|
|
c78ad9c047 | ||
|
|
fa88fb74c4 | ||
|
|
094125c970 | ||
|
|
f313001b2d | ||
|
|
baa6b44567 | ||
|
|
f10ea03173 | ||
|
|
e0dc7a27a0 | ||
|
|
861219f502 | ||
|
|
63c6ba7e31 | ||
|
|
f370d74609 | ||
|
|
0971af803c | ||
|
|
e1f7c91728 | ||
|
|
0f2992ddec | ||
|
|
079f7690a8 | ||
|
|
6dbaec0cc6 | ||
|
|
6eff8c7b4b | ||
|
|
57a501ebce | ||
|
|
8e3f8c4c14 | ||
|
|
d5ca46157a | ||
|
|
f1811e7f0e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,4 +21,5 @@ workspace.xml
|
||||
.gradle/
|
||||
build/
|
||||
!**/src/**/build
|
||||
!**/test/**/build
|
||||
|
||||
|
||||
3
.idea/artifacts/KotlinPlugin.xml
generated
3
.idea/artifacts/KotlinPlugin.xml
generated
@@ -61,6 +61,8 @@
|
||||
<element id="module-output" name="ir.psi2ir" />
|
||||
<element id="module-output" name="annotation-based-compiler-plugins-ide-support" />
|
||||
<element id="module-output" name="frontend.script" />
|
||||
<element id="extracted-dir" path="$PROJECT_DIR$/dependencies/json-org.jar" path-in-jar="/" />
|
||||
<element id="module-output" name="idea-gradle" />
|
||||
</element>
|
||||
<element id="library" level="project" name="javax.inject" />
|
||||
<element id="directory" name="jps">
|
||||
@@ -103,7 +105,6 @@
|
||||
<element id="archive" name="kotlin-gradle-tooling.jar">
|
||||
<element id="module-output" name="kotlin-gradle-tooling" />
|
||||
</element>
|
||||
<element id="library" level="project" name="uast-java" />
|
||||
<element id="library" level="project" name="kotlinx-coroutines-core" />
|
||||
<element id="library" level="project" name="javaslang" />
|
||||
<element id="library" level="project" name="kotlinx-coroutines-jdk8" />
|
||||
|
||||
2
.idea/dictionaries/yan.xml
generated
2
.idea/dictionaries/yan.xml
generated
@@ -1,8 +1,10 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="yan">
|
||||
<words>
|
||||
<w>deserializes</w>
|
||||
<w>impls</w>
|
||||
<w>kapt</w>
|
||||
<w>parceler</w>
|
||||
<w>uast</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
||||
1
.idea/inspectionProfiles/idea_default.xml
generated
1
.idea/inspectionProfiles/idea_default.xml
generated
@@ -235,7 +235,6 @@
|
||||
<scope name="idea openapi" level="WARNING" enabled="true" />
|
||||
<scope name="runtime.classes" level="ERROR" enabled="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LoopToCallChain" enabled="false" level="INFO" enabled_by_default="false" />
|
||||
<inspection_tool class="MethodMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="m_onlyPrivateOrFinal" value="false" />
|
||||
<option name="m_ignoreEmptyMethods" value="true" />
|
||||
|
||||
9
.idea/kotlinc.xml
generated
9
.idea/kotlinc.xml
generated
@@ -1,8 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinCommonCompilerArguments">
|
||||
<option name="languageVersion" value="1.1" />
|
||||
<option name="apiVersion" value="1.1" />
|
||||
<component name="Kotlin2JsCompilerArguments">
|
||||
<option name="sourceMapPrefix" value="" />
|
||||
<option name="sourceMapEmbedSources" value="inlining" />
|
||||
</component>
|
||||
<component name="Kotlin2JvmCompilerArguments">
|
||||
<option name="jvmTarget" value="1.8" />
|
||||
</component>
|
||||
<component name="KotlinCompilerSettings">
|
||||
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check" />
|
||||
|
||||
4
.idea/libraries/intellij_core.xml
generated
4
.idea/libraries/intellij_core.xml
generated
@@ -7,7 +7,7 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/annotations.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/asm-all.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/guava-19.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/guava-21.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/intellij-core.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/jdom.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core/jna.jar!/" />
|
||||
@@ -22,7 +22,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-21.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/jsr305.jar!/" />
|
||||
|
||||
4
.idea/libraries/jline.xml
generated
4
.idea/libraries/jline.xml
generated
@@ -4,11 +4,11 @@
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/jline.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/jline3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/jline-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/jline3-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
59
.idea/libraries/robolectric.xml
generated
Normal file
59
.idea/libraries/robolectric.xml
generated
Normal file
@@ -0,0 +1,59 @@
|
||||
<component name="libraryTable">
|
||||
<library name="robolectric">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/accessibility-test-framework-2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/ant-1.8.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/ant-launcher-1.8.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-commons-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-tree-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/assertj-core-2.6.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/backport-util-concurrent-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/bcprov-jdk16-1.46.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/classworlds-1.1-alpha-2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/guava-20.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/hamcrest-core-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/hamcrest-library-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/icu4j-53.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-ant-tasks-2.1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-artifact-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-artifact-manager-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-error-diagnostics-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-model-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-plugin-registry-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-profile-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-project-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-repository-metadata-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-settings-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/nekohtml-1.9.6.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-container-default-1.0-alpha-9-stable-1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-interpolation-1.11.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-utils-1.5.15.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/protobuf-java-2.6.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-annotations-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-junit-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-resources-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-sandbox-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-utils-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadow-api-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadows-core-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/sqlite4java-0.282.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-file-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-http-lightweight-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-http-shared-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-provider-api-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xercesMinimal-1.9.6.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xmlpull-1.1.3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xpp3_min-1.1.4c.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xstream-1.4.8.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-sources-source.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
8
.idea/libraries/uast_java.xml
generated
8
.idea/libraries/uast_java.xml
generated
@@ -1,15 +1,15 @@
|
||||
<component name="libraryTable">
|
||||
<library name="uast-java">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/uast-common.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/uast-java.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/uast-tests.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/idea.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/openapi.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/uast-common-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/uast-java-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/uast-tests-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@@ -51,6 +51,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" filepath="$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-gradle/idea-gradle.iml" filepath="$PROJECT_DIR$/idea/idea-gradle/idea-gradle.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" filepath="$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" group="ide" />
|
||||
|
||||
2
.idea/runConfigurations/IDEA.xml
generated
2
.idea/runConfigurations/IDEA.xml
generated
@@ -3,7 +3,7 @@
|
||||
<log_file path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" checked="true" skipped="true" show_all="false" alias="idea.log" />
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=128m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<log_file path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" checked="true" skipped="true" show_all="false" alias="idea.log" />
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=128m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
2
.idea/runConfigurations/Update_Dist_Run.xml
generated
2
.idea/runConfigurations/Update_Dist_Run.xml
generated
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="Update-Dist-Run" type="Application" factoryName="Application" singleton="true">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=64m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
136
ChangeLog.md
136
ChangeLog.md
@@ -3,6 +3,142 @@
|
||||
<!-- Find: ([^\`/\[])(KT-\d+) -->
|
||||
<!-- Replace: $1[`$2`](https://youtrack.jetbrains.com/issue/$2) -->
|
||||
|
||||
## 1.1.4-EAP-54
|
||||
|
||||
### Android
|
||||
|
||||
- [`KT-10542`](https://youtrack.jetbrains.com/issue/KT-10542) Android Extensions: No cache for Views
|
||||
- [`KT-18250`](https://youtrack.jetbrains.com/issue/KT-18250) Android Extensions: Allow to use SparseArray as a View cache
|
||||
- [`KT-14086`](https://youtrack.jetbrains.com/issue/KT-14086) Android-extensions not generated using flavors dimension
|
||||
- [`KT-17641`](https://youtrack.jetbrains.com/issue/KT-17641) Problem with Kotlin Android Extensions and Gradle syntax
|
||||
- [`KT-18012`](https://youtrack.jetbrains.com/issue/KT-18012) Kotlin Android Extensions generates `@NotNull` properties for views present in a configuration and potentially missing in another
|
||||
|
||||
### Compiler
|
||||
|
||||
- [`KT-14323`](https://youtrack.jetbrains.com/issue/KT-14323) IntelliJ lockup when using Apache Spark UDF
|
||||
- [`KT-14375`](https://youtrack.jetbrains.com/issue/KT-14375) Kotlin compiler failure with spark when creating a flexible type for scala.Function22
|
||||
- [`KT-18983`](https://youtrack.jetbrains.com/issue/KT-18983) Coroutines: miscompiled suspend for loop (local variables are not spilled around suspension points)
|
||||
- [`KT-19175`](https://youtrack.jetbrains.com/issue/KT-19175) Compiler generates different bytecode when classes are compiled separately or together
|
||||
- [`KT-19246`](https://youtrack.jetbrains.com/issue/KT-19246) Using generic inline function inside inline extension function throws java.lang.VerifyError: Bad return type
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-14929`](https://youtrack.jetbrains.com/issue/KT-14929) Deprecated ReplaceWith for type aliases
|
||||
- [`KT-14606`](https://youtrack.jetbrains.com/issue/KT-14606) Code completion calculates decompiled text when building lookup elements for PSI from compiled classes
|
||||
- [`KT-17835`](https://youtrack.jetbrains.com/issue/KT-17835) 10s hang on IDEA project open
|
||||
- [`KT-14561`](https://youtrack.jetbrains.com/issue/KT-14561) Use regular indent for the primary constructor parameters
|
||||
- [`KT-17956`](https://youtrack.jetbrains.com/issue/KT-17956) Type hints for properties that only consist of constructor calls don't add much value
|
||||
- [`KT-18444`](https://youtrack.jetbrains.com/issue/KT-18444) Type hints don't work for destructuring declarations
|
||||
- [`KT-18974`](https://youtrack.jetbrains.com/issue/KT-18974) Type hints shouldn't appear for negative literals
|
||||
- [`KT-19210`](https://youtrack.jetbrains.com/issue/KT-19210) Command line flags like -Xload-jsr305-annotations have no effect in IDE
|
||||
|
||||
### IDE. Completion
|
||||
|
||||
- [`KT-19191`](https://youtrack.jetbrains.com/issue/KT-19191) Disable completion binding context caching by default
|
||||
|
||||
### IDE. Inspections and Intentions
|
||||
|
||||
- [`KT-13886`](https://youtrack.jetbrains.com/issue/KT-13886) Unused variable intention should remove constant initializer
|
||||
- [`KT-16046`](https://youtrack.jetbrains.com/issue/KT-16046) Globally unused typealias is not marked as such
|
||||
- [`KT-18368`](https://youtrack.jetbrains.com/issue/KT-18368) "Cast expression x to Type" fails for expression inside argument list
|
||||
- [`KT-18852`](https://youtrack.jetbrains.com/issue/KT-18852) "Lift return out of when" does not work for exhaustive when without else
|
||||
- [`KT-18928`](https://youtrack.jetbrains.com/issue/KT-18928) In IDE, "Replace 'if' expression with safe access expression incorrectly replace expression when using property
|
||||
- [`KT-19232`](https://youtrack.jetbrains.com/issue/KT-19232) Replace Math.min with coerceAtMost intention is broken
|
||||
|
||||
### IDE. Refactorings
|
||||
|
||||
- [`KT-19130`](https://youtrack.jetbrains.com/issue/KT-19130) Refactor / Inline val: "Show inline dialog for local variables" setting is ignored
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-18671`](https://youtrack.jetbrains.com/issue/KT-18671) Provide implementation for CoroutineContext.Element functions.
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-17197`](https://youtrack.jetbrains.com/issue/KT-17197) Gradle Kotlin plugin does not wire task dependencies correctly, causing compilation failures
|
||||
|
||||
### Tools. JPS
|
||||
|
||||
- [`KT-19155`](https://youtrack.jetbrains.com/issue/KT-19155) IllegalArgumentException: Unsupported kind: PACKAGE_LOCAL_VARIABLE_LIST in incremental compilation
|
||||
|
||||
### Tools. kapt
|
||||
|
||||
- [`KT-19178`](https://youtrack.jetbrains.com/issue/KT-19178) Kapt: Build dependencies from 'kapt' configuration should go into the 'kaptCompile' task dependencies
|
||||
- [`KT-19179`](https://youtrack.jetbrains.com/issue/KT-19179) Kapt: Gradle silently skips 'kotlinKapt' task sometimes
|
||||
- [`KT-19211`](https://youtrack.jetbrains.com/issue/KT-19211) Kapt3: Generated classes output is not synchronized with Java classes output in pure Java projects (Gradle 4+)
|
||||
|
||||
## 1.1.4-EAP-33
|
||||
|
||||
### Compiler
|
||||
|
||||
- [`KT-12551`](https://youtrack.jetbrains.com/issue/KT-12551) Report "unused expression" on unused bound double colon expressions
|
||||
- [`KT-18698`](https://youtrack.jetbrains.com/issue/KT-18698) java.lang.IllegalStateException: resolveToInstruction: incorrect index -1 for label L12 in subroutine
|
||||
- [`KT-18916`](https://youtrack.jetbrains.com/issue/KT-18916) Strange bytecode generated for 'null' passed as SAM adapter for Java interface
|
||||
|
||||
### IDE
|
||||
|
||||
#### New Features
|
||||
|
||||
- [`KT-11994`](https://youtrack.jetbrains.com/issue/KT-11994) Data flow analysis support for Kotlin in IntelliJ
|
||||
- [`KT-14126`](https://youtrack.jetbrains.com/issue/KT-14126) Code style wrapping options for enum constants
|
||||
- [`KT-14950`](https://youtrack.jetbrains.com/issue/KT-14950) Code Style: Wrapping and Braces / "Local variable annotations" setting could be supported
|
||||
#### Performance Improvements
|
||||
|
||||
- [`KT-18921`](https://youtrack.jetbrains.com/issue/KT-18921) Configure library kind explicitly
|
||||
#### Fixes
|
||||
|
||||
- [`KT-14083`](https://youtrack.jetbrains.com/issue/KT-14083) Formatting of where clasuses
|
||||
- [`KT-16352`](https://youtrack.jetbrains.com/issue/KT-16352) Create from usage inserts extra space in first step
|
||||
- [`KT-17394`](https://youtrack.jetbrains.com/issue/KT-17394) Core formatting is wrong for expression body properties
|
||||
- [`KT-17771`](https://youtrack.jetbrains.com/issue/KT-17771) Kotlin IntelliJ plugin should resolve Gradle script classpath asynchronously
|
||||
- [`KT-17818`](https://youtrack.jetbrains.com/issue/KT-17818) Formatting of long constructors is inconsistent with Kotlin code conventions
|
||||
- [`KT-18186`](https://youtrack.jetbrains.com/issue/KT-18186) Create function from usage should infer expected return type
|
||||
- [`KT-19054`](https://youtrack.jetbrains.com/issue/KT-19054) Lags in typing in string literal
|
||||
- [`KT-19062`](https://youtrack.jetbrains.com/issue/KT-19062) Member navigation doesn't work in expression bodies of getters with inferred property type
|
||||
|
||||
### IDE. Completion
|
||||
|
||||
- [`KT-17074`](https://youtrack.jetbrains.com/issue/KT-17074) Incorrect autocomplete suggestions for contexts affected by @DslMarker
|
||||
|
||||
### IDE. Debugger
|
||||
|
||||
- [`KT-17120`](https://youtrack.jetbrains.com/issue/KT-17120) Evaluate expression: cannot find local variable
|
||||
- [`KT-18949`](https://youtrack.jetbrains.com/issue/KT-18949) Can't stop on breakpoint after call to inline in Android Studio
|
||||
|
||||
### IDE. Inspections and Intentions
|
||||
|
||||
#### New Features
|
||||
|
||||
- [`KT-14799`](https://youtrack.jetbrains.com/issue/KT-14799) Add inspection to simplify successive null checks into safe-call and null check
|
||||
- [`KT-15958`](https://youtrack.jetbrains.com/issue/KT-15958) Inspection to inline "unnecessary" variables
|
||||
- [`KT-17919`](https://youtrack.jetbrains.com/issue/KT-17919) Add "Simplify if" intention/inspection
|
||||
- [`KT-18540`](https://youtrack.jetbrains.com/issue/KT-18540) Add quickfix to create data class property from usage in destructuring declaration
|
||||
- [`KT-18830`](https://youtrack.jetbrains.com/issue/KT-18830) "Lift return out of try"
|
||||
#### Fixes
|
||||
|
||||
- [`KT-13870`](https://youtrack.jetbrains.com/issue/KT-13870) Wrong caption "Change to property access" for Quick Fix to convert class instantiation to object reference
|
||||
- [`KT-15242`](https://youtrack.jetbrains.com/issue/KT-15242) Create type from usage should include constraints into base types
|
||||
- [`KT-17092`](https://youtrack.jetbrains.com/issue/KT-17092) Create function from usage works incorrectly with ::class expression
|
||||
- [`KT-17353`](https://youtrack.jetbrains.com/issue/KT-17353) "Create type parameter from usage" should not be offered for unresolved annotations
|
||||
- [`KT-17651`](https://youtrack.jetbrains.com/issue/KT-17651) Create property from usage should make lateinit var
|
||||
- [`KT-18074`](https://youtrack.jetbrains.com/issue/KT-18074) Suggestion in Intention 'Specify return type explicitly' doesn't support generic type parameter
|
||||
- [`KT-18722`](https://youtrack.jetbrains.com/issue/KT-18722) Correct "before" sample in description for intention Convert to enum class
|
||||
- [`KT-18723`](https://youtrack.jetbrains.com/issue/KT-18723) Correct "after" sample for intention Convert to apply
|
||||
- [`KT-18954`](https://youtrack.jetbrains.com/issue/KT-18954) Kotlin plugin updater activates in headless mode
|
||||
- [`KT-18970`](https://youtrack.jetbrains.com/issue/KT-18970) Do not report "property can be private" on JvmField properties
|
||||
|
||||
### IDE. Refactorings
|
||||
|
||||
- [`KT-18738`](https://youtrack.jetbrains.com/issue/KT-18738) Misleading quick fix message for an 'open' modifier on an interface member
|
||||
|
||||
### Reflection
|
||||
|
||||
- [`KT-15222`](https://youtrack.jetbrains.com/issue/KT-15222) Support reflection for local delegated properties
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-18647`](https://youtrack.jetbrains.com/issue/KT-18647) Kotlin incremental compile cannot be disabled.
|
||||
|
||||
## 1.1.4-EAP-11
|
||||
|
||||
### Android
|
||||
|
||||
@@ -37,6 +37,8 @@ In order to build Kotlin distribution you need to have:
|
||||
JDK_17="path to JDK 1.7"
|
||||
JDK_18="path to JDK 1.8"
|
||||
|
||||
> Note: The JDK 6 for MacOS is not available on Oracle's site. You can [download it here](https://support.apple.com/kb/DL1572).
|
||||
|
||||
## Building
|
||||
|
||||
To build this project, first time you try to build you need to run this:
|
||||
@@ -113,7 +115,7 @@ From this root project there are Run/Debug Configurations for running IDEA or th
|
||||
|
||||
We love contributions! There's [lots to do on Kotlin](https://youtrack.jetbrains.com/issues/KT) and on the
|
||||
[standard library](https://youtrack.jetbrains.com/issues/KT?q=%23Kotlin%20%23Unresolved%20and%20(links:%20KT-2554,%20KT-4089%20or%20%23Libraries)) so why not chat with us
|
||||
about what you're interested in doing? Please join the #kontributors channel in [our Slack chat](http://kotlinslackin.herokuapp.com/)
|
||||
about what you're interested in doing? Please join the #kontributors channel in [our Slack chat](http://slack.kotlinlang.org/)
|
||||
and let us know about your plans.
|
||||
|
||||
If you want to find some issues to start off with, try [this query](https://youtrack.jetbrains.com/issues/KT?q=tag:%20%7BUp%20For%20Grabs%7D%20%23Unresolved) which should find all Kotlin issues that marked as "up-for-grabs".
|
||||
|
||||
@@ -39,9 +39,7 @@ class KotlinCompilerAdapter : Javac13() {
|
||||
return argument
|
||||
}
|
||||
|
||||
override fun getSupportedFileExtensions(): Array<String> {
|
||||
return super.getSupportedFileExtensions() + KOTLIN_EXTENSIONS
|
||||
}
|
||||
override fun getSupportedFileExtensions(): Array<String> = super.getSupportedFileExtensions() + KOTLIN_EXTENSIONS
|
||||
|
||||
@Throws(BuildException::class)
|
||||
override fun execute(): Boolean {
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
<orderEntry type="module" module-name="tests-common" scope="TEST" />
|
||||
<orderEntry type="library" scope="TEST" name="idea-full" level="project" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
<orderEntry type="module" module-name="js.serializer" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -16,13 +16,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.jvm.JvmClassMappingKt;
|
||||
import kotlin.reflect.KClass;
|
||||
import kotlin.reflect.KProperty1;
|
||||
import kotlin.reflect.KVisibility;
|
||||
import kotlin.reflect.full.KClasses;
|
||||
import kotlin.reflect.jvm.ReflectJvmMapping;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.Argument;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt;
|
||||
import org.jetbrains.kotlin.utils.StringsKt;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -33,39 +41,35 @@ public class ArgumentUtils {
|
||||
|
||||
@NotNull
|
||||
public static List<String> convertArgumentsToStringList(@NotNull CommonToolArguments arguments)
|
||||
throws InstantiationException, IllegalAccessException {
|
||||
throws InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
List<String> result = new ArrayList<>();
|
||||
convertArgumentsToStringList(arguments, arguments.getClass().newInstance(), arguments.getClass(), result);
|
||||
result.addAll(arguments.freeArgs);
|
||||
Class<? extends CommonToolArguments> argumentsClass = arguments.getClass();
|
||||
convertArgumentsToStringList(arguments, argumentsClass.newInstance(), JvmClassMappingKt.getKotlinClass(argumentsClass), result);
|
||||
result.addAll(arguments.getFreeArgs());
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void convertArgumentsToStringList(
|
||||
@NotNull CommonToolArguments arguments,
|
||||
@NotNull CommonToolArguments defaultArguments,
|
||||
@NotNull Class<?> clazz,
|
||||
@NotNull KClass<?> clazz,
|
||||
@NotNull List<String> result
|
||||
) throws IllegalAccessException, InstantiationException {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
Argument argument = field.getAnnotation(Argument.class);
|
||||
) throws IllegalAccessException, InstantiationException, InvocationTargetException {
|
||||
for (KProperty1 property : KClasses.getMemberProperties(clazz)) {
|
||||
Argument argument = ContainerUtil.findInstance(property.getAnnotations(), Argument.class);
|
||||
if (argument == null) continue;
|
||||
|
||||
Object value;
|
||||
Object defaultValue;
|
||||
try {
|
||||
value = field.get(arguments);
|
||||
defaultValue = field.get(defaultArguments);
|
||||
}
|
||||
catch (IllegalAccessException ignored) {
|
||||
// skip this field
|
||||
continue;
|
||||
}
|
||||
if (property.getVisibility() != KVisibility.PUBLIC) continue;
|
||||
|
||||
Object value = property.get(arguments);
|
||||
Object defaultValue = property.get(defaultArguments);
|
||||
|
||||
if (value == null || Objects.equals(value, defaultValue)) continue;
|
||||
|
||||
Class<?> fieldType = field.getType();
|
||||
Type propertyJavaType = ReflectJvmMapping.getJavaType(property.getReturnType());
|
||||
|
||||
if (fieldType.isArray()) {
|
||||
if (propertyJavaType instanceof Class && ((Class) propertyJavaType).isArray()) {
|
||||
Object[] values = (Object[]) value;
|
||||
if (values.length == 0) continue;
|
||||
value = StringsKt.join(Arrays.asList(values), ",");
|
||||
@@ -73,7 +77,7 @@ public class ArgumentUtils {
|
||||
|
||||
result.add(argument.value());
|
||||
|
||||
if (fieldType == boolean.class || fieldType == Boolean.class) continue;
|
||||
if (propertyJavaType == boolean.class || propertyJavaType == Boolean.class) continue;
|
||||
|
||||
if (ParseCommandLineArgumentsKt.isAdvanced(argument)) {
|
||||
result.set(result.size() - 1, argument.value() + "=" + value.toString());
|
||||
@@ -82,10 +86,5 @@ public class ArgumentUtils {
|
||||
result.add(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> superClazz = clazz.getSuperclass();
|
||||
if (superClazz != null) {
|
||||
convertArgumentsToStringList(arguments, defaultArguments, superClazz, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
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.cli.common.messages.OutputMessageUtil
|
||||
|
||||
class MessageCollectorToOutputItemsCollectorAdapter(
|
||||
private val delegate: MessageCollector,
|
||||
private val outputCollector: OutputItemsCollector
|
||||
) : MessageCollector by delegate {
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
|
||||
// TODO: consider adding some other way of passing input -> output mapping from compiler, e.g. dedicated service
|
||||
OutputMessageUtil.parseOutputMessage(message)?.let {
|
||||
outputCollector.add(it.sourceFiles, it.outputFile)
|
||||
}
|
||||
delegate.report(severity, message, location)
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
public class SimpleOutputItem {
|
||||
private final Collection<File> sourceFiles;
|
||||
private final File outputFile;
|
||||
|
||||
public SimpleOutputItem(@NotNull Collection<File> sourceFiles, @NotNull File outputFile) {
|
||||
this.sourceFiles = sourceFiles;
|
||||
this.outputFile = outputFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<File> getSourceFiles() {
|
||||
return sourceFiles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public File getOutputFile() {
|
||||
return outputFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return sourceFiles + " -> " + outputFile;
|
||||
}
|
||||
}
|
||||
@@ -14,22 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.checkers;
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.TestJdkKind;
|
||||
import java.io.File
|
||||
|
||||
public abstract class AbstractDiagnosticsWithFullJdkTest extends AbstractDiagnosticsTest {
|
||||
@NotNull
|
||||
@Override
|
||||
protected ConfigurationKind getConfigurationKind() {
|
||||
return ConfigurationKind.ALL;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected TestJdkKind getTestJdkKind() {
|
||||
return TestJdkKind.FULL_JDK;
|
||||
}
|
||||
data class SimpleOutputItem(val sourceFiles: Collection<File>, val outputFile: File) {
|
||||
override fun toString(): String =
|
||||
"$sourceFiles->$outputFile"
|
||||
}
|
||||
@@ -24,11 +24,9 @@ import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
private val NORMAL_VERSION = 8
|
||||
private val EXPERIMENTAL_VERSION = 4
|
||||
private val DATA_CONTAINER_VERSION = 2
|
||||
|
||||
private val NORMAL_VERSION_FILE_NAME = "format-version.txt"
|
||||
private val EXPERIMENTAL_VERSION_FILE_NAME = "experimental-format-version.txt"
|
||||
private val DATA_CONTAINER_VERSION_FILE_NAME = "data-container-format-version.txt"
|
||||
|
||||
class CacheVersion(
|
||||
@@ -92,7 +90,6 @@ class CacheVersion(
|
||||
REBUILD_ALL_KOTLIN,
|
||||
REBUILD_CHUNK,
|
||||
CLEAN_NORMAL_CACHES,
|
||||
CLEAN_EXPERIMENTAL_CACHES,
|
||||
CLEAN_DATA_CONTAINER,
|
||||
DO_NOTHING
|
||||
}
|
||||
@@ -106,18 +103,10 @@ fun normalCacheVersion(dataRoot: File): CacheVersion =
|
||||
whenTurnedOff = CacheVersion.Action.CLEAN_NORMAL_CACHES,
|
||||
isEnabled = { IncrementalCompilation.isEnabled() })
|
||||
|
||||
fun experimentalCacheVersion(dataRoot: File): CacheVersion =
|
||||
CacheVersion(ownVersion = EXPERIMENTAL_VERSION,
|
||||
versionFile = File(dataRoot, EXPERIMENTAL_VERSION_FILE_NAME),
|
||||
whenVersionChanged = CacheVersion.Action.REBUILD_CHUNK,
|
||||
whenTurnedOn = CacheVersion.Action.REBUILD_CHUNK,
|
||||
whenTurnedOff = CacheVersion.Action.CLEAN_EXPERIMENTAL_CACHES,
|
||||
isEnabled = { IncrementalCompilation.isExperimental() })
|
||||
|
||||
fun dataContainerCacheVersion(dataRoot: File): CacheVersion =
|
||||
CacheVersion(ownVersion = DATA_CONTAINER_VERSION,
|
||||
versionFile = File(dataRoot, DATA_CONTAINER_VERSION_FILE_NAME),
|
||||
whenVersionChanged = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
whenTurnedOn = CacheVersion.Action.REBUILD_ALL_KOTLIN,
|
||||
whenTurnedOff = CacheVersion.Action.CLEAN_DATA_CONTAINER,
|
||||
isEnabled = { IncrementalCompilation.isExperimental() })
|
||||
isEnabled = { IncrementalCompilation.isEnabled() })
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import gnu.trove.THashSet
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.incremental.ChangeInfo.MembersChanged
|
||||
import org.jetbrains.kotlin.incremental.ChangeInfo.Removed
|
||||
import org.jetbrains.kotlin.incremental.storage.*
|
||||
@@ -73,12 +72,6 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
|
||||
private val baseDir = File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)
|
||||
private val experimentalMaps = arrayListOf<BasicMap<*, *>>()
|
||||
|
||||
private fun <K, V, M : BasicMap<K, V>> registerExperimentalMap(map: M): M {
|
||||
experimentalMaps.add(map)
|
||||
return registerMap(map)
|
||||
}
|
||||
|
||||
protected val String.storageFile: File
|
||||
get() = File(baseDir, this + "." + CACHE_EXTENSION)
|
||||
@@ -91,11 +84,11 @@ open class IncrementalCacheImpl<Target>(
|
||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||
private val subtypesMap = registerExperimentalMap(SubtypesMap(SUBTYPES.storageFile))
|
||||
private val supertypesMap = registerExperimentalMap(SupertypesMap(SUPERTYPES.storageFile))
|
||||
private val classFqNameToSourceMap = registerExperimentalMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
|
||||
private val subtypesMap = registerMap(SubtypesMap(SUBTYPES.storageFile))
|
||||
private val supertypesMap = registerMap(SupertypesMap(SUPERTYPES.storageFile))
|
||||
private val classFqNameToSourceMap = registerMap(ClassFqNameToSourceMap(CLASS_FQ_NAME_TO_SOURCE.storageFile))
|
||||
// todo: try to use internal names only?
|
||||
private val internalNameToSource = registerExperimentalMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
|
||||
private val internalNameToSource = registerMap(InternalNameToSourcesMap(INTERNAL_NAME_TO_SOURCE.storageFile))
|
||||
|
||||
private val dependents = arrayListOf<IncrementalCacheImpl<Target>>()
|
||||
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory: $target" } }
|
||||
@@ -106,9 +99,6 @@ open class IncrementalCacheImpl<Target>(
|
||||
result
|
||||
}
|
||||
|
||||
override fun registerInline(fromPath: String, jvmSignature: String, toPath: String) {
|
||||
}
|
||||
|
||||
protected open fun debugLog(message: String) {}
|
||||
|
||||
fun addDependentCache(cache: IncrementalCacheImpl<Target>) {
|
||||
@@ -149,7 +139,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
|
||||
fun saveModuleMappingToCache(sourceFiles: Collection<File>, file: File): CompilationResult {
|
||||
val jvmClassName = JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)
|
||||
protoMap.process(jvmClassName, file.readBytes(), emptyArray<String>(), isPackage = false, checkChangesIsOpenPart = false)
|
||||
protoMap.storeModuleMapping(jvmClassName, file.readBytes())
|
||||
dirtyOutputClassesMap.notDirty(MODULE_MAPPING_FILE_NAME)
|
||||
sourceFiles.forEach { sourceToClassesMap.add(it, jvmClassName) }
|
||||
return CompilationResult.NO_CHANGES
|
||||
@@ -165,9 +155,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
sourceToClassesMap.add(it, className)
|
||||
}
|
||||
|
||||
if (IncrementalCompilation.isExperimental()) {
|
||||
internalNameToSource[className.internalName] = sourceFiles
|
||||
}
|
||||
internalNameToSource[className.internalName] = sourceFiles
|
||||
|
||||
if (kotlinClass.classId.isLocal) {
|
||||
return CompilationResult.NO_CHANGES
|
||||
@@ -193,7 +181,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
// As a workaround we can remove proto values for multifile facades.
|
||||
val additionalChangeInfo = if (className in protoMap) {
|
||||
val info = ChangeInfo.SignatureChanged(className.fqNameForClassNameWithoutDollars, areSubclassesAffected = true)
|
||||
CompilationResult(protoChanged = true, changes = sequenceOf(info))
|
||||
CompilationResult(changes = sequenceOf(info))
|
||||
}
|
||||
else CompilationResult.NO_CHANGES
|
||||
protoMap.remove(className)
|
||||
@@ -289,18 +277,8 @@ open class IncrementalCacheImpl<Target>(
|
||||
.map(JvmClassName::byInternalName)
|
||||
.toList()
|
||||
|
||||
val changes =
|
||||
if (IncrementalCompilation.isExperimental())
|
||||
dirtyClasses.flatMap { computeChanges(it, ::Removed) }.asSequence()
|
||||
else
|
||||
emptySequence<ChangeInfo>()
|
||||
|
||||
val changesInfo = dirtyClasses.fold(CompilationResult(changes = changes)) { info, className ->
|
||||
val newInfo = CompilationResult(protoChanged = className in protoMap,
|
||||
constantsChanged = className in constantsMap)
|
||||
newInfo.logIfSomethingChanged(className)
|
||||
info + newInfo
|
||||
}
|
||||
val changes = dirtyClasses.flatMap { computeChanges(it, ::Removed) }.asSequence()
|
||||
val changesInfo = CompilationResult(changes = changes)
|
||||
|
||||
val facadesWithRemovedParts = hashMapOf<JvmClassName, MutableSet<String>>()
|
||||
for (dirtyClass in dirtyClasses) {
|
||||
@@ -373,12 +351,6 @@ open class IncrementalCacheImpl<Target>(
|
||||
override fun clean() {
|
||||
super.clean()
|
||||
normalCacheVersion(targetDataRoot).clean()
|
||||
experimentalCacheVersion(targetDataRoot).clean()
|
||||
}
|
||||
|
||||
fun cleanExperimental() {
|
||||
experimentalCacheVersion(targetDataRoot).clean()
|
||||
experimentalMaps.forEach { it.clean() }
|
||||
}
|
||||
|
||||
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
|
||||
@@ -386,15 +358,26 @@ open class IncrementalCacheImpl<Target>(
|
||||
fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean): CompilationResult {
|
||||
val header = kotlinClass.classHeader
|
||||
val bytes = BitEncoding.decodeBytes(header.data!!)
|
||||
return put(kotlinClass.className, bytes, header.strings!!, isPackage, checkChangesIsOpenPart = true)
|
||||
return put(kotlinClass.className, bytes, header.strings!!, isPackage)
|
||||
}
|
||||
|
||||
fun process(className: JvmClassName, data: ByteArray, strings: Array<String>, isPackage: Boolean, checkChangesIsOpenPart: Boolean): CompilationResult {
|
||||
return put(className, data, strings, isPackage, checkChangesIsOpenPart)
|
||||
// A module mapping (.kotlin_module file) is stored in a cache,
|
||||
// because a corresponding file will be deleted on each round
|
||||
// (it is reported as output for each [package part?] source file).
|
||||
// If a mapping is not preserved, a resulting file will only contain data
|
||||
// from files compiled during last round.
|
||||
// However there is no need to compare old and new data in this case
|
||||
// (also that would fail with exception).
|
||||
fun storeModuleMapping(className: JvmClassName, bytes: ByteArray): CompilationResult {
|
||||
storage[className.internalName] = ProtoMapValue(isPackageFacade = false, bytes = bytes, strings = emptyArray())
|
||||
return CompilationResult()
|
||||
}
|
||||
|
||||
private fun put(
|
||||
className: JvmClassName, bytes: ByteArray, strings: Array<String>, isPackage: Boolean, checkChangesIsOpenPart: Boolean
|
||||
className: JvmClassName,
|
||||
bytes: ByteArray,
|
||||
strings: Array<String>,
|
||||
isPackage: Boolean
|
||||
): CompilationResult {
|
||||
val key = className.internalName
|
||||
val oldData = storage[key]
|
||||
@@ -408,16 +391,9 @@ open class IncrementalCacheImpl<Target>(
|
||||
storage[key] = data
|
||||
}
|
||||
|
||||
if (!checkChangesIsOpenPart) return CompilationResult(protoChanged = true)
|
||||
|
||||
if (oldData == null) {
|
||||
val changes =
|
||||
if (IncrementalCompilation.isExperimental())
|
||||
computeChanges(className, ::MembersChanged).asSequence()
|
||||
else
|
||||
emptySequence<ChangeInfo>()
|
||||
|
||||
return CompilationResult(protoChanged = true, changes = changes)
|
||||
val changes = computeChanges(className, ::MembersChanged).asSequence()
|
||||
return CompilationResult(changes = changes)
|
||||
}
|
||||
|
||||
val difference = difference(oldData, data)
|
||||
@@ -432,7 +408,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
changeList.add(ChangeInfo.MembersChanged(fqName, difference.changedMembersNames))
|
||||
}
|
||||
|
||||
return CompilationResult(protoChanged = changeList.isNotEmpty(), changes = changeList.asSequence())
|
||||
return CompilationResult(changes = changeList.asSequence())
|
||||
}
|
||||
|
||||
operator fun contains(className: JvmClassName): Boolean =
|
||||
@@ -488,8 +464,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
|
||||
val changes =
|
||||
if (!IncrementalCompilation.isExperimental() ||
|
||||
constantsMap == null || constantsMap.isEmpty() ||
|
||||
if (constantsMap == null || constantsMap.isEmpty() ||
|
||||
oldMap == null || oldMap.isEmpty()
|
||||
) {
|
||||
emptySequence<ChangeInfo>()
|
||||
@@ -503,7 +478,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
sequenceOf(ChangeInfo.MembersChanged(fqName, changedNames))
|
||||
}
|
||||
|
||||
return CompilationResult(constantsChanged = true, changes = changes)
|
||||
return CompilationResult(changes = changes)
|
||||
}
|
||||
|
||||
fun remove(className: JvmClassName) {
|
||||
@@ -613,8 +588,6 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
|
||||
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) {
|
||||
if (!IncrementalCompilation.isExperimental()) return
|
||||
|
||||
val classData = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!)
|
||||
val supertypes = classData.classProto.supertypes(TypeTable(classData.classProto.typeTable))
|
||||
val parents = supertypes.map { classData.nameResolver.getClassId(it.className).asSingleFqName() }
|
||||
@@ -632,7 +605,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
|
||||
private fun removeAllFromClassStorage(removedClasses: Collection<JvmClassName>) {
|
||||
if (!IncrementalCompilation.isExperimental() || removedClasses.isEmpty()) return
|
||||
if (removedClasses.isEmpty()) return
|
||||
|
||||
val removedFqNames = removedClasses.map { it.fqNameForClassNameWithoutDollars }.toSet()
|
||||
|
||||
@@ -733,20 +706,10 @@ open class IncrementalCacheImpl<Target>(
|
||||
else -> storage.remove(internalName)
|
||||
}
|
||||
|
||||
val changes =
|
||||
if (IncrementalCompilation.isExperimental()) {
|
||||
val fqName = if (isPackage) className.packageFqName else className.fqNameForClassNameWithoutDollars
|
||||
// TODO get name in better way instead of using substringBefore
|
||||
(added.asSequence() + changed.asSequence()).map { ChangeInfo.MembersChanged(fqName, listOf(it.substringBefore("("))) }
|
||||
}
|
||||
else {
|
||||
emptySequence<ChangeInfo>()
|
||||
}
|
||||
|
||||
processChangedInlineFunctions(className, changed)
|
||||
return CompilationResult(inlineChanged = changed.isNotEmpty(),
|
||||
inlineAdded = added.isNotEmpty(),
|
||||
changes = changes)
|
||||
val fqName = if (isPackage) className.packageFqName else className.fqNameForClassNameWithoutDollars
|
||||
// TODO get name in better way instead of using substringBefore
|
||||
val changes = (added.asSequence() + changed.asSequence()).map { ChangeInfo.MembersChanged(fqName, listOf(it.substringBefore("("))) }
|
||||
return CompilationResult(changes = changes)
|
||||
}
|
||||
|
||||
fun remove(className: JvmClassName) {
|
||||
@@ -756,12 +719,6 @@ open class IncrementalCacheImpl<Target>(
|
||||
override fun dumpValue(value: Map<String, Long>): String =
|
||||
value.dumpMap { java.lang.Long.toHexString(it) }
|
||||
}
|
||||
|
||||
protected open fun processChangedInlineFunctions(
|
||||
className: JvmClassName,
|
||||
changedFunctions: Collection<String>
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
private object PathCollectionExternalizer : CollectionExternalizer<String>(PathStringDescriptor, { THashSet(FileUtil.PATH_HASHING_STRATEGY) })
|
||||
@@ -784,10 +741,6 @@ sealed class ChangeInfo(val fqName: FqName) {
|
||||
}
|
||||
|
||||
data class CompilationResult(
|
||||
val protoChanged: Boolean = false,
|
||||
val constantsChanged: Boolean = false,
|
||||
val inlineChanged: Boolean = false,
|
||||
val inlineAdded: Boolean = false,
|
||||
val changes: Sequence<ChangeInfo> = emptySequence()
|
||||
) {
|
||||
companion object {
|
||||
@@ -795,11 +748,7 @@ data class CompilationResult(
|
||||
}
|
||||
|
||||
operator fun plus(other: CompilationResult): CompilationResult =
|
||||
CompilationResult(protoChanged || other.protoChanged,
|
||||
constantsChanged || other.constantsChanged,
|
||||
inlineChanged || other.inlineChanged,
|
||||
inlineAdded || other.inlineAdded,
|
||||
changes + other.changes)
|
||||
CompilationResult(changes + other.changes)
|
||||
}
|
||||
|
||||
fun ByteArray.md5(): Long {
|
||||
|
||||
@@ -16,17 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
|
||||
class IncrementalCompilationComponentsImpl(
|
||||
private val caches: Map<TargetId, IncrementalCache>,
|
||||
private val lookupTracker: LookupTracker
|
||||
private val caches: Map<TargetId, IncrementalCache>
|
||||
): IncrementalCompilationComponents {
|
||||
override fun getIncrementalCache(target: TargetId): IncrementalCache =
|
||||
caches[target] ?: throw Exception("Incremental cache for target ${target.name} not found")
|
||||
|
||||
override fun getLookupTracker(): LookupTracker = lookupTracker
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.js.JsProtoBuf
|
||||
import org.jetbrains.kotlin.utils.Interner
|
||||
import java.util.*
|
||||
|
||||
@@ -56,10 +57,18 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) return false
|
||||
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) return false
|
||||
if (old.hasExtension(JsProtoBuf.packageFqName) != new.hasExtension(JsProtoBuf.packageFqName)) return false
|
||||
if (old.hasExtension(JsProtoBuf.packageFqName)) {
|
||||
if (old.getExtension(JsProtoBuf.packageFqName) != new.getExtension(JsProtoBuf.packageFqName)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -70,8 +79,9 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
TYPE_ALIAS_LIST,
|
||||
TYPE_TABLE,
|
||||
SINCE_KOTLIN_INFO_TABLE,
|
||||
PACKAGE_MODULE_NAME,
|
||||
PACKAGE_LOCAL_VARIABLE_LIST
|
||||
JVM_EXT_PACKAGE_MODULE_NAME,
|
||||
JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST,
|
||||
JS_EXT_PACKAGE_FQ_NAME
|
||||
}
|
||||
|
||||
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
|
||||
@@ -93,15 +103,23 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkEquals(old.sinceKotlinInfoTable, new.sinceKotlinInfoTable)) result.add(ProtoBufPackageKind.SINCE_KOTLIN_INFO_TABLE)
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_MODULE_NAME)
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_MODULE_NAME)
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
|
||||
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) {
|
||||
result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST)
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST)
|
||||
}
|
||||
}
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
|
||||
if (old.hasExtension(JsProtoBuf.packageFqName) != new.hasExtension(JsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME)
|
||||
if (old.hasExtension(JsProtoBuf.packageFqName)) {
|
||||
if (old.getExtension(JsProtoBuf.packageFqName) != new.getExtension(JsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME)
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -160,10 +178,27 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) return false
|
||||
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) return false
|
||||
if (old.getExtensionCount(JsProtoBuf.classAnnotation) != new.getExtensionCount(JsProtoBuf.classAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.classAnnotation, i), new.getExtension(JsProtoBuf.classAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
if (old.hasExtension(JsProtoBuf.classContainingFileId) != new.hasExtension(JsProtoBuf.classContainingFileId)) return false
|
||||
if (old.hasExtension(JsProtoBuf.classContainingFileId)) {
|
||||
if (old.getExtension(JsProtoBuf.classContainingFileId) != new.getExtension(JsProtoBuf.classContainingFileId)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -185,8 +220,10 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
TYPE_TABLE,
|
||||
SINCE_KOTLIN_INFO,
|
||||
SINCE_KOTLIN_INFO_TABLE,
|
||||
CLASS_MODULE_NAME,
|
||||
CLASS_LOCAL_VARIABLE_LIST
|
||||
JVM_EXT_CLASS_MODULE_NAME,
|
||||
JVM_EXT_CLASS_LOCAL_VARIABLE_LIST,
|
||||
JS_EXT_CLASS_ANNOTATION_LIST,
|
||||
JS_EXT_CLASS_CONTAINING_FILE_ID
|
||||
}
|
||||
|
||||
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
|
||||
@@ -239,15 +276,32 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkEquals(old.sinceKotlinInfoTable, new.sinceKotlinInfoTable)) result.add(ProtoBufClassKind.SINCE_KOTLIN_INFO_TABLE)
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) result.add(ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME)
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME)
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
|
||||
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) {
|
||||
result.add(ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST)
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) result.add(ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST)
|
||||
}
|
||||
}
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
|
||||
if (old.getExtensionCount(JsProtoBuf.classAnnotation) != new.getExtensionCount(JsProtoBuf.classAnnotation)) {
|
||||
result.add(ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST)
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.classAnnotation, i), new.getExtension(JsProtoBuf.classAnnotation, i))) result.add(ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST)
|
||||
}
|
||||
}
|
||||
|
||||
if (old.hasExtension(JsProtoBuf.classContainingFileId) != new.hasExtension(JsProtoBuf.classContainingFileId)) result.add(ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID)
|
||||
if (old.hasExtension(JsProtoBuf.classContainingFileId)) {
|
||||
if (old.getExtension(JsProtoBuf.classContainingFileId) != new.getExtension(JsProtoBuf.classContainingFileId)) result.add(ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID)
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -305,6 +359,20 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.methodSignature), new.getExtension(JvmProtoBuf.methodSignature))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JsProtoBuf.functionAnnotation) != new.getExtensionCount(JsProtoBuf.functionAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.functionAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.functionAnnotation, i), new.getExtension(JsProtoBuf.functionAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
if (old.hasExtension(JsProtoBuf.functionContainingFileId) != new.hasExtension(JsProtoBuf.functionContainingFileId)) return false
|
||||
if (old.hasExtension(JsProtoBuf.functionContainingFileId)) {
|
||||
if (old.getExtension(JsProtoBuf.functionContainingFileId) != new.getExtension(JsProtoBuf.functionContainingFileId)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -368,6 +436,25 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.propertySignature), new.getExtension(JvmProtoBuf.propertySignature))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JsProtoBuf.propertyAnnotation) != new.getExtensionCount(JsProtoBuf.propertyAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.propertyAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.propertyAnnotation, i), new.getExtension(JsProtoBuf.propertyAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
if (old.hasExtension(JsProtoBuf.compileTimeValue) != new.hasExtension(JsProtoBuf.compileTimeValue)) return false
|
||||
if (old.hasExtension(JsProtoBuf.compileTimeValue)) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.compileTimeValue), new.getExtension(JsProtoBuf.compileTimeValue))) return false
|
||||
}
|
||||
|
||||
if (old.hasExtension(JsProtoBuf.propertyContainingFileId) != new.hasExtension(JsProtoBuf.propertyContainingFileId)) return false
|
||||
if (old.hasExtension(JsProtoBuf.propertyContainingFileId)) {
|
||||
if (old.getExtension(JsProtoBuf.propertyContainingFileId) != new.getExtension(JsProtoBuf.propertyContainingFileId)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -447,10 +534,22 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
|
||||
if (!checkEqualsTypeParameterUpperBoundId(old, new)) return false
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.typeParameterAnnotation) != new.getExtensionCount(JvmProtoBuf.typeParameterAnnotation)) return false
|
||||
if (old.getExtensionCount(JvmProtoBuf.typeParameterAnnotation) != new.getExtensionCount(JvmProtoBuf.typeParameterAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.typeParameterAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.typeParameterAnnotation, i), new.getExtension(JvmProtoBuf.typeParameterAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.typeParameterAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.typeParameterAnnotation, i), new.getExtension(JvmProtoBuf.typeParameterAnnotation, i))) return false
|
||||
if (old.getExtensionCount(JsProtoBuf.typeParameterAnnotation) != new.getExtensionCount(JsProtoBuf.typeParameterAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.typeParameterAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.typeParameterAnnotation, i), new.getExtension(JsProtoBuf.typeParameterAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -524,10 +623,13 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (old.flags != new.flags) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.typeAnnotation) != new.getExtensionCount(JvmProtoBuf.typeAnnotation)) return false
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.typeAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.typeAnnotation, i), new.getExtension(JvmProtoBuf.typeAnnotation, i))) return false
|
||||
if (old.getExtensionCount(JvmProtoBuf.typeAnnotation) != new.getExtensionCount(JvmProtoBuf.typeAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.typeAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.typeAnnotation, i), new.getExtension(JvmProtoBuf.typeAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.isRaw) != new.hasExtension(JvmProtoBuf.isRaw)) return false
|
||||
@@ -535,6 +637,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (old.getExtension(JvmProtoBuf.isRaw) != new.getExtension(JvmProtoBuf.isRaw)) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JsProtoBuf.typeAnnotation) != new.getExtensionCount(JsProtoBuf.typeAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.typeAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.typeAnnotation, i), new.getExtension(JsProtoBuf.typeAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -556,6 +667,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.constructorSignature), new.getExtension(JvmProtoBuf.constructorSignature))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JsProtoBuf.constructorAnnotation) != new.getExtensionCount(JsProtoBuf.constructorAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.constructorAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.constructorAnnotation, i), new.getExtension(JsProtoBuf.constructorAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -565,6 +685,23 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.name, new.name)) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JsProtoBuf.enumEntryAnnotation) != new.getExtensionCount(JsProtoBuf.enumEntryAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.enumEntryAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.enumEntryAnnotation, i), new.getExtension(JsProtoBuf.enumEntryAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEquals(old: ProtoBuf.Annotation, new: ProtoBuf.Annotation): Boolean {
|
||||
if (!checkClassIdEquals(old.id, new.id)) return false
|
||||
|
||||
if (!checkEqualsAnnotationArgument(old, new)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -596,6 +733,15 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (old.varargElementTypeId != new.varargElementTypeId) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JsProtoBuf.parameterAnnotation) != new.getExtensionCount(JsProtoBuf.parameterAnnotation)) {
|
||||
return false
|
||||
}
|
||||
else {
|
||||
for(i in 0..old.getExtensionCount(JsProtoBuf.parameterAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JsProtoBuf.parameterAnnotation, i), new.getExtension(JsProtoBuf.parameterAnnotation, i))) return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -637,10 +783,48 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEquals(old: ProtoBuf.Annotation, new: ProtoBuf.Annotation): Boolean {
|
||||
if (!checkClassIdEquals(old.id, new.id)) return false
|
||||
open fun checkEquals(old: ProtoBuf.Annotation.Argument.Value, new: ProtoBuf.Annotation.Argument.Value): Boolean {
|
||||
if (old.hasType() != new.hasType()) return false
|
||||
if (old.hasType()) {
|
||||
if (old.type != new.type) return false
|
||||
}
|
||||
|
||||
if (!checkEqualsAnnotationArgument(old, new)) return false
|
||||
if (old.hasIntValue() != new.hasIntValue()) return false
|
||||
if (old.hasIntValue()) {
|
||||
if (old.intValue != new.intValue) return false
|
||||
}
|
||||
|
||||
if (old.hasFloatValue() != new.hasFloatValue()) return false
|
||||
if (old.hasFloatValue()) {
|
||||
if (old.floatValue != new.floatValue) return false
|
||||
}
|
||||
|
||||
if (old.hasDoubleValue() != new.hasDoubleValue()) return false
|
||||
if (old.hasDoubleValue()) {
|
||||
if (old.doubleValue != new.doubleValue) return false
|
||||
}
|
||||
|
||||
if (old.hasStringValue() != new.hasStringValue()) return false
|
||||
if (old.hasStringValue()) {
|
||||
if (!checkStringEquals(old.stringValue, new.stringValue)) return false
|
||||
}
|
||||
|
||||
if (old.hasClassId() != new.hasClassId()) return false
|
||||
if (old.hasClassId()) {
|
||||
if (!checkClassIdEquals(old.classId, new.classId)) return false
|
||||
}
|
||||
|
||||
if (old.hasEnumValueId() != new.hasEnumValueId()) return false
|
||||
if (old.hasEnumValueId()) {
|
||||
if (!checkStringEquals(old.enumValueId, new.enumValueId)) return false
|
||||
}
|
||||
|
||||
if (old.hasAnnotation() != new.hasAnnotation()) return false
|
||||
if (old.hasAnnotation()) {
|
||||
if (!checkEquals(old.annotation, new.annotation)) return false
|
||||
}
|
||||
|
||||
if (!checkEqualsAnnotationArgumentValueArrayElement(old, new)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -693,6 +877,14 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEquals(old: ProtoBuf.Annotation.Argument, new: ProtoBuf.Annotation.Argument): Boolean {
|
||||
if (!checkStringEquals(old.nameId, new.nameId)) return false
|
||||
|
||||
if (!checkEquals(old.value, new.value)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEquals(old: JvmProtoBuf.JvmFieldSignature, new: JvmProtoBuf.JvmFieldSignature): Boolean {
|
||||
if (old.hasName() != new.hasName()) return false
|
||||
if (old.hasName()) {
|
||||
@@ -707,60 +899,6 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEquals(old: ProtoBuf.Annotation.Argument, new: ProtoBuf.Annotation.Argument): Boolean {
|
||||
if (!checkStringEquals(old.nameId, new.nameId)) return false
|
||||
|
||||
if (!checkEquals(old.value, new.value)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEquals(old: ProtoBuf.Annotation.Argument.Value, new: ProtoBuf.Annotation.Argument.Value): Boolean {
|
||||
if (old.hasType() != new.hasType()) return false
|
||||
if (old.hasType()) {
|
||||
if (old.type != new.type) return false
|
||||
}
|
||||
|
||||
if (old.hasIntValue() != new.hasIntValue()) return false
|
||||
if (old.hasIntValue()) {
|
||||
if (old.intValue != new.intValue) return false
|
||||
}
|
||||
|
||||
if (old.hasFloatValue() != new.hasFloatValue()) return false
|
||||
if (old.hasFloatValue()) {
|
||||
if (old.floatValue != new.floatValue) return false
|
||||
}
|
||||
|
||||
if (old.hasDoubleValue() != new.hasDoubleValue()) return false
|
||||
if (old.hasDoubleValue()) {
|
||||
if (old.doubleValue != new.doubleValue) return false
|
||||
}
|
||||
|
||||
if (old.hasStringValue() != new.hasStringValue()) return false
|
||||
if (old.hasStringValue()) {
|
||||
if (!checkStringEquals(old.stringValue, new.stringValue)) return false
|
||||
}
|
||||
|
||||
if (old.hasClassId() != new.hasClassId()) return false
|
||||
if (old.hasClassId()) {
|
||||
if (!checkClassIdEquals(old.classId, new.classId)) return false
|
||||
}
|
||||
|
||||
if (old.hasEnumValueId() != new.hasEnumValueId()) return false
|
||||
if (old.hasEnumValueId()) {
|
||||
if (!checkStringEquals(old.enumValueId, new.enumValueId)) return false
|
||||
}
|
||||
|
||||
if (old.hasAnnotation() != new.hasAnnotation()) return false
|
||||
if (old.hasAnnotation()) {
|
||||
if (!checkEquals(old.annotation, new.annotation)) return false
|
||||
}
|
||||
|
||||
if (!checkEqualsAnnotationArgumentValueArrayElement(old, new)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
open fun checkEqualsPackageFunction(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
|
||||
if (old.functionCount != new.functionCount) return false
|
||||
|
||||
@@ -1083,6 +1221,10 @@ fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.packageLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JsProtoBuf.packageFqName)) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.packageFqName)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1159,6 +1301,14 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.classLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JsProtoBuf.classContainingFileId)) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.classContainingFileId)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1211,6 +1361,14 @@ fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.methodSignature).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.functionAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.functionAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JsProtoBuf.functionContainingFileId)) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.functionContainingFileId)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1267,6 +1425,18 @@ fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.propertySignature).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.propertyAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertyAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JsProtoBuf.compileTimeValue)) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.compileTimeValue).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JsProtoBuf.propertyContainingFileId)) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertyContainingFileId)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1361,6 +1531,10 @@ fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.typeParameterAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1431,6 +1605,10 @@ fun ProtoBuf.Type.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.isRaw).hashCode()
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.typeAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1453,6 +1631,10 @@ fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (I
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.constructorSignature).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.constructorAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.constructorAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1463,6 +1645,22 @@ fun ProtoBuf.EnumEntry.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int
|
||||
hashCode = 31 * hashCode + stringIndexes(name)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.enumEntryAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.enumEntryAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
fun ProtoBuf.Annotation.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
hashCode = 31 * hashCode + fqNameIndexes(id)
|
||||
|
||||
for(i in 0..argumentCount - 1) {
|
||||
hashCode = 31 * hashCode + getArgument(i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1491,6 +1689,10 @@ fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
|
||||
hashCode = 31 * hashCode + varargElementTypeId
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JsProtoBuf.parameterAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JsProtoBuf.parameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1530,13 +1732,43 @@ fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int, fqNam
|
||||
return hashCode
|
||||
}
|
||||
|
||||
fun ProtoBuf.Annotation.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Annotation.Argument.Value.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
hashCode = 31 * hashCode + fqNameIndexes(id)
|
||||
if (hasType()) {
|
||||
hashCode = 31 * hashCode + type.hashCode()
|
||||
}
|
||||
|
||||
for(i in 0..argumentCount - 1) {
|
||||
hashCode = 31 * hashCode + getArgument(i).hashCode(stringIndexes, fqNameIndexes)
|
||||
if (hasIntValue()) {
|
||||
hashCode = 31 * hashCode + intValue.hashCode()
|
||||
}
|
||||
|
||||
if (hasFloatValue()) {
|
||||
hashCode = 31 * hashCode + floatValue.hashCode()
|
||||
}
|
||||
|
||||
if (hasDoubleValue()) {
|
||||
hashCode = 31 * hashCode + doubleValue.hashCode()
|
||||
}
|
||||
|
||||
if (hasStringValue()) {
|
||||
hashCode = 31 * hashCode + stringIndexes(stringValue)
|
||||
}
|
||||
|
||||
if (hasClassId()) {
|
||||
hashCode = 31 * hashCode + fqNameIndexes(classId)
|
||||
}
|
||||
|
||||
if (hasEnumValueId()) {
|
||||
hashCode = 31 * hashCode + stringIndexes(enumValueId)
|
||||
}
|
||||
|
||||
if (hasAnnotation()) {
|
||||
hashCode = 31 * hashCode + annotation.hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..arrayElementCount - 1) {
|
||||
hashCode = 31 * hashCode + getArrayElement(i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
@@ -1586,6 +1818,16 @@ fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
|
||||
return hashCode
|
||||
}
|
||||
|
||||
fun ProtoBuf.Annotation.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
hashCode = 31 * hashCode + stringIndexes(nameId)
|
||||
|
||||
hashCode = 31 * hashCode + value.hashCode(stringIndexes, fqNameIndexes)
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
@@ -1599,55 +1841,3 @@ fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIn
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
fun ProtoBuf.Annotation.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
hashCode = 31 * hashCode + stringIndexes(nameId)
|
||||
|
||||
hashCode = 31 * hashCode + value.hashCode(stringIndexes, fqNameIndexes)
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
fun ProtoBuf.Annotation.Argument.Value.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasType()) {
|
||||
hashCode = 31 * hashCode + type.hashCode()
|
||||
}
|
||||
|
||||
if (hasIntValue()) {
|
||||
hashCode = 31 * hashCode + intValue.hashCode()
|
||||
}
|
||||
|
||||
if (hasFloatValue()) {
|
||||
hashCode = 31 * hashCode + floatValue.hashCode()
|
||||
}
|
||||
|
||||
if (hasDoubleValue()) {
|
||||
hashCode = 31 * hashCode + doubleValue.hashCode()
|
||||
}
|
||||
|
||||
if (hasStringValue()) {
|
||||
hashCode = 31 * hashCode + stringIndexes(stringValue)
|
||||
}
|
||||
|
||||
if (hasClassId()) {
|
||||
hashCode = 31 * hashCode + fqNameIndexes(classId)
|
||||
}
|
||||
|
||||
if (hasEnumValueId()) {
|
||||
hashCode = 31 * hashCode + stringIndexes(enumValueId)
|
||||
}
|
||||
|
||||
if (hasAnnotation()) {
|
||||
hashCode = 31 * hashCode + annotation.hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..arrayElementCount - 1) {
|
||||
hashCode = 31 * hashCode + getArrayElement(i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -43,13 +43,21 @@ import java.util.*
|
||||
fun Iterable<File>.javaSourceRoots(roots: Iterable<File>): Iterable<File> =
|
||||
filter(File::isJavaFile).mapNotNull { findSrcDirRoot(it, roots) }
|
||||
|
||||
fun makeModuleFile(name: String, isTest: Boolean, outputDir: File, sourcesToCompile: Iterable<File>, javaSourceRoots: Iterable<File>, classpath: Iterable<File>, friendDirs: Iterable<File>): File {
|
||||
fun makeModuleFile(
|
||||
name: String,
|
||||
isTest: Boolean,
|
||||
outputDir: File,
|
||||
sourcesToCompile: Iterable<File>,
|
||||
javaSourceRoots: Iterable<JvmSourceRoot>,
|
||||
classpath: Iterable<File>,
|
||||
friendDirs: Iterable<File>
|
||||
): File {
|
||||
val builder = KotlinModuleXmlBuilder()
|
||||
builder.addModule(
|
||||
name,
|
||||
outputDir.absolutePath,
|
||||
sourcesToCompile,
|
||||
javaSourceRoots.map { JvmSourceRoot(it) },
|
||||
javaSourceRoots,
|
||||
classpath,
|
||||
null,
|
||||
"java-production",
|
||||
@@ -70,8 +78,8 @@ fun makeCompileServices(
|
||||
compilationCanceledStatus: CompilationCanceledStatus?
|
||||
): Services =
|
||||
with(Services.Builder()) {
|
||||
register(IncrementalCompilationComponents::class.java,
|
||||
IncrementalCompilationComponentsImpl(incrementalCaches, lookupTracker))
|
||||
register(LookupTracker::class.java, lookupTracker)
|
||||
register(IncrementalCompilationComponents::class.java, IncrementalCompilationComponentsImpl(incrementalCaches))
|
||||
compilationCanceledStatus?.let {
|
||||
register(CompilationCanceledStatus::class.java, it)
|
||||
}
|
||||
@@ -79,7 +87,7 @@ fun makeCompileServices(
|
||||
}
|
||||
|
||||
fun makeLookupTracker(parentLookupTracker: LookupTracker = LookupTracker.DO_NOTHING): LookupTracker =
|
||||
if (IncrementalCompilation.isExperimental()) LookupTrackerImpl(parentLookupTracker)
|
||||
if (IncrementalCompilation.isEnabled()) LookupTrackerImpl(parentLookupTracker)
|
||||
else parentLookupTracker
|
||||
|
||||
fun<Target> makeIncrementalCachesMap(
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.incremental.ProtoCompareGenerated.ProtoBufClassKind
|
||||
import org.jetbrains.kotlin.incremental.ProtoCompareGenerated.ProtoBufPackageKind
|
||||
@@ -31,24 +32,47 @@ import java.util.*
|
||||
data class Difference(
|
||||
val isClassAffected: Boolean = false,
|
||||
val areSubclassesAffected: Boolean = false,
|
||||
val changedMembersNames: Set<String> = emptySet()
|
||||
val changedMembersNames: Set<String> = emptySet(),
|
||||
@TestOnly
|
||||
val rawProtoDifference: EnumSet<*>? = null
|
||||
)
|
||||
|
||||
fun difference(oldData: ProtoMapValue, newData: ProtoMapValue): Difference {
|
||||
if (!oldData.isPackageFacade && newData.isPackageFacade) return Difference(isClassAffected = true, areSubclassesAffected = true)
|
||||
sealed class ProtoData
|
||||
data class ClassProtoData(val proto: ProtoBuf.Class, val nameResolver: NameResolver) : ProtoData()
|
||||
data class PackagePartProtoData(val proto: ProtoBuf.Package, val nameResolver: NameResolver) : ProtoData()
|
||||
|
||||
if (oldData.isPackageFacade && !newData.isPackageFacade) return Difference(isClassAffected = true)
|
||||
fun ProtoMapValue.toProtoData(): ProtoData =
|
||||
if (isPackageFacade) {
|
||||
val packageData = JvmProtoBufUtil.readPackageDataFrom(bytes, strings)
|
||||
PackagePartProtoData(packageData.packageProto, packageData.nameResolver)
|
||||
}
|
||||
else {
|
||||
val classData = JvmProtoBufUtil.readClassDataFrom(bytes, strings)
|
||||
ClassProtoData(classData.classProto, classData.nameResolver)
|
||||
}
|
||||
|
||||
val differenceObject =
|
||||
if (oldData.isPackageFacade) {
|
||||
DifferenceCalculatorForPackageFacade(oldData, newData)
|
||||
fun difference(oldValue: ProtoMapValue, newValue: ProtoMapValue): Difference =
|
||||
difference(oldValue.toProtoData(), newValue.toProtoData())
|
||||
|
||||
fun difference(oldData: ProtoData, newData: ProtoData): Difference =
|
||||
when (oldData) {
|
||||
is ClassProtoData -> {
|
||||
when (newData) {
|
||||
is ClassProtoData ->
|
||||
DifferenceCalculatorForClass(oldData, newData).difference()
|
||||
is PackagePartProtoData ->
|
||||
Difference(isClassAffected = true, areSubclassesAffected = true)
|
||||
}
|
||||
}
|
||||
else {
|
||||
DifferenceCalculatorForClass(oldData, newData)
|
||||
is PackagePartProtoData -> {
|
||||
when (newData) {
|
||||
is ClassProtoData ->
|
||||
Difference(isClassAffected = true)
|
||||
is PackagePartProtoData ->
|
||||
DifferenceCalculatorForPackageFacade(oldData, newData).difference()
|
||||
}
|
||||
}
|
||||
|
||||
return differenceObject.difference()
|
||||
}
|
||||
}
|
||||
|
||||
internal val MessageLite.isPrivate: Boolean
|
||||
get() = Visibilities.isPrivate(Deserialization.visibility(
|
||||
@@ -72,11 +96,8 @@ private fun MessageLite.name(nameResolver: NameResolver): String {
|
||||
|
||||
internal fun List<MessageLite>.names(nameResolver: NameResolver): List<String> = map { it.name(nameResolver) }
|
||||
|
||||
private abstract class DifferenceCalculator() {
|
||||
protected abstract val oldNameResolver: NameResolver
|
||||
protected abstract val newNameResolver: NameResolver
|
||||
|
||||
protected val compareObject by lazy { ProtoCompareGenerated(oldNameResolver, newNameResolver) }
|
||||
private abstract class DifferenceCalculator {
|
||||
protected abstract val compareObject: ProtoCompareGenerated
|
||||
|
||||
abstract fun difference(): Difference
|
||||
|
||||
@@ -158,19 +179,18 @@ private abstract class DifferenceCalculator() {
|
||||
}
|
||||
}
|
||||
|
||||
private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: ProtoMapValue) : DifferenceCalculator() {
|
||||
val oldClassData = JvmProtoBufUtil.readClassDataFrom(oldData.bytes, oldData.strings)
|
||||
val newClassData = JvmProtoBufUtil.readClassDataFrom(newData.bytes, newData.strings)
|
||||
|
||||
val oldProto = oldClassData.classProto
|
||||
val newProto = newClassData.classProto
|
||||
|
||||
override val oldNameResolver = oldClassData.nameResolver
|
||||
override val newNameResolver = newClassData.nameResolver
|
||||
|
||||
val diff = compareObject.difference(oldProto, newProto)
|
||||
private class DifferenceCalculatorForClass(
|
||||
private val oldData: ClassProtoData,
|
||||
private val newData: ClassProtoData
|
||||
) : DifferenceCalculator() {
|
||||
override val compareObject = ProtoCompareGenerated(oldData.nameResolver, newData.nameResolver)
|
||||
|
||||
override fun difference(): Difference {
|
||||
val (oldProto, oldNameResolver) = oldData
|
||||
val (newProto, newNameResolver) = newData
|
||||
|
||||
val diff = compareObject.difference(oldProto, newProto)
|
||||
|
||||
var isClassAffected = false
|
||||
var areSubclassesAffected = false
|
||||
val names = hashSetOf<String>()
|
||||
@@ -216,7 +236,15 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
isClassAffected = true
|
||||
}
|
||||
ProtoBufClassKind.SEALED_SUBCLASS_FQ_NAME_LIST -> {
|
||||
// TODO
|
||||
isClassAffected = true
|
||||
// Subclasses are considered to be affected to fix the case where
|
||||
// an implementation is added to an nth-level (n > 1) sealed class.
|
||||
// In case of the following hierarchy:
|
||||
// Base <- Intermediate <- Impl
|
||||
// the change of the SEALED_SUBCLASS_FQ_NAME_LIST will be detected in the Intermediate,
|
||||
// but there can be usages, that should be rebuilt, without direct references to the Intermediate:
|
||||
// when (x as Base) { is Impl -> ... }
|
||||
areSubclassesAffected = true
|
||||
}
|
||||
ProtoBufClassKind.TYPE_TABLE -> {
|
||||
// TODO
|
||||
@@ -229,36 +257,37 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
ProtoBufClassKind.FQ_NAME,
|
||||
ProtoBufClassKind.TYPE_PARAMETER_LIST,
|
||||
ProtoBufClassKind.SUPERTYPE_LIST,
|
||||
ProtoBufClassKind.SUPERTYPE_ID_LIST-> {
|
||||
ProtoBufClassKind.SUPERTYPE_ID_LIST,
|
||||
ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST -> {
|
||||
isClassAffected = true
|
||||
areSubclassesAffected = true
|
||||
}
|
||||
ProtoBufClassKind.CLASS_MODULE_NAME -> {
|
||||
// TODO
|
||||
ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME,
|
||||
ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID -> {
|
||||
// TODO
|
||||
}
|
||||
ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST -> {
|
||||
ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST -> {
|
||||
// Not affected, local variables are not accessible outside of a file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Difference(isClassAffected, areSubclassesAffected, names)
|
||||
return Difference(isClassAffected, areSubclassesAffected, names, rawProtoDifference = diff)
|
||||
}
|
||||
}
|
||||
|
||||
private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newData: ProtoMapValue) : DifferenceCalculator() {
|
||||
val oldPackageData = JvmProtoBufUtil.readPackageDataFrom(oldData.bytes, oldData.strings)
|
||||
val newPackageData = JvmProtoBufUtil.readPackageDataFrom(newData.bytes, newData.strings)
|
||||
|
||||
val oldProto = oldPackageData.packageProto
|
||||
val newProto = newPackageData.packageProto
|
||||
|
||||
override val oldNameResolver = oldPackageData.nameResolver
|
||||
override val newNameResolver = newPackageData.nameResolver
|
||||
|
||||
val diff = compareObject.difference(oldProto, newProto)
|
||||
private class DifferenceCalculatorForPackageFacade(
|
||||
private val oldData: PackagePartProtoData,
|
||||
private val newData: PackagePartProtoData
|
||||
) : DifferenceCalculator() {
|
||||
override val compareObject = ProtoCompareGenerated(oldData.nameResolver, newData.nameResolver)
|
||||
|
||||
override fun difference(): Difference {
|
||||
val oldProto = oldData.proto
|
||||
val newProto = newData.proto
|
||||
|
||||
val diff = compareObject.difference(oldProto, newProto)
|
||||
|
||||
val names = hashSetOf<String>()
|
||||
|
||||
fun calcDifferenceForNonPrivateMembers(members: (ProtoBuf.Package) -> List<MessageLite>): Collection<String> {
|
||||
@@ -278,16 +307,17 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
|
||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getTypeAliasList))
|
||||
ProtoBufPackageKind.TYPE_TABLE,
|
||||
ProtoBufPackageKind.SINCE_KOTLIN_INFO_TABLE,
|
||||
ProtoBufPackageKind.PACKAGE_MODULE_NAME -> {
|
||||
ProtoBufPackageKind.JVM_EXT_PACKAGE_MODULE_NAME,
|
||||
ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME-> {
|
||||
// TODO
|
||||
}
|
||||
ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST -> {
|
||||
ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST -> {
|
||||
// Not affected, local variables are not accessible outside of a file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Difference(changedMembersNames = names)
|
||||
return Difference(changedMembersNames = names, rawProtoDifference = diff)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,22 +17,25 @@
|
||||
package org.jetbrains.kotlin
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import junit.framework.TestCase
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import java.io.File
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
abstract class TestWithWorkingDir {
|
||||
abstract class TestWithWorkingDir : TestCase() {
|
||||
protected var workingDir: File by Delegates.notNull()
|
||||
private set
|
||||
|
||||
@Before
|
||||
open fun setUp() {
|
||||
workingDir = FileUtil.createTempDirectory(this::class.java.simpleName, null)
|
||||
public override fun setUp() {
|
||||
super.setUp()
|
||||
workingDir = FileUtil.createTempDirectory(this::class.java.simpleName, null, /* deleteOnExit = */ true)
|
||||
}
|
||||
|
||||
@After
|
||||
open fun tearDown() {
|
||||
public override fun tearDown() {
|
||||
workingDir.deleteRecursively()
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.incremental.testingUtils
|
||||
import java.io.File
|
||||
|
||||
class BuildLogFinder(
|
||||
private val isExperimentalEnabled: Boolean = false,
|
||||
private val isDataContainerBuildLogEnabled: Boolean = false,
|
||||
private val isGradleEnabled: Boolean = false
|
||||
) {
|
||||
companion object {
|
||||
private const val GRADLE_LOG = "gradle-build.log"
|
||||
private const val DATA_CONTAINER_LOG = "data-container-version-build.log"
|
||||
private const val EXPERIMENTAL_LOG = "experimental-ic-build.log"
|
||||
private const val SIMPLE_LOG = "build.log"
|
||||
}
|
||||
|
||||
@@ -36,7 +34,6 @@ class BuildLogFinder(
|
||||
val matchedName = when {
|
||||
isGradleEnabled && GRADLE_LOG in files -> GRADLE_LOG
|
||||
isDataContainerBuildLogEnabled && DATA_CONTAINER_LOG in files -> DATA_CONTAINER_LOG
|
||||
isExperimentalEnabled && EXPERIMENTAL_LOG in files -> EXPERIMENTAL_LOG
|
||||
SIMPLE_LOG in files -> SIMPLE_LOG
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -128,13 +128,13 @@ fun getModificationsToPerform(
|
||||
}
|
||||
|
||||
abstract class Modification(val path: String) {
|
||||
abstract fun perform(workDir: File, mapping: MutableMap<File, File>)
|
||||
abstract fun perform(workDir: File, mapping: MutableMap<File, File>): File?
|
||||
|
||||
override fun toString(): String = "${this::class.java.simpleName} $path"
|
||||
}
|
||||
|
||||
class ModifyContent(path: String, val dataFile: File) : Modification(path) {
|
||||
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
|
||||
override fun perform(workDir: File, mapping: MutableMap<File, File>): File? {
|
||||
val file = File(workDir, path)
|
||||
|
||||
val oldLastModified = file.lastModified()
|
||||
@@ -148,11 +148,12 @@ class ModifyContent(path: String, val dataFile: File) : Modification(path) {
|
||||
}
|
||||
|
||||
mapping[file] = dataFile
|
||||
return file
|
||||
}
|
||||
}
|
||||
|
||||
class TouchFile(path: String, private val touchPolicy: TouchPolicy) : Modification(path) {
|
||||
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
|
||||
override fun perform(workDir: File, mapping: MutableMap<File, File>): File? {
|
||||
val file = File(workDir, path)
|
||||
|
||||
when (touchPolicy) {
|
||||
@@ -166,16 +167,18 @@ class TouchFile(path: String, private val touchPolicy: TouchPolicy) : Modificati
|
||||
}
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
}
|
||||
|
||||
class DeleteFile(path: String) : Modification(path) {
|
||||
override fun perform(workDir: File, mapping: MutableMap<File, File>) {
|
||||
override fun perform(workDir: File, mapping: MutableMap<File, File>): File? {
|
||||
val fileToDelete = File(workDir, path)
|
||||
if (!fileToDelete.delete()) {
|
||||
throw AssertionError("Couldn't delete $fileToDelete")
|
||||
}
|
||||
|
||||
mapping.remove(fileToDelete)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
10
build.xml
10
build.xml
@@ -61,8 +61,8 @@
|
||||
<pathelement location="${tools.jar}"/>
|
||||
|
||||
<fileset dir="${basedir}/lib" includes="**/*.jar"/>
|
||||
<fileset dir="${dependencies}" includes="jline3.jar"/>
|
||||
<fileset dir="${dependencies}" includes="jansi.jar"/>
|
||||
<fileset dir="${dependencies}" includes="jline.jar"/>
|
||||
<fileset dir="${dependencies}" includes="javaslang-2.0.6.jar"/>
|
||||
<fileset dir="${dependencies}" includes="json-org.jar"/>
|
||||
<fileset dir="${dependencies}" includes="kotlinx-coroutines-core.jar"/>
|
||||
@@ -387,20 +387,22 @@
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/annotations.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/asm-all.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/guava-19.0.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/guava-21.0.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/intellij-core.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/jdom.jar" excludes="META-INF/jb/** META-INF/LICENSE"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/jna.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/log4j.jar" excludes="META-INF/jb/** META-INF/LICENSE"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/picocontainer.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/snappy-in-java-0.5.1.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/streamex-0.6.2.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/trove4j.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/xpp3-1.1.4-min.jar"/>
|
||||
<zipfileset src="${basedir}/ideaSDK/core/xstream-1.4.8.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-platform.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/oromatcher.jar" excludes="META-INF/jb/** META-INF/LICENSE"/>
|
||||
<zipfileset src="${idea.sdk}/jps/jps-model.jar"/>
|
||||
<zipfileset src="${dependencies}/jline.jar"/>
|
||||
<zipfileset src="${idea.sdk}/jps/jps-model.jar" excludes="META-INF/services/**"/>
|
||||
<zipfileset src="${dependencies}/jline3.jar"/>
|
||||
<zipfileset src="${dependencies}/jansi.jar"/>
|
||||
<zipfileset src="${dependencies}/javaslang-2.0.6.jar"/>
|
||||
<zipfileset src="${dependencies}/json-org.jar"/>
|
||||
<zipfileset src="${protobuf.jar}"/>
|
||||
|
||||
@@ -152,14 +152,6 @@ public class AsmUtil {
|
||||
return isIntPrimitive(type) || type == Type.LONG_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isNumberPrimitiveOrBoolean(Type type) {
|
||||
return isNumberPrimitive(type) || type.getSort() == Type.BOOLEAN;
|
||||
}
|
||||
|
||||
public static boolean isNumberPrimitive(Type type) {
|
||||
return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE;
|
||||
}
|
||||
|
||||
public static boolean isPrimitive(Type type) {
|
||||
return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY;
|
||||
}
|
||||
@@ -362,7 +354,9 @@ public class AsmUtil {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||
|
||||
if (isEffectivelyInlineOnly(memberDescriptor)) return ACC_PRIVATE;
|
||||
if (isEffectivelyInlineOnly(memberDescriptor)) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
return ACC_PUBLIC;
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.StackValue.createDefaulValue;
|
||||
import static org.jetbrains.kotlin.codegen.StackValue.createDefaultValue;
|
||||
|
||||
public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
private final ExpressionCodegen codegen;
|
||||
@@ -64,7 +64,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
|
||||
@Override
|
||||
protected void generateDefault(int i, @NotNull DefaultValueArgument argument) {
|
||||
callGenerator.putValueIfNeeded(valueParameterTypes.get(i), createDefaulValue(valueParameterTypes.get(i)), ValueKind.DEFAULT_PARAMETER, i);
|
||||
callGenerator.putValueIfNeeded(valueParameterTypes.get(i), createDefaultValue(valueParameterTypes.get(i)), ValueKind.DEFAULT_PARAMETER, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,8 +27,11 @@ import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptorKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -101,6 +104,16 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) companionObjectDescriptor);
|
||||
}
|
||||
|
||||
// Generate synthetic nested classes
|
||||
Collection<DeclarationDescriptor> classifiers = descriptor
|
||||
.getUnsubstitutedMemberScope()
|
||||
.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.Companion.getALL_NAME_FILTER());
|
||||
for (DeclarationDescriptor memberDescriptor : classifiers) {
|
||||
if (memberDescriptor instanceof SyntheticClassOrObjectDescriptor) {
|
||||
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) memberDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (generateNonClassMembers) {
|
||||
generateBridges();
|
||||
}
|
||||
@@ -182,7 +195,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected List<KtParameter> getPrimaryConstructorParameters() {
|
||||
public List<KtParameter> getPrimaryConstructorParameters() {
|
||||
if (myClass instanceof KtClass) {
|
||||
return myClass.getPrimaryConstructorParameters();
|
||||
}
|
||||
@@ -192,6 +205,6 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
@Nullable
|
||||
@Override
|
||||
protected ClassDescriptor classForInnerClassRecord() {
|
||||
return DescriptorUtils.isTopLevelDeclaration(descriptor) ? null : descriptor;
|
||||
return InnerClassConsumer.Companion.classForInnerClassRecord(descriptor, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.*
|
||||
|
||||
class DefaultCallArgs(val size: Int) {
|
||||
|
||||
val bits: BitSet = BitSet(size)
|
||||
private val bits: BitSet = BitSet(size)
|
||||
|
||||
fun mark(index: Int) {
|
||||
assert (index < size) {
|
||||
@@ -39,7 +39,7 @@ class DefaultCallArgs(val size: Int) {
|
||||
val masks = ArrayList<Int>(1)
|
||||
|
||||
var mask = 0
|
||||
for (i in 0..size - 1) {
|
||||
for (i in 0 until size) {
|
||||
if (i != 0 && i % Integer.SIZE == 0) {
|
||||
masks.add(mask)
|
||||
mask = 0
|
||||
|
||||
@@ -50,7 +50,7 @@ import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider;
|
||||
import org.jetbrains.kotlin.config.ApiVersion;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
@@ -65,10 +65,7 @@ import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
@@ -134,6 +131,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
private final MemberCodegen<?> parentCodegen;
|
||||
private final TailRecursionCodegen tailRecursionCodegen;
|
||||
public final CallGenerator defaultCallGenerator = new CallGenerator.DefaultCallGenerator(this);
|
||||
private final SwitchCodegenProvider switchCodegenProvider;
|
||||
|
||||
private final Stack<BlockStackElement> blockStackElements = new Stack<>();
|
||||
|
||||
@@ -165,6 +163,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
this.parentCodegen = parentCodegen;
|
||||
this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state);
|
||||
this.switchCodegenProvider = new SwitchCodegenProvider(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -750,11 +749,21 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitConstantExpression(@NotNull KtConstantExpression expression, StackValue receiver) {
|
||||
ConstantValue<?> compileTimeValue = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
ConstantValue<?> compileTimeValue = getPrimitiveOrStringCompileTimeConstant(expression);
|
||||
assert compileTimeValue != null;
|
||||
return StackValue.constant(compileTimeValue.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConstantValue<?> getCompileTimeConstant(@NotNull KtExpression expression) {
|
||||
return getCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ConstantValue<?> getPrimitiveOrStringCompileTimeConstant(@NotNull KtExpression expression) {
|
||||
return getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getPrimitiveOrStringCompileTimeConstant(
|
||||
@NotNull KtExpression expression,
|
||||
@@ -910,8 +919,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
KtExpression entryExpression = entry.getExpression();
|
||||
if (entryExpression == null) throw new AssertionError("No expression in " + entry);
|
||||
|
||||
ConstantValue<?> compileTimeConstant =
|
||||
getPrimitiveOrStringCompileTimeConstant(entryExpression, bindingContext, state.getShouldInlineConstVals());
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(entryExpression);
|
||||
|
||||
if (compileTimeConstant != null && isConstantValueInlinableInStringTemplate(compileTimeConstant)) {
|
||||
constantValue.append(String.valueOf(compileTimeConstant.getValue()));
|
||||
@@ -1862,7 +1870,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull DeclarationDescriptor containingDeclaration
|
||||
) {
|
||||
switch (accessorKind) {
|
||||
case NORMAL: return context.getParentContext();
|
||||
case NORMAL:
|
||||
if (containingDeclaration instanceof ClassDescriptor) {
|
||||
CodegenContext parentWithDescriptor = context.findParentContextWithDescriptor(containingDeclaration);
|
||||
if (parentWithDescriptor != null) {
|
||||
return parentWithDescriptor;
|
||||
}
|
||||
}
|
||||
return context.getParentContext();
|
||||
// For companion object property, backing field lives in object containing class
|
||||
// Otherwise, it lives in its containing declaration
|
||||
case IN_CLASS_COMPANION: return context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration());
|
||||
@@ -1884,6 +1899,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return intermediateValueForSyntheticExtensionProperty((SyntheticJavaPropertyDescriptor) propertyDescriptor, receiver);
|
||||
}
|
||||
|
||||
if (propertyDescriptor instanceof PropertyImportedFromObject) {
|
||||
propertyDescriptor = ((PropertyImportedFromObject) propertyDescriptor).getCallableFromObject();
|
||||
}
|
||||
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
|
||||
@@ -2823,7 +2842,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
else if (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ ||
|
||||
opToken == KtTokens.EQEQEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
return generateEquals(expression.getLeft(), expression.getRight(), opToken);
|
||||
return generateEquals(expression.getLeft(), expression.getRight(), opToken, null);
|
||||
}
|
||||
else if (opToken == KtTokens.LT || opToken == KtTokens.LTEQ ||
|
||||
opToken == KtTokens.GT || opToken == KtTokens.GTEQ) {
|
||||
@@ -2837,7 +2856,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
expression.getRight(), reference);
|
||||
}
|
||||
else {
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression);
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
@@ -2868,44 +2887,76 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.or(gen(expression.getLeft()), gen(expression.getRight()));
|
||||
}
|
||||
|
||||
private StackValue generateEquals(@Nullable KtExpression left, @Nullable KtExpression right, @NotNull IElementType opToken) {
|
||||
private StackValue genLazyUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
return pregenerated != null ? StackValue.coercion(pregenerated, type) : genLazy(expr, type);
|
||||
}
|
||||
|
||||
private StackValue genUnlessProvided(@Nullable StackValue pregenerated, @NotNull KtExpression expr, @NotNull Type type) {
|
||||
if (pregenerated != null) {
|
||||
pregenerated.put(type, v);
|
||||
}
|
||||
else {
|
||||
gen(expr, type);
|
||||
}
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
private StackValue generateEquals(
|
||||
@Nullable KtExpression left,
|
||||
@Nullable KtExpression right,
|
||||
@NotNull IElementType opToken,
|
||||
@Nullable StackValue pregeneratedLeft
|
||||
) {
|
||||
Type leftType = expressionType(left);
|
||||
Type rightType = expressionType(right);
|
||||
|
||||
if (KtPsiUtil.isNullConstant(left)) {
|
||||
return genCmpWithNull(right, opToken);
|
||||
return genCmpWithNull(right, opToken, null);
|
||||
}
|
||||
|
||||
if (KtPsiUtil.isNullConstant(right)) {
|
||||
return genCmpWithNull(left, opToken);
|
||||
return genCmpWithNull(left, opToken, pregeneratedLeft);
|
||||
}
|
||||
|
||||
if (isIntZero(left, leftType) && isIntPrimitive(rightType)) {
|
||||
return genCmpWithZero(right, opToken);
|
||||
return genCmpWithZero(right, opToken, null);
|
||||
}
|
||||
|
||||
if (isIntZero(right, rightType) && isIntPrimitive(leftType)) {
|
||||
return genCmpWithZero(left, opToken);
|
||||
return genCmpWithZero(left, opToken, pregeneratedLeft);
|
||||
}
|
||||
|
||||
if (left instanceof KtSafeQualifiedExpression && isPrimitive(rightType)) {
|
||||
if (pregeneratedLeft == null && left instanceof KtSafeQualifiedExpression && isPrimitive(rightType)) {
|
||||
return genCmpSafeCallToPrimitive((KtSafeQualifiedExpression) left, right, rightType, opToken);
|
||||
}
|
||||
|
||||
if (isPrimitive(leftType) && right instanceof KtSafeQualifiedExpression) {
|
||||
return genCmpPrimitiveToSafeCall(left, leftType, (KtSafeQualifiedExpression) right, opToken);
|
||||
return genCmpPrimitiveToSafeCall(left, leftType, (KtSafeQualifiedExpression) right, opToken, pregeneratedLeft);
|
||||
}
|
||||
|
||||
if (BoxedToPrimitiveEquality.isApplicable(opToken, leftType, rightType)) {
|
||||
return BoxedToPrimitiveEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType,
|
||||
myFrameMap);
|
||||
return BoxedToPrimitiveEquality.create(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType), leftType,
|
||||
genLazy(right, rightType), rightType,
|
||||
myFrameMap
|
||||
);
|
||||
}
|
||||
|
||||
if (PrimitiveToBoxedEquality.isApplicable(opToken, leftType, rightType)) {
|
||||
return PrimitiveToBoxedEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType);
|
||||
return PrimitiveToBoxedEquality.create(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType), leftType,
|
||||
genLazy(right, rightType), rightType
|
||||
);
|
||||
}
|
||||
|
||||
if (PrimitiveToObjectEquality.isApplicable(opToken, leftType, rightType)) {
|
||||
return PrimitiveToObjectEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType);
|
||||
return PrimitiveToObjectEquality.create(
|
||||
opToken,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType), leftType,
|
||||
genLazy(right, rightType), rightType
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2917,23 +2968,29 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (opToken == KtTokens.EQEQEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
// TODO: always casting to the type of the left operand in case of primitives looks wrong
|
||||
Type operandType = isPrimitive(leftType) ? leftType : OBJECT_TYPE;
|
||||
return StackValue.cmp(opToken, operandType, genLazy(left, leftType), genLazy(right, rightType));
|
||||
return StackValue.cmp(
|
||||
opToken,
|
||||
operandType,
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
genLazy(right, rightType)
|
||||
);
|
||||
}
|
||||
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(left, right, opToken, leftType, rightType, null);
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(left, right, opToken, leftType, rightType, pregeneratedLeft);
|
||||
}
|
||||
|
||||
private StackValue genCmpPrimitiveToSafeCall(
|
||||
@NotNull KtExpression left,
|
||||
@NotNull Type leftType,
|
||||
@NotNull KtSafeQualifiedExpression right,
|
||||
@NotNull IElementType opToken
|
||||
@NotNull IElementType opToken,
|
||||
@Nullable StackValue pregeneratedLeft
|
||||
) {
|
||||
Label rightIsNull = new Label();
|
||||
return new PrimitiveToSafeCallEquality(
|
||||
opToken,
|
||||
leftType,
|
||||
genLazy(left, leftType),
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
generateSafeQualifiedExpression(right, rightIsNull),
|
||||
expressionType(right.getReceiverExpression()),
|
||||
rightIsNull
|
||||
@@ -2994,7 +3051,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
return genEqualsForExpressionsOnStack(
|
||||
opToken,
|
||||
pregeneratedLeft != null ? StackValue.coercion(pregeneratedLeft, leftType) : genLazy(left, leftType),
|
||||
genLazyUnlessProvided(pregeneratedLeft, left, leftType),
|
||||
genLazy(right, rightType)
|
||||
);
|
||||
}
|
||||
@@ -3010,12 +3067,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
) {
|
||||
Type leftType = left754Type.isNullable ? AsmUtil.boxType(left754Type.type) : left754Type.type;
|
||||
|
||||
if (pregeneratedLeft != null) {
|
||||
StackValue.coercion(pregeneratedLeft, leftType).put(leftType, v);
|
||||
}
|
||||
else {
|
||||
gen(left, leftType);
|
||||
}
|
||||
genUnlessProvided(pregeneratedLeft, left, leftType);
|
||||
Type rightType = right754Type.isNullable ? AsmUtil.boxType(right754Type.type) : right754Type.type;
|
||||
gen(right, rightType);
|
||||
|
||||
@@ -3120,16 +3172,22 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
private boolean isIntZero(KtExpression expr, Type exprType) {
|
||||
ConstantValue<?> exprValue = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals());
|
||||
ConstantValue<?> exprValue = getPrimitiveOrStringCompileTimeConstant(expr);
|
||||
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
|
||||
}
|
||||
|
||||
private StackValue genCmpWithZero(KtExpression exp, IElementType opToken) {
|
||||
return StackValue.compareIntWithZero(gen(exp), (KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNE : IFEQ);
|
||||
private StackValue genCmpWithZero(KtExpression exp, IElementType opToken, @Nullable StackValue pregeneratedExpr) {
|
||||
return StackValue.compareIntWithZero(
|
||||
pregeneratedExpr != null ? pregeneratedExpr : gen(exp),
|
||||
(KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNE : IFEQ
|
||||
);
|
||||
}
|
||||
|
||||
private StackValue genCmpWithNull(KtExpression exp, IElementType opToken) {
|
||||
return StackValue.compareWithNull(gen(exp), (KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNONNULL : IFNULL);
|
||||
private StackValue genCmpWithNull(KtExpression exp, IElementType opToken, @Nullable StackValue pregeneratedExpr) {
|
||||
return StackValue.compareWithNull(
|
||||
pregeneratedExpr != null ? pregeneratedExpr : gen(exp),
|
||||
(KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNONNULL : IFNULL
|
||||
);
|
||||
}
|
||||
|
||||
private StackValue generateElvis(@NotNull KtBinaryExpression expression) {
|
||||
@@ -3249,7 +3307,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public void invokeAppend(InstructionAdapter v, KtExpression expr) {
|
||||
expr = KtPsiUtil.safeDeparenthesize(expr);
|
||||
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals());
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
||||
|
||||
if (compileTimeConstant == null) {
|
||||
if (expr instanceof KtBinaryExpression) {
|
||||
@@ -3299,7 +3357,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitPrefixExpression(@NotNull KtPrefixExpression expression, @NotNull StackValue receiver) {
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression, bindingContext, state.getShouldInlineConstVals());
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expression);
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
@@ -3448,10 +3506,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
initializeDestructuringDeclarationVariables(multiDeclaration, initializerAsReceiver, local, asProperty);
|
||||
|
||||
if (initializerAsmType.getSort() == Type.OBJECT || initializerAsmType.getSort() == Type.ARRAY) {
|
||||
v.aconst(null);
|
||||
v.store(tempVarIndex, initializerAsmType);
|
||||
}
|
||||
myFrameMap.leaveTemp(initializerAsmType);
|
||||
|
||||
return StackValue.none();
|
||||
@@ -3997,22 +4051,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
private StackValue generateExpressionMatch(StackValue expressionToMatch, KtExpression subjectExpression, KtExpression patternExpression) {
|
||||
if (expressionToMatch != null) {
|
||||
Type subjectType = expressionToMatch.type;
|
||||
markStartLineNumber(patternExpression);
|
||||
KotlinType condJetType = bindingContext.getType(patternExpression);
|
||||
Type condType;
|
||||
if (isNumberPrimitiveOrBoolean(subjectType)) {
|
||||
assert condJetType != null;
|
||||
condType = asmType(condJetType);
|
||||
if (!isNumberPrimitiveOrBoolean(condType)) {
|
||||
subjectType = boxType(subjectType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
condType = OBJECT_TYPE;
|
||||
}
|
||||
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(subjectExpression, patternExpression, KtTokens.EQEQ, subjectType, condType, expressionToMatch);
|
||||
return generateEquals(subjectExpression, patternExpression, KtTokens.EQEQ, expressionToMatch);
|
||||
}
|
||||
else {
|
||||
return gen(patternExpression);
|
||||
@@ -4085,12 +4124,12 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
Type resultType = isStatement ? Type.VOID_TYPE : expressionType(expression);
|
||||
|
||||
return StackValue.operation(resultType, v -> {
|
||||
SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(
|
||||
expression, isStatement, CodegenUtil.isExhaustive(bindingContext, expression, isStatement), this
|
||||
SwitchCodegen switchCodegen = switchCodegenProvider.buildAppropriateSwitchCodegenIfPossible(
|
||||
expression, isStatement, CodegenUtil.isExhaustive(bindingContext, expression, isStatement)
|
||||
);
|
||||
if (switchCodegen != null) {
|
||||
switchCodegen.generate();
|
||||
return Unit.INSTANCE;
|
||||
return null;
|
||||
}
|
||||
|
||||
int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;
|
||||
|
||||
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
class InlineCycleReporter(private val diagnostics: DiagnosticSink) {
|
||||
|
||||
val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>()
|
||||
private val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>()
|
||||
|
||||
fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
|
||||
//null call for default method inlining
|
||||
|
||||
@@ -17,7 +17,35 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import java.util.*
|
||||
|
||||
interface InnerClassConsumer {
|
||||
fun addInnerClassInfoFromAnnotation(classDescriptor: ClassDescriptor)
|
||||
|
||||
companion object {
|
||||
|
||||
fun classForInnerClassRecord(descriptor: ClassDescriptor, defaultImpls: Boolean): ClassDescriptor? {
|
||||
if (defaultImpls) {
|
||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||
val classDescriptorImpl = ClassDescriptorImpl(
|
||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE,
|
||||
/* isExternal = */ false)
|
||||
|
||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||
return classDescriptorImpl
|
||||
}
|
||||
else {
|
||||
return if (DescriptorUtils.isTopLevelDeclaration(descriptor)) null else descriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,20 +22,14 @@ import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import java.util.*
|
||||
|
||||
class InterfaceImplBodyCodegen(
|
||||
aClass: KtPureClassOrObject,
|
||||
@@ -47,12 +41,14 @@ class InterfaceImplBodyCodegen(
|
||||
private var isAnythingGenerated: Boolean = false
|
||||
get() = (v as InterfaceImplClassBuilder).isAnythingGenerated
|
||||
|
||||
private val defaultImplType = typeMapper.mapDefaultImpls(descriptor)
|
||||
|
||||
override fun generateDeclaration() {
|
||||
val codegenFlags = ACC_PUBLIC or ACC_FINAL or ACC_SUPER
|
||||
val flags = if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) codegenFlags or ACC_STATIC else codegenFlags
|
||||
v.defineClass(
|
||||
myClass.psiOrParent, state.classFileVersion, flags,
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
defaultImplType.internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
v.visitSource(myClass.containingKtFile.name, null)
|
||||
@@ -60,14 +56,7 @@ class InterfaceImplBodyCodegen(
|
||||
|
||||
override fun classForInnerClassRecord(): ClassDescriptor? {
|
||||
if (!isAnythingGenerated) return null
|
||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||
val classDescriptorImpl = ClassDescriptorImpl(
|
||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE,
|
||||
/* isExternal = */ false)
|
||||
|
||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||
return classDescriptorImpl
|
||||
return InnerClassConsumer.classForInnerClassRecord(descriptor, true)
|
||||
}
|
||||
|
||||
override fun generateSyntheticPartsAfterBody() {
|
||||
@@ -161,7 +150,7 @@ class InterfaceImplBodyCodegen(
|
||||
override fun done() {
|
||||
super.done()
|
||||
if (!isAnythingGenerated) {
|
||||
state.factory.removeClasses(setOf(typeMapper.mapDefaultImpls(descriptor).internalName))
|
||||
state.factory.removeClasses(setOf(defaultImplType.internalName))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,4 +179,8 @@ class InterfaceImplBodyCodegen(
|
||||
return super.newMethod(origin, access, name, desc, signature, exceptions)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateSyntheticPartsBeforeBody() {
|
||||
generatePropertyMetadataArrayFieldIfNeeded(defaultImplType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
class JvmStaticInCompanionObjectGenerator(
|
||||
val descriptor: FunctionDescriptor,
|
||||
val declarationOrigin: JvmDeclarationOrigin,
|
||||
val state: GenerationState,
|
||||
private val descriptor: FunctionDescriptor,
|
||||
private val declarationOrigin: JvmDeclarationOrigin,
|
||||
private val state: GenerationState,
|
||||
parentBodyCodegen: ImplementationBodyCodegen
|
||||
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
|
||||
private val typeMapper = state.typeMapper
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import kotlin.collections.SetsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
@@ -66,13 +66,13 @@ public class KotlinCodegenFacade {
|
||||
}
|
||||
|
||||
Set<FqName> obsoleteMultifileClasses = new HashSet<>(state.getObsoleteMultifileClasses());
|
||||
for (FqName multifileClassFqName : Sets.union(filesInMultifileClasses.keySet(), obsoleteMultifileClasses)) {
|
||||
for (FqName multifileClassFqName : SetsKt.plus(filesInMultifileClasses.keySet(), obsoleteMultifileClasses)) {
|
||||
doCheckCancelled(state);
|
||||
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler);
|
||||
}
|
||||
|
||||
Set<FqName> packagesWithObsoleteParts = new HashSet<>(state.getPackagesWithObsoleteParts());
|
||||
for (FqName packageFqName : Sets.union(packagesWithObsoleteParts, filesInPackages.keySet())) {
|
||||
for (FqName packageFqName : SetsKt.plus(packagesWithObsoleteParts, filesInPackages.keySet())) {
|
||||
doCheckCancelled(state);
|
||||
generatePackage(state, packageFqName, filesInPackages.get(packageFqName), errorHandler);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClasses;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
@@ -50,7 +49,6 @@ import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
@@ -344,12 +342,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
parentCodegen.innerClasses.add(classDescriptor);
|
||||
}
|
||||
|
||||
for (MemberCodegen<?> codegen = this; codegen != null; codegen = codegen.getParentCodegen()) {
|
||||
ClassDescriptor outerClass = codegen.classForInnerClassRecord();
|
||||
if (outerClass != null) {
|
||||
innerClasses.add(outerClass);
|
||||
}
|
||||
}
|
||||
addParentsToInnerClassesIfNeeded(innerClasses);
|
||||
}
|
||||
|
||||
for (ClassDescriptor innerClass : innerClasses) {
|
||||
@@ -357,6 +350,18 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
}
|
||||
}
|
||||
|
||||
protected void addParentsToInnerClassesIfNeeded(@NotNull Collection<ClassDescriptor> innerClasses) {
|
||||
ClassDescriptor outerClass = classForInnerClassRecord();
|
||||
if (outerClass != null) {
|
||||
innerClasses.add(outerClass);
|
||||
}
|
||||
|
||||
MemberCodegen<?> parentCodegen = getParentCodegen();
|
||||
if (parentCodegen != null) {
|
||||
parentCodegen.addParentsToInnerClassesIfNeeded(innerClasses);
|
||||
}
|
||||
}
|
||||
|
||||
// It's necessary for proper recovering of classId by plain string JVM descriptor when loading annotations
|
||||
// See FileBasedKotlinClass.convertAnnotationVisitor
|
||||
@Override
|
||||
@@ -511,7 +516,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public void beforeMethodBody(@NotNull MethodVisitor mv) {
|
||||
}
|
||||
|
||||
private void initializeProperty(@NotNull ExpressionCodegen codegen, @NotNull KtProperty property) {
|
||||
// Requires public access, because it is used by serialization plugin to generate initializer in synthetic constructor
|
||||
public void initializeProperty(@NotNull ExpressionCodegen codegen, @NotNull KtProperty property) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
||||
assert propertyDescriptor != null;
|
||||
|
||||
@@ -536,7 +542,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
propValue.store(delegateValue, codegen.v);
|
||||
}
|
||||
|
||||
protected boolean shouldInitializeProperty(@NotNull KtProperty property) {
|
||||
// Public accessible for serialization plugin to check whether call to initializeProperty(..) is legal.
|
||||
public boolean shouldInitializeProperty(@NotNull KtProperty property) {
|
||||
if (!property.hasDelegateExpressionOrInitializer()) return false;
|
||||
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(VARIABLE, property);
|
||||
|
||||
@@ -62,7 +62,7 @@ class PropertyReferenceCodegen(
|
||||
|
||||
private val isLocalDelegatedProperty = target is LocalVariableDescriptor
|
||||
|
||||
val getFunction =
|
||||
private val getFunction =
|
||||
if (isLocalDelegatedProperty)
|
||||
(localVariableDescriptorForReference as VariableDescriptorWithAccessors).getter!!
|
||||
else
|
||||
@@ -250,13 +250,13 @@ class PropertyReferenceCodegen(
|
||||
|
||||
class PropertyReferenceGenerationStrategy(
|
||||
val isGetter: Boolean,
|
||||
val originalFunctionDesc: FunctionDescriptor,
|
||||
private val originalFunctionDesc: FunctionDescriptor,
|
||||
val target: VariableDescriptor,
|
||||
val asmType: Type,
|
||||
val receiverType: Type?,
|
||||
val expression: KtElement,
|
||||
state: GenerationState,
|
||||
val isInliningStrategy: Boolean
|
||||
private val isInliningStrategy: Boolean
|
||||
) :
|
||||
FunctionGenerationStrategy.CodegenBased(state) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
|
||||
@@ -178,7 +178,7 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
public static StackValue createDefaulValue(@NotNull Type type) {
|
||||
public static StackValue createDefaultValue(@NotNull Type type) {
|
||||
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
||||
return constant(null, type);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class CoercionValue(
|
||||
val value: StackValue,
|
||||
val castType: Type
|
||||
private val castType: Type
|
||||
) : StackValue(castType, value.canHaveSideEffects()) {
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClasses;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
@@ -56,6 +57,7 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.NullValue;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
@@ -82,7 +84,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
private final JvmRuntimeTypes runtimeTypes;
|
||||
private final JvmFileClassesProvider fileClassesProvider;
|
||||
private final TypeMappingConfiguration<Type> typeMappingConfiguration;
|
||||
private final boolean shouldInlineConstVals;
|
||||
private final SwitchCodegenProvider switchCodegenProvider;
|
||||
|
||||
public CodegenAnnotatingVisitor(@NotNull GenerationState state) {
|
||||
this.bindingTrace = state.getBindingTrace();
|
||||
@@ -91,7 +93,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
this.runtimeTypes = state.getJvmRuntimeTypes();
|
||||
this.fileClassesProvider = state.getFileClassesProvider();
|
||||
this.typeMappingConfiguration = state.getTypeMapper().getTypeMappingConfiguration();
|
||||
this.shouldInlineConstVals = state.getShouldInlineConstVals();
|
||||
this.switchCodegenProvider = new SwitchCodegenProvider(state);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -439,9 +441,15 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
// The first "real" containing class (not a synthetic class for lambda) is the owner of the delegated property metadata
|
||||
if (!(descriptor instanceof SyntheticClassDescriptorForLambda)) {
|
||||
ClassId classId = DescriptorUtilsKt.getClassId(descriptor);
|
||||
return classId != null
|
||||
? AsmUtil.asmTypeByClassId(classId)
|
||||
: CodegenBinding.getAsmType(bindingContext, descriptor);
|
||||
if (classId == null) {
|
||||
return CodegenBinding.getAsmType(bindingContext, descriptor);
|
||||
}
|
||||
|
||||
return AsmUtil.asmTypeByClassId(
|
||||
DescriptorUtils.isInterface(descriptor)
|
||||
? classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME))
|
||||
: classId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,6 +567,9 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
if (valueArguments == null) return;
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : original.getValueParameters()) {
|
||||
ValueParameterDescriptor adaptedParameter = descriptor.getValueParameters().get(valueParameter.getIndex());
|
||||
if (KotlinTypeChecker.DEFAULT.equalTypes(adaptedParameter.getType(), valueParameter.getType())) continue;
|
||||
|
||||
SamType samType = SamType.create(TypeMapperUtilsKt.removeExternalProjections(valueParameter.getType()));
|
||||
if (samType == null) continue;
|
||||
|
||||
@@ -678,7 +689,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
WhenByEnumsMapping mapping = new WhenByEnumsMapping(classDescriptor, currentClassName, fieldNumber);
|
||||
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext, shouldInlineConstVals)) {
|
||||
for (ConstantValue<?> constant : switchCodegenProvider.getAllConstants(expression)) {
|
||||
if (constant instanceof NullValue) continue;
|
||||
|
||||
assert constant instanceof EnumValue : "expression in when should be EnumValue";
|
||||
@@ -692,10 +703,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
private boolean isWhenWithEnums(@NotNull KtWhenExpression expression) {
|
||||
return WhenChecker.isWhenByEnum(expression, bindingContext) &&
|
||||
SwitchCodegenUtil.checkAllItemsAreConstantsSatisfying(
|
||||
switchCodegenProvider.checkAllItemsAreConstantsSatisfying(
|
||||
expression,
|
||||
bindingContext,
|
||||
shouldInlineConstVals,
|
||||
constant -> constant instanceof EnumValue || constant instanceof NullValue
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -574,7 +574,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
if (descriptorContext == null &&
|
||||
JavaVisibilities.PROTECTED_STATIC_VISIBILITY == descriptor.getVisibility() &&
|
||||
!(descriptor instanceof SamConstructorDescriptor)) {
|
||||
(!(descriptor.getOriginal() instanceof SamConstructorDescriptor))) {
|
||||
//seems we need static receiver in resolved call
|
||||
descriptorContext = ExpressionCodegen.getParentContextSubclassOf((ClassDescriptor) enclosed, this);
|
||||
superCallTarget = (ClassDescriptor) enclosed;
|
||||
|
||||
@@ -28,12 +28,10 @@ class DefaultImplsClassContext(
|
||||
contextKind: OwnerKind,
|
||||
parentContext: CodegenContext<*>?,
|
||||
localLookup: ((DeclarationDescriptor) -> Boolean)?,
|
||||
val interfaceContext: ClassContext
|
||||
private val interfaceContext: ClassContext
|
||||
) : ClassContext(typeMapper, contextDescriptor, contextKind, parentContext, localLookup) {
|
||||
|
||||
override fun getCompanionObjectContext(): CodegenContext<*>? {
|
||||
return interfaceContext.companionObjectContext
|
||||
}
|
||||
override fun getCompanionObjectContext(): CodegenContext<*>? = interfaceContext.companionObjectContext
|
||||
|
||||
override fun getAccessors(): Collection<AccessorForCallableDescriptor<*>> {
|
||||
val accessors = super.getAccessors()
|
||||
|
||||
@@ -25,8 +25,8 @@ class InlineLambdaContext(
|
||||
contextKind: OwnerKind,
|
||||
parentContext: CodegenContext<*>,
|
||||
closure: MutableClosure?,
|
||||
val isCrossInline: Boolean,
|
||||
val isPropertyReference: Boolean
|
||||
private val isCrossInline: Boolean,
|
||||
private val isPropertyReference: Boolean
|
||||
) : MethodContext(functionDescriptor, contextKind, parentContext, closure, false) {
|
||||
|
||||
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -103,7 +104,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||
return replacedFunctionCall.copy(
|
||||
VariableAsFunctionResolvedCallImpl(
|
||||
replacedFunctionCall.resolvedCall as MutableResolvedCall<FunctionDescriptor>,
|
||||
variableCall as MutableResolvedCall<VariableDescriptor>
|
||||
variableCall.asMutableResolvedCall(bindingContext)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -148,6 +149,24 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||
return ResolvedCallWithRealDescriptor(newCall, thisExpression)
|
||||
}
|
||||
|
||||
private fun ResolvedCall<VariableDescriptor>.asMutableResolvedCall(bindingContext: BindingContext): MutableResolvedCall<VariableDescriptor> {
|
||||
return when (this) {
|
||||
is ResolvedCallImpl<*> -> this as MutableResolvedCall<VariableDescriptor>
|
||||
is NewResolvedCallImpl<*> -> (this as NewResolvedCallImpl<VariableDescriptor>).asDummyOldResolvedCall(bindingContext)
|
||||
else -> throw IllegalStateException("No mutable resolved call for $this")
|
||||
}
|
||||
}
|
||||
|
||||
private fun NewResolvedCallImpl<VariableDescriptor>.asDummyOldResolvedCall(bindingContext: BindingContext): ResolvedCallImpl<VariableDescriptor> {
|
||||
return ResolvedCallImpl(
|
||||
call,
|
||||
candidateDescriptor,
|
||||
dispatchReceiver, extensionReceiver, explicitReceiverKind,
|
||||
null, DelegatingBindingTrace(bindingContext, "Trace for old call"),
|
||||
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
|
||||
)
|
||||
}
|
||||
|
||||
fun ResolvedCall<*>.isSuspendNoInlineCall() =
|
||||
resultingDescriptor.safeAs<FunctionDescriptor>()
|
||||
?.let {
|
||||
|
||||
@@ -253,18 +253,15 @@ class AnonymousObjectTransformer(
|
||||
val newFieldsWithSkipped = getNewFieldsToGenerate(allCapturedBuilder.listCaptured())
|
||||
val fieldInfoWithSkipped = transformToFieldInfo(Type.getObjectType(transformationInfo.newClassName), newFieldsWithSkipped)
|
||||
|
||||
var paramIndex = 0
|
||||
val capturedFieldInitializer = InstructionAdapter(constructorVisitor)
|
||||
for (i in fieldInfoWithSkipped.indices) {
|
||||
val fieldInfo = fieldInfoWithSkipped[i]
|
||||
if (!newFieldsWithSkipped[i].skip) {
|
||||
fieldInfoWithSkipped.forEachIndexed { paramIndex, fieldInfo ->
|
||||
if (!newFieldsWithSkipped[paramIndex].skip) {
|
||||
AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], capturedFieldInitializer)
|
||||
}
|
||||
paramIndex++
|
||||
}
|
||||
|
||||
//then transform constructor
|
||||
//HACK: in inlinining into constructor we access original captured fields with field access not local var
|
||||
//HACK: in inlining into constructor we access original captured fields with field access not local var
|
||||
//but this fields added to general params (this assumes local var access) not captured one,
|
||||
//so we need to add them to captured params
|
||||
for (info in constructorAdditionalFakeParams) {
|
||||
@@ -288,7 +285,7 @@ class AnonymousObjectTransformer(
|
||||
removeFinallyMarkers(intermediateMethodNode)
|
||||
|
||||
val first = intermediateMethodNode.instructions.first
|
||||
val oldStartLabel = if (first is LabelNode) first.label else null
|
||||
val oldStartLabel = (first as? LabelNode)?.label
|
||||
intermediateMethodNode.accept(object : MethodBodyVisitor(capturedFieldInitializer) {
|
||||
override fun visitLocalVariable(
|
||||
name: String, desc: String, signature: String?, start: Label, end: Label, index: Int
|
||||
@@ -444,16 +441,10 @@ class AnonymousObjectTransformer(
|
||||
}
|
||||
|
||||
private fun shouldRenameThis0(parentFieldRemapper: FieldRemapper, values: Collection<LambdaInfo>): Boolean {
|
||||
if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
||||
for (value in values) {
|
||||
for (desc in value.capturedVars) {
|
||||
if (isThis0(desc.fieldName)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
||||
values.any { it.capturedVars.any { isThis0(it.fieldName) }}
|
||||
}
|
||||
return false
|
||||
else false
|
||||
}
|
||||
|
||||
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
|
||||
@@ -470,14 +461,13 @@ class AnonymousObjectTransformer(
|
||||
}
|
||||
|
||||
private fun addUniqueField(name: String): String {
|
||||
val existNames = fieldNames.getOrPut(name) { LinkedList<String>() }
|
||||
val existNames = fieldNames.getOrPut(name) { LinkedList() }
|
||||
val suffix = if (existNames.isEmpty()) "" else "$" + existNames.size
|
||||
val newName = name + suffix
|
||||
existNames.add(newName)
|
||||
return newName
|
||||
}
|
||||
|
||||
private fun isFirstDeclSiteLambdaFieldRemapper(parentRemapper: FieldRemapper): Boolean {
|
||||
return parentRemapper !is RegeneratedLambdaFieldRemapper && parentRemapper !is InlinedLambdaRemapper
|
||||
}
|
||||
private fun isFirstDeclSiteLambdaFieldRemapper(parentRemapper: FieldRemapper): Boolean =
|
||||
parentRemapper !is RegeneratedLambdaFieldRemapper && parentRemapper !is InlinedLambdaRemapper
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ class IntervalMetaInfo<T : SplittableInterval<T>> {
|
||||
return splitPair
|
||||
}
|
||||
|
||||
fun getInterval(curIns: LabelNode, isOpen: Boolean) =
|
||||
private fun getInterval(curIns: LabelNode, isOpen: Boolean) =
|
||||
if (isOpen) intervalStarts.get(curIns) else intervalEnds.get(curIns)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
class DeferredMethodVisitor(
|
||||
val intermediate: MethodNode,
|
||||
val resultNode: () -> MethodVisitor
|
||||
private val resultNode: () -> MethodVisitor
|
||||
) : MethodVisitor(API, intermediate) {
|
||||
|
||||
override fun visitEnd() {
|
||||
|
||||
@@ -107,7 +107,6 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
isSameModule = sourceCompiler.isCallInsideSameModuleAsDeclared(functionDescriptor)
|
||||
|
||||
if (functionDescriptor !is FictitiousArrayConstructor) {
|
||||
reportIncrementalInfo(functionDescriptor, sourceCompiler.compilationContextFunctionDescriptor.original, jvmSignature, state)
|
||||
val functionOrAccessorName = typeMapper.mapAsmMethod(function).name
|
||||
//track changes for property accessor and @JvmName inline functions/property accessors
|
||||
if (functionOrAccessorName != functionDescriptor.name.asString()) {
|
||||
@@ -460,7 +459,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
if (isBuiltInArrayIntrinsic(callableDescriptor)) {
|
||||
val classId = classId
|
||||
val bytes = state.inlineCache.classBytes.getOrPut(classId) { bytecode }
|
||||
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString())
|
||||
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(classId))
|
||||
}
|
||||
|
||||
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
|
||||
@@ -474,7 +473,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
throw IllegalStateException("Couldn't find declaration file for " + containerId)
|
||||
}
|
||||
|
||||
val methodNode = getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString()) ?: return null
|
||||
val methodNode = getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(containerId)) ?: return null
|
||||
|
||||
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
|
||||
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
|
||||
@@ -530,7 +529,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
val varDescriptor = field.descriptor
|
||||
//check that variable is inline function parameter
|
||||
return !(varDescriptor is ParameterDescriptor &&
|
||||
InlineUtil.isInlineLambdaParameter(varDescriptor) &&
|
||||
InlineUtil.isInlineParameter(varDescriptor) &&
|
||||
InlineUtil.isInline(varDescriptor.containingDeclaration))
|
||||
}
|
||||
|
||||
@@ -561,19 +560,6 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
fun createNestedSourceMapper(nodeAndSmap: SMAPAndMethodNode, parent: SourceMapper): SourceMapper {
|
||||
return NestedSourceMapper(parent, nodeAndSmap.sortedRanges, nodeAndSmap.classSMAP.sourceInfo)
|
||||
}
|
||||
|
||||
internal fun reportIncrementalInfo(
|
||||
sourceDescriptor: FunctionDescriptor,
|
||||
targetDescriptor: FunctionDescriptor,
|
||||
jvmSignature: JvmMethodSignature,
|
||||
state: GenerationState
|
||||
) {
|
||||
val incrementalCache = state.incrementalCacheForThisTarget ?: return
|
||||
val classFilePath = sourceDescriptor.getClassFilePath(state.typeMapper, incrementalCache)
|
||||
val sourceFilePath = targetDescriptor.sourceFilePath
|
||||
val method = jvmSignature.asmMethod
|
||||
incrementalCache.registerInline(classFilePath, method.name + method.descriptor, sourceFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,7 +631,7 @@ class PsiInlineCodegen(
|
||||
//TODO deparenthisise typed
|
||||
val deparenthesized = KtPsiUtil.deparenthesize(expression)
|
||||
|
||||
return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized)
|
||||
return InlineUtil.isInlineParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized)
|
||||
}
|
||||
|
||||
override fun genValueAndPut(
|
||||
|
||||
@@ -61,8 +61,6 @@ class InlineCodegenForDefaultBody(
|
||||
sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor)
|
||||
jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompilerForInline.contextKind)
|
||||
|
||||
InlineCodegen.reportIncrementalInfo(functionDescriptor, codegen.context.functionDescriptor.original, jvmSignature, state)
|
||||
|
||||
//InlineCodegenForDefaultBody created just after visitCode call
|
||||
codegen.v.visitLabel(methodStartLabel)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class InlinedLambdaRemapper(
|
||||
originalLambdaInternalName: String,
|
||||
parent: FieldRemapper,
|
||||
methodParams: Parameters,
|
||||
val isDefaultBoundCallableReference: Boolean
|
||||
private val isDefaultBoundCallableReference: Boolean
|
||||
) : FieldRemapper(originalLambdaInternalName, parent, methodParams) {
|
||||
|
||||
public override fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean) =
|
||||
|
||||
@@ -84,7 +84,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : LabelOwner {
|
||||
|
||||
class DefaultLambda(
|
||||
override val lambdaClassType: Type,
|
||||
val capturedArgs: Array<Type>,
|
||||
private val capturedArgs: Array<Type>,
|
||||
val parameterDescriptor: ValueParameterDescriptor,
|
||||
val offset: Int,
|
||||
val needReification: Boolean
|
||||
@@ -135,7 +135,7 @@ class DefaultLambda(
|
||||
classReader.b,
|
||||
"<init>",
|
||||
descriptor,
|
||||
lambdaClassType.internalName)?.node
|
||||
lambdaClassType)?.node
|
||||
|
||||
assert(constructor != null || capturedArgs.isEmpty()) {
|
||||
"Can't find non-default constructor <init>$descriptor for default lambda $lambdaClassType"
|
||||
@@ -164,7 +164,7 @@ class DefaultLambda(
|
||||
classReader.b,
|
||||
invokeMethod.name,
|
||||
invokeMethod.descriptor,
|
||||
lambdaClassType.internalName)!!
|
||||
lambdaClassType)!!
|
||||
|
||||
if (needReification) {
|
||||
//nested classes could also require reification
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Attribute;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.TypePath;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API;
|
||||
|
||||
public class MethodBodyVisitor extends InstructionAdapter {
|
||||
|
||||
public MethodBodyVisitor(MethodVisitor mv) {
|
||||
super(API, mv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParameter(String name, int access) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAttribute(@NotNull Attribute attr) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCode() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMaxs(int maxStack, int maxLocals) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Attribute
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.TypePath
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
open class MethodBodyVisitor(mv: MethodVisitor, private val visitAnnotationsAndAttributes: Boolean = false) : InstructionAdapter(API, mv) {
|
||||
|
||||
override fun visitParameter(name: String, access: Int) {
|
||||
if (visitAnnotationsAndAttributes) super.visitParameter(name, access)
|
||||
}
|
||||
|
||||
override fun visitAnnotationDefault(): AnnotationVisitor? =
|
||||
if (visitAnnotationsAndAttributes) super.visitAnnotationDefault() else null
|
||||
|
||||
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? =
|
||||
if (visitAnnotationsAndAttributes) super.visitAnnotation(desc, visible) else null
|
||||
|
||||
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath, desc: String, visible: Boolean): AnnotationVisitor? =
|
||||
if (visitAnnotationsAndAttributes) super.visitTypeAnnotation(typeRef, typePath, desc, visible) else null
|
||||
|
||||
override fun visitParameterAnnotation(parameter: Int, desc: String, visible: Boolean): AnnotationVisitor? =
|
||||
if (visitAnnotationsAndAttributes) super.visitParameterAnnotation(parameter, desc, visible) else null
|
||||
|
||||
override fun visitAttribute(attr: Attribute) {
|
||||
if (visitAnnotationsAndAttributes) super.visitAttribute(attr)
|
||||
}
|
||||
|
||||
override fun visitCode() {
|
||||
if (visitAnnotationsAndAttributes) super.visitCode()
|
||||
}
|
||||
|
||||
override fun visitMaxs(maxStack: Int, maxLocals: Int) {}
|
||||
|
||||
override fun visitEnd() {}
|
||||
}
|
||||
@@ -90,7 +90,11 @@ class MethodInliner(
|
||||
API, transformedNode.access, transformedNode.name, transformedNode.desc,
|
||||
transformedNode.signature, transformedNode.exceptions?.toTypedArray()
|
||||
)
|
||||
val visitor = RemapVisitor(resultNode, remapper, nodeRemapper)
|
||||
val visitor = RemapVisitor(
|
||||
resultNode, remapper, nodeRemapper,
|
||||
/*copy annotation and attributes*/
|
||||
nodeRemapper is RegeneratedLambdaFieldRemapper
|
||||
)
|
||||
try {
|
||||
transformedNode.accept(visitor)
|
||||
}
|
||||
@@ -109,7 +113,7 @@ class MethodInliner(
|
||||
|
||||
processReturns(resultNode, labelOwner, remapReturn, end)
|
||||
//flush transformed node to output
|
||||
resultNode.accept(MethodBodyVisitor(adapter))
|
||||
resultNode.accept(MethodBodyVisitor(adapter, true))
|
||||
|
||||
sourceMapper.endMapping()
|
||||
return result
|
||||
|
||||
@@ -53,7 +53,7 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
|
||||
|
||||
class WhenMappingTransformer(
|
||||
whenObjectRegenerationInfo: WhenMappingTransformationInfo,
|
||||
val inliningContext: InliningContext
|
||||
private val inliningContext: InliningContext
|
||||
) : ObjectTransformer<WhenMappingTransformationInfo>(whenObjectRegenerationInfo, inliningContext.state) {
|
||||
|
||||
override fun doTransform(parentRemapper: FieldRemapper): InlineResult {
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||
import org.jetbrains.kotlin.codegen.generateAsCast
|
||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||
import org.jetbrains.kotlin.codegen.optimization.removeNodeGetNext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -34,7 +32,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
class ReificationArgument(
|
||||
val parameterName: String, val nullable: Boolean, val arrayDepth: Int
|
||||
val parameterName: String, val nullable: Boolean, private val arrayDepth: Int
|
||||
) {
|
||||
fun asString() = "[".repeat(arrayDepth) + parameterName + (if (nullable) "?" else "")
|
||||
fun combine(replacement: ReificationArgument) =
|
||||
@@ -302,7 +300,7 @@ class TypeParameterMapping(
|
||||
)
|
||||
|
||||
class ReifiedTypeParametersUsages {
|
||||
val usedTypeParameters: MutableSet<String> = hashSetOf()
|
||||
private val usedTypeParameters: MutableSet<String> = hashSetOf()
|
||||
|
||||
fun wereUsedReifiedParameters(): Boolean = usedTypeParameters.isNotEmpty()
|
||||
|
||||
|
||||
@@ -34,9 +34,10 @@ public class RemapVisitor extends MethodBodyVisitor {
|
||||
public RemapVisitor(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull LocalVarRemapper remapper,
|
||||
@NotNull FieldRemapper nodeRemapper
|
||||
@NotNull FieldRemapper nodeRemapper,
|
||||
boolean copyAnnotationsAndAttributes
|
||||
) {
|
||||
super(mv);
|
||||
super(mv, copyAnnotationsAndAttributes);
|
||||
this.instructionAdapter = new InstructionAdapter(mv);
|
||||
this.remapper = remapper;
|
||||
this.nodeRemapper = nodeRemapper;
|
||||
|
||||
@@ -28,7 +28,7 @@ val KOTLIN_DEBUG_STRATA_NAME = "KotlinDebug"
|
||||
class SMAPBuilder(
|
||||
val source: String,
|
||||
val path: String,
|
||||
val fileMappings: List<FileMapping>
|
||||
private val fileMappings: List<FileMapping>
|
||||
) {
|
||||
private val header = "SMAP\n$source\nKotlin"
|
||||
|
||||
@@ -91,9 +91,9 @@ open class NestedSourceMapper(
|
||||
override val parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
|
||||
) : DefaultSourceMapper(sourceInfo) {
|
||||
|
||||
val visitedLines = TIntIntHashMap()
|
||||
private val visitedLines = TIntIntHashMap()
|
||||
|
||||
var lastVisitedRange: RangeMapping? = null
|
||||
private var lastVisitedRange: RangeMapping? = null
|
||||
|
||||
override fun mapLineNumber(lineNumber: Int): Int {
|
||||
val mappedLineNumber = visitedLines.get(lineNumber)
|
||||
@@ -115,7 +115,7 @@ open class NestedSourceMapper(
|
||||
}
|
||||
}
|
||||
|
||||
fun findMappingIfExists(lineNumber: Int): RangeMapping? {
|
||||
private fun findMappingIfExists(lineNumber: Int): RangeMapping? {
|
||||
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator {
|
||||
value, key ->
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
@@ -94,6 +95,8 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
|
||||
private var context by Delegates.notNull<CodegenContext<*>>()
|
||||
|
||||
private var additionalInnerClasses = mutableListOf<ClassDescriptor>()
|
||||
|
||||
override val lookupLocation = KotlinLookupLocation(callElement)
|
||||
|
||||
|
||||
@@ -164,7 +167,9 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
if (isLambda)
|
||||
codegen.parentCodegen.className
|
||||
else
|
||||
state.typeMapper.mapImplementationOwner(descriptor).internalName
|
||||
state.typeMapper.mapImplementationOwner(descriptor).internalName,
|
||||
if (isLambda) emptyList() else additionalInnerClasses,
|
||||
isLambda
|
||||
)
|
||||
|
||||
val strategy = when (expression) {
|
||||
@@ -222,7 +227,9 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
internal val delegate: MemberCodegen<*>,
|
||||
declaration: KtElement,
|
||||
codegenContext: FieldOwnerContext<*>,
|
||||
private val className: String
|
||||
private val className: String,
|
||||
private val parentAsInnerClasses: List<ClassDescriptor>,
|
||||
private val isInlineLambdaCodegen: Boolean
|
||||
) : MemberCodegen<KtPureElement>(delegate as MemberCodegen<KtPureElement>, declaration, codegenContext) {
|
||||
|
||||
override fun generateDeclaration() {
|
||||
@@ -246,6 +253,14 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
return className
|
||||
}
|
||||
|
||||
override fun addParentsToInnerClassesIfNeeded(innerClasses: MutableCollection<ClassDescriptor>) {
|
||||
if (isInlineLambdaCodegen) {
|
||||
super.addParentsToInnerClassesIfNeeded(innerClasses)
|
||||
}
|
||||
else {
|
||||
innerClasses.addAll(parentAsInnerClasses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun doCreateMethodNodeFromSource(
|
||||
@@ -278,7 +293,9 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
val implementationOwner = state.typeMapper.mapImplementationOwner(callableDescriptor)
|
||||
val parentCodegen = FakeMemberCodegen(
|
||||
codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>,
|
||||
implementationOwner.internalName
|
||||
implementationOwner.internalName,
|
||||
additionalInnerClasses,
|
||||
false
|
||||
)
|
||||
if (element !is KtNamedFunction) {
|
||||
throw IllegalStateException("Property accessors with default parameters not supported " + callableDescriptor)
|
||||
@@ -389,22 +406,25 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
}
|
||||
|
||||
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
||||
context = getContext(functionDescriptor, state, DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile)
|
||||
context = getContext(functionDescriptor, functionDescriptor, state, DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile, additionalInnerClasses)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getContext(
|
||||
descriptor: DeclarationDescriptor, state: GenerationState, sourceFile: KtFile?
|
||||
descriptor: DeclarationDescriptor, innerDescriptor: DeclarationDescriptor, state: GenerationState, sourceFile: KtFile?, additionalInners: MutableList<ClassDescriptor>
|
||||
): CodegenContext<*> {
|
||||
if (descriptor is PackageFragmentDescriptor) {
|
||||
//no inners
|
||||
return PackageContext(descriptor, state.rootContext, null, sourceFile)
|
||||
}
|
||||
|
||||
val container = descriptor.containingDeclaration ?: error("No container for descriptor: " + descriptor)
|
||||
val parent = getContext(
|
||||
container,
|
||||
descriptor,
|
||||
state,
|
||||
sourceFile
|
||||
sourceFile,
|
||||
additionalInners
|
||||
)
|
||||
|
||||
return when (descriptor) {
|
||||
@@ -417,7 +437,14 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
)
|
||||
}
|
||||
is ClassDescriptor -> {
|
||||
val kind = if (DescriptorUtils.isInterface(descriptor)) OwnerKind.DEFAULT_IMPLS else OwnerKind.IMPLEMENTATION
|
||||
val kind =
|
||||
if (DescriptorUtils.isInterface(descriptor) && innerDescriptor !is ClassDescriptor)
|
||||
OwnerKind.DEFAULT_IMPLS
|
||||
else OwnerKind.IMPLEMENTATION
|
||||
|
||||
additionalInners.addIfNotNull(
|
||||
InnerClassConsumer.classForInnerClassRecord(descriptor, kind == OwnerKind.DEFAULT_IMPLS)
|
||||
)
|
||||
parent.intoClass(descriptor, kind, state)
|
||||
}
|
||||
is FunctionDescriptor -> {
|
||||
|
||||
@@ -40,7 +40,7 @@ interface TransformationInfo {
|
||||
class WhenMappingTransformationInfo(
|
||||
override val oldClassName: String,
|
||||
parentNameGenerator: NameGenerator,
|
||||
val alreadyRegenerated: Boolean,
|
||||
private val alreadyRegenerated: Boolean,
|
||||
val fieldNode: FieldInsnNode
|
||||
) : TransformationInfo {
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class TypeParameter(val oldName: String, val newName: String?, val isReified: Bo
|
||||
class TypeRemapper private constructor(
|
||||
private val typeMapping: MutableMap<String, String>,
|
||||
val parent: TypeRemapper? = null,
|
||||
val isRootInlineLambda: Boolean = false
|
||||
private val isRootInlineLambda: Boolean = false
|
||||
) {
|
||||
private val additionalMappings = hashMapOf<String, String>()
|
||||
private val typeParametersMapping = hashMapOf<String, TypeParameter>()
|
||||
|
||||
@@ -51,7 +51,7 @@ fun extractDefaultLambdaOffsetAndDescriptor(jvmSignature: JvmMethodSignature, fu
|
||||
val valueParameterOffset = valueParameters.takeWhile { it.kind != JvmMethodParameterKind.VALUE }.size
|
||||
|
||||
return functionDescriptor.valueParameters.filter {
|
||||
InlineUtil.isInlineLambdaParameter(it) && it.declaresDefaultValue()
|
||||
InlineUtil.isInlineParameter(it) && it.declaresDefaultValue()
|
||||
}.associateBy {
|
||||
parameterOffsets[valueParameterOffset + it.index]
|
||||
}
|
||||
|
||||
@@ -89,12 +89,13 @@ private const val INLINE_MARKER_FINALLY_START = "finallyStart"
|
||||
private const val INLINE_MARKER_FINALLY_END = "finallyEnd"
|
||||
private const val INLINE_MARKER_BEFORE_SUSPEND_ID = 0
|
||||
private const val INLINE_MARKER_AFTER_SUSPEND_ID = 1
|
||||
private val INTRINSIC_ARRAY_CONSTRUCTOR_TYPE = AsmUtil.asmTypeByClassId(classId)
|
||||
|
||||
internal fun getMethodNode(
|
||||
classData: ByteArray,
|
||||
methodName: String,
|
||||
methodDescriptor: String,
|
||||
classInternalName: String
|
||||
classType: Type
|
||||
): SMAPAndMethodNode? {
|
||||
val cr = ClassReader(classData)
|
||||
var node: MethodNode? = null
|
||||
@@ -136,12 +137,12 @@ internal fun getMethodNode(
|
||||
return null
|
||||
}
|
||||
|
||||
if (classId.asString() == classInternalName) {
|
||||
if (INTRINSIC_ARRAY_CONSTRUCTOR_TYPE == classType) {
|
||||
// Don't load source map for intrinsic array constructors
|
||||
debugInfo[0] = null
|
||||
}
|
||||
|
||||
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classInternalName, lines[0], lines[1])
|
||||
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classType.internalName, lines[0], lines[1])
|
||||
return SMAPAndMethodNode(node!!, smap)
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ class DeadCodeEliminationMethodTransformer : MethodTransformer() {
|
||||
return true
|
||||
}
|
||||
|
||||
class Result(val removedNodes: Set<AbstractInsnNode>) {
|
||||
class Result(private val removedNodes: Set<AbstractInsnNode>) {
|
||||
fun hasRemovedAnything() = removedNodes.isNotEmpty()
|
||||
fun isRemoved(node: AbstractInsnNode) = removedNodes.contains(node)
|
||||
fun isAlive(node: AbstractInsnNode) = !isRemoved(node)
|
||||
|
||||
@@ -45,7 +45,7 @@ class CleanBoxedValue(
|
||||
}
|
||||
|
||||
|
||||
class TaintedBoxedValue(val boxedBasicValue: CleanBoxedValue) : BoxedBasicValue(boxedBasicValue.type) {
|
||||
class TaintedBoxedValue(private val boxedBasicValue: CleanBoxedValue) : BoxedBasicValue(boxedBasicValue.type) {
|
||||
override val descriptor get() = boxedBasicValue.descriptor
|
||||
|
||||
override fun taint(): BoxedBasicValue = this
|
||||
@@ -53,7 +53,7 @@ class TaintedBoxedValue(val boxedBasicValue: CleanBoxedValue) : BoxedBasicValue(
|
||||
|
||||
|
||||
class BoxedValueDescriptor(
|
||||
val boxedType: Type,
|
||||
private val boxedType: Type,
|
||||
val boxingInsn: AbstractInsnNode,
|
||||
val progressionIterator: ProgressionIteratorBasicValue?
|
||||
) {
|
||||
|
||||
@@ -67,7 +67,7 @@ open class MethodAnalyzer<V : Value>(
|
||||
protected val interpreter: Interpreter<V>
|
||||
) {
|
||||
val instructions: InsnList = method.instructions
|
||||
val nInsns: Int = instructions.size()
|
||||
private val nInsns: Int = instructions.size()
|
||||
|
||||
val frames: Array<Frame<V>?> = arrayOfNulls(nInsns)
|
||||
|
||||
@@ -146,10 +146,10 @@ open class MethodAnalyzer<V : Value>(
|
||||
|
||||
}
|
||||
catch (e: AnalyzerException) {
|
||||
throw AnalyzerException(e.node, "Error at instruction #" + insn + " ${insnNode.insnText}: " + e.message, e)
|
||||
throw AnalyzerException(e.node, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
throw AnalyzerException(insnNode, "Error at instruction #" + insn + " ${insnNode.insnText}: " + e.message, e)
|
||||
throw AnalyzerException(insnNode, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -236,7 +236,7 @@ open class MethodAnalyzer<V : Value>(
|
||||
for (tcb in m.tryCatchBlocks) {
|
||||
val begin = instructions.indexOf(tcb.start)
|
||||
val end = instructions.indexOf(tcb.end)
|
||||
for (j in begin..end - 1) {
|
||||
for (j in begin until end) {
|
||||
var insnHandlers: MutableList<TryCatchBlockNode>? = handlers[j]
|
||||
if (insnHandlers == null) {
|
||||
insnHandlers = ArrayList<TryCatchBlockNode>()
|
||||
@@ -249,15 +249,13 @@ open class MethodAnalyzer<V : Value>(
|
||||
|
||||
private fun mergeControlFlowEdge(insn: Int, frame: Frame<V>) {
|
||||
val oldFrame = frames[insn]
|
||||
val changes: Boolean
|
||||
|
||||
if (oldFrame == null) {
|
||||
frames[insn] = newFrame(frame)
|
||||
changes = true
|
||||
}
|
||||
else {
|
||||
changes = oldFrame.merge(frame, interpreter)
|
||||
}
|
||||
val changes =
|
||||
if (oldFrame != null)
|
||||
oldFrame.merge(frame, interpreter)
|
||||
else {
|
||||
frames[insn] = newFrame(frame)
|
||||
true
|
||||
}
|
||||
if (changes && !queued[insn]) {
|
||||
queued[insn] = true
|
||||
queue[top++] = insn
|
||||
|
||||
@@ -32,7 +32,8 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
|
||||
internal class FixStackAnalyzer(
|
||||
owner: String,
|
||||
val method: MethodNode,
|
||||
val context: FixStackContext
|
||||
val context: FixStackContext,
|
||||
private val skipBreakContinueGotoEdges: Boolean = true
|
||||
) {
|
||||
companion object {
|
||||
// Stack size is always non-negative
|
||||
@@ -65,17 +66,14 @@ internal class FixStackAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
private val analyzer = InternalAnalyzer(owner, method, context)
|
||||
private val analyzer = InternalAnalyzer(owner)
|
||||
|
||||
private class InternalAnalyzer(
|
||||
owner: String,
|
||||
method: MethodNode,
|
||||
val context: FixStackContext
|
||||
) : MethodAnalyzer<BasicValue>(owner, method, OptimizationBasicInterpreter()) {
|
||||
private inner class InternalAnalyzer(owner: String) : MethodAnalyzer<BasicValue>(owner, method, OptimizationBasicInterpreter()) {
|
||||
val spilledStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>()
|
||||
var maxExtraStackSize = 0; private set
|
||||
|
||||
override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean {
|
||||
if (!skipBreakContinueGotoEdges) return true
|
||||
val insnNode = instructions[insn]
|
||||
return !(insnNode is JumpInsnNode && context.breakContinueGotoNodes.contains(insnNode))
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class FixStackMethodTransformer : MethodTransformer() {
|
||||
}
|
||||
|
||||
private fun analyzeAndTransformSaveRestoreStack(context: FixStackContext, internalClassName: String, methodNode: MethodNode) {
|
||||
val analyzer = FixStackAnalyzer(internalClassName, methodNode, context)
|
||||
val analyzer = FixStackAnalyzer(internalClassName, methodNode, context, skipBreakContinueGotoEdges = false)
|
||||
analyzer.analyze()
|
||||
|
||||
val actions = arrayListOf<() -> Unit>()
|
||||
|
||||
@@ -57,7 +57,7 @@ class SavedStackDescriptor(
|
||||
val savedValues: List<BasicValue>,
|
||||
val firstLocalVarIndex: Int
|
||||
) {
|
||||
val savedValuesSize = savedValues.fold(0, { size, value -> size + value.size })
|
||||
private val savedValuesSize = savedValues.fold(0, { size, value -> size + value.size })
|
||||
val firstUnusedLocalVarIndex = firstLocalVarIndex + savedValuesSize
|
||||
|
||||
override fun toString(): String =
|
||||
|
||||
@@ -44,13 +44,14 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
private var changes = false
|
||||
|
||||
fun run(): Boolean {
|
||||
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode()
|
||||
eliminateRedundantChecks(checkedReferenceTypes)
|
||||
val stackOnThrowExceptions = hashMapOf<AbstractInsnNode, Int>()
|
||||
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode(stackOnThrowExceptions)
|
||||
eliminateRedundantChecks(checkedReferenceTypes, stackOnThrowExceptions)
|
||||
|
||||
return changes
|
||||
}
|
||||
|
||||
private fun analyzeTypesAndRemoveDeadCode(): Map<AbstractInsnNode, Type> {
|
||||
private fun analyzeTypesAndRemoveDeadCode(stackOnThrowExceptionsHolder: MutableMap<AbstractInsnNode, Int>): Map<AbstractInsnNode, Type> {
|
||||
val insns = methodNode.instructions.toArray()
|
||||
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
|
||||
|
||||
@@ -64,6 +65,9 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
else if (insn.isCheckParameterIsNotNull() || insn.isCheckExpressionValueIsNotNull()) {
|
||||
checkedReferenceTypes[insn] = frame?.peek(1)?.type ?: continue
|
||||
}
|
||||
else if (insn.isThrowNpeIntrinsic()) {
|
||||
stackOnThrowExceptionsHolder[insn] = frame?.maxStackSize ?: continue
|
||||
}
|
||||
}
|
||||
|
||||
val dceResult = DeadCodeEliminationMethodTransformer().removeDeadCodeByFrames(methodNode, frames)
|
||||
@@ -74,8 +78,11 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
return checkedReferenceTypes
|
||||
}
|
||||
|
||||
private fun eliminateRedundantChecks(checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
|
||||
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes)
|
||||
private fun eliminateRedundantChecks(
|
||||
checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||
stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||
) {
|
||||
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes, stackOnThrowExceptions)
|
||||
|
||||
val nullabilityMap = analyzeNullabilities()
|
||||
|
||||
@@ -84,8 +91,10 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
transformTrivialChecks(nullabilityMap)
|
||||
}
|
||||
|
||||
private fun injectNullabilityAssumptions(checkedReferenceTypes: Map<AbstractInsnNode, Type>) =
|
||||
NullabilityAssumptionsBuilder(checkedReferenceTypes).injectNullabilityAssumptions()
|
||||
private fun injectNullabilityAssumptions(
|
||||
checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||
stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||
) = NullabilityAssumptionsBuilder(checkedReferenceTypes, stackOnThrowExceptions).injectNullabilityAssumptions()
|
||||
|
||||
private fun analyzeNullabilities(): Map<AbstractInsnNode, StrictBasicValue> {
|
||||
val frames = analyze(internalClassName, methodNode, NullabilityInterpreter())
|
||||
@@ -168,7 +177,10 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
}
|
||||
}
|
||||
|
||||
private inner class NullabilityAssumptionsBuilder(val checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
|
||||
private inner class NullabilityAssumptionsBuilder(
|
||||
val checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||
val stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||
) {
|
||||
|
||||
private val checksDependingOnVariable = HashMap<Int, MutableList<AbstractInsnNode>>()
|
||||
|
||||
@@ -362,6 +374,8 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
athrow()
|
||||
})
|
||||
}
|
||||
|
||||
methodNode.maxStack = Math.max(methodNode.maxStack, (stackOnThrowExceptions[insn] ?: -1) + 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.codegen.optimization.transformer
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
open class CompositeMethodTransformer(vararg val transformers: MethodTransformer) : MethodTransformer() {
|
||||
open class CompositeMethodTransformer(private vararg val transformers: MethodTransformer) : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
transformers.forEach { it.transform(internalClassName, methodNode) }
|
||||
}
|
||||
|
||||
@@ -18,14 +18,33 @@ package org.jetbrains.kotlin.codegen.range
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInRangeLiteralLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInUntilConstantRangeLoopGenerator
|
||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class PrimitiveNumberRangeLiteralRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(codegen, rangeCall)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
getConstRangeForInRangeLiteralGenerator(codegen, forExpression) ?:
|
||||
ForInRangeLiteralLoopGenerator(codegen, forExpression, rangeCall)
|
||||
|
||||
private fun getConstRangeForInRangeLiteralGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator? {
|
||||
val rhsExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
||||
val constValue = codegen.getCompileTimeConstant(rhsExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
||||
val untilValue = when (constValue) {
|
||||
is ByteValue -> constValue.value + 1
|
||||
is ShortValue -> constValue.value + 1
|
||||
is IntValue -> constValue.value + 1
|
||||
else -> return null
|
||||
}
|
||||
// Watch out for integer overflow
|
||||
if (untilValue == Int.MIN_VALUE) return null
|
||||
return ForInUntilConstantRangeLoopGenerator(codegen, forExpression, rangeCall, untilValue)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.range.forLoop
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
|
||||
class ForInUntilConstantRangeLoopGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
loopRangeCall: ResolvedCall<*>,
|
||||
private val untilValue: Int
|
||||
) : AbstractForInExclusiveRangeLoopGenerator(codegen, forExpression) {
|
||||
private val from: ReceiverValue = loopRangeCall.dispatchReceiver!!
|
||||
|
||||
override fun generateFrom(): StackValue =
|
||||
codegen.generateReceiverValue(from, false)
|
||||
|
||||
override fun generateTo(): StackValue =
|
||||
StackValue.constant(untilValue, asmElementType)
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.serialization.*;
|
||||
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
||||
@@ -85,7 +86,9 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
|
||||
}
|
||||
|
||||
writeLocalProperties(proto, typeMapper.mapClass(descriptor), JvmProtoBuf.classLocalVariable);
|
||||
Type containerAsmType =
|
||||
DescriptorUtils.isInterface(descriptor) ? typeMapper.mapDefaultImpls(descriptor) : typeMapper.mapClass(descriptor);
|
||||
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -99,20 +99,6 @@ public class KotlinTypeMapper {
|
||||
private final boolean isJvm8TargetWithDefaults;
|
||||
|
||||
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
|
||||
private final Function2<String, String, String> defaultClassNameFactory
|
||||
= TypeMappingConfiguration.Companion.getDEFAULT_INNER_CLASS_NAME_FACTORY();
|
||||
|
||||
private final Function2<String, String, String> innerClassNameFactory = new Function2<String, String, String>() {
|
||||
@Override
|
||||
public String invoke(String outer, String inner) {
|
||||
if (classBuilderMode == ClassBuilderMode.KAPT3) {
|
||||
return outer + '/' + inner;
|
||||
}
|
||||
|
||||
return defaultClassNameFactory.invoke(outer, inner);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
|
||||
@@ -122,7 +108,7 @@ public class KotlinTypeMapper {
|
||||
@NotNull
|
||||
@Override
|
||||
public Function2<String, String, String> getInnerClassNameFactory() {
|
||||
return innerClassNameFactory;
|
||||
return TypeMappingConfiguration.DefaultImpls.getInnerClassNameFactory(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1474,7 +1460,7 @@ public class KotlinTypeMapper {
|
||||
while (true) {
|
||||
ResolvedCall<ConstructorDescriptor> next = getDelegationConstructorCall(bindingContext, descriptor);
|
||||
if (next == null) return null;
|
||||
descriptor = next.getResultingDescriptor();
|
||||
descriptor = next.getResultingDescriptor().getOriginal();
|
||||
if (descriptor.getContainingDeclaration() != constructorOwner) return next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ abstract public class SwitchCodegen {
|
||||
protected Label endLabel = new Label();
|
||||
protected Label defaultLabel;
|
||||
|
||||
protected final SwitchCodegenProvider switchCodegenProvider;
|
||||
|
||||
public SwitchCodegen(
|
||||
@NotNull KtWhenExpression expression, boolean isStatement,
|
||||
boolean isExhaustive, @NotNull ExpressionCodegen codegen,
|
||||
@@ -59,6 +61,7 @@ abstract public class SwitchCodegen {
|
||||
this.isExhaustive = isExhaustive;
|
||||
this.codegen = codegen;
|
||||
this.bindingContext = codegen.getBindingContext();
|
||||
this.switchCodegenProvider = new SwitchCodegenProvider(codegen);
|
||||
|
||||
this.subjectType = subjectType != null ? subjectType : codegen.expressionType(expression.getSubjectExpression());
|
||||
resultType = isStatement ? Type.VOID_TYPE : codegen.expressionType(expression);
|
||||
@@ -100,7 +103,7 @@ abstract public class SwitchCodegen {
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
Label entryLabel = new Label();
|
||||
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext, codegen.getState().getShouldInlineConstVals())) {
|
||||
for (ConstantValue<?> constant : switchCodegenProvider.getConstantsFromEntry(entry)) {
|
||||
if (constant instanceof NullValue) continue;
|
||||
processConstant(constant, entryLabel);
|
||||
}
|
||||
@@ -158,7 +161,7 @@ abstract public class SwitchCodegen {
|
||||
private int findNullEntryIndex(@NotNull KtWhenExpression expression) {
|
||||
int entryIndex = 0;
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getConstantsFromEntry(entry, bindingContext, codegen.getState().getShouldInlineConstVals())) {
|
||||
for (ConstantValue<?> constant : switchCodegenProvider.getConstantsFromEntry(entry)) {
|
||||
if (constant instanceof NullValue) {
|
||||
return entryIndex;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.`when`
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.NullValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
class SwitchCodegenProvider
|
||||
private constructor (
|
||||
private val bindingContext: BindingContext,
|
||||
private val shouldInlineConstVals: Boolean,
|
||||
private val codegen: ExpressionCodegen?
|
||||
) {
|
||||
constructor(state: GenerationState) : this(state.bindingContext, state.shouldInlineConstVals, null)
|
||||
constructor(codegen: ExpressionCodegen) : this(codegen.bindingContext, codegen.state.shouldInlineConstVals, codegen)
|
||||
|
||||
fun checkAllItemsAreConstantsSatisfying(expression: KtWhenExpression, predicate: Function1<ConstantValue<*>, Boolean>): Boolean =
|
||||
expression.entries.all { entry ->
|
||||
entry.conditions.all { condition ->
|
||||
if (condition !is KtWhenConditionWithExpression) return false
|
||||
val patternExpression = condition.expression ?: return false
|
||||
val constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext, shouldInlineConstVals) ?: return false
|
||||
predicate.invoke(constant)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllConstants(expression: KtWhenExpression): Iterable<ConstantValue<*>?> =
|
||||
ArrayList<ConstantValue<*>?>().apply {
|
||||
for (entry in expression.entries) {
|
||||
addConstantsFromConditions(entry)
|
||||
}
|
||||
}
|
||||
|
||||
fun getConstantsFromEntry(entry: KtWhenEntry): Iterable<ConstantValue<*>?> =
|
||||
ArrayList<ConstantValue<*>?>().apply {
|
||||
addConstantsFromConditions(entry)
|
||||
}
|
||||
|
||||
private fun ArrayList<ConstantValue<*>?>.addConstantsFromConditions(entry: KtWhenEntry) {
|
||||
for (condition in entry.conditions) {
|
||||
if (condition !is KtWhenConditionWithExpression) continue
|
||||
val patternExpression = condition.expression ?: throw AssertionError("expression in when should not be null")
|
||||
add(ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext, shouldInlineConstVals))
|
||||
}
|
||||
}
|
||||
|
||||
fun buildAppropriateSwitchCodegenIfPossible(
|
||||
expression: KtWhenExpression,
|
||||
isStatement: Boolean,
|
||||
isExhaustive: Boolean
|
||||
): SwitchCodegen? {
|
||||
val codegen = codegen ?: throw AssertionError("Can't create SwitchCodegen in this context")
|
||||
|
||||
if (!isThereConstantEntriesButNulls(expression)) {
|
||||
return null
|
||||
}
|
||||
|
||||
val subjectType = codegen.expressionType(expression.subjectExpression)
|
||||
|
||||
val mapping = codegen.bindingContext.get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression)
|
||||
|
||||
return when {
|
||||
mapping != null ->
|
||||
EnumSwitchCodegen(expression, isStatement, isExhaustive, codegen, mapping)
|
||||
isIntegralConstantsSwitch(expression, subjectType) ->
|
||||
IntegralConstantsSwitchCodegen(expression, isStatement, isExhaustive, codegen)
|
||||
isStringConstantsSwitch(expression, subjectType) ->
|
||||
StringSwitchCodegen(expression, isStatement, isExhaustive, codegen)
|
||||
else -> null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun isThereConstantEntriesButNulls(expression: KtWhenExpression): Boolean =
|
||||
getAllConstants(expression).any { it != null && it !is NullValue }
|
||||
|
||||
private fun isIntegralConstantsSwitch(expression: KtWhenExpression, subjectType: Type): Boolean =
|
||||
AsmUtil.isIntPrimitive(subjectType) &&
|
||||
checkAllItemsAreConstantsSatisfying(expression) { it is IntegerValueConstant<*> }
|
||||
|
||||
private fun isStringConstantsSwitch(expression: KtWhenExpression, subjectType: Type): Boolean =
|
||||
subjectType.className == String::class.java.name &&
|
||||
checkAllItemsAreConstantsSatisfying(expression) { it is StringValue || it is NullValue }
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.when;
|
||||
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.NullValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SwitchCodegenUtil {
|
||||
public static boolean checkAllItemsAreConstantsSatisfying(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals,
|
||||
Function1<ConstantValue<?>, Boolean> predicate
|
||||
) {
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
for (KtWhenCondition condition : entry.getConditions()) {
|
||||
if (!(condition instanceof KtWhenConditionWithExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ensure that expression is constant
|
||||
KtExpression patternExpression = ((KtWhenConditionWithExpression) condition).getExpression();
|
||||
|
||||
if (patternExpression == null) return false;
|
||||
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext, shouldInlineConstVals);
|
||||
if (constant == null || !predicate.invoke(constant)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Iterable<ConstantValue<?>> getAllConstants(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
List<ConstantValue<?>> result = new ArrayList<>();
|
||||
|
||||
for (KtWhenEntry entry : expression.getEntries()) {
|
||||
addConstantsFromEntry(result, entry, bindingContext, shouldInlineConstVals);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void addConstantsFromEntry(
|
||||
@NotNull List<ConstantValue<?>> result,
|
||||
@NotNull KtWhenEntry entry,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
for (KtWhenCondition condition : entry.getConditions()) {
|
||||
if (!(condition instanceof KtWhenConditionWithExpression)) continue;
|
||||
|
||||
KtExpression patternExpression = ((KtWhenConditionWithExpression) condition).getExpression();
|
||||
|
||||
assert patternExpression != null : "expression in when should not be null";
|
||||
result.add(ExpressionCodegen.getCompileTimeConstant(patternExpression, bindingContext, shouldInlineConstVals));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Iterable<ConstantValue<?>> getConstantsFromEntry(
|
||||
@NotNull KtWhenEntry entry,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
List<ConstantValue<?>> result = new ArrayList<>();
|
||||
addConstantsFromEntry(result, entry, bindingContext, shouldInlineConstVals);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SwitchCodegen buildAppropriateSwitchCodegenIfPossible(
|
||||
@NotNull KtWhenExpression expression,
|
||||
boolean isStatement,
|
||||
boolean isExhaustive,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
BindingContext bindingContext = codegen.getBindingContext();
|
||||
boolean shouldInlineConstVals = codegen.getState().getShouldInlineConstVals();
|
||||
if (!isThereConstantEntriesButNulls(expression, bindingContext, shouldInlineConstVals)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Type subjectType = codegen.expressionType(expression.getSubjectExpression());
|
||||
|
||||
WhenByEnumsMapping mapping = codegen.getBindingContext().get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression);
|
||||
|
||||
if (mapping != null) {
|
||||
return new EnumSwitchCodegen(expression, isStatement, isExhaustive, codegen, mapping);
|
||||
}
|
||||
|
||||
if (isIntegralConstantsSwitch(expression, subjectType, bindingContext, shouldInlineConstVals)) {
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
if (isStringConstantsSwitch(expression, subjectType, bindingContext, shouldInlineConstVals)) {
|
||||
return new StringSwitchCodegen(expression, isStatement, isExhaustive, codegen);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isThereConstantEntriesButNulls(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
for (ConstantValue<?> constant : getAllConstants(expression, bindingContext, shouldInlineConstVals)) {
|
||||
if (constant != null && !(constant instanceof NullValue)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isIntegralConstantsSwitch(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull Type subjectType,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
int typeSort = subjectType.getSort();
|
||||
|
||||
if (typeSort != Type.INT && typeSort != Type.CHAR && typeSort != Type.SHORT && typeSort != Type.BYTE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, shouldInlineConstVals,
|
||||
constant -> constant instanceof IntegerValueConstant);
|
||||
}
|
||||
|
||||
private static boolean isStringConstantsSwitch(
|
||||
@NotNull KtWhenExpression expression,
|
||||
@NotNull Type subjectType,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean shouldInlineConstVals
|
||||
) {
|
||||
|
||||
if (!subjectType.getClassName().equals(String.class.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return checkAllItemsAreConstantsSatisfying(expression, bindingContext, shouldInlineConstVals,
|
||||
constant -> constant instanceof StringValue || constant instanceof NullValue);
|
||||
}
|
||||
}
|
||||
@@ -14,36 +14,53 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
public abstract class CommonCompilerArguments extends CommonToolArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import java.util.*
|
||||
|
||||
public static final String PLUGIN_OPTION_FORMAT = "plugin:<pluginId>:<optionName>=<value>";
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
|
||||
@GradleOption(DefaultValues.LanguageVersions.class)
|
||||
const val PLUGIN_OPTION_FORMAT = "plugin:<pluginId>:<optionName>=<value>"
|
||||
|
||||
const val WARN = "warn"
|
||||
const val ERROR = "error"
|
||||
const val ENABLE = "enable"
|
||||
}
|
||||
|
||||
@GradleOption(DefaultValues.LanguageVersions::class)
|
||||
@Argument(
|
||||
value = "-language-version",
|
||||
valueDescription = "<version>",
|
||||
description = "Provide source compatibility with specified language version"
|
||||
)
|
||||
public String languageVersion;
|
||||
var languageVersion: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.LanguageVersions.class)
|
||||
@GradleOption(DefaultValues.LanguageVersions::class)
|
||||
@Argument(
|
||||
value = "-api-version",
|
||||
valueDescription = "<version>",
|
||||
description = "Allow to use declarations only from the specified version of bundled libraries"
|
||||
)
|
||||
public String apiVersion;
|
||||
var apiVersion: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-kotlin-home",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to Kotlin compiler home directory, used for runtime libraries discovery"
|
||||
)
|
||||
var kotlinHome: String? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-P", valueDescription = PLUGIN_OPTION_FORMAT, description = "Pass an option to a plugin")
|
||||
public String[] pluginOptions;
|
||||
var pluginOptions: Array<String>? by FreezableVar(null)
|
||||
|
||||
// Advanced options
|
||||
|
||||
@Argument(value = "-Xno-inline", description = "Disable method inlining")
|
||||
public boolean noInline;
|
||||
var noInline: Boolean by FreezableVar(false)
|
||||
|
||||
// TODO Remove in 1.0
|
||||
@Argument(
|
||||
@@ -51,44 +68,50 @@ public abstract class CommonCompilerArguments extends CommonToolArguments {
|
||||
valueDescription = "<count>",
|
||||
description = "Repeat compilation (for performance analysis)"
|
||||
)
|
||||
public String repeat;
|
||||
var repeat: String? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xskip-metadata-version-check", description = "Load classes with bad metadata version anyway (incl. pre-release classes)")
|
||||
public boolean skipMetadataVersionCheck;
|
||||
@Argument(
|
||||
value = "-Xskip-metadata-version-check",
|
||||
description = "Load classes with bad metadata version anyway (incl. pre-release classes)"
|
||||
)
|
||||
var skipMetadataVersionCheck: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xallow-kotlin-package", description = "Allow compiling code in package 'kotlin'")
|
||||
public boolean allowKotlinPackage;
|
||||
var allowKotlinPackage: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xreport-output-files", description = "Report source to output files mapping")
|
||||
public boolean reportOutputFiles;
|
||||
var reportOutputFiles: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xplugin", valueDescription = "<path>", description = "Load plugins from the given classpath")
|
||||
public String[] pluginClasspaths;
|
||||
var pluginClasspaths: Array<String>? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xmulti-platform", description = "Enable experimental language support for multi-platform projects")
|
||||
public boolean multiPlatform;
|
||||
var multiPlatform: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xno-check-impl", description = "Do not check presence of 'impl' modifier in multi-platform projects")
|
||||
public boolean noCheckImpl;
|
||||
var noCheckImpl: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xintellij-plugin-root",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found"
|
||||
)
|
||||
public String intellijPluginRoot;
|
||||
var intellijPluginRoot: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xcoroutines",
|
||||
valueDescription = "{enable|warn|error}",
|
||||
description = "Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier"
|
||||
)
|
||||
public String coroutinesState = WARN;
|
||||
var coroutinesState: String? by FreezableVar(WARN)
|
||||
|
||||
public static final String WARN = "warn";
|
||||
public static final String ERROR = "error";
|
||||
public static final String ENABLE = "enable";
|
||||
open fun configureAnalysisFlags(): MutableMap<AnalysisFlag<*>, Any> {
|
||||
return HashMap<AnalysisFlag<*>, Any>().apply {
|
||||
put(AnalysisFlag.skipMetadataVersionCheck, skipMetadataVersionCheck)
|
||||
put(AnalysisFlag.multiPlatformDoNotCheckImpl, noCheckImpl)
|
||||
}
|
||||
}
|
||||
|
||||
// Used only for serialize and deserialize settings. Don't use in other places!
|
||||
public static final class DummyImpl extends CommonCompilerArguments {}
|
||||
class DummyImpl : CommonCompilerArguments()
|
||||
}
|
||||
@@ -14,34 +14,34 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import org.jetbrains.kotlin.utils.SmartList;
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import java.io.Serializable
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
abstract class CommonToolArguments : Freezable(), Serializable {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
}
|
||||
|
||||
public abstract class CommonToolArguments implements Serializable {
|
||||
private static final long serialVersionUID = 0L;
|
||||
var freeArgs: MutableList<String> = SmartList()
|
||||
|
||||
public List<String> freeArgs = new SmartList<>();
|
||||
|
||||
public transient ArgumentParseErrors errors = new ArgumentParseErrors();
|
||||
@Transient var errors: ArgumentParseErrors = ArgumentParseErrors()
|
||||
|
||||
@Argument(value = "-help", shortName = "-h", description = "Print a synopsis of standard options")
|
||||
public boolean help;
|
||||
var help: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-X", description = "Print a synopsis of advanced options")
|
||||
public boolean extraHelp;
|
||||
var extraHelp: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-version", description = "Display compiler version")
|
||||
public boolean version;
|
||||
var version: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-verbose", description = "Enable verbose logging output")
|
||||
public boolean verbose;
|
||||
var verbose: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-nowarn", description = "Generate no warnings")
|
||||
public boolean suppressWarnings;
|
||||
var suppressWarnings: Boolean by FreezableVar(false)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
abstract class Freezable {
|
||||
protected inner class FreezableVar<T>(private var value: T) : ReadWriteProperty<Any, T> {
|
||||
override fun getValue(thisRef: Any, property: KProperty<*>) = value
|
||||
|
||||
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
|
||||
if (frozen) throw IllegalStateException("Instance of ${this::class} is frozen")
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
|
||||
private var frozen: Boolean = false
|
||||
|
||||
private fun getInstanceWithFreezeStatus(value: Boolean) = if (value == frozen) this else copyBean(this).apply { frozen = value }
|
||||
|
||||
fun frozen() = getInstanceWithFreezeStatus(true)
|
||||
fun unfrozen() = getInstanceWithFreezeStatus(false)
|
||||
}
|
||||
@@ -14,100 +14,102 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL;
|
||||
import static org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL
|
||||
|
||||
public class K2JSCompilerArguments extends CommonCompilerArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
}
|
||||
|
||||
@GradleOption(DefaultValues.StringNullDefault.class)
|
||||
@GradleOption(DefaultValues.StringNullDefault::class)
|
||||
@Argument(value = "-output", valueDescription = "<path>", description = "Output file path")
|
||||
public String outputFile;
|
||||
var outputFile: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
||||
@Argument(value = "-no-stdlib", description = "Don't use bundled Kotlin stdlib")
|
||||
public boolean noStdlib;
|
||||
var noStdlib: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-libraries",
|
||||
valueDescription = "<path>",
|
||||
description = "Paths to Kotlin libraries with .meta.js and .kjsm files, separated by system path separator"
|
||||
)
|
||||
public String libraries;
|
||||
var libraries: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-source-map", description = "Generate source map")
|
||||
public boolean sourceMap;
|
||||
var sourceMap: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.StringNullDefault.class)
|
||||
@GradleOption(DefaultValues.StringNullDefault::class)
|
||||
@Argument(value = "-source-map-prefix", description = "Prefix for paths in a source map")
|
||||
public String sourceMapPrefix;
|
||||
var sourceMapPrefix: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-source-map-source-roots",
|
||||
valueDescription = "<path>",
|
||||
description = "Base directories which are used to calculate relative paths to source files in source map"
|
||||
)
|
||||
public String sourceMapSourceRoots;
|
||||
var sourceMapSourceRoots: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.JsSourceMapContentModes.class)
|
||||
@GradleOption(DefaultValues.JsSourceMapContentModes::class)
|
||||
@Argument(
|
||||
value = "-source-map-embed-sources",
|
||||
valueDescription = "{ always, never, inlining }",
|
||||
description = "Embed source files into source map"
|
||||
)
|
||||
public String sourceMapEmbedSources;
|
||||
var sourceMapEmbedSources: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
||||
@Argument(value = "-meta-info", description = "Generate .meta.js and .kjsm files with metadata. Use to create a library")
|
||||
public boolean metaInfo;
|
||||
var metaInfo: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.JsEcmaVersions.class)
|
||||
@GradleOption(DefaultValues.JsEcmaVersions::class)
|
||||
@Argument(value = "-target", valueDescription = "{ v5 }", description = "Generate JS files for specific ECMA version")
|
||||
public String target;
|
||||
var target: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.JsModuleKinds.class)
|
||||
@GradleOption(DefaultValues.JsModuleKinds::class)
|
||||
@Argument(
|
||||
value = "-module-kind",
|
||||
valueDescription = "{ plain, amd, commonjs, umd }",
|
||||
description = "Kind of a module generated by compiler"
|
||||
)
|
||||
public String moduleKind = K2JsArgumentConstants.MODULE_PLAIN;
|
||||
var moduleKind: String? by FreezableVar(K2JsArgumentConstants.MODULE_PLAIN)
|
||||
|
||||
@GradleOption(DefaultValues.JsMain.class)
|
||||
@Argument(value = "-main", valueDescription = "{" + CALL + "," + NO_CALL + "}", description = "Whether a main function should be called")
|
||||
public String main;
|
||||
@GradleOption(DefaultValues.JsMain::class)
|
||||
@Argument(value = "-main", valueDescription = "{$CALL,$NO_CALL}", description = "Whether a main function should be called")
|
||||
var main: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-output-prefix",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to file which will be added to the beginning of output file"
|
||||
)
|
||||
public String outputPrefix;
|
||||
var outputPrefix: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-output-postfix",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to file which will be added to the end of output file"
|
||||
)
|
||||
public String outputPostfix;
|
||||
var outputPostfix: String? by FreezableVar(null)
|
||||
|
||||
// Advanced options
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-Xtyped-arrays", description = "Translate primitive arrays to JS typed arrays")
|
||||
public boolean typedArrays;
|
||||
var typedArrays: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-Xfriend-modules-disabled", description = "Disable internal declaration export")
|
||||
public boolean friendModulesDisabled;
|
||||
var friendModulesDisabled: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xfriend-modules",
|
||||
valueDescription = "<path>",
|
||||
description = "Paths to friend modules"
|
||||
)
|
||||
public String friendModules;
|
||||
var friendModules: String? by FreezableVar(null)
|
||||
}
|
||||
@@ -14,28 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
public class K2JSDceArguments extends CommonToolArguments {
|
||||
private static final long serialVersionUID = 0;
|
||||
class K2JSDceArguments : CommonToolArguments() {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
}
|
||||
|
||||
@Argument(
|
||||
value = "-output-dir",
|
||||
valueDescription = "<path>",
|
||||
description = "Output directory"
|
||||
)
|
||||
public String outputDirectory;
|
||||
var outputDirectory: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-keep",
|
||||
valueDescription = "<fully.qualified.name[,]>",
|
||||
description = "List of fully-qualified names of declarations that shouldn't be eliminated"
|
||||
)
|
||||
public String[] declarationsToKeep;
|
||||
var declarationsToKeep: Array<String>? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xprint-reachability-info",
|
||||
description = "Print declarations marked as reachable"
|
||||
)
|
||||
public boolean printReachabilityInfo;
|
||||
var printReachabilityInfo: Boolean by FreezableVar(false)
|
||||
}
|
||||
@@ -14,79 +14,76 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.utils.Jsr305State
|
||||
|
||||
public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
}
|
||||
|
||||
@Argument(value = "-d", valueDescription = "<directory|jar>", description = "Destination for generated class files")
|
||||
public String destination;
|
||||
var destination: String? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-classpath", shortName = "-cp", valueDescription = "<path>", description = "Paths where to find user class files")
|
||||
public String classpath;
|
||||
var classpath: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-include-runtime", description = "Include Kotlin runtime in to resulting .jar")
|
||||
public boolean includeRuntime;
|
||||
var includeRuntime: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.StringNullDefault.class)
|
||||
@GradleOption(DefaultValues.StringNullDefault::class)
|
||||
@Argument(
|
||||
value = "-jdk-home",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to JDK home directory to include into classpath, if differs from default JAVA_HOME"
|
||||
)
|
||||
public String jdkHome;
|
||||
var jdkHome: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-no-jdk", description = "Don't include Java runtime into classpath")
|
||||
public boolean noJdk;
|
||||
var noJdk: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
||||
@Argument(value = "-no-stdlib", description = "Don't include Kotlin runtime into classpath")
|
||||
public boolean noStdlib;
|
||||
var noStdlib: Boolean by FreezableVar(false)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanTrueDefault::class)
|
||||
@Argument(value = "-no-reflect", description = "Don't include Kotlin reflection implementation into classpath")
|
||||
public boolean noReflect;
|
||||
var noReflect: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-script", description = "Evaluate the script file")
|
||||
public boolean script;
|
||||
var script: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-script-templates",
|
||||
valueDescription = "<fully qualified class name[,]>",
|
||||
description = "Script definition template classes"
|
||||
)
|
||||
public String[] scriptTemplates;
|
||||
|
||||
@Argument(
|
||||
value = "-kotlin-home",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to Kotlin compiler home directory, used for runtime libraries discovery"
|
||||
)
|
||||
public String kotlinHome;
|
||||
var scriptTemplates: Array<String>? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-module-name", description = "Module name")
|
||||
public String moduleName;
|
||||
var moduleName: String? by FreezableVar(null)
|
||||
|
||||
@GradleOption(DefaultValues.JvmTargetVersions.class)
|
||||
@GradleOption(DefaultValues.JvmTargetVersions::class)
|
||||
@Argument(
|
||||
value = "-jvm-target",
|
||||
valueDescription = "<version>",
|
||||
description = "Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6"
|
||||
)
|
||||
public String jvmTarget = JvmTarget.DEFAULT.getDescription();
|
||||
var jvmTarget: String? by FreezableVar(JvmTarget.DEFAULT.description)
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault.class)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-java-parameters", description = "Generate metadata for Java 1.8 reflection on method parameters")
|
||||
public boolean javaParameters;
|
||||
var javaParameters: Boolean by FreezableVar(false)
|
||||
|
||||
// Advanced options
|
||||
|
||||
@Argument(value = "-Xmodule-path", valueDescription = "<path>", description = "Paths where to find Java 9+ modules")
|
||||
public String javaModulePath;
|
||||
var javaModulePath: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-Xadd-modules",
|
||||
@@ -94,72 +91,84 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
description = "Root modules to resolve in addition to the initial modules,\n" +
|
||||
"or all modules on the module path if <module> is ALL-MODULE-PATH"
|
||||
)
|
||||
public String[] additionalJavaModules;
|
||||
var additionalJavaModules: Array<String>? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xno-call-assertions", description = "Don't generate not-null assertion after each invocation of method returning not-null")
|
||||
public boolean noCallAssertions;
|
||||
var noCallAssertions: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xno-param-assertions", description = "Don't generate not-null assertions on parameters of methods accessible from Java")
|
||||
public boolean noParamAssertions;
|
||||
var noParamAssertions: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xno-optimize", description = "Disable optimizations")
|
||||
public boolean noOptimize;
|
||||
var noOptimize: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xreport-perf", description = "Report detailed performance statistics")
|
||||
public boolean reportPerf;
|
||||
var reportPerf: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xbuild-file", deprecatedName = "-module", valueDescription = "<path>", description = "Path to the .xml build file to compile")
|
||||
public String buildFile;
|
||||
var buildFile: String? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xmultifile-parts-inherit", description = "Compile multifile classes as a hierarchy of parts and facade")
|
||||
public boolean inheritMultifileParts;
|
||||
var inheritMultifileParts: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xskip-runtime-version-check", description = "Allow Kotlin runtime libraries of incompatible versions in the classpath")
|
||||
public boolean skipRuntimeVersionCheck;
|
||||
var skipRuntimeVersionCheck: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xuse-old-class-files-reading",
|
||||
description = "Use old class files reading implementation " +
|
||||
"(may slow down the build and should be used in case of problems with the new implementation)"
|
||||
)
|
||||
public boolean useOldClassFilesReading;
|
||||
var useOldClassFilesReading: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xdump-declarations-to",
|
||||
valueDescription = "<path>",
|
||||
description = "Path to JSON file to dump Java to Kotlin declaration mappings"
|
||||
)
|
||||
public String declarationsOutputPath;
|
||||
var declarationsOutputPath: String? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xsingle-module", description = "Combine modules for source files and binary dependencies into a single module")
|
||||
public boolean singleModule;
|
||||
var singleModule: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xadd-compiler-builtins", description = "Add definitions of built-in declarations to the compilation classpath (useful with -no-stdlib)")
|
||||
public boolean addCompilerBuiltIns;
|
||||
var addCompilerBuiltIns: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xload-builtins-from-dependencies", description = "Load definitions of built-in declarations from module dependencies, instead of from the compiler")
|
||||
public boolean loadBuiltInsFromDependencies;
|
||||
var loadBuiltInsFromDependencies: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xscript-resolver-environment",
|
||||
valueDescription = "<key=value[,]>",
|
||||
description = "Script resolver environment in key-value pairs (the value could be quoted and escaped)"
|
||||
)
|
||||
public String[] scriptResolverEnvironment;
|
||||
var scriptResolverEnvironment: Array<String>? by FreezableVar(null)
|
||||
|
||||
// Javac options
|
||||
@Argument(value = "-Xuse-javac", description = "Use javac for Java source and class files analysis")
|
||||
public boolean useJavac;
|
||||
var useJavac: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xjavac-arguments",
|
||||
valueDescription = "<option[,]>",
|
||||
description = "Java compiler arguments")
|
||||
public String[] javacArguments;
|
||||
var javacArguments: Array<String>? by FreezableVar(null)
|
||||
|
||||
@Argument(value = "-Xload-jsr305-annotations", description = "Load JSR-305 nullability annotations")
|
||||
public boolean loadJsr305annotations;
|
||||
@Argument(
|
||||
value = "-Xjsr305-annotations",
|
||||
valueDescription = "{ignore|enable|warn}",
|
||||
description = "Specify global behavior for JSR-305 nullability annotations: ignore, treat as other supported nullability annotations, or report a warning"
|
||||
)
|
||||
var jsr305GlobalState: String? by FreezableVar(Jsr305State.DEFAULT.description)
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
public String[] friendPaths;
|
||||
var friendPaths: Array<String>? by FreezableVar(null)
|
||||
|
||||
override fun configureAnalysisFlags(): MutableMap<AnalysisFlag<*>, Any> {
|
||||
val result = super.configureAnalysisFlags()
|
||||
Jsr305State.findByDescription(jsr305GlobalState)?.let {
|
||||
result.put(AnalysisFlag.jsr305GlobalState, it)
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
public class K2MetadataCompilerArguments extends CommonCompilerArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
class K2MetadataCompilerArguments : CommonCompilerArguments() {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
}
|
||||
|
||||
@Argument(value = "-d", valueDescription = "<directory|jar>", description = "Destination for generated .kotlin_metadata files")
|
||||
public String destination;
|
||||
var destination: String? by FreezableVar(null)
|
||||
|
||||
@Argument(
|
||||
value = "-classpath",
|
||||
@@ -28,5 +30,5 @@ public class K2MetadataCompilerArguments extends CommonCompilerArguments {
|
||||
valueDescription = "<path>",
|
||||
description = "Paths where to find library .kotlin_metadata files"
|
||||
)
|
||||
public String classpath;
|
||||
var classpath: String? by FreezableVar(null)
|
||||
}
|
||||
@@ -16,29 +16,47 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.KVisibility
|
||||
import kotlin.reflect.full.declaredMemberProperties
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
fun <T : Any> copyBean(bean: T) = copyFields(bean, bean::class.java.newInstance(), true, collectFieldsToCopy(bean::class.java, false))
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> copyBean(bean: T) =
|
||||
copyProperties(bean, bean::class.java.newInstance()!!, true, collectProperties(bean::class as KClass<T>, false))
|
||||
|
||||
fun <From : Any, To : From> mergeBeans(from: From, to: To): To {
|
||||
// TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity
|
||||
return copyFields(from, to, false, collectFieldsToCopy(from::class.java, false))
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return copyProperties(from, to, false, collectProperties(from::class as KClass<From>, false))
|
||||
}
|
||||
|
||||
fun <From : Any, To : Any> copyInheritedFields(from: From, to: To) = copyFields(from, to, true, collectFieldsToCopy(from::class.java, true))
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <From : Any, To : Any> copyInheritedFields(from: From, to: To) =
|
||||
copyProperties(from, to, true, collectProperties(from::class as KClass<From>, true))
|
||||
|
||||
fun <From : Any, To : Any> copyFieldsSatisfying(from: From, to: To, predicate: (Field) -> Boolean) =
|
||||
copyFields(from, to, true, collectFieldsToCopy(from::class.java, false).filter(predicate))
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <From : Any, To : Any> copyFieldsSatisfying(from: From, to: To, predicate: (KProperty1<From, Any?>) -> Boolean) =
|
||||
copyProperties(from, to, true, collectProperties(from::class as KClass<From>, false).filter(predicate))
|
||||
|
||||
private fun <From : Any, To : Any> copyFields(from: From, to: To, deepCopyWhenNeeded: Boolean, fieldsToCopy: List<Field>): To {
|
||||
private fun <From : Any, To : Any> copyProperties(
|
||||
from: From,
|
||||
to: To,
|
||||
deepCopyWhenNeeded: Boolean,
|
||||
propertiesToCopy: List<KProperty1<From, Any?>>
|
||||
): To {
|
||||
if (from == to) return to
|
||||
|
||||
for (fromField in fieldsToCopy) {
|
||||
val toField = to::class.java.getField(fromField.name)
|
||||
val fromValue = fromField.get(from)
|
||||
toField.set(to, if (deepCopyWhenNeeded) fromValue?.copyValueIfNeeded() else fromValue)
|
||||
for (fromProperty in propertiesToCopy) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val toProperty = to::class.memberProperties.firstOrNull { it.name == fromProperty.name } as? KMutableProperty1<To, Any?>
|
||||
?: continue
|
||||
val fromValue = fromProperty.get(from)
|
||||
toProperty.set(to, if (deepCopyWhenNeeded) fromValue?.copyValueIfNeeded() else fromValue)
|
||||
}
|
||||
return to
|
||||
}
|
||||
@@ -72,19 +90,12 @@ private fun Any.copyValueIfNeeded(): Any {
|
||||
}
|
||||
}
|
||||
|
||||
fun collectFieldsToCopy(clazz: Class<*>, inheritedOnly: Boolean): List<Field> {
|
||||
val fromFields = ArrayList<Field>()
|
||||
|
||||
var currentClass: Class<*>? = if (inheritedOnly) clazz.superclass else clazz
|
||||
while (currentClass != null) {
|
||||
for (field in currentClass.declaredFields) {
|
||||
val modifiers = field.modifiers
|
||||
if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && !Modifier.isTransient(modifiers)) {
|
||||
fromFields.add(field)
|
||||
}
|
||||
}
|
||||
currentClass = currentClass.superclass
|
||||
fun <T : Any> collectProperties(kClass: KClass<T>, inheritedOnly: Boolean): List<KProperty1<T, Any?>> {
|
||||
val properties = ArrayList(kClass.memberProperties)
|
||||
if (inheritedOnly) {
|
||||
properties.removeAll(kClass.declaredMemberProperties)
|
||||
}
|
||||
|
||||
return fromFields
|
||||
}
|
||||
return properties.filter {
|
||||
it.visibility == KVisibility.PUBLIC && it.findAnnotation<Transient>() == null
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,10 @@
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import java.lang.reflect.Field
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
annotation class Argument(
|
||||
val value: String,
|
||||
@@ -54,12 +56,14 @@ data class ArgumentParseErrors(
|
||||
)
|
||||
|
||||
// Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors].
|
||||
fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>, result: A) {
|
||||
data class ArgumentField(val field: Field, val argument: Argument)
|
||||
fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, result: A) {
|
||||
data class ArgumentField(val property: KMutableProperty1<A, Any?>, val argument: Argument)
|
||||
|
||||
val fields = result::class.java.fields.mapNotNull { field ->
|
||||
val argument = field.getAnnotation(Argument::class.java)
|
||||
if (argument != null) ArgumentField(field, argument) else null
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val properties = result::class.memberProperties.mapNotNull { property ->
|
||||
if (property !is KMutableProperty1<*, *>) return@mapNotNull null
|
||||
val argument = property.findAnnotation<Argument>() ?: return@mapNotNull null
|
||||
ArgumentField(property as KMutableProperty1<A, Any?>, argument)
|
||||
}
|
||||
|
||||
val errors = result.errors
|
||||
@@ -73,7 +77,7 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>,
|
||||
}
|
||||
|
||||
if (argument.value == arg) {
|
||||
if (argument.isAdvanced && field.type != Boolean::class.java) {
|
||||
if (argument.isAdvanced && property.returnType.classifier != Boolean::class) {
|
||||
errors.extraArgumentsPassedInObsoleteForm.add(arg)
|
||||
}
|
||||
return true
|
||||
@@ -96,7 +100,7 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>,
|
||||
continue
|
||||
}
|
||||
|
||||
val argumentField = fields.firstOrNull { it.matches(arg) }
|
||||
val argumentField = properties.firstOrNull { it.matches(arg) }
|
||||
if (argumentField == null) {
|
||||
when {
|
||||
arg.startsWith(ADVANCED_ARGUMENT_PREFIX) -> errors.unknownExtraFlags.add(arg)
|
||||
@@ -106,9 +110,9 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>,
|
||||
continue
|
||||
}
|
||||
|
||||
val (field, argument) = argumentField
|
||||
val (property, argument) = argumentField
|
||||
val value: Any = when {
|
||||
field.type == Boolean::class.java -> true
|
||||
argumentField.property.returnType.classifier == Boolean::class -> true
|
||||
argument.isAdvanced && arg.startsWith(argument.value + "=") -> {
|
||||
arg.substring(argument.value.length + 1)
|
||||
}
|
||||
@@ -121,24 +125,25 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>,
|
||||
}
|
||||
}
|
||||
|
||||
if (!field.type.isArray && !visitedArgs.add(argument.value) && value is String && field.get(result) != value) {
|
||||
if ((argumentField.property.returnType.classifier as? KClass<*>)?.java?.isArray == false
|
||||
&& !visitedArgs.add(argument.value) && value is String && property.get(result) != value) {
|
||||
errors.duplicateArguments.put(argument.value, value)
|
||||
}
|
||||
|
||||
updateField(field, result, value, argument.delimiter)
|
||||
updateField(property, result, value, argument.delimiter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <A : CommonToolArguments> updateField(field: Field, result: A, value: Any, delimiter: String) {
|
||||
when (field.type) {
|
||||
Boolean::class.java, String::class.java -> field.set(result, value)
|
||||
Array<String>::class.java -> {
|
||||
private fun <A : CommonToolArguments> updateField(property: KMutableProperty1<A, Any?>, result: A, value: Any, delimiter: String) {
|
||||
when (property.returnType.classifier) {
|
||||
Boolean::class, String::class -> property.set(result, value)
|
||||
Array<String>::class -> {
|
||||
val newElements = (value as String).split(delimiter).toTypedArray()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val oldValue = field.get(result) as Array<String>?
|
||||
field.set(result, if (oldValue != null) arrayOf(*oldValue, *newElements) else newElements)
|
||||
val oldValue = property.get(result) as Array<String>?
|
||||
property.set(result, if (oldValue != null) arrayOf(*oldValue, *newElements) else newElements)
|
||||
}
|
||||
else -> throw IllegalStateException("Unsupported argument type: ${field.type}")
|
||||
else -> throw IllegalStateException("Unsupported argument type: ${property.returnType}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,11 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
open class AggregatedReplStateHistory<T1, T2>(val history1: IReplStageHistory<T1>, val history2: IReplStageHistory<T2>, override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock())
|
||||
: IReplStageHistory<Pair<T1, T2>>, AbstractList<ReplHistoryRecord<Pair<T1, T2>>>()
|
||||
open class AggregatedReplStateHistory<T1, T2>(
|
||||
private val history1: IReplStageHistory<T1>,
|
||||
private val history2: IReplStageHistory<T2>,
|
||||
override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()
|
||||
) : IReplStageHistory<Pair<T1, T2>>, AbstractList<ReplHistoryRecord<Pair<T1, T2>>>()
|
||||
{
|
||||
override val size: Int
|
||||
get() = minOf(history1.size, history2.size)
|
||||
|
||||
@@ -26,7 +26,7 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
private val fallbackScriptArgs: ScriptArgsWithTypes? = null,
|
||||
repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
|
||||
) : ReplFullEvaluator {
|
||||
val evaluator = GenericReplEvaluator(baseClasspath, baseClassloader, fallbackScriptArgs, repeatingMode)
|
||||
private val evaluator = GenericReplEvaluator(baseClasspath, baseClassloader, fallbackScriptArgs, repeatingMode)
|
||||
|
||||
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = AggregatedReplStageState(compiler.createState(lock), evaluator.createState(lock), lock)
|
||||
|
||||
@@ -63,10 +63,8 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
is ReplEvalResult.ValueResult,
|
||||
is ReplEvalResult.UnitResult ->
|
||||
result
|
||||
else -> throw IllegalStateException("Unknown evaluator result type $compiled")
|
||||
}
|
||||
}
|
||||
else -> throw IllegalStateException("Unknown compiler result type $compiled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ import java.lang.reflect.InvocationTargetException
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.write
|
||||
|
||||
open class GenericReplEvaluator(val baseClasspath: Iterable<File>,
|
||||
val baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
|
||||
protected val fallbackScriptArgs: ScriptArgsWithTypes? = null,
|
||||
protected val repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
|
||||
open class GenericReplEvaluator(
|
||||
val baseClasspath: Iterable<File>,
|
||||
val baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
|
||||
protected val fallbackScriptArgs: ScriptArgsWithTypes? = null,
|
||||
protected val repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
|
||||
) : ReplEvaluator {
|
||||
|
||||
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = GenericReplEvaluatorState(baseClasspath, baseClassloader, lock)
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.cli.common;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
|
||||
@@ -32,8 +33,12 @@ import org.jetbrains.kotlin.config.*;
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledException;
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths;
|
||||
import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir;
|
||||
import org.jetbrains.kotlin.utils.PathUtil;
|
||||
import org.jetbrains.kotlin.utils.StringsKt;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -65,16 +70,21 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
CompilerConfiguration configuration = new CompilerConfiguration();
|
||||
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, groupingCollector);
|
||||
|
||||
setupCommonArgumentsAndServices(configuration, arguments, services);
|
||||
setupPlatformSpecificArgumentsAndServices(configuration, arguments, services);
|
||||
|
||||
try {
|
||||
setupCommonArgumentsAndServices(configuration, arguments, services);
|
||||
setupPlatformSpecificArgumentsAndServices(configuration, arguments, services);
|
||||
KotlinPaths paths = computeKotlinPaths(groupingCollector, arguments);
|
||||
if (groupingCollector.hasErrors()) {
|
||||
return ExitCode.COMPILATION_ERROR;
|
||||
}
|
||||
|
||||
ExitCode exitCode = OK;
|
||||
|
||||
int repeatCount = 1;
|
||||
if (arguments.repeat != null) {
|
||||
String repeat = arguments.getRepeat();
|
||||
if (repeat != null) {
|
||||
try {
|
||||
repeatCount = Integer.parseInt(arguments.repeat);
|
||||
repeatCount = Integer.parseInt(repeat);
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
}
|
||||
@@ -90,7 +100,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
Disposable rootDisposable = Disposer.newDisposable();
|
||||
try {
|
||||
setIdeaIoUseFallback();
|
||||
ExitCode code = doExecute(arguments, configuration, rootDisposable);
|
||||
ExitCode code = doExecute(arguments, configuration, rootDisposable, paths);
|
||||
exitCode = groupingCollector.hasErrors() ? COMPILATION_ERROR : code;
|
||||
}
|
||||
catch (CompilationCanceledException e) {
|
||||
@@ -125,13 +135,13 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
private void setupCommonArgumentsAndServices(
|
||||
@NotNull CompilerConfiguration configuration, @NotNull A arguments, @NotNull Services services
|
||||
) {
|
||||
if (arguments.noInline) {
|
||||
if (arguments.getNoInline()) {
|
||||
configuration.put(CommonConfigurationKeys.DISABLE_INLINE, true);
|
||||
}
|
||||
if (arguments.intellijPluginRoot != null) {
|
||||
configuration.put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, arguments.intellijPluginRoot);
|
||||
if (arguments.getIntellijPluginRoot()!= null) {
|
||||
configuration.put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, arguments.getIntellijPluginRoot());
|
||||
}
|
||||
if (arguments.reportOutputFiles) {
|
||||
if (arguments.getReportOutputFiles()) {
|
||||
configuration.put(CommonConfigurationKeys.REPORT_OUTPUT_FILES, true);
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -144,8 +154,8 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
}
|
||||
|
||||
private void setupLanguageVersionSettings(@NotNull CompilerConfiguration configuration, @NotNull A arguments) {
|
||||
LanguageVersion languageVersion = parseVersion(configuration, arguments.languageVersion, "language");
|
||||
LanguageVersion apiVersion = parseVersion(configuration, arguments.apiVersion, "API");
|
||||
LanguageVersion languageVersion = parseVersion(configuration, arguments.getLanguageVersion(), "language");
|
||||
LanguageVersion apiVersion = parseVersion(configuration, arguments.getApiVersion(), "API");
|
||||
|
||||
if (languageVersion == null) {
|
||||
// If only "-api-version" is specified, language version is assumed to be the latest stable
|
||||
@@ -180,7 +190,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
}
|
||||
|
||||
Map<LanguageFeature, LanguageFeature.State> extraLanguageFeatures = new HashMap<>(0);
|
||||
if (arguments.multiPlatform) {
|
||||
if (arguments.getMultiPlatform()) {
|
||||
extraLanguageFeatures.put(LanguageFeature.MultiPlatformProjects, LanguageFeature.State.ENABLED);
|
||||
}
|
||||
|
||||
@@ -189,15 +199,57 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
extraLanguageFeatures.put(LanguageFeature.Coroutines, coroutinesState);
|
||||
}
|
||||
|
||||
LanguageVersionSettingsImpl settings =
|
||||
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures);
|
||||
settings.switchFlag(AnalysisFlags.getSkipMetadataVersionCheck(), arguments.skipMetadataVersionCheck);
|
||||
settings.switchFlag(AnalysisFlags.getMultiPlatformDoNotCheckImpl(), arguments.noCheckImpl);
|
||||
configureAnalysisFlags(settings, arguments);
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, settings);
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, new LanguageVersionSettingsImpl(
|
||||
languageVersion,
|
||||
ApiVersion.createByLanguageVersion(apiVersion),
|
||||
arguments.configureAnalysisFlags(),
|
||||
extraLanguageFeatures
|
||||
));
|
||||
}
|
||||
|
||||
protected void configureAnalysisFlags(@NotNull LanguageVersionSettingsImpl settings, @NotNull A arguments) {
|
||||
@Nullable
|
||||
private static KotlinPaths computeKotlinPaths(@NotNull MessageCollector messageCollector, @NotNull CommonCompilerArguments arguments) {
|
||||
KotlinPaths paths;
|
||||
if (arguments.getKotlinHome() != null) {
|
||||
File kotlinHome = new File(arguments.getKotlinHome());
|
||||
if (kotlinHome.isDirectory()) {
|
||||
paths = new KotlinPathsFromHomeDir(kotlinHome);
|
||||
}
|
||||
else {
|
||||
messageCollector.report(ERROR, "Kotlin home does not exist or is not a directory: " + kotlinHome, null);
|
||||
paths = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
paths = PathUtil.getKotlinPathsForCompiler();
|
||||
}
|
||||
|
||||
if (paths != null) {
|
||||
messageCollector.report(LOGGING, "Using Kotlin home directory " + paths.getHomePath(), null);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getLibraryFromHome(
|
||||
@Nullable KotlinPaths paths,
|
||||
@NotNull Function1<KotlinPaths, File> getLibrary,
|
||||
@NotNull String libraryName,
|
||||
@NotNull MessageCollector messageCollector,
|
||||
@NotNull String noLibraryArgument
|
||||
) {
|
||||
if (paths != null) {
|
||||
File stdlibJar = getLibrary.invoke(paths);
|
||||
if (stdlibJar.exists()) {
|
||||
return stdlibJar;
|
||||
}
|
||||
}
|
||||
|
||||
messageCollector.report(STRONG_WARNING, "Unable to find " + libraryName + " in the Kotlin home directory. " +
|
||||
"Pass either " + noLibraryArgument + " to prevent adding it to the classpath, " +
|
||||
"or the correct '-kotlin-home'", null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -205,7 +257,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
@NotNull CompilerConfiguration configuration,
|
||||
@NotNull CommonCompilerArguments arguments
|
||||
) {
|
||||
switch (arguments.coroutinesState) {
|
||||
switch (arguments.getCoroutinesState()) {
|
||||
case CommonCompilerArguments.ERROR:
|
||||
return LanguageFeature.State.ENABLED_WITH_ERROR;
|
||||
case CommonCompilerArguments.ENABLE:
|
||||
@@ -213,7 +265,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
case CommonCompilerArguments.WARN:
|
||||
return null;
|
||||
default:
|
||||
String message = "Invalid value of -Xcoroutines (should be: enable, warn or error): " + arguments.coroutinesState;
|
||||
String message = "Invalid value of -Xcoroutines (should be: enable, warn or error): " + arguments.getCoroutinesState();
|
||||
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(ERROR, message, null);
|
||||
return null;
|
||||
}
|
||||
@@ -245,6 +297,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
protected abstract ExitCode doExecute(
|
||||
@NotNull A arguments,
|
||||
@NotNull CompilerConfiguration configuration,
|
||||
@NotNull Disposable rootDisposable
|
||||
@NotNull Disposable rootDisposable,
|
||||
@Nullable KotlinPaths paths
|
||||
);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
K2JVMCompiler.resetInitStartTime()
|
||||
|
||||
val arguments = createArguments()
|
||||
parseCommandLineArguments(args, arguments)
|
||||
parseCommandLineArguments(args.asList(), arguments)
|
||||
val collector = PrintingMessageCollector(errStream, messageRenderer, arguments.verbose)
|
||||
|
||||
try {
|
||||
@@ -99,7 +99,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
|
||||
// Used in kotlin-maven-plugin (KotlinCompileMojoBase) and in kotlin-gradle-plugin (KotlinJvmOptionsImpl, KotlinJsOptionsImpl)
|
||||
fun parseArguments(args: Array<out String>, arguments: A) {
|
||||
parseCommandLineArguments(args, arguments)
|
||||
parseCommandLineArguments(args.asList(), arguments)
|
||||
val message = validateArguments(arguments.errors)
|
||||
if (message != null) {
|
||||
throw IllegalArgumentException(message)
|
||||
|
||||
@@ -16,14 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.jvm.JvmClassMappingKt;
|
||||
import kotlin.reflect.KCallable;
|
||||
import kotlin.reflect.KClass;
|
||||
import kotlin.reflect.KProperty1;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.Argument;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class Usage {
|
||||
// The magic number 29 corresponds to the similar padding width in javac and scalac command line compilers
|
||||
private static final int OPTION_NAME_PADDING_WIDTH = 29;
|
||||
@@ -32,14 +35,14 @@ public class Usage {
|
||||
public static <A extends CommonToolArguments> String render(@NotNull CLITool<A> tool, @NotNull A arguments) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendln(sb, "Usage: " + tool.executableScriptFileName() + " <options> <source files>");
|
||||
appendln(sb, "where " + (arguments.extraHelp ? "advanced" : "possible") + " options include:");
|
||||
for (Class<?> clazz = arguments.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
fieldUsage(sb, field, arguments.extraHelp);
|
||||
}
|
||||
appendln(sb, "where " + (arguments.getExtraHelp() ? "advanced" : "possible") + " options include:");
|
||||
KClass<? extends CommonToolArguments> kClass = JvmClassMappingKt.getKotlinClass(arguments.getClass());
|
||||
for (KCallable<?> callable : kClass.getMembers()) {
|
||||
if (!(callable instanceof KProperty1)) continue;
|
||||
propertyUsage(sb, (KProperty1) callable, arguments.getExtraHelp());
|
||||
}
|
||||
|
||||
if (arguments.extraHelp) {
|
||||
if (arguments.getExtraHelp()) {
|
||||
appendln(sb, "");
|
||||
appendln(sb, "Advanced options are non-standard and may be changed or removed without any notice.");
|
||||
}
|
||||
@@ -47,8 +50,8 @@ public class Usage {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void fieldUsage(@NotNull StringBuilder sb, @NotNull Field field, boolean extraHelp) {
|
||||
Argument argument = field.getAnnotation(Argument.class);
|
||||
private static void propertyUsage(@NotNull StringBuilder sb, @NotNull KProperty1 property, boolean extraHelp) {
|
||||
Argument argument = ContainerUtil.findInstance(property.getAnnotations(), Argument.class);
|
||||
if (argument == null) return;
|
||||
|
||||
if (extraHelp != ParseCommandLineArgumentsKt.isAdvanced(argument)) return;
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.io.File
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
import kotlin.script.dependencies.ScriptDependencies
|
||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||
|
||||
class CliScriptDependenciesProvider(
|
||||
project: Project,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user