mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-28 00:21:29 +00:00
Compare commits
1078 Commits
stdlib/add
...
ab/bintray
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a11a846f9f | ||
|
|
311a074f28 | ||
|
|
a1d0ae6729 | ||
|
|
4787ec24fe | ||
|
|
4a2c3aa31b | ||
|
|
b08c903022 | ||
|
|
8b96b0e071 | ||
|
|
7fcad4d534 | ||
|
|
21ae0b47a4 | ||
|
|
5fdc5e4fee | ||
|
|
c960d00b0a | ||
|
|
53561407b8 | ||
|
|
284f8f985a | ||
|
|
aa284c5ffd | ||
|
|
326df0456b | ||
|
|
4dc958e1bd | ||
|
|
add519e164 | ||
|
|
ad8247b806 | ||
|
|
6c93e8de1d | ||
|
|
3a1663febc | ||
|
|
5ef274b988 | ||
|
|
346fb74751 | ||
|
|
1b885818fe | ||
|
|
61756aee19 | ||
|
|
8ff4f75ead | ||
|
|
55b7e4bbf0 | ||
|
|
a33c840939 | ||
|
|
f371e67ce8 | ||
|
|
b49e08fe04 | ||
|
|
a76d16931c | ||
|
|
829978a37d | ||
|
|
875287574f | ||
|
|
4d5ec9be3f | ||
|
|
f5f5a2dcc1 | ||
|
|
2a125ca92d | ||
|
|
31ec7bcbea | ||
|
|
2257fa36ec | ||
|
|
8bf638c60f | ||
|
|
e9c14a02d3 | ||
|
|
c1ad82ff8c | ||
|
|
6d5a65cac6 | ||
|
|
d728a1a6c7 | ||
|
|
b39b29dfea | ||
|
|
25c4453dc5 | ||
|
|
eefbd72a64 | ||
|
|
cbc3a3b595 | ||
|
|
9142025df6 | ||
|
|
69f884dcd3 | ||
|
|
768a23f7eb | ||
|
|
2813840769 | ||
|
|
ef0d998fbc | ||
|
|
d1a5988bfc | ||
|
|
4f1d2252f0 | ||
|
|
d7f8754282 | ||
|
|
473773723b | ||
|
|
85a02d40c6 | ||
|
|
264c9a0fc9 | ||
|
|
b97e436a50 | ||
|
|
d48ec7e296 | ||
|
|
91f4cf0ebc | ||
|
|
6dd8470835 | ||
|
|
e8621cb738 | ||
|
|
face6d449b | ||
|
|
6eabd1d692 | ||
|
|
f4822cd757 | ||
|
|
98e2d27c77 | ||
|
|
c84cbfb36a | ||
|
|
3262a4ddc2 | ||
|
|
db9e458cf9 | ||
|
|
46a59b7550 | ||
|
|
0213a129ce | ||
|
|
26a6147a56 | ||
|
|
1129cee0ff | ||
|
|
e500e4bdf4 | ||
|
|
e485bd4909 | ||
|
|
83ef48d0ac | ||
|
|
346291af7b | ||
|
|
9c0f0cad70 | ||
|
|
9fbbc9db98 | ||
|
|
a3efa1ea6c | ||
|
|
3176f7d06c | ||
|
|
0b7d2e3a68 | ||
|
|
300a4be060 | ||
|
|
7896e58afc | ||
|
|
63e8865123 | ||
|
|
dbcad08a35 | ||
|
|
3459a24b0a | ||
|
|
1fe749c114 | ||
|
|
2972dbca00 | ||
|
|
06215ca932 | ||
|
|
36d5798a2e | ||
|
|
1e6b3c5ae1 | ||
|
|
c585d91e79 | ||
|
|
3615ca5b02 | ||
|
|
a61e5a6736 | ||
|
|
6198d0abbc | ||
|
|
a36e6a2e07 | ||
|
|
60892f2b9c | ||
|
|
cc1c5b7e10 | ||
|
|
e2e0167880 | ||
|
|
5ead2edaa0 | ||
|
|
84e530bc1a | ||
|
|
bf16783fb7 | ||
|
|
53fe1568c9 | ||
|
|
bc8095ce33 | ||
|
|
9bb876e6da | ||
|
|
94d4dae1fe | ||
|
|
5fcb9ca2bd | ||
|
|
10648f44ac | ||
|
|
84d507b770 | ||
|
|
4910b06f2c | ||
|
|
170ba98b20 | ||
|
|
6f80f36f2e | ||
|
|
b1c5d3644e | ||
|
|
e20fdac9df | ||
|
|
2379fd80fc | ||
|
|
85ea295e92 | ||
|
|
ca9979f9fb | ||
|
|
2272516d09 | ||
|
|
f588ef2912 | ||
|
|
6c2a2b91b4 | ||
|
|
4ffac80710 | ||
|
|
cff06cccf7 | ||
|
|
3b4a6afe01 | ||
|
|
51799ef70e | ||
|
|
ad24092fd1 | ||
|
|
ba506170e9 | ||
|
|
3a7ed33de1 | ||
|
|
d2d0f399db | ||
|
|
8fe964f269 | ||
|
|
ccef1ad49e | ||
|
|
4f5b2ec4b4 | ||
|
|
bf5cdcb6b4 | ||
|
|
ae1e680319 | ||
|
|
b34a91eeaa | ||
|
|
d72bc78550 | ||
|
|
7d72875227 | ||
|
|
23480a5698 | ||
|
|
84dbdf2ccb | ||
|
|
aacf2ad68c | ||
|
|
f88f38f7d2 | ||
|
|
4ab6436f93 | ||
|
|
ede4b61980 | ||
|
|
06fbc9bdd3 | ||
|
|
28331bca9f | ||
|
|
83ca4b84f9 | ||
|
|
17e8eafe33 | ||
|
|
59fb90a5ee | ||
|
|
808c7453a4 | ||
|
|
68853fecc3 | ||
|
|
38d374d4b9 | ||
|
|
2791d99f9d | ||
|
|
d337dff5fa | ||
|
|
d749f85a60 | ||
|
|
bfe728526a | ||
|
|
e83bd759e6 | ||
|
|
e2f49536f5 | ||
|
|
c78bf6c807 | ||
|
|
27dbfc7aef | ||
|
|
4d93d18af7 | ||
|
|
3efa51af40 | ||
|
|
432d458c02 | ||
|
|
b216ed99b4 | ||
|
|
9620893fa4 | ||
|
|
aef6d49b48 | ||
|
|
e17cd12c3c | ||
|
|
4bd1d064bb | ||
|
|
625c46d568 | ||
|
|
6dbd29e6a4 | ||
|
|
5585c7da7f | ||
|
|
fe15984a59 | ||
|
|
693a9c9453 | ||
|
|
86bbc9f15b | ||
|
|
a4daa08e5c | ||
|
|
d4c4515944 | ||
|
|
e37bd4eba6 | ||
|
|
7906ac63b5 | ||
|
|
59dab0a558 | ||
|
|
661af854fa | ||
|
|
b587d3a78d | ||
|
|
bd47e9d47b | ||
|
|
fc88a0186f | ||
|
|
9552accaec | ||
|
|
04d335db15 | ||
|
|
2f64680b63 | ||
|
|
4cd2ff040d | ||
|
|
bd9b2f9f06 | ||
|
|
9360bd49a6 | ||
|
|
5d3186ac49 | ||
|
|
4cc2450b37 | ||
|
|
a1d760fc36 | ||
|
|
eef68e0a94 | ||
|
|
3e2d9a6a27 | ||
|
|
ce42d47383 | ||
|
|
adbf098166 | ||
|
|
5431c6937f | ||
|
|
61bd0e7265 | ||
|
|
803bd55f70 | ||
|
|
f85c4dd458 | ||
|
|
52acd34a61 | ||
|
|
b60621c428 | ||
|
|
39c6e3712b | ||
|
|
39ad2b2378 | ||
|
|
f3faa10fcc | ||
|
|
6b354748ba | ||
|
|
bccd64de19 | ||
|
|
0d88595baf | ||
|
|
e4903c1a47 | ||
|
|
7f2624c9a1 | ||
|
|
e4f7446bec | ||
|
|
a2bba7c8f1 | ||
|
|
ec909d0775 | ||
|
|
b78d481bb1 | ||
|
|
474076a550 | ||
|
|
e9693e987f | ||
|
|
0c52960d7a | ||
|
|
5889ba4293 | ||
|
|
f1b5e72b99 | ||
|
|
14f17e76e1 | ||
|
|
5bbce7a1de | ||
|
|
67ef790abc | ||
|
|
c250921643 | ||
|
|
aafd79078f | ||
|
|
fe8ba4d356 | ||
|
|
60ca1cbcf3 | ||
|
|
8cca34a00e | ||
|
|
f4d4ab691b | ||
|
|
206fecf872 | ||
|
|
4c62304a1d | ||
|
|
4c2a14ff43 | ||
|
|
bec16efbd7 | ||
|
|
c44340a351 | ||
|
|
65f5dd1dd5 | ||
|
|
552359ce03 | ||
|
|
5ad4571ddf | ||
|
|
380e2dd153 | ||
|
|
1c789f6862 | ||
|
|
a073f29006 | ||
|
|
d21ce08548 | ||
|
|
f88abc5b1f | ||
|
|
d50a531934 | ||
|
|
cf7f2b762f | ||
|
|
0f2befd327 | ||
|
|
f6b5c31e39 | ||
|
|
8c3661c01c | ||
|
|
078a53e6a0 | ||
|
|
4a31ad0d53 | ||
|
|
d1f2255d38 | ||
|
|
f9085327e7 | ||
|
|
57dcbe0aea | ||
|
|
19a4f65fd1 | ||
|
|
92c2d17910 | ||
|
|
3d5e415c87 | ||
|
|
133155f4cc | ||
|
|
56ddd496c5 | ||
|
|
b185316a6e | ||
|
|
0c995d0ae1 | ||
|
|
63dd0fc4ae | ||
|
|
765d58b8eb | ||
|
|
9cbde911ce | ||
|
|
7eec1d8e1d | ||
|
|
abf4a5cf43 | ||
|
|
af1e83422e | ||
|
|
db07d783a2 | ||
|
|
9b3d97470f | ||
|
|
c48c3fc8ed | ||
|
|
6157ebe3b8 | ||
|
|
fe11b5a473 | ||
|
|
1049d4c53a | ||
|
|
0f80df7b2e | ||
|
|
16d97ab72c | ||
|
|
5ceb973ee9 | ||
|
|
bb68aacee4 | ||
|
|
b73ce68dbd | ||
|
|
d4fcb59965 | ||
|
|
8f441a020e | ||
|
|
3a9ecf0bce | ||
|
|
dee040a5b5 | ||
|
|
dbd6982b3a | ||
|
|
a2f8ad1396 | ||
|
|
be2f857670 | ||
|
|
b2e98e9353 | ||
|
|
15930a42b8 | ||
|
|
f4613b8db1 | ||
|
|
fd8a718797 | ||
|
|
01fd3905be | ||
|
|
7c6a33a36c | ||
|
|
b41f2dcda3 | ||
|
|
2f1108421e | ||
|
|
23d2b87a52 | ||
|
|
06d0a7c17c | ||
|
|
7ddac1945e | ||
|
|
4eb3cff129 | ||
|
|
c9ddea6d03 | ||
|
|
a64c1ff0f4 | ||
|
|
d64882e19b | ||
|
|
ddcafdd9b3 | ||
|
|
ac15807ba4 | ||
|
|
68971e2162 | ||
|
|
b99e1111f6 | ||
|
|
eb5b5331fb | ||
|
|
362e463b26 | ||
|
|
90a33fb19c | ||
|
|
ea3a2eefe7 | ||
|
|
5e6489f1a2 | ||
|
|
3ee9c2b9d8 | ||
|
|
5a079defc7 | ||
|
|
47041885ca | ||
|
|
866f3f189f | ||
|
|
89843685c2 | ||
|
|
af66af07a0 | ||
|
|
1bc4420734 | ||
|
|
607f32615f | ||
|
|
2228cb6a9a | ||
|
|
6e5a2208c0 | ||
|
|
1d9bafe196 | ||
|
|
ed8674c0f9 | ||
|
|
59bacd932a | ||
|
|
e7de6400e5 | ||
|
|
70a851fe44 | ||
|
|
73233b2e90 | ||
|
|
5a108c5cde | ||
|
|
7b67eed3dd | ||
|
|
128440b16f | ||
|
|
ea3ba6f534 | ||
|
|
5667a92472 | ||
|
|
2b1d60397d | ||
|
|
41e7c3d70b | ||
|
|
29af6586f2 | ||
|
|
dd11fa9320 | ||
|
|
bd57096b66 | ||
|
|
bde556fc10 | ||
|
|
85b4f5d593 | ||
|
|
1523586717 | ||
|
|
609ffc10a9 | ||
|
|
f54de08073 | ||
|
|
f91c01919b | ||
|
|
8fdd8179b9 | ||
|
|
c1dbfee2a9 | ||
|
|
d9af9472f0 | ||
|
|
3df091e7cf | ||
|
|
6b09c5dfae | ||
|
|
b8c79e689b | ||
|
|
ba0efda2f0 | ||
|
|
328169cd2e | ||
|
|
e54471abbc | ||
|
|
b7790177e0 | ||
|
|
6ae7309c54 | ||
|
|
2e18ad7160 | ||
|
|
6be44f59da | ||
|
|
de8a3c17a2 | ||
|
|
ed679fef9d | ||
|
|
28a0e8ebe6 | ||
|
|
9a8aef6b6d | ||
|
|
0a4a486048 | ||
|
|
cac479102a | ||
|
|
2fcce20c73 | ||
|
|
0fea86c10a | ||
|
|
f2a6805f8b | ||
|
|
474ab531ea | ||
|
|
c3b3ad52a9 | ||
|
|
012a36d97c | ||
|
|
f1c38f5f16 | ||
|
|
111a670d66 | ||
|
|
212504bbd4 | ||
|
|
b8a8f1638f | ||
|
|
1e77caedbc | ||
|
|
c44d0ed619 | ||
|
|
96e6319ee1 | ||
|
|
64eeaf8b9d | ||
|
|
04b8f16576 | ||
|
|
6c44aa4d76 | ||
|
|
584d3ad374 | ||
|
|
a7a5619523 | ||
|
|
625967fc15 | ||
|
|
3153196343 | ||
|
|
11ef780adf | ||
|
|
05506a24d7 | ||
|
|
2e25d2d885 | ||
|
|
a696efc3ef | ||
|
|
54b149ce71 | ||
|
|
4e54cee693 | ||
|
|
63ab9df275 | ||
|
|
7cb5bc8902 | ||
|
|
c0ca4e6b79 | ||
|
|
f8be2f23a1 | ||
|
|
50497e8013 | ||
|
|
8264cef004 | ||
|
|
66ab1c484c | ||
|
|
94cea25e2e | ||
|
|
0cf2928761 | ||
|
|
e7f8d7103f | ||
|
|
b0627b4ce6 | ||
|
|
c3cce53aa2 | ||
|
|
0a3631db6a | ||
|
|
12b9002c0e | ||
|
|
7390e0ac66 | ||
|
|
9bfa90dc0e | ||
|
|
060864f7af | ||
|
|
94ce1d1193 | ||
|
|
9fea22885e | ||
|
|
657b9ff808 | ||
|
|
8ab1190082 | ||
|
|
fee6d4f282 | ||
|
|
5cdf170511 | ||
|
|
cb41f1cc2a | ||
|
|
dd336a5581 | ||
|
|
833cdb0706 | ||
|
|
0bcae4e0c0 | ||
|
|
d928ac744e | ||
|
|
756c78bfcc | ||
|
|
f137910e63 | ||
|
|
f20b39d02e | ||
|
|
d36810ab42 | ||
|
|
9190029fcc | ||
|
|
e2794cfa3f | ||
|
|
2286268929 | ||
|
|
a9fb5647b8 | ||
|
|
dfc08b8f38 | ||
|
|
ab13b2ddfc | ||
|
|
8b6156abd6 | ||
|
|
44b07d8dfa | ||
|
|
936fee0afa | ||
|
|
c085eb650f | ||
|
|
61c2a88a32 | ||
|
|
a99b2a6799 | ||
|
|
e59fed7d9b | ||
|
|
682a61ad26 | ||
|
|
76c9bbc06d | ||
|
|
36488d21da | ||
|
|
d0a4e542af | ||
|
|
8d22eafe3f | ||
|
|
41a8ded182 | ||
|
|
0274ce4619 | ||
|
|
b11acdfbea | ||
|
|
f885459a43 | ||
|
|
5d3ba1ad6c | ||
|
|
d5903c5374 | ||
|
|
44138f499e | ||
|
|
d6a11b839b | ||
|
|
33ef7ad024 | ||
|
|
6684dff14b | ||
|
|
43a6e13f4b | ||
|
|
4afbf02bdd | ||
|
|
951a313331 | ||
|
|
3870bd04b8 | ||
|
|
117a0d8b7b | ||
|
|
b72ea1ff07 | ||
|
|
e47e9f6763 | ||
|
|
b736880787 | ||
|
|
ffd1bcf72f | ||
|
|
f9a6da05df | ||
|
|
0518c6f618 | ||
|
|
ad9303b97b | ||
|
|
754b02aa3c | ||
|
|
0a6dbc91ae | ||
|
|
5c83e2ac5b | ||
|
|
36d154babf | ||
|
|
c351293394 | ||
|
|
e8aef7d29e | ||
|
|
3678bda409 | ||
|
|
1d70b58d17 | ||
|
|
11268331a8 | ||
|
|
74c13906ed | ||
|
|
4b3290dd8c | ||
|
|
c97294a066 | ||
|
|
02daeac41b | ||
|
|
aeefdffaab | ||
|
|
2b4f03feef | ||
|
|
00cc9d4150 | ||
|
|
21fd894d75 | ||
|
|
c391882651 | ||
|
|
5b5e7fb9b7 | ||
|
|
9180a99342 | ||
|
|
3af7c7b57a | ||
|
|
004c266433 | ||
|
|
0aef321c73 | ||
|
|
145722b20d | ||
|
|
865fdd7962 | ||
|
|
6ffc407158 | ||
|
|
be590312f7 | ||
|
|
bce9514739 | ||
|
|
fcfb063eca | ||
|
|
da4b1ae0fb | ||
|
|
80916d5ed7 | ||
|
|
911adfd04d | ||
|
|
b71b336a69 | ||
|
|
f9944e28b0 | ||
|
|
d54c3f4fc7 | ||
|
|
91f27ba176 | ||
|
|
ae4ca3b5bb | ||
|
|
bb63bcd520 | ||
|
|
e671d05105 | ||
|
|
e116cc3206 | ||
|
|
85ae0cb78e | ||
|
|
6f0c2a0260 | ||
|
|
9096a443ea | ||
|
|
b38fc7b3c1 | ||
|
|
1c4d4f3e36 | ||
|
|
06e829936e | ||
|
|
4f5f56e4a5 | ||
|
|
d511059cfa | ||
|
|
da53d8cbf4 | ||
|
|
87b6374351 | ||
|
|
39bbd7c795 | ||
|
|
890c961383 | ||
|
|
688a1b6305 | ||
|
|
722a152a74 | ||
|
|
397d2ca312 | ||
|
|
b6edddbe8b | ||
|
|
ec0ec55ab5 | ||
|
|
9773e98d8a | ||
|
|
e2c02f825f | ||
|
|
365ff593f3 | ||
|
|
58caff3411 | ||
|
|
7aaa6422b4 | ||
|
|
8d0a90a838 | ||
|
|
e7dbcfe21f | ||
|
|
555286849e | ||
|
|
48b89a5db7 | ||
|
|
3fd35636ad | ||
|
|
73b961e885 | ||
|
|
0cc09872b6 | ||
|
|
7d6ccc40c2 | ||
|
|
011a9f23b9 | ||
|
|
52c3fb03a2 | ||
|
|
0f3997c6ca | ||
|
|
4c4456c808 | ||
|
|
7179b37d95 | ||
|
|
b93894953d | ||
|
|
d62d7dd84f | ||
|
|
b805ce06c2 | ||
|
|
697228eae0 | ||
|
|
3513a64351 | ||
|
|
0685f06200 | ||
|
|
0ecf04dcc5 | ||
|
|
39c10867a0 | ||
|
|
8dc604ac8b | ||
|
|
64b48f4458 | ||
|
|
002dc92d89 | ||
|
|
dc6a176282 | ||
|
|
fc74759231 | ||
|
|
57b96f38a9 | ||
|
|
b4addd0567 | ||
|
|
e7da56baf4 | ||
|
|
ddcdc11099 | ||
|
|
906d706961 | ||
|
|
7592f31596 | ||
|
|
07a23cab10 | ||
|
|
75f046fa81 | ||
|
|
3d44471659 | ||
|
|
4de26bed93 | ||
|
|
c90d283ff5 | ||
|
|
6978d842fb | ||
|
|
5dcf531048 | ||
|
|
2895e2e86f | ||
|
|
4fba251fba | ||
|
|
03641ffbee | ||
|
|
123b813073 | ||
|
|
ae636a0d32 | ||
|
|
1d3054e7a6 | ||
|
|
1c74bab1cc | ||
|
|
ee9389d089 | ||
|
|
da2806acde | ||
|
|
f870e365fa | ||
|
|
b4db23a7b3 | ||
|
|
2e73559f33 | ||
|
|
aeb6486473 | ||
|
|
80fd9e3cbb | ||
|
|
f9ba35af64 | ||
|
|
de11ed4fc6 | ||
|
|
fc4250b02b | ||
|
|
99a32b93fb | ||
|
|
15746cbf56 | ||
|
|
6b8b39a7bd | ||
|
|
f56dc722d9 | ||
|
|
ebda21c68a | ||
|
|
60521e20ff | ||
|
|
cfacd5da1e | ||
|
|
a7324ebad2 | ||
|
|
12e921ab15 | ||
|
|
7170d488bd | ||
|
|
e67318e049 | ||
|
|
48a0a95e8f | ||
|
|
cd435c4130 | ||
|
|
03606c13aa | ||
|
|
f4c5289cfc | ||
|
|
51cdb981f4 | ||
|
|
f7969621d6 | ||
|
|
696dce68fb | ||
|
|
19372a7210 | ||
|
|
745de229cc | ||
|
|
b3877b5f0b | ||
|
|
70dc5a5c4c | ||
|
|
a8c5e0cc95 | ||
|
|
f20aba63a6 | ||
|
|
6a1ca7b9c9 | ||
|
|
00db7d150b | ||
|
|
f25d80c38b | ||
|
|
259397db9d | ||
|
|
2fba6c361a | ||
|
|
5467671a21 | ||
|
|
1b92fa94bc | ||
|
|
99966c17da | ||
|
|
de6f52030c | ||
|
|
142e85be04 | ||
|
|
ed2ad8e8e3 | ||
|
|
97ce61ac44 | ||
|
|
7449ad2763 | ||
|
|
6d40d94127 | ||
|
|
c10cc30f40 | ||
|
|
6048ebf871 | ||
|
|
2ccd6d54b7 | ||
|
|
a9476dfe37 | ||
|
|
fa8c1f1a37 | ||
|
|
12922c3abd | ||
|
|
c5e43a1327 | ||
|
|
2b6ae3127b | ||
|
|
8139070754 | ||
|
|
5ad0a84039 | ||
|
|
a7e7d53e2b | ||
|
|
45074841a4 | ||
|
|
318f0c89b2 | ||
|
|
afc1e24571 | ||
|
|
01095bc652 | ||
|
|
2c1bf4dbd9 | ||
|
|
aee36c40cd | ||
|
|
b79aa686bb | ||
|
|
697132561f | ||
|
|
8196621be5 | ||
|
|
aff83087a3 | ||
|
|
712d2bdec0 | ||
|
|
94c0ccf2bf | ||
|
|
36210f0a27 | ||
|
|
ef265e23f8 | ||
|
|
b61b4e1c90 | ||
|
|
20379028e8 | ||
|
|
e562b73eff | ||
|
|
5cd23daf4e | ||
|
|
0aa8d89b16 | ||
|
|
0a1f4d6088 | ||
|
|
fbfeb98ecf | ||
|
|
6ba68da811 | ||
|
|
9e986db840 | ||
|
|
bcaa755c4e | ||
|
|
1574dc78df | ||
|
|
e8a697cb6d | ||
|
|
fe9cbd982d | ||
|
|
3b08e5e547 | ||
|
|
a97e623d04 | ||
|
|
f21b6a4777 | ||
|
|
fe4f51617c | ||
|
|
790524e391 | ||
|
|
f1783530ac | ||
|
|
e25d31618c | ||
|
|
b57d2ff702 | ||
|
|
7aae2bd452 | ||
|
|
a5b098c4a7 | ||
|
|
149ce70ce2 | ||
|
|
1867abbbe7 | ||
|
|
dd36ef5712 | ||
|
|
6155d836a5 | ||
|
|
75ab0dd509 | ||
|
|
c36eeadab1 | ||
|
|
09f53ea0bb | ||
|
|
52f0e0bc93 | ||
|
|
ca6153e8f1 | ||
|
|
03816373b3 | ||
|
|
513c4a4562 | ||
|
|
ecdef71580 | ||
|
|
1d787ed222 | ||
|
|
188119aa83 | ||
|
|
8b5a194dd6 | ||
|
|
1b6f96ac2b | ||
|
|
2fb3c727a7 | ||
|
|
3fca8f765c | ||
|
|
ad55c8fb96 | ||
|
|
f745f27694 | ||
|
|
784b250de8 | ||
|
|
05ec9cc424 | ||
|
|
fd79145b73 | ||
|
|
e558581667 | ||
|
|
24951e8a38 | ||
|
|
6fe48243c7 | ||
|
|
594ad27952 | ||
|
|
cfe1c44260 | ||
|
|
ea8da18338 | ||
|
|
4e36edb5d6 | ||
|
|
44bdac6e11 | ||
|
|
055c71e8d0 | ||
|
|
b5e637bed5 | ||
|
|
544bc9a70c | ||
|
|
2966420d24 | ||
|
|
7521b89b3e | ||
|
|
1a6f9b8d1c | ||
|
|
0d7c8635b3 | ||
|
|
ba180f915a | ||
|
|
d9b67ae0ef | ||
|
|
fe57a9e48f | ||
|
|
f5989aa4f2 | ||
|
|
91621704a2 | ||
|
|
16f482f723 | ||
|
|
7384d25cb3 | ||
|
|
35f788a89c | ||
|
|
3fb04aceb9 | ||
|
|
f55574df36 | ||
|
|
ca9e8fc5a7 | ||
|
|
d40e9ffc13 | ||
|
|
9aa38d99fb | ||
|
|
2e6d82a72b | ||
|
|
43476bd773 | ||
|
|
f84b3414c8 | ||
|
|
4b1edf7bb0 | ||
|
|
7e6495618b | ||
|
|
fc7c45d4d0 | ||
|
|
7f0065c806 | ||
|
|
6bfbec8c88 | ||
|
|
ce3d53d2ee | ||
|
|
2c29f6f5ab | ||
|
|
2dc1ba1d62 | ||
|
|
269676ee2e | ||
|
|
abd7ed5c70 | ||
|
|
6a3ac66208 | ||
|
|
78d737f3f4 | ||
|
|
cc259c2d15 | ||
|
|
5e231db631 | ||
|
|
3f7b8554dd | ||
|
|
a520e93b5b | ||
|
|
f3a6c541ec | ||
|
|
693e158759 | ||
|
|
c79ffbac5c | ||
|
|
a983e6cf60 | ||
|
|
68101eeffa | ||
|
|
293b8eeda8 | ||
|
|
7a1d789e9a | ||
|
|
ebbc68dfae | ||
|
|
9cad1a912a | ||
|
|
033698c51d | ||
|
|
b0a7706812 | ||
|
|
179498d971 | ||
|
|
5330248f6e | ||
|
|
0ba0ea5e1f | ||
|
|
dc84445e2e | ||
|
|
f25f0db10e | ||
|
|
75089a3af8 | ||
|
|
c725ed47f5 | ||
|
|
3692318c38 | ||
|
|
56cd29dff2 | ||
|
|
8d5d1b7dcc | ||
|
|
bd9221beaa | ||
|
|
623ecd2503 | ||
|
|
ca38a50e1a | ||
|
|
4fdc77f86f | ||
|
|
6a780f01bd | ||
|
|
a667aa2f71 | ||
|
|
539b84b561 | ||
|
|
ddde372fad | ||
|
|
ef134ffb1b | ||
|
|
0099c10e4e | ||
|
|
3f0d71411e | ||
|
|
b5568f9ace | ||
|
|
7ccdbfd596 | ||
|
|
01b79f640f | ||
|
|
d89b609960 | ||
|
|
9ad6685310 | ||
|
|
976fbf32ba | ||
|
|
5008a66a5b | ||
|
|
674a15daa1 | ||
|
|
8fa2e28729 | ||
|
|
e201268f46 | ||
|
|
8c4deb80e5 | ||
|
|
0b6e100aff | ||
|
|
51a8d5b9f0 | ||
|
|
69c2668530 | ||
|
|
e9ea4cc953 | ||
|
|
38522f60ea | ||
|
|
7756644eb1 | ||
|
|
154657a374 | ||
|
|
5df2a58003 | ||
|
|
b4bb92d136 | ||
|
|
8d0c3281cd | ||
|
|
02311538d6 | ||
|
|
19a6cc74de | ||
|
|
c83b6ed3a5 | ||
|
|
3dfb9d2e5e | ||
|
|
b5fad71b18 | ||
|
|
ffb382e3bc | ||
|
|
d0b9b6a3b4 | ||
|
|
fff011f60a | ||
|
|
258a6328a8 | ||
|
|
04c6ea78c7 | ||
|
|
ee9eb55b59 | ||
|
|
49e7417741 | ||
|
|
233e8e58e8 | ||
|
|
4ffd60cf52 | ||
|
|
43ce8222fc | ||
|
|
46798ed845 | ||
|
|
cd80d9408d | ||
|
|
a7503303d5 | ||
|
|
d2fce9b16d | ||
|
|
8db3fb03f9 | ||
|
|
19084b8182 | ||
|
|
fdc9e9d7f5 | ||
|
|
9d753f24b7 | ||
|
|
a4f82a2dc4 | ||
|
|
d2e22dc794 | ||
|
|
645c78e2f4 | ||
|
|
cb71e05c51 | ||
|
|
7c9b53c75c | ||
|
|
52eb9e4276 | ||
|
|
8deefd56db | ||
|
|
e24dbcefb6 | ||
|
|
061803d7b1 | ||
|
|
4f2887df64 | ||
|
|
162b152133 | ||
|
|
9f5a972816 | ||
|
|
923effe11d | ||
|
|
6301c707cd | ||
|
|
c23c2dbe85 | ||
|
|
515d2cd3e7 | ||
|
|
27551a8399 | ||
|
|
33967a09f6 | ||
|
|
33b366b9b9 | ||
|
|
58e93d5e1b | ||
|
|
bf9d50ccc4 | ||
|
|
59a9e2549c | ||
|
|
f55b421853 | ||
|
|
d296d91272 | ||
|
|
5df94da216 | ||
|
|
4dde59368c | ||
|
|
f509937037 | ||
|
|
5aff07561d | ||
|
|
feff5b2327 | ||
|
|
2d85c437cd | ||
|
|
0ab33ab075 | ||
|
|
597f2c0a8c | ||
|
|
16fbdcf107 | ||
|
|
ae3135c770 | ||
|
|
594d981094 | ||
|
|
91b920f18e | ||
|
|
871c5c66b4 | ||
|
|
dd2ae15531 | ||
|
|
81e7826568 | ||
|
|
477e25ae2f | ||
|
|
09191622e5 | ||
|
|
42565129ee | ||
|
|
65c5c99c68 | ||
|
|
6f347f351a | ||
|
|
3e2eb8c1a0 | ||
|
|
5e421b4024 | ||
|
|
39d9b35e27 | ||
|
|
a849f3f5d4 | ||
|
|
4ad113d836 | ||
|
|
7c7786f7d0 | ||
|
|
a2d644f708 | ||
|
|
a7eea6e4dd | ||
|
|
b443f605ed | ||
|
|
871fe7680b | ||
|
|
45c0bc3610 | ||
|
|
417ff281ee | ||
|
|
fe78f944a6 | ||
|
|
00504a3f6d | ||
|
|
470dfc9bec | ||
|
|
39b6637c7c | ||
|
|
616bb444ec | ||
|
|
1890b8cbd3 | ||
|
|
dd24fd47f7 | ||
|
|
79b30dddf9 | ||
|
|
239502368a | ||
|
|
66a031f7a0 | ||
|
|
1dca49cecc | ||
|
|
cbe1ffed55 | ||
|
|
f699adda33 | ||
|
|
ea8de883ac | ||
|
|
b950bf0e6e | ||
|
|
9452c200a0 | ||
|
|
6fb871a088 | ||
|
|
d024045638 | ||
|
|
745a3aeeac | ||
|
|
7cd867b936 | ||
|
|
e7fc6bcc6e | ||
|
|
c8b50eec1e | ||
|
|
521b216602 | ||
|
|
3254641c5a | ||
|
|
0fe74a8b43 | ||
|
|
199827635f | ||
|
|
4c3f620255 | ||
|
|
f87d2d1fcc | ||
|
|
ae2fc19fe5 | ||
|
|
354e1dc337 | ||
|
|
1824f10f07 | ||
|
|
ffc8b6fd89 | ||
|
|
a76f43b66c | ||
|
|
f50059a11a | ||
|
|
87aebd2cdf | ||
|
|
44743aade5 | ||
|
|
76cf284b77 | ||
|
|
15faa6610c | ||
|
|
ac9a1350c2 | ||
|
|
009e3f9cd7 | ||
|
|
ef4b3c99f4 | ||
|
|
6a74b1c8bf | ||
|
|
49778d2fb6 | ||
|
|
d10c3ffbe4 | ||
|
|
58d62fde4d | ||
|
|
1dbe560734 | ||
|
|
1ca6c695e6 | ||
|
|
9b8e5c5684 | ||
|
|
42119b311d | ||
|
|
49e484d796 | ||
|
|
08c29b7325 | ||
|
|
3b3dbbab04 | ||
|
|
2bc2d81486 | ||
|
|
280e00981f | ||
|
|
fb19552920 | ||
|
|
5bf8b4d946 | ||
|
|
f319b1b93a | ||
|
|
9a4eb2a368 | ||
|
|
fb406bfc24 | ||
|
|
c73f01927a | ||
|
|
5b72afe8a0 | ||
|
|
d80206376a | ||
|
|
8e71006e86 | ||
|
|
da02ed9057 | ||
|
|
2e971b13aa | ||
|
|
7e6bed7ad8 | ||
|
|
fee19ad9de | ||
|
|
deb6410a5c | ||
|
|
5cc04e41fe | ||
|
|
c40d6af1e5 | ||
|
|
6164566cad | ||
|
|
34c3c04ead | ||
|
|
5846769b43 | ||
|
|
9ff6be6f0f | ||
|
|
e458534c93 | ||
|
|
f05de6d6eb | ||
|
|
9a2442bba6 | ||
|
|
dc34d4fc31 | ||
|
|
136e8d9d02 | ||
|
|
70c200d265 | ||
|
|
94bea54db3 | ||
|
|
594039ac42 | ||
|
|
84824b1024 | ||
|
|
ef72c594c4 | ||
|
|
6e2d42daf9 | ||
|
|
8f5df45edc | ||
|
|
2fcb7e532b | ||
|
|
135c30323b | ||
|
|
18e343d405 | ||
|
|
863e32c5cd | ||
|
|
83189013c6 | ||
|
|
0a0e4f1ba2 | ||
|
|
3eeab68261 | ||
|
|
421f84e05a | ||
|
|
434082cadb | ||
|
|
e6bba01798 | ||
|
|
c567376e35 | ||
|
|
6ba5dcaa06 | ||
|
|
8a95f23a23 | ||
|
|
966ad9d3b6 | ||
|
|
a2d6bd09f3 | ||
|
|
3374ac7606 | ||
|
|
3c5b02e54a | ||
|
|
789738c45f | ||
|
|
e97e82d119 | ||
|
|
4a0e33003b | ||
|
|
9a01c0d9cb | ||
|
|
cfed28c2ff | ||
|
|
b7e4fdf4d5 | ||
|
|
57b5588498 | ||
|
|
3275542426 | ||
|
|
d65c8fb06c | ||
|
|
0ec57e7fee | ||
|
|
10a13e737e | ||
|
|
11410000b4 | ||
|
|
859a8adc31 | ||
|
|
64b101785f | ||
|
|
e82e4bcfc8 | ||
|
|
5c88a1c63e | ||
|
|
b2bdb8ed02 | ||
|
|
0af2243245 | ||
|
|
2fef2763ab | ||
|
|
f4135a0a9f | ||
|
|
9df3ce018b | ||
|
|
f6b374f829 | ||
|
|
e517cbcf78 | ||
|
|
d850d7bbad | ||
|
|
8f8acf7a83 | ||
|
|
80051b8303 | ||
|
|
99c88cb0c5 | ||
|
|
8fcda32287 | ||
|
|
ecac0f177b | ||
|
|
d08f6f8238 | ||
|
|
57b3bc0496 | ||
|
|
2330ce2c28 | ||
|
|
5c9e55f3fb | ||
|
|
2e73bcb3a6 | ||
|
|
96d0c4a1db | ||
|
|
bfad9bd87f | ||
|
|
75245b3046 | ||
|
|
11c86405bf | ||
|
|
f2e60a0e11 | ||
|
|
da5f71773a | ||
|
|
1e0b133e19 | ||
|
|
fa77808319 | ||
|
|
2dce7ad1e2 | ||
|
|
d3c17ec337 | ||
|
|
b1fa740341 | ||
|
|
5fbb9bfe3b | ||
|
|
21e64e02bd | ||
|
|
5541224288 | ||
|
|
6b49ac6b46 | ||
|
|
dc70c0d31e | ||
|
|
a15ca7c374 | ||
|
|
5729855e4f | ||
|
|
51abb021bc | ||
|
|
c523817213 | ||
|
|
408dd9bc9d | ||
|
|
9c73502bdc | ||
|
|
a19708693b | ||
|
|
8683582c40 | ||
|
|
703f39f492 | ||
|
|
95cecdbc42 | ||
|
|
4f06cece37 | ||
|
|
8838e46578 | ||
|
|
e2b51f30ed | ||
|
|
a197fc8cb8 | ||
|
|
4b8017e34b | ||
|
|
3478a6fb6c | ||
|
|
ce9012c352 | ||
|
|
d53cd3c70b | ||
|
|
73444ce59b | ||
|
|
7fff17ba7c | ||
|
|
7063e1f56a | ||
|
|
4800cff87f | ||
|
|
19089f8b17 | ||
|
|
87f09ab5b0 | ||
|
|
98e0905eb3 | ||
|
|
3d3d670cd7 | ||
|
|
60a8db1c6c | ||
|
|
a447c39f69 | ||
|
|
b1b0da5228 | ||
|
|
c9012b10c5 | ||
|
|
aea6ad0f0c | ||
|
|
e90dc047bd | ||
|
|
a8b551e518 | ||
|
|
69c906014f | ||
|
|
d20fb5ddd7 | ||
|
|
05a62c5892 | ||
|
|
f9306d9c3c | ||
|
|
3abbdb4d15 | ||
|
|
5bc70b3150 | ||
|
|
dd3b85dca3 | ||
|
|
ea3a65d0b8 | ||
|
|
b9ce9f8576 | ||
|
|
ffd8863875 | ||
|
|
39b46bb3ef | ||
|
|
6abf13be41 | ||
|
|
03e1480476 | ||
|
|
44bc937499 | ||
|
|
2dcc38b92f | ||
|
|
3c87ccc5ff | ||
|
|
bcadfd4661 | ||
|
|
c1c6d0ee3a | ||
|
|
6313ecac1c | ||
|
|
60e457167d | ||
|
|
36206ddf6d | ||
|
|
b7a50b333e | ||
|
|
2821448dd8 | ||
|
|
8807cd828f | ||
|
|
846fb397c4 | ||
|
|
2b66af29aa | ||
|
|
22b14cfc5c | ||
|
|
3776e5698f | ||
|
|
e92c314b46 | ||
|
|
2987576a0a | ||
|
|
5edadfe8ea | ||
|
|
bc49825f55 |
2
.idea/ant.xml
generated
2
.idea/ant.xml
generated
@@ -3,7 +3,7 @@
|
||||
<component name="AntConfiguration">
|
||||
<buildFile url="file://$PROJECT_DIR$/compiler/frontend/buildLexer.xml" />
|
||||
<buildFile url="file://$PROJECT_DIR$/build.xml">
|
||||
<antCommandLine value="-J-XX:MaxPermSize=100m" />
|
||||
<antCommandLine value="-J-XX:MaxPermSize=100m -J-ea" />
|
||||
<maximumHeapSize value="1024" />
|
||||
</buildFile>
|
||||
<buildFile url="file://$PROJECT_DIR$/update_dependencies.xml" />
|
||||
|
||||
1
.idea/artifacts/KotlinJpsPlugin.xml
generated
1
.idea/artifacts/KotlinJpsPlugin.xml
generated
@@ -24,6 +24,7 @@
|
||||
<element id="module-output" name="deserialization" />
|
||||
<element id="extracted-dir" path="$PROJECT_DIR$/dependencies/native-platform-uberjar.jar" path-in-jar="/" />
|
||||
<element id="module-output" name="android-jps-plugin" />
|
||||
<element id="module-output" name="build" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
1
.idea/dictionaries/Nikolay_Krasko.xml
generated
1
.idea/dictionaries/Nikolay_Krasko.xml
generated
@@ -2,6 +2,7 @@
|
||||
<dictionary name="Nikolay.Krasko">
|
||||
<words>
|
||||
<w>accessors</w>
|
||||
<w>fqname</w>
|
||||
<w>goto</w>
|
||||
<w>gradle</w>
|
||||
<w>intrinsics</w>
|
||||
|
||||
8
.idea/dictionaries/dzharkov.xml
generated
Normal file
8
.idea/dictionaries/dzharkov.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="dzharkov">
|
||||
<words>
|
||||
<w>checkcast</w>
|
||||
<w>insn</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
BIN
.idea/icon.png
generated
Normal file
BIN
.idea/icon.png
generated
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
6
.idea/kotlinc.xml
generated
Normal file
6
.idea/kotlinc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinCompilerSettings">
|
||||
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check" />
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/libraries/kotlin_reflect.xml
generated
Normal file
9
.idea/libraries/kotlin_reflect.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-reflect">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
3
.idea/libraries/kotlin_runtime.xml
generated
3
.idea/libraries/kotlin_runtime.xml
generated
@@ -2,11 +2,12 @@
|
||||
<library name="kotlin-runtime">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar!/" />
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/libraries/stdlib/src" />
|
||||
<root url="file://$PROJECT_DIR$/core/builtins/native" />
|
||||
<root url="file://$PROJECT_DIR$/core/builtins/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
13
.idea/libraries/kotlin_test.xml
generated
Normal file
13
.idea/libraries/kotlin_test.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-test">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-test.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin" />
|
||||
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin.jvm" />
|
||||
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/junit/src/main/kotlin" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
4
.idea/modules.xml
generated
4
.idea/modules.xml
generated
@@ -13,6 +13,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/compiler/backend/backend.iml" group="compiler/java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/backend-common/backend-common.iml" filepath="$PROJECT_DIR$/compiler/backend-common/backend-common.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps-plugin/bare-plugin/bare-plugin.iml" filepath="$PROJECT_DIR$/jps-plugin/bare-plugin/bare-plugin.iml" group="ide/jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/build/build.iml" filepath="$PROJECT_DIR$/build/build.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/builtins/builtins.iml" filepath="$PROJECT_DIR$/core/builtins/builtins.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/builtins-serializer/builtins-serializer.iml" filepath="$PROJECT_DIR$/compiler/builtins-serializer/builtins-serializer.iml" group="compiler/cli" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/cli/cli.iml" filepath="$PROJECT_DIR$/compiler/cli/cli.iml" group="compiler/cli" />
|
||||
@@ -40,7 +41,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea-runner/idea-runner.iml" filepath="$PROJECT_DIR$/idea-runner/idea-runner.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" filepath="$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" filepath="$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" group="compiler/cli" />
|
||||
@@ -62,6 +63,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" filepath="$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" filepath="$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/serialization/serialization.iml" filepath="$PROJECT_DIR$/compiler/serialization/serialization.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/temp-jdk8/temp-jdk8.iml" filepath="$PROJECT_DIR$/temp-jdk8/temp-jdk8.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/util/util.iml" filepath="$PROJECT_DIR$/compiler/util/util.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/util.runtime/util.runtime.iml" filepath="$PROJECT_DIR$/core/util.runtime/util.runtime.iml" group="core" />
|
||||
</modules>
|
||||
|
||||
2
.idea/runConfigurations/IDEA__win_.xml
generated
2
.idea/runConfigurations/IDEA__win_.xml
generated
@@ -5,7 +5,7 @@
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=${JAVA_HOME}\lib\tools.jar,../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="1.7" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
|
||||
@@ -158,11 +158,11 @@
|
||||
<print-file-size-statistic path="${kotlin-home}/lib" file-name="kotlin-reflect.jar"/>
|
||||
|
||||
<print-file-size-statistic path="${kotlin-home}/lib" file-name="kotlin-jslib.jar"/>
|
||||
<print-file-size-statistic path="${output}" file-name="kotlin.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="builtins.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="builtins.meta.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="stdlib.js"/>
|
||||
<print-file-size-statistic path="${output}" file-name="stdlib.meta.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="kotlin.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="builtins.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="builtins.meta.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="stdlib.js"/>
|
||||
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="stdlib.meta.js"/>
|
||||
</target>
|
||||
|
||||
<target name="post_build" depends="zipArtifacts, revertTemplateFiles, printStatistics, remove_internal_artifacts, dont_remove_internal_artifacts"/>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="ant" level="project" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="library" name="kotlin-reflect" level="project" />
|
||||
<orderEntry type="module" module-name="preloader" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,7 +0,0 @@
|
||||
<!-- NOTE: this Antlib is deprecated. Use org/jetbrains/kotlin/ant/antlib.xml instead -->
|
||||
<!-- TODO: delete this file -->
|
||||
<antlib>
|
||||
<taskdef name="kotlinc" classname="org.jetbrains.kotlin.ant.Kotlin2JvmTask"/>
|
||||
<taskdef name="kotlin2js" classname="org.jetbrains.kotlin.ant.Kotlin2JsTask"/>
|
||||
<typedef name="withKotlin" classname="org.jetbrains.kotlin.ant.KotlinCompilerAdapter"/>
|
||||
</antlib>
|
||||
@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.ant
|
||||
import org.apache.tools.ant.types.Path
|
||||
import java.io.File
|
||||
|
||||
public class Kotlin2JsTask : KotlinCompilerBaseTask() {
|
||||
class Kotlin2JsTask : KotlinCompilerBaseTask() {
|
||||
override val compilerFqName = "org.jetbrains.kotlin.cli.js.K2JSCompiler"
|
||||
|
||||
public var library: Path? = null
|
||||
public var outputPrefix: File? = null
|
||||
public var outputPostfix: File? = null
|
||||
public var sourceMap: Boolean = false
|
||||
public var metaInfo: Boolean = false
|
||||
var library: Path? = null
|
||||
var outputPrefix: File? = null
|
||||
var outputPostfix: File? = null
|
||||
var sourceMap: Boolean = false
|
||||
var metaInfo: Boolean = false
|
||||
|
||||
/**
|
||||
* {@link K2JsArgumentConstants.CALL} (default) if need generate a main function call (main function will be auto detected)
|
||||
* {@link K2JsArgumentConstants.NO_CALL} otherwise.
|
||||
*/
|
||||
public var main: String? = null
|
||||
var main: String? = null
|
||||
|
||||
public fun createLibrary(): Path {
|
||||
fun createLibrary(): Path {
|
||||
val libraryPath = library
|
||||
if (libraryPath == null) {
|
||||
val t = Path(getProject())
|
||||
|
||||
@@ -20,15 +20,15 @@ import org.apache.tools.ant.types.Path
|
||||
import org.apache.tools.ant.types.Reference
|
||||
import java.io.File.pathSeparator
|
||||
|
||||
public class Kotlin2JvmTask : KotlinCompilerBaseTask() {
|
||||
class Kotlin2JvmTask : KotlinCompilerBaseTask() {
|
||||
override val compilerFqName = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"
|
||||
|
||||
public var includeRuntime: Boolean = true
|
||||
public var moduleName: String? = null
|
||||
var includeRuntime: Boolean = true
|
||||
var moduleName: String? = null
|
||||
|
||||
private var compileClasspath: Path? = null
|
||||
|
||||
public fun setClasspath(classpath: Path) {
|
||||
fun setClasspath(classpath: Path) {
|
||||
if (compileClasspath == null) {
|
||||
compileClasspath = classpath
|
||||
}
|
||||
@@ -37,14 +37,14 @@ public class Kotlin2JvmTask : KotlinCompilerBaseTask() {
|
||||
}
|
||||
}
|
||||
|
||||
public fun setClasspathRef(ref: Reference) {
|
||||
fun setClasspathRef(ref: Reference) {
|
||||
if (compileClasspath == null) {
|
||||
compileClasspath = Path(getProject())
|
||||
}
|
||||
compileClasspath!!.createPath().setRefid(ref)
|
||||
compileClasspath!!.createPath().refid = ref
|
||||
}
|
||||
|
||||
public fun addConfiguredClasspath(classpath: Path) {
|
||||
fun addConfiguredClasspath(classpath: Path) {
|
||||
setClasspath(classpath)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ object KotlinAntTaskUtil {
|
||||
|
||||
private val libPath: File by lazy {
|
||||
// Find path of kotlin-ant.jar in the filesystem and find kotlin-compiler.jar in the same directory
|
||||
val resourcePath = "/" + javaClass.getName().replace('.', '/') + ".class"
|
||||
val resourcePath = "/" + javaClass.name.replace('.', '/') + ".class"
|
||||
val jarConnection = javaClass.getResource(resourcePath).openConnection() as? JarURLConnection
|
||||
?: throw UnsupportedOperationException("Kotlin compiler Ant task should be loaded from the JAR file")
|
||||
val antTaskJarPath = File(jarConnection.getJarFileURL().toURI())
|
||||
val antTaskJarPath = File(jarConnection.jarFileURL.toURI())
|
||||
|
||||
antTaskJarPath.getParentFile()
|
||||
antTaskJarPath.parentFile
|
||||
}
|
||||
|
||||
val compilerJar: File by lazy {
|
||||
@@ -47,7 +47,7 @@ object KotlinAntTaskUtil {
|
||||
|
||||
private fun File.assertExists(): File {
|
||||
if (!this.exists()) {
|
||||
throw IllegalStateException("${getName()} is not found in the directory of Kotlin Ant task")
|
||||
throw IllegalStateException("${name} is not found in the directory of Kotlin Ant task")
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -68,5 +68,5 @@ object KotlinAntTaskUtil {
|
||||
|
||||
}
|
||||
|
||||
public val Task.defaultModuleName: String?
|
||||
val Task.defaultModuleName: String?
|
||||
get() = owningTarget?.name ?: project?.name
|
||||
@@ -70,7 +70,7 @@ class KotlinCompilerAdapter : Javac13() {
|
||||
// Javac13#execute passes everything in compileList to javac, which doesn't recognize .kt files
|
||||
val compileListForJavac = filterOutKotlinSources(compileList)
|
||||
|
||||
val hasKotlinFilesInSources = compileListForJavac.size() < compileList.size()
|
||||
val hasKotlinFilesInSources = compileListForJavac.size < compileList.size
|
||||
|
||||
if (hasKotlinFilesInSources) {
|
||||
kotlinc.execute()
|
||||
|
||||
@@ -24,25 +24,25 @@ import org.apache.tools.ant.types.Reference
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
|
||||
public abstract class KotlinCompilerBaseTask : Task() {
|
||||
abstract class KotlinCompilerBaseTask : Task() {
|
||||
protected abstract val compilerFqName: String
|
||||
|
||||
public val args: MutableList<String> = arrayListOf()
|
||||
val args: MutableList<String> = arrayListOf()
|
||||
|
||||
public var src: Path? = null
|
||||
public var output: File? = null
|
||||
public var nowarn: Boolean = false
|
||||
public var verbose: Boolean = false
|
||||
public var printVersion: Boolean = false
|
||||
public var failOnError: Boolean = true
|
||||
var src: Path? = null
|
||||
var output: File? = null
|
||||
var nowarn: Boolean = false
|
||||
var verbose: Boolean = false
|
||||
var printVersion: Boolean = false
|
||||
var failOnError: Boolean = true
|
||||
|
||||
public var noStdlib: Boolean = false
|
||||
var noStdlib: Boolean = false
|
||||
|
||||
public val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
|
||||
val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
|
||||
|
||||
public var exitCode: Int? = null
|
||||
var exitCode: Int? = null
|
||||
|
||||
public fun createSrc(): Path {
|
||||
fun createSrc(): Path {
|
||||
val srcPath = src
|
||||
if (srcPath == null) {
|
||||
val t = Path(getProject())
|
||||
@@ -53,11 +53,11 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
return srcPath.createPath()
|
||||
}
|
||||
|
||||
public fun setSrcRef(ref: Reference) {
|
||||
createSrc().setRefid(ref)
|
||||
fun setSrcRef(ref: Reference) {
|
||||
createSrc().refid = ref
|
||||
}
|
||||
|
||||
public fun createCompilerArg(): Commandline.Argument {
|
||||
fun createCompilerArg(): Commandline.Argument {
|
||||
val argument = Commandline.Argument()
|
||||
additionalArguments.add(argument)
|
||||
return argument
|
||||
@@ -65,7 +65,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
|
||||
abstract fun fillSpecificArguments()
|
||||
|
||||
public fun fillArguments() {
|
||||
fun fillArguments() {
|
||||
val sourcePaths = src ?: throw BuildException("\"src\" should be specified")
|
||||
args.addAll(sourcePaths.list().map { File(it).canonicalPath })
|
||||
|
||||
@@ -75,7 +75,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
if (verbose) args.add("-verbose")
|
||||
if (printVersion) args.add("-version")
|
||||
|
||||
args.addAll(additionalArguments.flatMap { it.getParts().toList() })
|
||||
args.addAll(additionalArguments.flatMap { it.parts.toList() })
|
||||
|
||||
fillSpecificArguments()
|
||||
}
|
||||
@@ -85,12 +85,12 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
|
||||
val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName)
|
||||
val compiler = compilerClass.newInstance()
|
||||
val exec = compilerClass.getMethod("execFullPathsInMessages", javaClass<PrintStream>(), javaClass<Array<String>>())
|
||||
val exec = compilerClass.getMethod("execFullPathsInMessages", PrintStream::class.java, Array<String>::class.java)
|
||||
|
||||
log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]");
|
||||
|
||||
val result = exec(compiler, System.err, args.toTypedArray())
|
||||
exitCode = (result as Enum<*>).ordinal()
|
||||
exitCode = (result as Enum<*>).ordinal
|
||||
|
||||
if (failOnError && exitCode != 0) {
|
||||
throw BuildException("Compile failed; see the compiler error output for details.")
|
||||
|
||||
185
build.xml
185
build.xml
@@ -6,14 +6,19 @@
|
||||
<!-- Set to false to disable compiler's javadoc generation. Speeds up the build -->
|
||||
<property name="generate.javadoc" value="true"/>
|
||||
|
||||
<!-- Set to false to prevent jarjar and metadata stripping on kotlin-reflect.jar and reflection sources. Use to debug reflection -->
|
||||
<property name="obfuscate.reflect" value="true"/>
|
||||
|
||||
<property name="max.heap.size.for.forked.jvm" value="1024m"/>
|
||||
|
||||
<property name="bootstrap.home" value="${basedir}/dependencies/bootstrap-compiler"/>
|
||||
<property name="bootstrap.compiler.home" value="${bootstrap.home}/Kotlin/kotlinc"/>
|
||||
<property name="bootstrap.runtime" value="${bootstrap.compiler.home}/lib/kotlin-runtime.jar"/>
|
||||
<property name="bootstrap.reflect" value="${bootstrap.compiler.home}/lib/kotlin-reflect.jar"/>
|
||||
<property name="bootstrap.kotlin.test" value="${bootstrap.compiler.home}/lib/kotlin-test.jar" />
|
||||
|
||||
<property name="output" value="${basedir}/dist"/>
|
||||
<property name="js.stdlib.output.dir" value="${output}/js"/>
|
||||
<property name="intermediate-sources" value="out/src" />
|
||||
<property name="kotlin-home" value="${output}/kotlinc"/>
|
||||
<property name="build.number" value="snapshot"/>
|
||||
@@ -55,6 +60,7 @@
|
||||
|
||||
<path id="classpath">
|
||||
<file file="${bootstrap.runtime}"/>
|
||||
<file file="${bootstrap.kotlin.test}" />
|
||||
<file file="${bootstrap.reflect}"/>
|
||||
<fileset dir="${idea.sdk}" includes="core/*.jar"/>
|
||||
<pathelement location="${protobuf.jar}"/>
|
||||
@@ -177,19 +183,33 @@
|
||||
<sequential if:true="${bootstrap.or.local.build}">
|
||||
<copy file="${bootstrap.runtime}" tofile="${kotlin-home}/lib/kotlin-runtime-internal-bootstrap.jar"/>
|
||||
<copy file="${bootstrap.reflect}" tofile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar"/>
|
||||
<copy file="${bootstrap.kotlin.test}" tofile="${kotlin-home}/lib/kotlin-test-internal-bootstrap.jar" failonerror="false"/>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar" update="true">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="kotlin-runtime-internal-bootstrap.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-test-internal-bootstrap.jar" update="true">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="kotlin-runtime-internal-bootstrap.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</sequential>
|
||||
|
||||
<sequential unless:true="${bootstrap.or.local.build}">
|
||||
<copy file="${bootstrap.runtime}" todir="${kotlin-home}/lib"/>
|
||||
<copy file="${bootstrap.reflect}" todir="${kotlin-home}/lib"/>
|
||||
<copy file="${bootstrap.kotlin.test}" todir="${kotlin-home}/lib"/>
|
||||
</sequential>
|
||||
</target>
|
||||
|
||||
<target name="copy-dist-to-bootstrap">
|
||||
<delete dir="${basedir}/dependencies/bootstrap-compiler/Kotlin/kotlinc" />
|
||||
<copy todir="${basedir}/dependencies/bootstrap-compiler/Kotlin/kotlinc">
|
||||
<fileset dir="${basedir}/dist/kotlinc" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="compiler-sources">
|
||||
<jar jarfile="${output}/kotlin-compiler-sources.jar">
|
||||
<!-- TODO How to convert it from pathset or dirset ? -->
|
||||
@@ -308,13 +328,13 @@
|
||||
|
||||
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
|
||||
|
||||
<new-kotlin2js output="${output}/js/${compiled.builtins.js}">
|
||||
<new-kotlin2js output="${js.stdlib.output.dir}/${compiled.builtins.js}">
|
||||
<src>
|
||||
<fileset refid="kotlin.builtin.files"/>
|
||||
</src>
|
||||
</new-kotlin2js>
|
||||
|
||||
<new-kotlin2js output="${output}/js/${compiled.stdlib.js}">
|
||||
<new-kotlin2js output="${js.stdlib.output.dir}/${compiled.stdlib.js}">
|
||||
<src>
|
||||
<resources refid="js.lib.files"/>
|
||||
</src>
|
||||
@@ -334,7 +354,7 @@
|
||||
prettyprint="true"
|
||||
languagein="ECMASCRIPT5_STRICT"
|
||||
warning="${warningLevel}"
|
||||
output="${output}/js/kotlin.js">
|
||||
output="${js.stdlib.output.dir}/kotlin.js">
|
||||
|
||||
<sources dir="${stdlib.js.dir}">
|
||||
<file name="kotlin_lib_ecma5.js"/>
|
||||
@@ -343,11 +363,11 @@
|
||||
<file name="long.js"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${output}/js">
|
||||
<sources dir="${js.stdlib.output.dir}">
|
||||
<file name="${compiled.builtins.js}"/>
|
||||
</sources>
|
||||
|
||||
<sources dir="${output}/js">
|
||||
<sources dir="${js.stdlib.output.dir}">
|
||||
<file name="${compiled.stdlib.js}"/>
|
||||
</sources>
|
||||
|
||||
@@ -362,7 +382,7 @@
|
||||
|
||||
<jar jarfile="${kotlin-home}/lib/kotlin-jslib.jar" duplicate="fail">
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
<zipfileset dir="${output}/js" prefix="">
|
||||
<zipfileset dir="${js.stdlib.output.dir}" prefix="">
|
||||
<include name="kotlin.js"/>
|
||||
<include name="${compiled.stdlib.meta.js}"/>
|
||||
<include name="stdlib/**"/>
|
||||
@@ -531,8 +551,12 @@
|
||||
|
||||
<javac2 destdir="${output}/classes/compiler" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin modulename="kotlin-compiler"/>
|
||||
<withKotlin modulename="kotlin-compiler">
|
||||
<!-- remove after bootstrapping packages -->
|
||||
<compilerarg value="-Xallow-kotlin-package"/>
|
||||
</withKotlin>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src refid="compilerSources.path"/>
|
||||
<classpath refid="classpath"/>
|
||||
</javac2>
|
||||
@@ -583,6 +607,51 @@
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="kotlin-build">
|
||||
<cleandir dir="${output}/classes/kotlin-build"/>
|
||||
|
||||
<javac2 destdir="${output}/classes/kotlin-build" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin modulename="kotlin-build"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<src>
|
||||
<pathelement path="build/src"/>
|
||||
</src>
|
||||
<classpath>
|
||||
<pathelement path="${bootstrap.runtime}"/>
|
||||
<pathelement path="${bootstrap.reflect}"/>
|
||||
<pathelement path="${idea.sdk}/lib/util.jar"/>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
</javac2>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-build.jar">
|
||||
<fileset dir="${output}/classes/kotlin-build"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.build}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
<jar jarfile="${output}/kotlin-build-sources.jar">
|
||||
<fileset dir="build/src"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.build.sources}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="daemon-client">
|
||||
<cleandir dir="${output}/classes/daemon-client"/>
|
||||
|
||||
@@ -602,6 +671,14 @@
|
||||
<fileset dir="${output}/classes/daemon-client"/>
|
||||
<zipfileset src="${dependencies.dir}/native-platform-uberjar.jar" includes="**" />
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.daemon-client}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
@@ -610,6 +687,7 @@
|
||||
<javac2 destdir="${output}/classes/android-compiler-plugin" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<withKotlin modulename="kotlin-android-compiler-plugin"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src>
|
||||
<pathelement path="plugins/android-compiler-plugin/src"/>
|
||||
</src>
|
||||
@@ -634,6 +712,7 @@
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin modulename="kotlin-ant-tools"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src>
|
||||
<dirset dir="${basedir}/ant">
|
||||
<include name="src"/>
|
||||
@@ -730,11 +809,13 @@
|
||||
<arg value="${toString:classpath.path}"/>
|
||||
<arg value="-module-name"/>
|
||||
<arg value="@{moduleName}"/>
|
||||
<arg value="-Xallow-kotlin-package"/>
|
||||
</java>
|
||||
|
||||
<javac2 srcdir="${toString:src.dirset}" destdir="@{output}" debug="true" debuglevel="lines,vars,source"
|
||||
includeAntRuntime="false" source="${java.target}" target="${java.target}">
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<classpath>
|
||||
<path refid="classpath.path"/>
|
||||
<!-- Include @{output} here for Java compiler to resolve symbols from Kotlin sources -->
|
||||
@@ -791,6 +872,26 @@
|
||||
</new-kotlinc>
|
||||
</target>
|
||||
|
||||
<target name="kotlin-test">
|
||||
<new-kotlinc output="${output}/classes/kotlin-test" moduleName="kotlin-test">
|
||||
<src>
|
||||
<include name="libraries/kotlin.test/shared/src/main/kotlin" />
|
||||
<include name="libraries/kotlin.test/shared/src/main/kotlin.jvm" />
|
||||
<include name="libraries/kotlin.test/junit/src/main/kotlin" />
|
||||
</src>
|
||||
<class-path>
|
||||
<pathelement path="${output}/classes/builtins"/>
|
||||
<pathelement path="libraries/lib/junit-4.11.jar"/>
|
||||
</class-path>
|
||||
</new-kotlinc>
|
||||
|
||||
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
|
||||
<jar-content>
|
||||
<fileset dir="${output}/classes/kotlin-test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
|
||||
</jar-content>
|
||||
</pack-runtime-jar>
|
||||
</target>
|
||||
|
||||
<target name="core">
|
||||
<new-kotlinc output="${output}/classes/core" moduleName="kotlin-core">
|
||||
<src>
|
||||
@@ -877,31 +978,46 @@
|
||||
</jar>
|
||||
|
||||
<delete file="${output}/kotlin-reflect-jarjar.jar" failonerror="false"/>
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
|
||||
<jarjar jarfile="${output}/kotlin-reflect-jarjar.jar" filesonly="true" filesetmanifest="merge">
|
||||
<zipfileset src="${output}/kotlin-reflect-before-jarjar.jar"/>
|
||||
<rule pattern="org.jetbrains.kotlin.**" result="kotlin.reflect.jvm.internal.impl.@1"/>
|
||||
<rule pattern="com.google.protobuf.**" result="kotlin.reflect.jvm.internal.impl.com.google.protobuf.@1"/>
|
||||
<rule pattern="javax.inject.**" result="kotlin.reflect.jvm.internal.impl.javax.inject.@1"/>
|
||||
</jarjar>
|
||||
|
||||
<kotlinc src="${basedir}/generators/infrastructure/strip-kotlin-annotations.kts" output="">
|
||||
<compilerarg value="-script"/>
|
||||
<compilerarg value="kotlin/jvm/internal/.*"/> <!-- Annotations to strip -->
|
||||
<compilerarg value="kotlin/reflect/jvm/internal/impl/.*"/> <!-- Classes to strip from -->
|
||||
<compilerarg value="${output}/kotlin-reflect-jarjar.jar"/>
|
||||
<compilerarg value="${kotlin-home}/lib/kotlin-reflect.jar"/>
|
||||
<classpath>
|
||||
<pathelement location="${idea.sdk}/lib/asm-all.jar"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
<sequential if:true="${obfuscate.reflect}">
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
|
||||
<jarjar jarfile="${output}/kotlin-reflect-jarjar.jar" filesonly="true" filesetmanifest="merge">
|
||||
<zipfileset src="${output}/kotlin-reflect-before-jarjar.jar"/>
|
||||
<rule pattern="org.jetbrains.kotlin.**" result="kotlin.reflect.jvm.internal.impl.@1"/>
|
||||
<rule pattern="com.google.protobuf.**" result="kotlin.reflect.jvm.internal.impl.com.google.protobuf.@1"/>
|
||||
<rule pattern="javax.inject.**" result="kotlin.reflect.jvm.internal.impl.javax.inject.@1"/>
|
||||
</jarjar>
|
||||
|
||||
<kotlinc src="${basedir}/generators/infrastructure/strip-kotlin-annotations.kts" output="">
|
||||
<compilerarg value="-script"/>
|
||||
<compilerarg value="kotlin/jvm/internal/.*|kotlin/Metadata"/> <!-- Annotations to strip -->
|
||||
<compilerarg value="kotlin/reflect/jvm/internal/impl/.*"/> <!-- Classes to strip from -->
|
||||
<compilerarg value="${output}/kotlin-reflect-jarjar.jar"/>
|
||||
<compilerarg value="${kotlin-home}/lib/kotlin-reflect.jar"/>
|
||||
<classpath>
|
||||
<pathelement location="${idea.sdk}/lib/asm-all.jar"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
</sequential>
|
||||
|
||||
<sequential unless:true="${obfuscate.reflect}">
|
||||
<echo message="Obfuscation of kotlin-reflect is disabled"/>
|
||||
<copy file="${output}/kotlin-reflect-before-jarjar.jar" tofile="${output}/kotlin-reflect-jarjar.jar" overwrite="true"/>
|
||||
<copy file="${output}/kotlin-reflect-before-jarjar.jar" tofile="${kotlin-home}/lib/kotlin-reflect.jar" overwrite="true"/>
|
||||
</sequential>
|
||||
</target>
|
||||
|
||||
<target name="pack-runtime-sources">
|
||||
|
||||
<!-- Rename packages in the sources of reflection impl (core) -->
|
||||
<delete dir="${output}/core.src" failonerror="false"/>
|
||||
<copy todir="${output}/core.src/kotlin/reflect/jvm/internal/impl">
|
||||
|
||||
<local name="runtime.sources.base.dir"/>
|
||||
<condition property="runtime.sources.base.dir"
|
||||
value="${output}/core.src/kotlin/reflect/jvm/internal/impl"
|
||||
else="${output}/core.src/org/jetbrains/kotlin">
|
||||
<istrue value="${obfuscate.reflect}"/>
|
||||
</condition>
|
||||
|
||||
<copy todir="${runtime.sources.base.dir}">
|
||||
<fileset dir="core">
|
||||
<include name="descriptor.loader.java/src/**"/>
|
||||
<include name="descriptors/src/**"/>
|
||||
@@ -911,9 +1027,13 @@
|
||||
</fileset>
|
||||
<cutdirsmapper dirs="5"/> <!-- module/src/org/jetbrains/kotlin -->
|
||||
</copy>
|
||||
<replaceregexp match="org\.jetbrains\.kotlin" replace="kotlin.reflect.jvm.internal.impl" flags="g">
|
||||
<fileset dir="${output}/core.src"/>
|
||||
</replaceregexp>
|
||||
|
||||
<sequential if:true="${obfuscate.reflect}">
|
||||
<!-- Rename packages in the sources of reflection impl (core) -->
|
||||
<replaceregexp match="org\.jetbrains\.kotlin" replace="kotlin.reflect.jvm.internal.impl" flags="g">
|
||||
<fileset dir="${output}/core.src"/>
|
||||
</replaceregexp>
|
||||
</sequential>
|
||||
|
||||
<pack-runtime-jar jar-name="kotlin-runtime-sources.jar" implementation-title="${manifest.impl.title.kotlin.jvm.runtime.sources}">
|
||||
<jar-content>
|
||||
@@ -936,10 +1056,10 @@
|
||||
</target>
|
||||
|
||||
<target name="runtime"
|
||||
depends="builtins,stdlib,core,reflection,pack-runtime,pack-runtime-sources"/>
|
||||
depends="builtins,stdlib,kotlin-test,core,reflection,pack-runtime,pack-runtime-sources"/>
|
||||
|
||||
<target name="dist"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,kotlin-build,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
|
||||
description="Builds redistributables from sources"/>
|
||||
|
||||
<target name="dist-quick"
|
||||
@@ -965,6 +1085,7 @@
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin modulename="kotlin-for-upsource"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src>
|
||||
<dirset dir="${basedir}/idea/ide-common" includes="src"/>
|
||||
<dirset dir="${basedir}/idea/idea-analysis" includes="src"/>
|
||||
|
||||
19
build/build.iml
Normal file
19
build/build.iml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/testData" type="java-test-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="util.runtime" />
|
||||
<orderEntry type="module" module-name="cli-common" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="compiler-tests" scope="TEST" />
|
||||
<orderEntry type="library" scope="TEST" name="idea-full" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
package org.jetbrains.kotlin.build
|
||||
|
||||
import java.io.File
|
||||
|
||||
40
build/src/org/jetbrains/kotlin/build/generatedFiles.kt
Normal file
40
build/src/org/jetbrains/kotlin/build/generatedFiles.kt
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.build
|
||||
|
||||
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import java.io.File
|
||||
|
||||
open class GeneratedFile<Target>(
|
||||
val target: Target,
|
||||
val sourceFiles: Collection<File>,
|
||||
val outputFile: File
|
||||
)
|
||||
|
||||
class GeneratedJvmClass<Target> (
|
||||
target: Target,
|
||||
sourceFiles: Collection<File>,
|
||||
outputFile: File
|
||||
) : GeneratedFile<Target>(target, sourceFiles, outputFile) {
|
||||
val outputClass = LocalFileKotlinClass.create(outputFile).sure {
|
||||
"Couldn't load KotlinClass from $outputFile; it may happen because class doesn't have valid Kotlin annotations"
|
||||
}
|
||||
}
|
||||
|
||||
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"
|
||||
126
build/src/org/jetbrains/kotlin/incremental/CacheVersion.kt
Normal file
126
build/src/org/jetbrains/kotlin/incremental/CacheVersion.kt
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.incremental
|
||||
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
|
||||
import java.io.File
|
||||
|
||||
private val NORMAL_VERSION = 8
|
||||
private val EXPERIMENTAL_VERSION = 2
|
||||
private val DATA_CONTAINER_VERSION = 1
|
||||
|
||||
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(
|
||||
private val ownVersion: Int,
|
||||
private val versionFile: File,
|
||||
private val whenVersionChanged: CacheVersion.Action,
|
||||
private val whenTurnedOn: CacheVersion.Action,
|
||||
private val whenTurnedOff: CacheVersion.Action,
|
||||
isEnabled: ()->Boolean
|
||||
) {
|
||||
private val isEnabled by lazy(isEnabled)
|
||||
|
||||
private val actualVersion: Int
|
||||
get() = versionFile.readText().toInt()
|
||||
|
||||
private val expectedVersion: Int
|
||||
get() {
|
||||
val metadata = JvmMetadataVersion.INSTANCE
|
||||
val bytecode = JvmBytecodeBinaryVersion.INSTANCE
|
||||
return ownVersion * 1000000 +
|
||||
bytecode.major * 10000 + bytecode.minor * 100 +
|
||||
metadata.major * 1000 + metadata.minor
|
||||
}
|
||||
|
||||
fun checkVersion(): Action =
|
||||
when (versionFile.exists() to isEnabled) {
|
||||
true to true -> if (actualVersion != expectedVersion) whenVersionChanged else Action.DO_NOTHING
|
||||
false to true -> whenTurnedOn
|
||||
true to false -> whenTurnedOff
|
||||
else -> Action.DO_NOTHING
|
||||
}
|
||||
|
||||
fun saveIfNeeded() {
|
||||
if (!isEnabled) return
|
||||
|
||||
if (!versionFile.parentFile.exists()) {
|
||||
versionFile.parentFile.mkdirs()
|
||||
}
|
||||
|
||||
versionFile.writeText(expectedVersion.toString())
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
versionFile.delete()
|
||||
}
|
||||
|
||||
@get:TestOnly
|
||||
val formatVersionFile: File
|
||||
get() = versionFile
|
||||
|
||||
// Order of entries is important, because actions are sorted in KotlinBuilder::checkVersions
|
||||
enum class Action {
|
||||
REBUILD_ALL_KOTLIN,
|
||||
REBUILD_CHUNK,
|
||||
CLEAN_NORMAL_CACHES,
|
||||
CLEAN_EXPERIMENTAL_CACHES,
|
||||
CLEAN_DATA_CONTAINER,
|
||||
DO_NOTHING
|
||||
}
|
||||
}
|
||||
|
||||
fun normalCacheVersion(dataRoot: File): CacheVersion =
|
||||
CacheVersion(ownVersion = NORMAL_VERSION,
|
||||
versionFile = File(dataRoot, NORMAL_VERSION_FILE_NAME),
|
||||
whenVersionChanged = CacheVersion.Action.REBUILD_CHUNK,
|
||||
whenTurnedOn = CacheVersion.Action.REBUILD_CHUNK,
|
||||
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() })
|
||||
|
||||
fun allCachesVersions(containerDataRoot: File, dataRoots: Iterable<File>): Iterable<CacheVersion> {
|
||||
val versions = arrayListOf<CacheVersion>()
|
||||
versions.add(dataContainerCacheVersion(containerDataRoot))
|
||||
|
||||
for (dataRoot in dataRoots) {
|
||||
versions.add(normalCacheVersion(dataRoot))
|
||||
versions.add(experimentalCacheVersion(dataRoot))
|
||||
}
|
||||
|
||||
return versions
|
||||
}
|
||||
@@ -14,99 +14,99 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.google.protobuf.MessageLite
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.io.BooleanDataDescriptor
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import com.intellij.util.io.IOUtil
|
||||
import gnu.trove.THashSet
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.jps.builders.BuildTarget
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
||||
import org.jetbrains.jps.builders.storage.StorageProvider
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.jps.incremental.storage.BuildDataManager
|
||||
import org.jetbrains.jps.incremental.storage.PathStringDescriptor
|
||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
||||
import org.jetbrains.kotlin.jps.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||
import org.jetbrains.kotlin.jps.incremental.storage.*
|
||||
import org.jetbrains.kotlin.incremental.storage.*
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassPartKind
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||
import org.jetbrains.kotlin.serialization.deserialization.supertypes
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.io.File
|
||||
import java.security.MessageDigest
|
||||
import java.util.*
|
||||
|
||||
internal val CACHE_DIRECTORY_NAME = "kotlin"
|
||||
val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
|
||||
|
||||
@TestOnly
|
||||
public fun getCacheDirectoryName(): String =
|
||||
CACHE_DIRECTORY_NAME
|
||||
|
||||
public class IncrementalCacheImpl(
|
||||
targetDataRoot: File,
|
||||
private val target: ModuleBuildTarget
|
||||
open class IncrementalCacheImpl<Target>(
|
||||
private val targetDataRoot: File,
|
||||
targetOutputDir: File?,
|
||||
target: Target
|
||||
) : BasicMapsOwner(), IncrementalCache {
|
||||
companion object {
|
||||
val PROTO_MAP = "proto"
|
||||
val CONSTANTS_MAP = "constants"
|
||||
val INLINE_FUNCTIONS = "inline-functions"
|
||||
val PACKAGE_PARTS = "package-parts"
|
||||
val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
|
||||
val MULTIFILE_CLASS_PARTS = "multifile-class-parts"
|
||||
val SOURCE_TO_CLASSES = "source-to-classes"
|
||||
val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||
val DIRTY_INLINE_FUNCTIONS = "dirty-inline-functions"
|
||||
val INLINED_TO = "inlined-to"
|
||||
private val PROTO_MAP = "proto"
|
||||
private val CONSTANTS_MAP = "constants"
|
||||
private val PACKAGE_PARTS = "package-parts"
|
||||
private val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
|
||||
private val MULTIFILE_CLASS_PARTS = "multifile-class-parts"
|
||||
private val SOURCE_TO_CLASSES = "source-to-classes"
|
||||
private val DIRTY_OUTPUT_CLASSES = "dirty-output-classes"
|
||||
private val SUBTYPES = "subtypes"
|
||||
private val SUPERTYPES = "supertypes"
|
||||
|
||||
private val MODULE_MAPPING_FILE_NAME = "." + ModuleMapping.MAPPING_FILE_EXT
|
||||
}
|
||||
|
||||
private val baseDir = File(targetDataRoot, CACHE_DIRECTORY_NAME)
|
||||
private val baseDir = File(targetDataRoot, KOTLIN_CACHE_DIRECTORY_NAME)
|
||||
private val experimentalMaps = arrayListOf<BasicMap<*, *>>()
|
||||
|
||||
private val String.storageFile: File
|
||||
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)
|
||||
|
||||
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||
private val inlineFunctionsMap = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile))
|
||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||
private val multifileClassFacadeMap = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||
private val multifileClassPartMap = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
private val dirtyInlineFunctionsMap = registerMap(DirtyInlineFunctionsMap(DIRTY_INLINE_FUNCTIONS.storageFile))
|
||||
private val inlinedTo = registerMap(InlineFunctionsFilesMap(INLINED_TO.storageFile))
|
||||
private val subtypesMap = registerExperimentalMap(SubtypesMap(SUBTYPES.storageFile))
|
||||
private val supertypesMap = registerExperimentalMap(SupertypesMap(SUPERTYPES.storageFile))
|
||||
|
||||
private val cacheFormatVersion = CacheFormatVersion(targetDataRoot)
|
||||
private val dependents = arrayListOf<IncrementalCacheImpl>()
|
||||
private val outputDir = requireNotNull(target.outputDir) { "Target is expected to have output directory: $target" }
|
||||
private val dependents = arrayListOf<IncrementalCacheImpl<Target>>()
|
||||
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(targetOutputDir) { "Target is expected to have output directory: $target" } }
|
||||
|
||||
// TODO: review
|
||||
val dependentsWithThis: Sequence<IncrementalCacheImpl<Target>>
|
||||
get() = sequenceOf(this).plus(dependents.asSequence())
|
||||
|
||||
internal val dependentCaches: Iterable<IncrementalCacheImpl<Target>>
|
||||
get() = dependents
|
||||
|
||||
override fun registerInline(fromPath: String, jvmSignature: String, toPath: String) {
|
||||
inlinedTo.add(fromPath, jvmSignature, toPath)
|
||||
}
|
||||
|
||||
public fun addDependentCache(cache: IncrementalCacheImpl) {
|
||||
protected open fun debugLog(message: String) {}
|
||||
|
||||
fun addDependentCache(cache: IncrementalCacheImpl<Target>) {
|
||||
dependents.add(cache)
|
||||
}
|
||||
|
||||
public fun markOutputClassesDirty(removedAndCompiledSources: List<File>) {
|
||||
fun markOutputClassesDirty(removedAndCompiledSources: List<File>) {
|
||||
for (sourceFile in removedAndCompiledSources) {
|
||||
val classes = sourceToClassesMap[sourceFile]
|
||||
classes.forEach {
|
||||
@@ -117,38 +117,14 @@ public class IncrementalCacheImpl(
|
||||
}
|
||||
}
|
||||
|
||||
public fun getFilesToReinline(): Collection<File> {
|
||||
val result = THashSet(FileUtil.PATH_HASHING_STRATEGY)
|
||||
|
||||
for ((className, functions) in dirtyInlineFunctionsMap.getEntries()) {
|
||||
val classFilePath = getClassFilePath(className.internalName)
|
||||
|
||||
fun addFilesAffectedByChangedInlineFuns(cache: IncrementalCacheImpl) {
|
||||
val targetFiles = functions.flatMap { cache.inlinedTo[classFilePath, it] }
|
||||
result.addAll(targetFiles)
|
||||
}
|
||||
|
||||
addFilesAffectedByChangedInlineFuns(this)
|
||||
dependents.forEach(::addFilesAffectedByChangedInlineFuns)
|
||||
}
|
||||
|
||||
cleanDirtyInlineFunctions()
|
||||
return result.map { File(it) }
|
||||
}
|
||||
|
||||
public fun cleanDirtyInlineFunctions() {
|
||||
dirtyInlineFunctionsMap.clean()
|
||||
}
|
||||
fun getSubtypesOf(className: FqName): Sequence<FqName> =
|
||||
subtypesMap[className].asSequence()
|
||||
|
||||
override fun getClassFilePath(internalClassName: String): String {
|
||||
return toSystemIndependentName(File(outputDir, "$internalClassName.class").canonicalPath)
|
||||
}
|
||||
|
||||
public fun saveCacheFormatVersion() {
|
||||
cacheFormatVersion.saveIfNeeded()
|
||||
}
|
||||
|
||||
public fun saveModuleMappingToCache(sourceFiles: Collection<File>, file: File): CompilationResult {
|
||||
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)
|
||||
dirtyOutputClassesMap.notDirty(MODULE_MAPPING_FILE_NAME)
|
||||
@@ -156,48 +132,59 @@ public class IncrementalCacheImpl(
|
||||
return CompilationResult.NO_CHANGES
|
||||
}
|
||||
|
||||
public fun saveFileToCache(generatedClass: GeneratedJvmClass): CompilationResult {
|
||||
fun saveFileToCache(generatedClass: GeneratedJvmClass<Target>): CompilationResult {
|
||||
val sourceFiles: Collection<File> = generatedClass.sourceFiles
|
||||
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
|
||||
val className = JvmClassName.byClassId(kotlinClass.classId)
|
||||
val className = kotlinClass.className
|
||||
|
||||
dirtyOutputClassesMap.notDirty(className.internalName)
|
||||
sourceFiles.forEach {
|
||||
sourceToClassesMap.add(it, className)
|
||||
}
|
||||
|
||||
if (kotlinClass.classId.isLocal) {
|
||||
return CompilationResult.NO_CHANGES
|
||||
}
|
||||
|
||||
val header = kotlinClass.classHeader
|
||||
val changesInfo = when {
|
||||
header.isCompatibleFileFacadeKind() -> {
|
||||
assert(sourceFiles.size() == 1) { "Package part from several source files: $sourceFiles" }
|
||||
val changesInfo = when (header.kind) {
|
||||
KotlinClassHeader.Kind.FILE_FACADE -> {
|
||||
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
|
||||
packagePartMap.addPackagePart(className)
|
||||
|
||||
protoMap.process(kotlinClass, isPackage = true) +
|
||||
constantsMap.process(kotlinClass) +
|
||||
inlineFunctionsMap.process(kotlinClass, isPackage = true)
|
||||
additionalProcessChangedClass(kotlinClass, isPackage = true)
|
||||
}
|
||||
header.isCompatibleMultifileClassKind() -> {
|
||||
val partNames = kotlinClass.classHeader.filePartClassNames?.toList()
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
|
||||
val partNames = kotlinClass.classHeader.data?.toList()
|
||||
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
|
||||
multifileClassFacadeMap.add(className, partNames)
|
||||
multifileFacadeToParts[className] = partNames
|
||||
// When a class is replaced with a facade with the same name,
|
||||
// the class' proto wouldn't ever be deleted,
|
||||
// because we don't write proto for multifile facades.
|
||||
// As a workaround we can remove proto values for multifile facades.
|
||||
protoMap.remove(className)
|
||||
|
||||
// TODO NO_CHANGES? (delegates only)
|
||||
constantsMap.process(kotlinClass) +
|
||||
inlineFunctionsMap.process(kotlinClass, isPackage = true)
|
||||
additionalProcessChangedClass(kotlinClass, isPackage = true)
|
||||
}
|
||||
header.isCompatibleMultifileClassPartKind() -> {
|
||||
assert(sourceFiles.size() == 1) { "Multifile class part from several source files: $sourceFiles" }
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
||||
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
|
||||
packagePartMap.addPackagePart(className)
|
||||
multifileClassPartMap.add(className.internalName, header.multifileClassName!!)
|
||||
partToMultifileFacade.set(className.internalName, header.multifileClassName!!)
|
||||
|
||||
protoMap.process(kotlinClass, isPackage = true) +
|
||||
constantsMap.process(kotlinClass) +
|
||||
inlineFunctionsMap.process(kotlinClass, isPackage = true)
|
||||
additionalProcessChangedClass(kotlinClass, isPackage = true)
|
||||
}
|
||||
header.isCompatibleClassKind() && !header.isLocalClass -> {
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
addToClassStorage(kotlinClass)
|
||||
|
||||
protoMap.process(kotlinClass, isPackage = false) +
|
||||
constantsMap.process(kotlinClass) +
|
||||
inlineFunctionsMap.process(kotlinClass, isPackage = false)
|
||||
additionalProcessChangedClass(kotlinClass, isPackage = false)
|
||||
}
|
||||
else -> CompilationResult.NO_CHANGES
|
||||
}
|
||||
@@ -206,15 +193,17 @@ public class IncrementalCacheImpl(
|
||||
return changesInfo
|
||||
}
|
||||
|
||||
protected open fun additionalProcessChangedClass(kotlinClass: LocalFileKotlinClass, isPackage: Boolean) = CompilationResult.NO_CHANGES
|
||||
|
||||
private fun CompilationResult.logIfSomethingChanged(className: JvmClassName) {
|
||||
if (this == CompilationResult.NO_CHANGES) return
|
||||
|
||||
KotlinBuilder.LOG.debug("$className is changed: $this")
|
||||
debugLog("$className is changed: $this")
|
||||
}
|
||||
|
||||
public fun clearCacheForRemovedClasses(): CompilationResult {
|
||||
fun clearCacheForRemovedClasses(): CompilationResult {
|
||||
|
||||
fun <T> T.getNonPrivateNames(nameResolver: NameResolver, vararg members: T.() -> List<MessageLite>) =
|
||||
fun <T> T.getNonPrivateNames(nameResolver: NameResolver, vararg members: T.() -> List<MessageLite>): Set<String> =
|
||||
members.flatMap { this.it().filterNot { it.isPrivate }.names(nameResolver) }.toSet()
|
||||
|
||||
fun createChangeInfo(className: JvmClassName): ChangeInfo? {
|
||||
@@ -244,8 +233,7 @@ public class IncrementalCacheImpl(
|
||||
ProtoBuf.Class::getConstructorList,
|
||||
ProtoBuf.Class::getFunctionList,
|
||||
ProtoBuf.Class::getPropertyList
|
||||
) +
|
||||
classData.classProto.enumEntryList.map { classData.nameResolver.getString(it) }.toSet()
|
||||
) + classData.classProto.enumEntryList.map { classData.nameResolver.getString(it.name) }
|
||||
|
||||
ChangeInfo.Removed(className.fqNameForClassNameWithoutDollars, memberNames)
|
||||
}
|
||||
@@ -270,27 +258,54 @@ public class IncrementalCacheImpl(
|
||||
info + newInfo
|
||||
}
|
||||
|
||||
val facadesWithRemovedParts = hashMapOf<JvmClassName, MutableSet<String>>()
|
||||
for (dirtyClass in dirtyClasses) {
|
||||
val facade = partToMultifileFacade.get(dirtyClass.internalName) ?: continue
|
||||
val facadeClassName = JvmClassName.byInternalName(facade)
|
||||
val removedParts = facadesWithRemovedParts.getOrPut(facadeClassName) { hashSetOf() }
|
||||
removedParts.add(dirtyClass.internalName)
|
||||
}
|
||||
|
||||
for ((facade, removedParts) in facadesWithRemovedParts.entries) {
|
||||
val allParts = multifileFacadeToParts[facade.internalName] ?: continue
|
||||
val notRemovedParts = allParts.filter { it !in removedParts }
|
||||
|
||||
if (notRemovedParts.isEmpty()) {
|
||||
multifileFacadeToParts.remove(facade)
|
||||
}
|
||||
else {
|
||||
multifileFacadeToParts[facade] = notRemovedParts
|
||||
}
|
||||
}
|
||||
|
||||
dirtyClasses.forEach {
|
||||
protoMap.remove(it)
|
||||
packagePartMap.remove(it)
|
||||
multifileClassFacadeMap.remove(it)
|
||||
multifileClassPartMap.remove(it)
|
||||
multifileFacadeToParts.remove(it)
|
||||
partToMultifileFacade.remove(it)
|
||||
constantsMap.remove(it)
|
||||
inlineFunctionsMap.remove(it)
|
||||
}
|
||||
|
||||
additionalProcessRemovedClasses(dirtyClasses)
|
||||
|
||||
removeAllFromClassStorage(dirtyClasses)
|
||||
|
||||
dirtyOutputClassesMap.clean()
|
||||
return changesInfo
|
||||
}
|
||||
|
||||
protected open fun additionalProcessRemovedClasses(dirtyClasses: List<JvmClassName>) {
|
||||
}
|
||||
|
||||
override fun getObsoletePackageParts(): Collection<String> {
|
||||
val obsoletePackageParts =
|
||||
dirtyOutputClassesMap.getDirtyOutputClasses().filter { packagePartMap.isPackagePart(JvmClassName.byInternalName(it)) }
|
||||
KotlinBuilder.LOG.debug("Obsolete package parts: ${obsoletePackageParts}")
|
||||
debugLog("Obsolete package parts: ${obsoletePackageParts}")
|
||||
return obsoletePackageParts
|
||||
}
|
||||
|
||||
override fun getPackagePartData(fqName: String): JvmPackagePartProto? {
|
||||
return protoMap[JvmClassName.byInternalName(fqName)]?.let { value ->
|
||||
override fun getPackagePartData(partInternalName: String): JvmPackagePartProto? {
|
||||
return protoMap[JvmClassName.byInternalName(partInternalName)]?.let { value ->
|
||||
JvmPackagePartProto(value.bytes, value.strings)
|
||||
}
|
||||
}
|
||||
@@ -298,40 +313,46 @@ public class IncrementalCacheImpl(
|
||||
override fun getObsoleteMultifileClasses(): Collection<String> {
|
||||
val obsoleteMultifileClasses = linkedSetOf<String>()
|
||||
for (dirtyClass in dirtyOutputClassesMap.getDirtyOutputClasses()) {
|
||||
val dirtyFacade = multifileClassPartMap.getFacadeName(dirtyClass) ?: continue
|
||||
val dirtyFacade = partToMultifileFacade.get(dirtyClass) ?: continue
|
||||
obsoleteMultifileClasses.add(dirtyFacade)
|
||||
}
|
||||
KotlinBuilder.LOG.debug("Obsolete multifile class facades: $obsoleteMultifileClasses")
|
||||
debugLog("Obsolete multifile class facades: $obsoleteMultifileClasses")
|
||||
return obsoleteMultifileClasses
|
||||
}
|
||||
|
||||
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
|
||||
val partNames = multifileClassFacadeMap.getMultifileClassParts(facadeInternalName) ?: return null
|
||||
val partNames = multifileFacadeToParts.get(facadeInternalName) ?: return null
|
||||
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
|
||||
}
|
||||
|
||||
override fun getMultifileFacade(partInternalName: String): String? {
|
||||
return multifileClassPartMap.getFacadeName(partInternalName)
|
||||
return partToMultifileFacade.get(partInternalName)
|
||||
}
|
||||
|
||||
override fun getModuleMappingData(): ByteArray? {
|
||||
return protoMap[JvmClassName.byInternalName(MODULE_MAPPING_FILE_NAME)]?.bytes
|
||||
}
|
||||
|
||||
public override fun clean() {
|
||||
override fun clean() {
|
||||
super.clean()
|
||||
cacheFormatVersion.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) {
|
||||
|
||||
public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean): CompilationResult {
|
||||
fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean): CompilationResult {
|
||||
val header = kotlinClass.classHeader
|
||||
val bytes = BitEncoding.decodeBytes(header.annotationData!!)
|
||||
val bytes = BitEncoding.decodeBytes(header.data!!)
|
||||
return put(kotlinClass.className, bytes, header.strings!!, isPackage, checkChangesIsOpenPart = true)
|
||||
}
|
||||
|
||||
public fun process(className: JvmClassName, data: ByteArray, strings: Array<String>, isPackage: Boolean, checkChangesIsOpenPart: Boolean): CompilationResult {
|
||||
fun process(className: JvmClassName, data: ByteArray, strings: Array<String>, isPackage: Boolean, checkChangesIsOpenPart: Boolean): CompilationResult {
|
||||
return put(className, data, strings, isPackage, checkChangesIsOpenPart)
|
||||
}
|
||||
|
||||
@@ -352,20 +373,19 @@ public class IncrementalCacheImpl(
|
||||
|
||||
if (oldData == null || !checkChangesIsOpenPart) return CompilationResult(protoChanged = true)
|
||||
|
||||
val diff = difference(oldData, data)
|
||||
|
||||
if (!IncrementalCompilation.isExperimental()) return CompilationResult(protoChanged = diff != DifferenceKind.NONE)
|
||||
|
||||
val difference = difference(oldData, data)
|
||||
val fqName = if (isPackage) className.packageFqName else className.fqNameForClassNameWithoutDollars
|
||||
val changeList = SmartList<ChangeInfo>()
|
||||
|
||||
val changes =
|
||||
when (diff) {
|
||||
is DifferenceKind.NONE -> emptySequence<ChangeInfo>()
|
||||
is DifferenceKind.CLASS_SIGNATURE -> sequenceOf(ChangeInfo.SignatureChanged(fqName))
|
||||
is DifferenceKind.MEMBERS -> sequenceOf(ChangeInfo.MembersChanged(fqName, diff.names))
|
||||
}
|
||||
if (difference.isClassAffected) {
|
||||
changeList.add(ChangeInfo.SignatureChanged(fqName, difference.areSubclassesAffected))
|
||||
}
|
||||
|
||||
return CompilationResult(protoChanged = diff != DifferenceKind.NONE, changes = changes)
|
||||
if (difference.changedMembersNames.isNotEmpty()) {
|
||||
changeList.add(ChangeInfo.MembersChanged(fqName, difference.changedMembersNames))
|
||||
}
|
||||
|
||||
return CompilationResult(protoChanged = changeList.isNotEmpty(), changes = changeList.asSequence())
|
||||
}
|
||||
|
||||
operator fun contains(className: JvmClassName): Boolean =
|
||||
@@ -374,7 +394,7 @@ public class IncrementalCacheImpl(
|
||||
operator fun get(className: JvmClassName): ProtoMapValue? =
|
||||
storage[className.internalName]
|
||||
|
||||
public fun remove(className: JvmClassName) {
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
}
|
||||
|
||||
@@ -403,12 +423,12 @@ public class IncrementalCacheImpl(
|
||||
operator fun contains(className: JvmClassName): Boolean =
|
||||
className.internalName in storage
|
||||
|
||||
public fun process(kotlinClass: LocalFileKotlinClass): CompilationResult {
|
||||
fun process(kotlinClass: LocalFileKotlinClass): CompilationResult {
|
||||
return put(kotlinClass.className, getConstantsMap(kotlinClass.fileContents))
|
||||
}
|
||||
|
||||
private fun put(className: JvmClassName, constantsMap: Map<String, Any>?): CompilationResult {
|
||||
val key = className.getInternalName()
|
||||
val key = className.internalName
|
||||
|
||||
val oldMap = storage[key]
|
||||
if (oldMap == constantsMap) return CompilationResult.NO_CHANGES
|
||||
@@ -423,7 +443,7 @@ public class IncrementalCacheImpl(
|
||||
return CompilationResult(constantsChanged = true)
|
||||
}
|
||||
|
||||
public fun remove(className: JvmClassName) {
|
||||
fun remove(className: JvmClassName) {
|
||||
put(className, null)
|
||||
}
|
||||
|
||||
@@ -431,214 +451,132 @@ public class IncrementalCacheImpl(
|
||||
value.dumpMap(Any::toString)
|
||||
}
|
||||
|
||||
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
|
||||
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> {
|
||||
val result = HashMap<String, Long>()
|
||||
|
||||
val inlineFunctions = inlineFunctionsJvmNames(bytes)
|
||||
if (inlineFunctions.isEmpty()) return emptyMap()
|
||||
|
||||
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.ASM5) {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||
val dummyClassWriter = ClassWriter(Opcodes.ASM5)
|
||||
|
||||
return object : MethodVisitor(Opcodes.ASM5, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
|
||||
override fun visitEnd() {
|
||||
val jvmName = name + desc
|
||||
if (jvmName !in inlineFunctions) return
|
||||
|
||||
val dummyBytes = dummyClassWriter.toByteArray()!!
|
||||
val hash = dummyBytes.md5()
|
||||
result[jvmName] = hash
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 0)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean): CompilationResult {
|
||||
return put(kotlinClass.className, getInlineFunctionsMap(kotlinClass.fileContents), isPackage)
|
||||
}
|
||||
|
||||
private fun put(className: JvmClassName, newMap: Map<String, Long>, isPackage: Boolean): CompilationResult {
|
||||
val internalName = className.internalName
|
||||
val oldMap = storage[internalName] ?: emptyMap()
|
||||
|
||||
val added = hashSetOf<String>()
|
||||
val changed = hashSetOf<String>()
|
||||
val allFunctions = oldMap.keySet() + newMap.keySet()
|
||||
|
||||
for (fn in allFunctions) {
|
||||
val oldHash = oldMap[fn]
|
||||
val newHash = newMap[fn]
|
||||
|
||||
when {
|
||||
oldHash == null -> added.add(fn)
|
||||
oldHash != newHash -> changed.add(fn)
|
||||
}
|
||||
}
|
||||
|
||||
when {
|
||||
newMap.isNotEmpty() -> storage[internalName] = newMap
|
||||
else -> storage.remove(internalName)
|
||||
}
|
||||
|
||||
if (changed.isNotEmpty()) {
|
||||
dirtyInlineFunctionsMap.put(className, changed.toList())
|
||||
}
|
||||
|
||||
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>()
|
||||
}
|
||||
|
||||
return CompilationResult(inlineChanged = changed.isNotEmpty(),
|
||||
inlineAdded = added.isNotEmpty(),
|
||||
changes = changes)
|
||||
}
|
||||
|
||||
public fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
}
|
||||
|
||||
override fun dumpValue(value: Map<String, Long>): String =
|
||||
value.dumpMap { java.lang.Long.toHexString(it) }
|
||||
}
|
||||
|
||||
private inner class PackagePartMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
|
||||
public fun addPackagePart(className: JvmClassName) {
|
||||
fun addPackagePart(className: JvmClassName) {
|
||||
storage[className.internalName] = true
|
||||
}
|
||||
|
||||
public fun remove(className: JvmClassName) {
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
}
|
||||
|
||||
public fun isPackagePart(className: JvmClassName): Boolean =
|
||||
fun isPackagePart(className: JvmClassName): Boolean =
|
||||
className.internalName in storage
|
||||
|
||||
override fun dumpValue(value: Boolean) = ""
|
||||
}
|
||||
|
||||
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
|
||||
public fun add(facadeName: JvmClassName, partNames: List<String>) {
|
||||
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
operator fun set(facadeName: JvmClassName, partNames: Collection<String>) {
|
||||
storage[facadeName.internalName] = partNames
|
||||
}
|
||||
|
||||
public fun getMultifileClassParts(facadeName: String): List<String>? = storage[facadeName]
|
||||
operator fun get(facadeName: String): Collection<String>? = storage[facadeName]
|
||||
|
||||
public fun remove(className: JvmClassName) {
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
}
|
||||
|
||||
override fun dumpValue(value: List<String>): String = value.toString()
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
}
|
||||
|
||||
private inner class MultifileClassPartMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
|
||||
public fun add(partName: String, facadeName: String) {
|
||||
fun set(partName: String, facadeName: String) {
|
||||
storage[partName] = facadeName
|
||||
}
|
||||
|
||||
public fun getFacadeName(partName: String): String? {
|
||||
fun get(partName: String): String? {
|
||||
return storage.get(partName)
|
||||
}
|
||||
|
||||
public fun remove(className: JvmClassName) {
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
}
|
||||
|
||||
override fun dumpValue(value: String): String = value
|
||||
}
|
||||
|
||||
private inner class SourceToClassesMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, PathStringDescriptor.INSTANCE, StringListExternalizer) {
|
||||
public fun clearOutputsForSource(sourceFile: File) {
|
||||
inner class SourceToClassesMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(sourceFile.absolutePath)
|
||||
}
|
||||
|
||||
public fun add(sourceFile: File, className: JvmClassName) {
|
||||
storage.append(sourceFile.absolutePath, { out -> IOUtil.writeUTF(out, className.internalName) })
|
||||
fun add(sourceFile: File, className: JvmClassName) {
|
||||
storage.append(sourceFile.absolutePath, className.internalName)
|
||||
}
|
||||
|
||||
public operator fun get(sourceFile: File): Collection<JvmClassName> =
|
||||
operator fun get(sourceFile: File): Collection<JvmClassName> =
|
||||
storage[sourceFile.absolutePath].orEmpty().map { JvmClassName.byInternalName(it) }
|
||||
|
||||
override fun dumpValue(value: List<String>) = value.toString()
|
||||
|
||||
override fun clean() {
|
||||
storage.keys.forEach { remove(it) }
|
||||
}
|
||||
override fun dumpValue(value: Collection<String>) = value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass) {
|
||||
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() }
|
||||
.filter { it.asString() != "kotlin.Any" }
|
||||
.toSet()
|
||||
val child = kotlinClass.classId.asSingleFqName()
|
||||
|
||||
parents.forEach { subtypesMap.add(it, child) }
|
||||
|
||||
val removedSupertypes = supertypesMap[child].filter { it !in parents }
|
||||
removedSupertypes.forEach { subtypesMap.removeValues(it, setOf(child)) }
|
||||
|
||||
supertypesMap[child] = parents
|
||||
}
|
||||
|
||||
private fun removeAllFromClassStorage(removedClasses: Collection<JvmClassName>) {
|
||||
if (!IncrementalCompilation.isExperimental() || removedClasses.isEmpty()) return
|
||||
|
||||
val removedFqNames = removedClasses.map { it.fqNameForClassNameWithoutDollars }.toSet()
|
||||
|
||||
for (cache in dependentsWithThis) {
|
||||
val parentsFqNames = hashSetOf<FqName>()
|
||||
val childrenFqNames = hashSetOf<FqName>()
|
||||
|
||||
for (removedFqName in removedFqNames) {
|
||||
parentsFqNames.addAll(cache.supertypesMap[removedFqName])
|
||||
childrenFqNames.addAll(cache.subtypesMap[removedFqName])
|
||||
|
||||
cache.supertypesMap.remove(removedFqName)
|
||||
cache.subtypesMap.remove(removedFqName)
|
||||
}
|
||||
|
||||
for (child in childrenFqNames) {
|
||||
cache.supertypesMap.removeValues(child, removedFqNames)
|
||||
}
|
||||
|
||||
for (parent in parentsFqNames) {
|
||||
cache.subtypesMap.removeValues(parent, removedFqNames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inner class DirtyOutputClassesMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
|
||||
public fun markDirty(className: String) {
|
||||
fun markDirty(className: String) {
|
||||
storage[className] = true
|
||||
}
|
||||
|
||||
public fun notDirty(className: String) {
|
||||
fun notDirty(className: String) {
|
||||
storage.remove(className)
|
||||
}
|
||||
|
||||
public fun getDirtyOutputClasses(): Collection<String> =
|
||||
fun getDirtyOutputClasses(): Collection<String> =
|
||||
storage.keys
|
||||
|
||||
public fun isDirty(className: String): Boolean =
|
||||
fun isDirty(className: String): Boolean =
|
||||
storage.contains(className)
|
||||
|
||||
override fun dumpValue(value: Boolean) = ""
|
||||
}
|
||||
|
||||
private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
|
||||
public fun getEntries(): Map<JvmClassName, List<String>> =
|
||||
storage.keys.toMap(JvmClassName::byInternalName) { storage[it]!! }
|
||||
|
||||
public fun put(className: JvmClassName, changedFunctions: List<String>) {
|
||||
storage[className.internalName] = changedFunctions
|
||||
}
|
||||
|
||||
override fun dumpValue(value: List<String>) =
|
||||
value.dumpCollection()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mapping: (sourceFile+inlineFunction)->(targetFiles)
|
||||
*
|
||||
* Where:
|
||||
* * sourceFile - path to some kotlin source
|
||||
* * inlineFunction - jvmSignature of some inline function in source file
|
||||
* * target files - collection of files inlineFunction has been inlined to
|
||||
*/
|
||||
private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap<PathFunctionPair, Collection<String>>(storageFile, PathFunctionPairKeyDescriptor, PathCollectionExternalizer) {
|
||||
public fun add(sourcePath: String, jvmSignature: String, targetPath: String) {
|
||||
val key = PathFunctionPair(sourcePath, jvmSignature)
|
||||
storage.append(key) { out ->
|
||||
IOUtil.writeUTF(out, targetPath)
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun get(sourcePath: String, jvmSignature: String): Collection<String> {
|
||||
val key = PathFunctionPair(sourcePath, jvmSignature)
|
||||
return storage[key] ?: emptySet()
|
||||
}
|
||||
|
||||
override fun dumpKey(key: PathFunctionPair): String =
|
||||
"(${key.path}, ${key.function})"
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ChangeInfo(val fqName: FqName) {
|
||||
@@ -648,7 +586,7 @@ sealed class ChangeInfo(val fqName: FqName) {
|
||||
|
||||
class Removed(fqName: FqName, names: Collection<String>) : MembersChanged(fqName, names)
|
||||
|
||||
class SignatureChanged(fqName: FqName) : ChangeInfo(fqName)
|
||||
class SignatureChanged(fqName: FqName, val areSubclassesAffected: Boolean) : ChangeInfo(fqName)
|
||||
|
||||
|
||||
protected open fun toStringProperties(): String = "fqName = $fqName"
|
||||
@@ -666,36 +604,18 @@ data class CompilationResult(
|
||||
val changes: Sequence<ChangeInfo> = emptySequence()
|
||||
) {
|
||||
companion object {
|
||||
public val NO_CHANGES: CompilationResult = CompilationResult()
|
||||
val NO_CHANGES: CompilationResult = CompilationResult()
|
||||
}
|
||||
|
||||
operator fun plus(other: CompilationResult): CompilationResult =
|
||||
CompilationResult(protoChanged || other.protoChanged,
|
||||
constantsChanged || other.constantsChanged,
|
||||
inlineChanged || other.inlineChanged,
|
||||
inlineAdded || other.inlineAdded,
|
||||
changes + other.changes)
|
||||
constantsChanged || other.constantsChanged,
|
||||
inlineChanged || other.inlineChanged,
|
||||
inlineAdded || other.inlineAdded,
|
||||
changes + other.changes)
|
||||
}
|
||||
|
||||
|
||||
public fun BuildDataPaths.getKotlinCacheVersion(target: BuildTarget<*>): CacheFormatVersion = CacheFormatVersion(getTargetDataRoot(target))
|
||||
|
||||
private class KotlinIncrementalStorageProvider(
|
||||
private val target: ModuleBuildTarget
|
||||
) : StorageProvider<IncrementalCacheImpl>() {
|
||||
|
||||
override fun equals(other: Any?) = other is KotlinIncrementalStorageProvider && target == other.target
|
||||
|
||||
override fun hashCode() = target.hashCode()
|
||||
|
||||
override fun createStorage(targetDataDir: File): IncrementalCacheImpl =
|
||||
IncrementalCacheImpl(targetDataDir, target)
|
||||
}
|
||||
|
||||
public fun BuildDataManager.getKotlinCache(target: ModuleBuildTarget): IncrementalCacheImpl =
|
||||
getStorage(target, KotlinIncrementalStorageProvider(target))
|
||||
|
||||
private fun ByteArray.md5(): Long {
|
||||
fun ByteArray.md5(): Long {
|
||||
val d = MessageDigest.getInstance("MD5").digest(this)!!
|
||||
return ((d[0].toLong() and 0xFFL)
|
||||
or ((d[1].toLong() and 0xFFL) shl 8)
|
||||
@@ -709,11 +629,11 @@ private fun ByteArray.md5(): Long {
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String =
|
||||
StringBuilder {
|
||||
fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): String =
|
||||
buildString {
|
||||
append("{")
|
||||
for (key in keySet().sorted()) {
|
||||
if (length() != 1) {
|
||||
for (key in keys.sorted()) {
|
||||
if (length != 1) {
|
||||
append(", ")
|
||||
}
|
||||
|
||||
@@ -721,8 +641,7 @@ private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): St
|
||||
append("$key -> $value")
|
||||
}
|
||||
append("}")
|
||||
}.toString()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
|
||||
@TestOnly fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
|
||||
"[${sorted().joinToString(", ", transform = Any::toString)}]"
|
||||
@@ -14,22 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
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
|
||||
|
||||
public class IncrementalCompilationComponentsImpl(
|
||||
caches: Map<ModuleBuildTarget, IncrementalCache>,
|
||||
class IncrementalCompilationComponentsImpl(
|
||||
private val caches: Map<TargetId, IncrementalCache>,
|
||||
private val lookupTracker: LookupTracker
|
||||
): IncrementalCompilationComponents {
|
||||
private val caches = caches.mapKeys { TargetId(it.key) }
|
||||
|
||||
override fun getIncrementalCache(target: TargetId): IncrementalCache =
|
||||
caches[target]!!
|
||||
caches[target] ?: throw Exception("Incremental cache for target ${target.name} not found")
|
||||
|
||||
override fun getLookupTracker(): LookupTracker = lookupTracker
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
@@ -40,7 +40,7 @@ class LocalFileKotlinClass private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
public val className: JvmClassName by lazy { JvmClassName.byClassId(classId) }
|
||||
val className: JvmClassName by lazy { JvmClassName.byClassId(classId) }
|
||||
|
||||
override fun getLocation(): String = file.absolutePath
|
||||
|
||||
@@ -14,24 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.jps.builders.storage.StorageProvider
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
import org.jetbrains.kotlin.jps.incremental.storage.*
|
||||
import org.jetbrains.kotlin.incremental.storage.*
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
object LookupStorageProvider : StorageProvider<LookupStorage>() {
|
||||
override fun createStorage(targetDataDir: File): LookupStorage = LookupStorage(targetDataDir)
|
||||
}
|
||||
|
||||
class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
|
||||
open class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
|
||||
companion object {
|
||||
private val DELETED_TO_SIZE_TRESHOLD = 0.5
|
||||
private val MINIMUM_GARBAGE_COLLECTIBLE_SIZE = 10000
|
||||
@@ -65,14 +61,14 @@ class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
|
||||
}
|
||||
}
|
||||
|
||||
public fun add(lookupSymbol: LookupSymbol, containingPaths: Collection<String>) {
|
||||
fun add(lookupSymbol: LookupSymbol, containingPaths: Collection<String>) {
|
||||
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
|
||||
val fileIds = containingPaths.map { addFileIfNeeded(File(it)) }.toHashSet()
|
||||
fileIds.addAll(lookupMap[key] ?: emptySet())
|
||||
lookupMap[key] = fileIds
|
||||
}
|
||||
|
||||
public fun removeLookupsFrom(file: File) {
|
||||
fun removeLookupsFrom(file: File) {
|
||||
val id = fileToId[file] ?: return
|
||||
idToFile.remove(id)
|
||||
fileToId.remove(file)
|
||||
@@ -149,14 +145,12 @@ class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public fun forceGC() {
|
||||
@TestOnly fun forceGC() {
|
||||
removeGarbageIfNeeded(force = true)
|
||||
flush(false)
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public fun dump(lookupSymbols: Set<LookupSymbol>): String {
|
||||
@TestOnly fun dump(lookupSymbols: Set<LookupSymbol>): String {
|
||||
flush(false)
|
||||
|
||||
val sb = StringBuilder()
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
@@ -25,12 +25,12 @@ import java.util.*
|
||||
|
||||
/** This file is generated by org.jetbrains.kotlin.generators.protobuf.GenerateProtoBufCompare. DO NOT MODIFY MANUALLY */
|
||||
|
||||
open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, public val newNameResolver: NameResolver) {
|
||||
open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameResolver: NameResolver) {
|
||||
private val strings = Interner<String>()
|
||||
public val oldStringIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
public val newStringIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
public val oldClassIdIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
public val newClassIdIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
val oldStringIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
val newStringIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
val oldClassIdIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
val newClassIdIndexesMap: MutableMap<Int, Int> = hashMapOf()
|
||||
|
||||
private val classIds = Interner<ClassId>()
|
||||
|
||||
@@ -44,15 +44,21 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkEquals(old.typeTable, new.typeTable)) return false
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) return false
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
public enum class ProtoBufPackageKind {
|
||||
enum class ProtoBufPackageKind {
|
||||
FUNCTION_LIST,
|
||||
PROPERTY_LIST,
|
||||
TYPE_TABLE
|
||||
TYPE_TABLE,
|
||||
PACKAGE_MODULE_NAME
|
||||
}
|
||||
|
||||
public fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
|
||||
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
|
||||
val result = EnumSet.noneOf(ProtoBufPackageKind::class.java)
|
||||
|
||||
if (!checkEqualsPackageFunction(old, new)) result.add(ProtoBufPackageKind.FUNCTION_LIST)
|
||||
@@ -64,6 +70,11 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkEquals(old.typeTable, new.typeTable)) result.add(ProtoBufPackageKind.TYPE_TABLE)
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
||||
if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -101,15 +112,14 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkEquals(old.typeTable, new.typeTable)) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.classAnnotation) != new.getExtensionCount(JvmProtoBuf.classAnnotation)) return false
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classAnnotation, i), new.getExtension(JvmProtoBuf.classAnnotation, i))) return false
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) return false
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
public enum class ProtoBufClassKind {
|
||||
enum class ProtoBufClassKind {
|
||||
FLAGS,
|
||||
FQ_NAME,
|
||||
COMPANION_OBJECT_NAME,
|
||||
@@ -122,10 +132,10 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
PROPERTY_LIST,
|
||||
ENUM_ENTRY_LIST,
|
||||
TYPE_TABLE,
|
||||
CLASS_ANNOTATION_LIST
|
||||
CLASS_MODULE_NAME
|
||||
}
|
||||
|
||||
public fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
|
||||
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
|
||||
val result = EnumSet.noneOf(ProtoBufClassKind::class.java)
|
||||
|
||||
if (old.hasFlags() != new.hasFlags()) result.add(ProtoBufClassKind.FLAGS)
|
||||
@@ -161,10 +171,9 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkEquals(old.typeTable, new.typeTable)) result.add(ProtoBufClassKind.TYPE_TABLE)
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.classAnnotation) != new.getExtensionCount(JvmProtoBuf.classAnnotation)) result.add(ProtoBufClassKind.CLASS_ANNOTATION_LIST)
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classAnnotation) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classAnnotation, i), new.getExtension(JvmProtoBuf.classAnnotation, i))) result.add(ProtoBufClassKind.CLASS_ANNOTATION_LIST)
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
||||
if (old.hasExtension(JvmProtoBuf.classModuleName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -176,6 +185,11 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (old.flags != new.flags) return false
|
||||
}
|
||||
|
||||
if (old.hasOldFlags() != new.hasOldFlags()) return false
|
||||
if (old.hasOldFlags()) {
|
||||
if (old.oldFlags != new.oldFlags) return false
|
||||
}
|
||||
|
||||
if (!checkStringEquals(old.name, new.name)) return false
|
||||
|
||||
if (old.hasReturnType() != new.hasReturnType()) return false
|
||||
@@ -212,11 +226,6 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.methodSignature), new.getExtension(JvmProtoBuf.methodSignature))) return false
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.methodImplClassName) != new.hasExtension(JvmProtoBuf.methodImplClassName)) return false
|
||||
if (old.hasExtension(JvmProtoBuf.methodImplClassName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.methodImplClassName), new.getExtension(JvmProtoBuf.methodImplClassName))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -226,6 +235,11 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (old.flags != new.flags) return false
|
||||
}
|
||||
|
||||
if (old.hasOldFlags() != new.hasOldFlags()) return false
|
||||
if (old.hasOldFlags()) {
|
||||
if (old.oldFlags != new.oldFlags) return false
|
||||
}
|
||||
|
||||
if (!checkStringEquals(old.name, new.name)) return false
|
||||
|
||||
if (old.hasReturnType() != new.hasReturnType()) return false
|
||||
@@ -270,11 +284,6 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.propertySignature), new.getExtension(JvmProtoBuf.propertySignature))) return false
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.propertyImplClassName) != new.hasExtension(JvmProtoBuf.propertyImplClassName)) return false
|
||||
if (old.hasExtension(JvmProtoBuf.propertyImplClassName)) {
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.propertyImplClassName), new.getExtension(JvmProtoBuf.propertyImplClassName))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -395,10 +404,11 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
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
|
||||
open fun checkEquals(old: ProtoBuf.EnumEntry, new: ProtoBuf.EnumEntry): Boolean {
|
||||
if (old.hasName() != new.hasName()) return false
|
||||
if (old.hasName()) {
|
||||
if (!checkStringEquals(old.name, new.name)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -431,11 +441,6 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (old.varargElementTypeId != new.varargElementTypeId) return false
|
||||
}
|
||||
|
||||
if (old.hasExtension(JvmProtoBuf.index) != new.hasExtension(JvmProtoBuf.index)) return false
|
||||
if (old.hasExtension(JvmProtoBuf.index)) {
|
||||
if (old.getExtension(JvmProtoBuf.index) != new.getExtension(JvmProtoBuf.index)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -477,6 +482,14 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
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
|
||||
}
|
||||
|
||||
open fun checkEquals(old: ProtoBuf.Type.Argument, new: ProtoBuf.Type.Argument): Boolean {
|
||||
if (old.hasProjection() != new.hasProjection()) return false
|
||||
if (old.hasProjection()) {
|
||||
@@ -496,14 +509,6 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
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()) {
|
||||
@@ -515,10 +520,13 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (!checkStringEquals(old.desc, new.desc)) return false
|
||||
}
|
||||
|
||||
if (old.hasIsStaticInOuter() != new.hasIsStaticInOuter()) return false
|
||||
if (old.hasIsStaticInOuter()) {
|
||||
if (old.isStaticInOuter != new.isStaticInOuter) return false
|
||||
}
|
||||
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
|
||||
}
|
||||
@@ -663,7 +671,7 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
if (old.enumEntryCount != new.enumEntryCount) return false
|
||||
|
||||
for(i in 0..old.enumEntryCount - 1) {
|
||||
if (!checkStringEquals(old.getEnumEntry(i), new.getEnumEntry(i))) return false
|
||||
if (!checkEquals(old.getEnumEntry(i), new.getEnumEntry(i))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -769,10 +777,10 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
return true
|
||||
}
|
||||
|
||||
public fun oldGetIndexOfString(index: Int): Int = getIndexOfString(index, oldStringIndexesMap, oldNameResolver)
|
||||
public fun newGetIndexOfString(index: Int): Int = getIndexOfString(index, newStringIndexesMap, newNameResolver)
|
||||
fun oldGetIndexOfString(index: Int): Int = getIndexOfString(index, oldStringIndexesMap, oldNameResolver)
|
||||
fun newGetIndexOfString(index: Int): Int = getIndexOfString(index, newStringIndexesMap, newNameResolver)
|
||||
|
||||
public fun getIndexOfString(index: Int, map: MutableMap<Int, Int>, nameResolver: NameResolver): Int {
|
||||
fun getIndexOfString(index: Int, map: MutableMap<Int, Int>, nameResolver: NameResolver): Int {
|
||||
map[index]?.let { return it }
|
||||
|
||||
val result = strings.intern(nameResolver.getString(index))
|
||||
@@ -780,10 +788,10 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
return result
|
||||
}
|
||||
|
||||
public fun oldGetIndexOfClassId(index: Int): Int = getIndexOfClassId(index, oldClassIdIndexesMap, oldNameResolver)
|
||||
public fun newGetIndexOfClassId(index: Int): Int = getIndexOfClassId(index, newClassIdIndexesMap, newNameResolver)
|
||||
fun oldGetIndexOfClassId(index: Int): Int = getIndexOfClassId(index, oldClassIdIndexesMap, oldNameResolver)
|
||||
fun newGetIndexOfClassId(index: Int): Int = getIndexOfClassId(index, newClassIdIndexesMap, newNameResolver)
|
||||
|
||||
public fun getIndexOfClassId(index: Int, map: MutableMap<Int, Int>, nameResolver: NameResolver): Int {
|
||||
fun getIndexOfClassId(index: Int, map: MutableMap<Int, Int>, nameResolver: NameResolver): Int {
|
||||
map[index]?.let { return it }
|
||||
|
||||
val result = classIds.intern(nameResolver.getClassId(index))
|
||||
@@ -800,7 +808,7 @@ open class ProtoCompareGenerated(public val oldNameResolver: NameResolver, publi
|
||||
}
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
for(i in 0..functionCount - 1) {
|
||||
@@ -815,10 +823,14 @@ public fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes:
|
||||
hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JvmProtoBuf.packageModuleName)) {
|
||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasFlags()) {
|
||||
@@ -860,27 +872,31 @@ public fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (
|
||||
}
|
||||
|
||||
for(i in 0..enumEntryCount - 1) {
|
||||
hashCode = 31 * hashCode + stringIndexes(getEnumEntry(i))
|
||||
hashCode = 31 * hashCode + getEnumEntry(i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasTypeTable()) {
|
||||
hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JvmProtoBuf.classAnnotation) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
if (hasExtension(JvmProtoBuf.classModuleName)) {
|
||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasFlags()) {
|
||||
hashCode = 31 * hashCode + flags
|
||||
}
|
||||
|
||||
if (hasOldFlags()) {
|
||||
hashCode = 31 * hashCode + oldFlags
|
||||
}
|
||||
|
||||
hashCode = 31 * hashCode + stringIndexes(name)
|
||||
|
||||
if (hasReturnType()) {
|
||||
@@ -915,20 +931,20 @@ public fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.methodSignature).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JvmProtoBuf.methodImplClassName)) {
|
||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.methodImplClassName))
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasFlags()) {
|
||||
hashCode = 31 * hashCode + flags
|
||||
}
|
||||
|
||||
if (hasOldFlags()) {
|
||||
hashCode = 31 * hashCode + oldFlags
|
||||
}
|
||||
|
||||
hashCode = 31 * hashCode + stringIndexes(name)
|
||||
|
||||
if (hasReturnType()) {
|
||||
@@ -967,14 +983,10 @@ public fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.propertySignature).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
if (hasExtension(JvmProtoBuf.propertyImplClassName)) {
|
||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.propertyImplClassName))
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.TypeTable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.TypeTable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
for(i in 0..typeCount - 1) {
|
||||
@@ -988,7 +1000,7 @@ public fun ProtoBuf.TypeTable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexe
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
hashCode = 31 * hashCode + id
|
||||
@@ -1018,7 +1030,7 @@ public fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIn
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Type.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Type.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
for(i in 0..argumentCount - 1) {
|
||||
@@ -1072,7 +1084,7 @@ public fun ProtoBuf.Type.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (I
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasFlags()) {
|
||||
@@ -1090,19 +1102,17 @@ public fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameInde
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Annotation.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.EnumEntry.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)
|
||||
if (hasName()) {
|
||||
hashCode = 31 * hashCode + stringIndexes(name)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasFlags()) {
|
||||
@@ -1127,14 +1137,10 @@ public fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameI
|
||||
hashCode = 31 * hashCode + varargElementTypeId
|
||||
}
|
||||
|
||||
if (hasExtension(JvmProtoBuf.index)) {
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.index)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun JvmProtoBuf.JvmMethodSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun JvmProtoBuf.JvmMethodSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasName()) {
|
||||
@@ -1148,7 +1154,7 @@ public fun JvmProtoBuf.JvmMethodSignature.hashCode(stringIndexes: (Int) -> Int,
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasField()) {
|
||||
@@ -1170,7 +1176,19 @@ public fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
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
|
||||
}
|
||||
|
||||
fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasProjection()) {
|
||||
@@ -1188,17 +1206,7 @@ public fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIn
|
||||
return hashCode
|
||||
}
|
||||
|
||||
public 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
|
||||
}
|
||||
|
||||
public fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasName()) {
|
||||
@@ -1209,14 +1217,20 @@ public fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, f
|
||||
hashCode = 31 * hashCode + stringIndexes(desc)
|
||||
}
|
||||
|
||||
if (hasIsStaticInOuter()) {
|
||||
hashCode = 31 * hashCode + isStaticInOuter.hashCode()
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
public fun ProtoBuf.Annotation.Argument.Value.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
fun ProtoBuf.Annotation.Argument.Value.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
|
||||
var hashCode = 1
|
||||
|
||||
if (hasType()) {
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.google.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufClassKind
|
||||
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufPackageKind
|
||||
import org.jetbrains.kotlin.jps.incremental.storage.ProtoMapValue
|
||||
import org.jetbrains.kotlin.incremental.ProtoCompareGenerated.ProtoBufClassKind
|
||||
import org.jetbrains.kotlin.incremental.ProtoCompareGenerated.ProtoBufPackageKind
|
||||
import org.jetbrains.kotlin.incremental.storage.ProtoMapValue
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.Deserialization
|
||||
@@ -29,17 +29,24 @@ import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.utils.HashSetUtil
|
||||
import java.util.*
|
||||
|
||||
public sealed class DifferenceKind() {
|
||||
public object NONE: DifferenceKind()
|
||||
public object CLASS_SIGNATURE: DifferenceKind()
|
||||
public class MEMBERS(val names: Collection<String>): DifferenceKind()
|
||||
}
|
||||
data class Difference(
|
||||
val isClassAffected: Boolean = false,
|
||||
val areSubclassesAffected: Boolean = false,
|
||||
val changedMembersNames: Set<String> = emptySet()
|
||||
)
|
||||
|
||||
public fun difference(oldData: ProtoMapValue, newData: ProtoMapValue): DifferenceKind {
|
||||
if (oldData.isPackageFacade != newData.isPackageFacade) return DifferenceKind.CLASS_SIGNATURE
|
||||
fun difference(oldData: ProtoMapValue, newData: ProtoMapValue): Difference {
|
||||
if (!oldData.isPackageFacade && newData.isPackageFacade) return Difference(isClassAffected = true, areSubclassesAffected = true)
|
||||
|
||||
if (oldData.isPackageFacade && !newData.isPackageFacade) return Difference(isClassAffected = true)
|
||||
|
||||
val differenceObject =
|
||||
if (oldData.isPackageFacade) DifferenceCalculatorForPackageFacade(oldData, newData) else DifferenceCalculatorForClass(oldData, newData)
|
||||
if (oldData.isPackageFacade) {
|
||||
DifferenceCalculatorForPackageFacade(oldData, newData)
|
||||
}
|
||||
else {
|
||||
DifferenceCalculatorForClass(oldData, newData)
|
||||
}
|
||||
|
||||
return differenceObject.difference()
|
||||
}
|
||||
@@ -70,9 +77,7 @@ private abstract class DifferenceCalculator() {
|
||||
|
||||
protected val compareObject by lazy { ProtoCompareGenerated(oldNameResolver, newNameResolver) }
|
||||
|
||||
abstract fun difference(): DifferenceKind
|
||||
|
||||
protected fun membersOrNone(names: Collection<String>): DifferenceKind = if (names.isEmpty()) DifferenceKind.NONE else DifferenceKind.MEMBERS(names)
|
||||
abstract fun difference(): Difference
|
||||
|
||||
protected fun calcDifferenceForMembers(oldList: List<MessageLite>, newList: List<MessageLite>): Collection<String> {
|
||||
val result = hashSetOf<String>()
|
||||
@@ -82,7 +87,7 @@ private abstract class DifferenceCalculator() {
|
||||
val newMap =
|
||||
newList.groupBy { it.getHashCode({ compareObject.newGetIndexOfString(it) }, { compareObject.newGetIndexOfClassId(it) }) }
|
||||
|
||||
val hashes = oldMap.keySet() + newMap.keySet()
|
||||
val hashes = oldMap.keys + newMap.keys
|
||||
for (hash in hashes) {
|
||||
val oldMembers = oldMap[hash]
|
||||
val newMembers = newMap[hash]
|
||||
@@ -156,8 +161,7 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
ProtoBufClassKind.FLAGS,
|
||||
ProtoBufClassKind.FQ_NAME,
|
||||
ProtoBufClassKind.TYPE_PARAMETER_LIST,
|
||||
ProtoBufClassKind.SUPERTYPE_LIST,
|
||||
ProtoBufClassKind.CLASS_ANNOTATION_LIST
|
||||
ProtoBufClassKind.SUPERTYPE_LIST
|
||||
)
|
||||
}
|
||||
|
||||
@@ -172,16 +176,11 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
|
||||
val diff = compareObject.difference(oldProto, newProto)
|
||||
|
||||
override fun difference(): DifferenceKind {
|
||||
if (diff.isEmpty()) return DifferenceKind.NONE
|
||||
|
||||
CLASS_SIGNATURE_ENUMS.forEach { if (it in diff) return DifferenceKind.CLASS_SIGNATURE }
|
||||
|
||||
return membersOrNone(getChangedMembersNames())
|
||||
}
|
||||
|
||||
private fun getChangedMembersNames(): Set<String> {
|
||||
override fun difference(): Difference {
|
||||
var isClassAffected = false
|
||||
var areSubclassesAffected = false
|
||||
val names = hashSetOf<String>()
|
||||
val classIsSealed = newProto.isSealed && oldProto.isSealed
|
||||
|
||||
fun Int.oldToNames() = names.add(oldNameResolver.getString(this))
|
||||
fun Int.newToNames() = names.add(newNameResolver.getString(this))
|
||||
@@ -198,30 +197,41 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
if (oldProto.hasCompanionObjectName()) oldProto.companionObjectName.oldToNames()
|
||||
if (newProto.hasCompanionObjectName()) newProto.companionObjectName.newToNames()
|
||||
}
|
||||
ProtoBufClassKind.NESTED_CLASS_NAME_LIST ->
|
||||
ProtoBufClassKind.NESTED_CLASS_NAME_LIST -> {
|
||||
if (classIsSealed) {
|
||||
// when class is sealed, adding an implementation can break exhaustive when expressions
|
||||
// the workaround is to recompile all class usages
|
||||
isClassAffected = true
|
||||
}
|
||||
|
||||
names.addAll(calcDifferenceForNames(oldProto.nestedClassNameList, newProto.nestedClassNameList))
|
||||
ProtoBufClassKind.CONSTRUCTOR_LIST ->
|
||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList))
|
||||
}
|
||||
ProtoBufClassKind.CONSTRUCTOR_LIST -> {
|
||||
val differentNonPrivateConstructors = calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList)
|
||||
|
||||
if (differentNonPrivateConstructors.isNotEmpty()) {
|
||||
isClassAffected = true
|
||||
}
|
||||
}
|
||||
ProtoBufClassKind.FUNCTION_LIST ->
|
||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getFunctionList))
|
||||
ProtoBufClassKind.PROPERTY_LIST ->
|
||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getPropertyList))
|
||||
ProtoBufClassKind.ENUM_ENTRY_LIST ->
|
||||
names.addAll(calcDifferenceForNames(oldProto.enumEntryList, newProto.enumEntryList))
|
||||
ProtoBufClassKind.ENUM_ENTRY_LIST -> {
|
||||
isClassAffected = true
|
||||
}
|
||||
ProtoBufClassKind.TYPE_TABLE -> {
|
||||
// TODO
|
||||
}
|
||||
ProtoBufClassKind.FLAGS,
|
||||
ProtoBufClassKind.FQ_NAME,
|
||||
ProtoBufClassKind.TYPE_PARAMETER_LIST,
|
||||
ProtoBufClassKind.SUPERTYPE_LIST,
|
||||
ProtoBufClassKind.CLASS_ANNOTATION_LIST ->
|
||||
throw IllegalArgumentException("Unexpected kind: $kind")
|
||||
else ->
|
||||
throw IllegalArgumentException("Unsupported kind: $kind")
|
||||
in CLASS_SIGNATURE_ENUMS -> {
|
||||
isClassAffected = true
|
||||
areSubclassesAffected = true
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unsupported kind: $kind")
|
||||
}
|
||||
}
|
||||
return names
|
||||
|
||||
return Difference(isClassAffected, areSubclassesAffected, names)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,13 +247,7 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
|
||||
|
||||
val diff = compareObject.difference(oldProto, newProto)
|
||||
|
||||
override fun difference(): DifferenceKind {
|
||||
if (diff.isEmpty()) return DifferenceKind.NONE
|
||||
|
||||
return membersOrNone(getChangedMembersNames())
|
||||
}
|
||||
|
||||
private fun getChangedMembersNames(): Set<String> {
|
||||
override fun difference(): Difference {
|
||||
val names = hashSetOf<String>()
|
||||
|
||||
fun calcDifferenceForNonPrivateMembers(members: (ProtoBuf.Package) -> List<MessageLite>): Collection<String> {
|
||||
@@ -261,11 +265,13 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
|
||||
ProtoBufPackageKind.TYPE_TABLE -> {
|
||||
// TODO
|
||||
}
|
||||
else ->
|
||||
throw IllegalArgumentException("Unsupported kind: $kind")
|
||||
else -> throw IllegalArgumentException("Unsupported kind: $kind")
|
||||
}
|
||||
}
|
||||
|
||||
return names
|
||||
return Difference(changedMembersNames = names)
|
||||
}
|
||||
}
|
||||
|
||||
private val ProtoBuf.Class.isSealed: Boolean
|
||||
get() = ProtoBuf.Modality.SEALED == Flags.MODALITY.get(flags)
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
@@ -23,14 +23,14 @@ import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
internal abstract class BasicMap<K : Comparable<K>, V>(
|
||||
abstract class BasicMap<K : Comparable<K>, V>(
|
||||
storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<K>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) {
|
||||
protected val storage = LazyStorage(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
open fun clean() {
|
||||
fun clean() {
|
||||
storage.clean()
|
||||
}
|
||||
|
||||
@@ -60,19 +60,22 @@ internal abstract class BasicMap<K : Comparable<K>, V>(
|
||||
}.toString()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpKey(key: K): String
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpValue(value: V): String
|
||||
}
|
||||
|
||||
internal abstract class BasicStringMap<V>(
|
||||
abstract class BasicStringMap<V>(
|
||||
storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<String>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : BasicMap<String, V>(storageFile, keyDescriptor, valueExternalizer) {
|
||||
public constructor(
|
||||
constructor(
|
||||
storageFile: File,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : this(storageFile, EnumeratorStringDescriptor.INSTANCE, valueExternalizer)
|
||||
|
||||
override fun dumpKey(key: String): String = key
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.jps.incremental.storage.StorageOwner
|
||||
|
||||
open class BasicMapsOwner : StorageOwner {
|
||||
open class BasicMapsOwner {
|
||||
private val maps = arrayListOf<BasicMap<*, *>>()
|
||||
|
||||
companion object {
|
||||
@@ -31,18 +30,17 @@ open class BasicMapsOwner : StorageOwner {
|
||||
return map
|
||||
}
|
||||
|
||||
override fun clean() {
|
||||
open fun clean() {
|
||||
maps.forEach { it.clean() }
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
open fun close() {
|
||||
maps.forEach { it.close() }
|
||||
}
|
||||
|
||||
override fun flush(memoryCachesOnly: Boolean) {
|
||||
open fun flush(memoryCachesOnly: Boolean) {
|
||||
maps.forEach { it.flush(memoryCachesOnly) }
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public fun dump(): String = maps.map { it.dump() }.joinToString("\n\n")
|
||||
@TestOnly fun dump(): String = maps.map { it.dump() }.joinToString("\n\n")
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
|
||||
internal open class ClassOneToManyMap(
|
||||
storageFile: File
|
||||
) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
|
||||
fun add(key: FqName, value: FqName) {
|
||||
storage.append(key.asString(), value.asString())
|
||||
}
|
||||
|
||||
operator fun get(key: FqName): Collection<FqName> =
|
||||
storage[key.asString()]?.map(::FqName) ?: setOf()
|
||||
|
||||
operator fun set(key: FqName, values: Collection<FqName>) {
|
||||
if (values.isEmpty()) {
|
||||
remove(key)
|
||||
return
|
||||
}
|
||||
|
||||
storage[key.asString()] = values.map(FqName::asString)
|
||||
}
|
||||
|
||||
fun remove(key: FqName) {
|
||||
storage.remove(key.asString())
|
||||
}
|
||||
|
||||
fun removeValues(key: FqName, removed: Set<FqName>) {
|
||||
val notRemoved = this[key].filter { it !in removed }
|
||||
this[key] = notRemoved
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubtypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
internal class SupertypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.io.File
|
||||
@@ -24,15 +24,15 @@ internal class FileToIdMap(file: File) : BasicMap<File, Int>(file, FileKeyDescri
|
||||
|
||||
override fun dumpValue(value: Int): String = value.toString()
|
||||
|
||||
public operator fun get(file: File): Int? = storage[file]
|
||||
operator fun get(file: File): Int? = storage[file]
|
||||
|
||||
public operator fun set(file: File, id: Int) {
|
||||
operator fun set(file: File, id: Int) {
|
||||
storage[file] = id
|
||||
}
|
||||
|
||||
public fun remove(file: File) {
|
||||
fun remove(file: File) {
|
||||
storage.remove(file)
|
||||
}
|
||||
|
||||
public fun toMap(): Map<File, Int> = storage.keys.keysToMap { storage[it]!! }
|
||||
fun toMap(): Map<File, Int> = storage.keys.keysToMap { storage[it]!! }
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.ExternalIntegerKeyDescriptor
|
||||
import java.io.File
|
||||
@@ -24,15 +24,15 @@ internal class IdToFileMap(file: File) : BasicMap<Int, File>(file, ExternalInteg
|
||||
|
||||
override fun dumpValue(value: File): String = value.toString()
|
||||
|
||||
public operator fun get(id: Int): File? = storage[id]
|
||||
operator fun get(id: Int): File? = storage[id]
|
||||
|
||||
public operator fun contains(id: Int): Boolean = id in storage
|
||||
operator fun contains(id: Int): Boolean = id in storage
|
||||
|
||||
public operator fun set(id: Int, file: File) {
|
||||
operator fun set(id: Int, file: File) {
|
||||
storage[id] = file
|
||||
}
|
||||
|
||||
public fun remove(id: Int) {
|
||||
fun remove(id: Int) {
|
||||
storage.remove(id)
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.IOUtil
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.DataOutput
|
||||
@@ -27,7 +28,7 @@ import java.io.IOException
|
||||
/**
|
||||
* It's lazy in a sense that PersistentHashMap is created only on write
|
||||
*/
|
||||
internal class LazyStorage<K, V>(
|
||||
class LazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
@@ -73,8 +74,12 @@ internal class LazyStorage<K, V>(
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
fun append(key: K, append: (DataOutput)->Unit) {
|
||||
getStorageOrCreateNew().appendData(key, append)
|
||||
fun append(key: K, value: String) {
|
||||
append(key) { out -> IOUtil.writeUTF(out, value) }
|
||||
}
|
||||
|
||||
fun append(key: K, value: Int) {
|
||||
append(key) { out -> out.writeInt(value) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -110,4 +115,8 @@ internal class LazyStorage<K, V>(
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
private fun append(key: K, append: (DataOutput)->Unit) {
|
||||
getStorageOrCreateNew().appendData(key, append)
|
||||
}
|
||||
}
|
||||
@@ -14,29 +14,29 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import java.io.File
|
||||
|
||||
internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Set<Int>>(storage, LookupSymbolKeyDescriptor, IntSetExternalizer) {
|
||||
internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(storage, LookupSymbolKeyDescriptor, IntCollectionExternalizer) {
|
||||
override fun dumpKey(key: LookupSymbolKey): String = key.toString()
|
||||
|
||||
override fun dumpValue(value: Set<Int>): String = value.toString()
|
||||
override fun dumpValue(value: Collection<Int>): String = value.toString()
|
||||
|
||||
public fun add(name: String, scope: String, fileId: Int) {
|
||||
storage.append(LookupSymbolKey(name, scope)) { out -> out.writeInt(fileId) }
|
||||
fun add(name: String, scope: String, fileId: Int) {
|
||||
storage.append(LookupSymbolKey(name, scope), fileId)
|
||||
}
|
||||
|
||||
public operator fun get(key: LookupSymbolKey): Set<Int>? = storage[key]
|
||||
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
|
||||
|
||||
public operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {
|
||||
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {
|
||||
storage[key] = fileIds
|
||||
}
|
||||
|
||||
public fun remove(key: LookupSymbolKey) {
|
||||
fun remove(key: LookupSymbolKey) {
|
||||
storage.remove(key)
|
||||
}
|
||||
|
||||
public val keys: Collection<LookupSymbolKey>
|
||||
val keys: Collection<LookupSymbolKey>
|
||||
get() = storage.keys
|
||||
}
|
||||
@@ -14,15 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental.storage
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import com.intellij.util.io.IOUtil
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import gnu.trove.THashSet
|
||||
import gnu.trove.TIntHashSet
|
||||
import gnu.trove.decorator.TIntHashSetDecorator
|
||||
import java.io.DataInput
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutput
|
||||
@@ -47,31 +45,12 @@ object LookupSymbolKeyDescriptor : KeyDescriptor<LookupSymbolKey> {
|
||||
override fun isEqual(val1: LookupSymbolKey, val2: LookupSymbolKey): Boolean = val1 == val2
|
||||
}
|
||||
|
||||
|
||||
object PathFunctionPairKeyDescriptor : KeyDescriptor<PathFunctionPair> {
|
||||
override fun read(input: DataInput): PathFunctionPair {
|
||||
val path = IOUtil.readUTF(input)
|
||||
val function = IOUtil.readUTF(input)
|
||||
return PathFunctionPair(path, function)
|
||||
}
|
||||
|
||||
override fun save(output: DataOutput, value: PathFunctionPair) {
|
||||
IOUtil.writeUTF(output, value.path)
|
||||
IOUtil.writeUTF(output, value.function)
|
||||
}
|
||||
|
||||
override fun getHashCode(value: PathFunctionPair): Int = value.hashCode()
|
||||
|
||||
override fun isEqual(val1: PathFunctionPair, val2: PathFunctionPair): Boolean = val1 == val2
|
||||
}
|
||||
|
||||
|
||||
object ProtoMapValueExternalizer : DataExternalizer<ProtoMapValue> {
|
||||
override fun save(output: DataOutput, value: ProtoMapValue) {
|
||||
output.writeBoolean(value.isPackageFacade)
|
||||
output.writeInt(value.bytes.size())
|
||||
output.writeInt(value.bytes.size)
|
||||
output.write(value.bytes)
|
||||
output.writeInt(value.strings.size())
|
||||
output.writeInt(value.strings.size)
|
||||
|
||||
for (string in value.strings) {
|
||||
output.writeUTF(string)
|
||||
@@ -92,9 +71,9 @@ object ProtoMapValueExternalizer : DataExternalizer<ProtoMapValue> {
|
||||
|
||||
abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
||||
override fun save(output: DataOutput, map: Map<String, T>?) {
|
||||
output.writeInt(map!!.size())
|
||||
output.writeInt(map!!.size)
|
||||
|
||||
for ((key, value) in map.entrySet()) {
|
||||
for ((key, value) in map.entries) {
|
||||
IOUtil.writeString(key, output)
|
||||
writeValue(output, value)
|
||||
}
|
||||
@@ -125,69 +104,31 @@ object StringToLongMapExternalizer : StringMapExternalizer<Long>() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object StringListExternalizer : DataExternalizer<List<String>> {
|
||||
override fun save(output: DataOutput, value: List<String>) {
|
||||
value.forEach { IOUtil.writeUTF(output, it) }
|
||||
}
|
||||
|
||||
override fun read(input: DataInput): List<String> {
|
||||
val result = ArrayList<String>()
|
||||
|
||||
while ((input as DataInputStream).available() > 0) {
|
||||
result.add(IOUtil.readUTF(input))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object PathCollectionExternalizer : DataExternalizer<Collection<String>> {
|
||||
override fun save(output: DataOutput, value: Collection<String>) {
|
||||
for (str in value) {
|
||||
IOUtil.writeUTF(output, str)
|
||||
}
|
||||
}
|
||||
|
||||
override fun read(input: DataInput): Collection<String> {
|
||||
val result = THashSet(FileUtil.PATH_HASHING_STRATEGY)
|
||||
val stream = input as DataInputStream
|
||||
|
||||
while (stream.available() > 0) {
|
||||
val str = IOUtil.readUTF(stream)
|
||||
result.add(str)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
object ConstantsMapExternalizer : DataExternalizer<Map<String, Any>> {
|
||||
override fun save(output: DataOutput, map: Map<String, Any>?) {
|
||||
output.writeInt(map!!.size())
|
||||
for (name in map.keySet().sorted()) {
|
||||
output.writeInt(map!!.size)
|
||||
for (name in map.keys.sorted()) {
|
||||
IOUtil.writeString(name, output)
|
||||
val value = map[name]!!
|
||||
when (value) {
|
||||
is Int -> {
|
||||
output.writeByte(Kind.INT.ordinal())
|
||||
output.writeByte(Kind.INT.ordinal)
|
||||
output.writeInt(value)
|
||||
}
|
||||
is Float -> {
|
||||
output.writeByte(Kind.FLOAT.ordinal())
|
||||
output.writeByte(Kind.FLOAT.ordinal)
|
||||
output.writeFloat(value)
|
||||
}
|
||||
is Long -> {
|
||||
output.writeByte(Kind.LONG.ordinal())
|
||||
output.writeByte(Kind.LONG.ordinal)
|
||||
output.writeLong(value)
|
||||
}
|
||||
is Double -> {
|
||||
output.writeByte(Kind.DOUBLE.ordinal())
|
||||
output.writeByte(Kind.DOUBLE.ordinal)
|
||||
output.writeDouble(value)
|
||||
}
|
||||
is String -> {
|
||||
output.writeByte(Kind.STRING.ordinal())
|
||||
output.writeByte(Kind.STRING.ordinal)
|
||||
IOUtil.writeString(value, output)
|
||||
}
|
||||
else -> throw IllegalStateException("Unexpected constant class: ${value.javaClass}")
|
||||
@@ -222,25 +163,6 @@ object ConstantsMapExternalizer : DataExternalizer<Map<String, Any>> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object IntSetExternalizer : DataExternalizer<Set<Int>> {
|
||||
override fun save(output: DataOutput, value: Set<Int>) {
|
||||
value.forEach { output.writeInt(it) }
|
||||
}
|
||||
|
||||
override fun read(input: DataInput): Set<Int> {
|
||||
val result = TIntHashSet()
|
||||
val stream = input as DataInputStream
|
||||
|
||||
while (stream.available() > 0) {
|
||||
val str = stream.readInt()
|
||||
result.add(str)
|
||||
}
|
||||
|
||||
return TIntHashSetDecorator(result)
|
||||
}
|
||||
}
|
||||
|
||||
object IntExternalizer : DataExternalizer<Int> {
|
||||
override fun read(input: DataInput): Int = input.readInt()
|
||||
|
||||
@@ -249,6 +171,12 @@ object IntExternalizer : DataExternalizer<Int> {
|
||||
}
|
||||
}
|
||||
|
||||
object PathStringDescriptor : EnumeratorStringDescriptor() {
|
||||
override fun getHashCode(value: String) = FileUtil.pathHashCode(value)
|
||||
|
||||
override fun isEqual(val1: String, val2: String?) = FileUtil.pathsEqual(val1, val2)
|
||||
}
|
||||
|
||||
object FileKeyDescriptor : KeyDescriptor<File> {
|
||||
override fun read(input: DataInput): File = File(input.readUTF())
|
||||
|
||||
@@ -261,4 +189,28 @@ object FileKeyDescriptor : KeyDescriptor<File> {
|
||||
|
||||
override fun isEqual(val1: File?, val2: File?): Boolean =
|
||||
FileUtil.FILE_HASHING_STRATEGY.equals(val1, val2)
|
||||
}
|
||||
}
|
||||
|
||||
open class CollectionExternalizer<T>(
|
||||
private val elementExternalizer: DataExternalizer<T>,
|
||||
private val newCollection: () -> MutableCollection<T>
|
||||
) : DataExternalizer<Collection<T>> {
|
||||
override fun read(input: DataInput): Collection<T> {
|
||||
val result = newCollection()
|
||||
val stream = input as DataInputStream
|
||||
|
||||
while (stream.available() > 0) {
|
||||
result.add(elementExternalizer.read(stream))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun save(output: DataOutput, value: Collection<T>) {
|
||||
value.forEach { elementExternalizer.save(output, it) }
|
||||
}
|
||||
}
|
||||
|
||||
object StringCollectionExternalizer : CollectionExternalizer<String>(EnumeratorStringDescriptor(), { HashSet() })
|
||||
|
||||
object IntCollectionExternalizer : CollectionExternalizer<Int>(IntExternalizer, { HashSet() })
|
||||
31
build/src/org/jetbrains/kotlin/incremental/storage/values.kt
Normal file
31
build/src/org/jetbrains/kotlin/incremental/storage/values.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.incremental.storage
|
||||
|
||||
data class LookupSymbolKey(val nameHash: Int, val scopeHash: Int) : Comparable<LookupSymbolKey> {
|
||||
constructor(name: String, scope: String) : this(name.hashCode(), scope.hashCode())
|
||||
|
||||
override fun compareTo(other: LookupSymbolKey): Int {
|
||||
val nameCmp = nameHash.compareTo(other.nameHash)
|
||||
|
||||
if (nameCmp != 0) return nameCmp
|
||||
|
||||
return scopeHash.compareTo(other.scopeHash)
|
||||
}
|
||||
}
|
||||
|
||||
data class ProtoMapValue(val isPackageFacade: Boolean, val bytes: ByteArray, val strings: Array<String>)
|
||||
131
build/src/org/jetbrains/kotlin/modules/KotlinModuleXmlBuilder.kt
Normal file
131
build/src/org/jetbrains/kotlin/modules/KotlinModuleXmlBuilder.kt
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.modules
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
|
||||
import com.intellij.openapi.util.text.StringUtil.escapeXml
|
||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser.*
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
class KotlinModuleXmlBuilder {
|
||||
private val xml = StringBuilder()
|
||||
private val p = Printer(xml)
|
||||
private var done = false
|
||||
|
||||
init {
|
||||
openTag(p, MODULES)
|
||||
}
|
||||
|
||||
fun addModule(
|
||||
moduleName: String,
|
||||
outputDir: String,
|
||||
sourceFiles: Iterable<File>,
|
||||
javaSourceRoots: Iterable<JvmSourceRoot>,
|
||||
classpathRoots: Iterable<File>,
|
||||
targetTypeId: String,
|
||||
isTests: Boolean,
|
||||
directoriesToFilterOut: Set<File>,
|
||||
friendDirs: Iterable<File>): KotlinModuleXmlBuilder {
|
||||
assert(!done) { "Already done" }
|
||||
|
||||
p.println("<!-- Module script for ${if (isTests) "tests" else "production"} -->")
|
||||
|
||||
p.println("<", MODULE, " ",
|
||||
NAME, "=\"", escapeXml(moduleName), "\" ",
|
||||
TYPE, "=\"", escapeXml(targetTypeId), "\" ",
|
||||
OUTPUT_DIR, "=\"", getEscapedPath(File(outputDir)), "\">")
|
||||
p.pushIndent()
|
||||
|
||||
for (friendDir in friendDirs) {
|
||||
p.println("<", FRIEND_DIR, " ", PATH, "=\"", getEscapedPath(friendDir), "\"/>")
|
||||
}
|
||||
|
||||
for (sourceFile in sourceFiles) {
|
||||
p.println("<", SOURCES, " ", PATH, "=\"", getEscapedPath(sourceFile), "\"/>")
|
||||
}
|
||||
|
||||
processJavaSourceRoots(javaSourceRoots)
|
||||
processClasspath(classpathRoots, directoriesToFilterOut)
|
||||
|
||||
closeTag(p, MODULE)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun processClasspath(
|
||||
files: Iterable<File>,
|
||||
directoriesToFilterOut: Set<File>) {
|
||||
p.println("<!-- Classpath -->")
|
||||
for (file in files) {
|
||||
val isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.isEnabled()
|
||||
if (isOutput) {
|
||||
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
|
||||
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
|
||||
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
|
||||
p.println("<!-- Output directory, commented out -->")
|
||||
p.println("<!-- ")
|
||||
p.pushIndent()
|
||||
}
|
||||
|
||||
p.println("<", CLASSPATH, " ", PATH, "=\"", getEscapedPath(file), "\"/>")
|
||||
|
||||
if (isOutput) {
|
||||
p.popIndent()
|
||||
p.println("-->")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processJavaSourceRoots(roots: Iterable<JvmSourceRoot>) {
|
||||
p.println("<!-- Java source roots -->")
|
||||
for (root in roots) {
|
||||
p.print("<")
|
||||
p.printWithNoIndent(JAVA_SOURCE_ROOTS, " ", PATH, "=\"", getEscapedPath(root.file), "\"")
|
||||
|
||||
if (root.packagePrefix != null) {
|
||||
p.printWithNoIndent(" ", JAVA_SOURCE_PACKAGE_PREFIX, "=\"", root.packagePrefix, "\"")
|
||||
}
|
||||
|
||||
p.printWithNoIndent("/>")
|
||||
p.println()
|
||||
}
|
||||
}
|
||||
|
||||
fun asText(): CharSequence {
|
||||
if (!done) {
|
||||
closeTag(p, MODULES)
|
||||
done = true
|
||||
}
|
||||
return xml
|
||||
}
|
||||
|
||||
private fun openTag(p: Printer, tag: String) {
|
||||
p.println("<$tag>")
|
||||
p.pushIndent()
|
||||
}
|
||||
|
||||
private fun closeTag(p: Printer, tag: String) {
|
||||
p.popIndent()
|
||||
p.println("</$tag>")
|
||||
}
|
||||
|
||||
private fun getEscapedPath(sourceFile: File): String {
|
||||
return escapeXml(toSystemIndependentName(sourceFile.path))
|
||||
}
|
||||
}
|
||||
@@ -93,14 +93,14 @@ public class CodegenUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<FunctionDescriptor, FunctionDescriptor> getTraitMethods(ClassDescriptor descriptor) {
|
||||
public static Map<FunctionDescriptor, FunctionDescriptor> getNonPrivateTraitMethods(ClassDescriptor descriptor) {
|
||||
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>();
|
||||
for (DeclarationDescriptor declaration : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
|
||||
if (!(declaration instanceof CallableMemberDescriptor)) continue;
|
||||
|
||||
CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration;
|
||||
CallableMemberDescriptor traitMember = ImplKt.findTraitImplementation(inheritedMember);
|
||||
if (traitMember == null) continue;
|
||||
if (traitMember == null || Visibilities.isPrivate(traitMember.getVisibility())) continue;
|
||||
|
||||
assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember;
|
||||
|
||||
@@ -140,7 +140,7 @@ public class CodegenUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor getSuperClassByDelegationSpecifier(@NotNull KtDelegationSpecifier specifier, @NotNull BindingContext bindingContext) {
|
||||
public static ClassDescriptor getSuperClassBySuperTypeListEntry(@NotNull KtSuperTypeListEntry specifier, @NotNull BindingContext bindingContext) {
|
||||
KotlinType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null : "superType should not be null: " + specifier.getText();
|
||||
|
||||
|
||||
@@ -27,43 +27,47 @@ import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
import java.util.Comparator
|
||||
|
||||
public object CodegenUtilKt {
|
||||
object CodegenUtilKt {
|
||||
|
||||
// class Foo : Bar by baz
|
||||
// descriptor = Foo
|
||||
// toTrait = Bar
|
||||
// toInterface = Bar
|
||||
// delegateExpressionType = typeof(baz)
|
||||
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||
@JvmStatic
|
||||
public fun getDelegates(
|
||||
@JvmStatic fun getDelegates(
|
||||
descriptor: ClassDescriptor,
|
||||
toTrait: ClassDescriptor,
|
||||
toInterface: ClassDescriptor,
|
||||
delegateExpressionType: KotlinType? = null
|
||||
): Map<CallableMemberDescriptor, CallableDescriptor> {
|
||||
if (delegateExpressionType?.isDynamic() ?: false) return mapOf();
|
||||
|
||||
return descriptor.getDefaultType().getMemberScope().getContributedDescriptors().asSequence()
|
||||
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.getKind() == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.asIterable()
|
||||
.sortedWith(MemberComparator.INSTANCE)
|
||||
.keysToMapExceptNulls {
|
||||
delegatingMember ->
|
||||
|
||||
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
|
||||
.filter { it.getContainingDeclaration() == toTrait }
|
||||
.map {
|
||||
.mapNotNull {
|
||||
overriddenDescriptor ->
|
||||
val scope = (delegateExpressionType ?: toTrait.getDefaultType()).getMemberScope()
|
||||
val name = overriddenDescriptor.getName()
|
||||
if (overriddenDescriptor.containingDeclaration == toInterface) {
|
||||
val scope = (delegateExpressionType ?: toInterface.defaultType).memberScope
|
||||
val name = overriddenDescriptor.name
|
||||
|
||||
// this is the actual member of delegateExpressionType that we are delegating to
|
||||
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
|
||||
.first {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it)).map { it.getOriginal() }.contains(overriddenDescriptor.getOriginal())
|
||||
}
|
||||
// this is the actual member of delegateExpressionType that we are delegating to
|
||||
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) as Collection<CallableMemberDescriptor> +
|
||||
scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
|
||||
.firstOrNull {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it))
|
||||
.map { it.original }
|
||||
.contains(overriddenDescriptor.original)
|
||||
}
|
||||
}
|
||||
else null
|
||||
}
|
||||
assert(actualDelegates.size() <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
|
||||
actualDelegates.firstOrNull()
|
||||
}
|
||||
|
||||
@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.backend.common.bridges
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import java.util.HashSet
|
||||
|
||||
public interface FunctionHandle {
|
||||
public val isDeclaration: Boolean
|
||||
public val isAbstract: Boolean
|
||||
interface FunctionHandle {
|
||||
val isDeclaration: Boolean
|
||||
val isAbstract: Boolean
|
||||
|
||||
public fun getOverridden(): Iterable<FunctionHandle>
|
||||
fun getOverridden(): Iterable<FunctionHandle>
|
||||
}
|
||||
|
||||
public data class Bridge<Signature>(
|
||||
public val from: Signature,
|
||||
public val to: Signature
|
||||
data class Bridge<Signature>(
|
||||
val from: Signature,
|
||||
val to: Signature
|
||||
) {
|
||||
override fun toString() = "$from -> $to"
|
||||
}
|
||||
|
||||
|
||||
public fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
function: Function,
|
||||
signature: (Function) -> Signature
|
||||
): Set<Bridge<Signature>> {
|
||||
@@ -69,7 +69,7 @@ public fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
return bridgesToGenerate.map { Bridge(it, method) }.toSet()
|
||||
}
|
||||
|
||||
public fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
|
||||
fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
|
||||
val collector = object : DFS.NodeHandlerWithListResult<Function, Function>() {
|
||||
override fun afterChildren(current: Function) {
|
||||
if (current.isDeclaration) {
|
||||
@@ -86,7 +86,7 @@ public fun <Function : FunctionHandle> findAllReachableDeclarations(function: Fu
|
||||
* Given a concrete function, finds an implementation (a concrete declaration) of this function in the supertypes.
|
||||
* The implementation is guaranteed to exist because if it wouldn't, the given function would've been abstract
|
||||
*/
|
||||
public fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function {
|
||||
fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function {
|
||||
require(!function.isAbstract, { "Only concrete functions have implementations: $function" })
|
||||
|
||||
if (function.isDeclaration) return function
|
||||
@@ -109,7 +109,7 @@ public fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Fu
|
||||
result.removeAll(toRemove)
|
||||
|
||||
val concreteRelevantDeclarations = result.filter { !it.isAbstract }
|
||||
if (concreteRelevantDeclarations.size() != 1) {
|
||||
if (concreteRelevantDeclarations.size != 1) {
|
||||
error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations")
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
|
||||
public fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
descriptor: FunctionDescriptor,
|
||||
signature: (FunctionDescriptor) -> Signature
|
||||
): Set<Bridge<Signature>> {
|
||||
@@ -47,16 +47,16 @@ public fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
* can generate a bridge near an implementation (of course, in case it has a super-declaration with a different signature). Ultimately this
|
||||
* eases the process of determining what bridges are already generated in our supertypes and need to be inherited, not regenerated.
|
||||
*/
|
||||
public data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
|
||||
private val overridden = descriptor.getOverriddenDescriptors().map { DescriptorBasedFunctionHandle(it.getOriginal()) }
|
||||
data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
|
||||
private val overridden = descriptor.overriddenDescriptors.map { DescriptorBasedFunctionHandle(it.original) }
|
||||
|
||||
override val isDeclaration: Boolean =
|
||||
descriptor.getKind().isReal() ||
|
||||
descriptor.kind.isReal ||
|
||||
findTraitImplementation(descriptor) != null
|
||||
|
||||
override val isAbstract: Boolean =
|
||||
descriptor.getModality() == Modality.ABSTRACT ||
|
||||
DescriptorUtils.isInterface(descriptor.getContainingDeclaration())
|
||||
descriptor.modality == Modality.ABSTRACT ||
|
||||
DescriptorUtils.isInterface(descriptor.containingDeclaration)
|
||||
|
||||
override fun getOverridden() = overridden
|
||||
}
|
||||
@@ -67,14 +67,14 @@ public data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescript
|
||||
* trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake
|
||||
* override of any trait implementation or such method was already generated into the superclass or is a method from Any.
|
||||
*/
|
||||
public fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
if (descriptor.getKind().isReal()) return null
|
||||
fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
if (descriptor.kind.isReal) return null
|
||||
if (isOrOverridesSynthesized(descriptor)) return null
|
||||
|
||||
val implementation = findImplementationFromInterface(descriptor) ?: return null
|
||||
val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null
|
||||
|
||||
if (!DescriptorUtils.isInterface(immediateConcreteSuper.getContainingDeclaration())) {
|
||||
if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) {
|
||||
// If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited
|
||||
return null
|
||||
}
|
||||
@@ -86,14 +86,13 @@ public fun findTraitImplementation(descriptor: CallableMemberDescriptor): Callab
|
||||
* Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function
|
||||
* that should be called when the given fake override is called.
|
||||
*/
|
||||
public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
val overridden = OverrideResolver.getOverriddenDeclarations(descriptor)
|
||||
val filtered = OverrideResolver.filterOutOverridden(overridden)
|
||||
|
||||
val result = filtered.firstOrNull { it.getModality() != Modality.ABSTRACT } ?: return null
|
||||
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
|
||||
|
||||
val container = result.getContainingDeclaration()
|
||||
if (DescriptorUtils.isClass(container) || DescriptorUtils.isEnumClass(container)) return null
|
||||
if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -103,12 +102,12 @@ public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor)
|
||||
* returns the first immediate super function of the given fake override which overrides that implementation.
|
||||
* The returned function should be called from TImpl-bridges generated for the given fake override.
|
||||
*/
|
||||
public fun firstSuperMethodFromKotlin(
|
||||
fun firstSuperMethodFromKotlin(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
implementation: CallableMemberDescriptor
|
||||
): CallableMemberDescriptor? {
|
||||
return descriptor.getOverriddenDescriptors().firstOrNull { overridden ->
|
||||
overridden.getModality() != Modality.ABSTRACT &&
|
||||
return descriptor.overriddenDescriptors.firstOrNull { overridden ->
|
||||
overridden.modality != Modality.ABSTRACT &&
|
||||
(overridden == implementation || OverrideResolver.overrides(overridden, implementation))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,24 +18,24 @@ package org.jetbrains.kotlin.backend.common.output
|
||||
|
||||
import java.io.File
|
||||
|
||||
public interface OutputFileCollection {
|
||||
public fun get(relativePath: String): OutputFile?
|
||||
public fun asList(): List<OutputFile>
|
||||
interface OutputFileCollection {
|
||||
fun get(relativePath: String): OutputFile?
|
||||
fun asList(): List<OutputFile>
|
||||
}
|
||||
|
||||
public class SimpleOutputFileCollection(private val outputFiles: List<OutputFile>) : OutputFileCollection {
|
||||
class SimpleOutputFileCollection(private val outputFiles: List<OutputFile>) : OutputFileCollection {
|
||||
override fun get(relativePath: String): OutputFile? = outputFiles.firstOrNull { it.relativePath == relativePath }
|
||||
override fun asList(): List<OutputFile> = outputFiles
|
||||
}
|
||||
|
||||
public interface OutputFile {
|
||||
public val relativePath: String
|
||||
public val sourceFiles: List<File>
|
||||
public fun asByteArray(): ByteArray
|
||||
public fun asText(): String
|
||||
interface OutputFile {
|
||||
val relativePath: String
|
||||
val sourceFiles: List<File>
|
||||
fun asByteArray(): ByteArray
|
||||
fun asText(): String
|
||||
}
|
||||
|
||||
public class SimpleOutputFile(
|
||||
class SimpleOutputFile(
|
||||
override val sourceFiles: List<File>,
|
||||
override val relativePath: String,
|
||||
private val content: String
|
||||
@@ -46,7 +46,7 @@ public class SimpleOutputFile(
|
||||
override fun toString() = "$relativePath (compiled from $sourceFiles)"
|
||||
}
|
||||
|
||||
public class SimpleOutputBinaryFile(
|
||||
class SimpleOutputBinaryFile(
|
||||
override val sourceFiles: List<File>,
|
||||
override val relativePath: String,
|
||||
private val content: ByteArray
|
||||
|
||||
@@ -24,18 +24,18 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import java.util.*
|
||||
|
||||
open public class AbstractAccessorForFunctionDescriptor(
|
||||
open class AbstractAccessorForFunctionDescriptor(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
name: Name
|
||||
) : SimpleFunctionDescriptorImpl(containingDeclaration, null, Annotations.EMPTY,
|
||||
name, CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE) {
|
||||
|
||||
protected fun copyTypeParameters(descriptor: FunctionDescriptor): List<TypeParameterDescriptor> = descriptor.getTypeParameters().map {
|
||||
protected fun copyTypeParameters(descriptor: FunctionDescriptor): List<TypeParameterDescriptor> = descriptor.typeParameters.map {
|
||||
val copy = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
this, it.getAnnotations(), it.isReified(),
|
||||
it.getVariance(), it.getName(),
|
||||
it.getIndex(), SourceElement.NO_SOURCE)
|
||||
for (upperBound in it.getUpperBounds()) {
|
||||
this, it.annotations, it.isReified,
|
||||
it.variance, it.name,
|
||||
it.index, SourceElement.NO_SOURCE)
|
||||
for (upperBound in it.upperBounds) {
|
||||
copy.addUpperBound(upperBound)
|
||||
}
|
||||
copy.setInitialized()
|
||||
@@ -43,5 +43,5 @@ open public class AbstractAccessorForFunctionDescriptor(
|
||||
}
|
||||
|
||||
protected fun copyValueParameters(descriptor: FunctionDescriptor): List<ValueParameterDescriptor> =
|
||||
descriptor.getValueParameters().map { it.copy(this, it.getName()) }
|
||||
descriptor.valueParameters.map { it.copy(this, it.name) }
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
public class AccessorForConstructorDescriptor(
|
||||
class AccessorForConstructorDescriptor(
|
||||
private val calleeDescriptor: ConstructorDescriptor,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
private val superCallTarget: ClassDescriptor?
|
||||
@@ -41,6 +41,14 @@ public class AccessorForConstructorDescriptor(
|
||||
|
||||
override fun substitute(substitutor: TypeSubstitutor) = super.substitute(substitutor) as ConstructorDescriptor
|
||||
|
||||
override fun copy(
|
||||
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?, kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
|
||||
): AccessorForConstructorDescriptor {
|
||||
throw UnsupportedOperationException("Trying to copy synthetic accessor $this")
|
||||
}
|
||||
|
||||
override fun getOriginal(): AccessorForConstructorDescriptor = this
|
||||
|
||||
init {
|
||||
initialize(
|
||||
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
|
||||
|
||||
@@ -31,9 +31,9 @@ abstract class ArgumentGenerator {
|
||||
*
|
||||
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
|
||||
*/
|
||||
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallMask {
|
||||
assert(valueArgumentsByIndex.size() == actualArgs.size()) {
|
||||
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size()} != ${actualArgs.size()}"
|
||||
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallArgs {
|
||||
assert(valueArgumentsByIndex.size == actualArgs.size) {
|
||||
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
|
||||
}
|
||||
|
||||
val arg2Index = valueArgumentsByIndex.mapToIndex()
|
||||
@@ -48,7 +48,7 @@ abstract class ArgumentGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
val masks = DefaultCallMask(valueArgumentsByIndex.size())
|
||||
val defaultArgs = DefaultCallArgs(valueArgumentsByIndex.size)
|
||||
|
||||
for (argumentWithDeclIndex in actualArgsWithDeclIndex) {
|
||||
val argument = argumentWithDeclIndex.arg
|
||||
@@ -59,7 +59,7 @@ abstract class ArgumentGenerator {
|
||||
generateExpression(declIndex, argument)
|
||||
}
|
||||
is DefaultValueArgument -> {
|
||||
masks.mark(declIndex)
|
||||
defaultArgs.mark(declIndex)
|
||||
generateDefault(declIndex, argument)
|
||||
}
|
||||
is VarargValueArgument -> {
|
||||
@@ -73,7 +73,7 @@ abstract class ArgumentGenerator {
|
||||
|
||||
reorderArgumentsIfNeeded(actualArgsWithDeclIndex)
|
||||
|
||||
return masks
|
||||
return defaultArgs
|
||||
}
|
||||
|
||||
protected open fun generateExpression(i: Int, argument: ExpressionValueArgument) {
|
||||
|
||||
@@ -61,11 +61,11 @@ import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
@@ -226,9 +226,9 @@ public class AsmUtil {
|
||||
int flags = getVisibilityAccessFlag(functionDescriptor);
|
||||
flags |= getVarargsFlag(functionDescriptor);
|
||||
flags |= getDeprecatedAccessFlag(functionDescriptor);
|
||||
if (DeprecationUtilKt.isAnnotatedAsHidden(functionDescriptor)
|
||||
if (DeprecationUtilKt.isHiddenInResolution(functionDescriptor)
|
||||
|| functionDescriptor instanceof PropertyAccessorDescriptor
|
||||
&& DeprecationUtilKt.isAnnotatedAsHidden(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
|
||||
&& DeprecationUtilKt.isHiddenInResolution(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
return flags;
|
||||
@@ -268,7 +268,7 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static int getVisibilityAccessFlagForAnonymous(@NotNull ClassDescriptor descriptor) {
|
||||
return InlineUtil.isInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
|
||||
return InlineUtil.isInlineOrContainingInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) {
|
||||
@@ -299,9 +299,6 @@ public class AsmUtil {
|
||||
|
||||
public static int getDeprecatedAccessFlag(@NotNull MemberDescriptor descriptor) {
|
||||
if (descriptor instanceof PropertyAccessorDescriptor) {
|
||||
if (((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().isConst()) {
|
||||
return ACC_DEPRECATED;
|
||||
}
|
||||
return KotlinBuiltIns.isDeprecated(descriptor)
|
||||
? ACC_DEPRECATED
|
||||
: getDeprecatedAccessFlag(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty());
|
||||
@@ -325,9 +322,8 @@ public class AsmUtil {
|
||||
private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||
if (isJvmInterface(containingDeclaration)) {
|
||||
return memberVisibility == Visibilities.PRIVATE ? NO_FLAG_PACKAGE_PRIVATE : ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (AnnotationUtilKt.isInlineOnly(memberDescriptor)) return ACC_PRIVATE;
|
||||
|
||||
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
return ACC_PUBLIC;
|
||||
@@ -379,11 +375,6 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof PropertyDescriptor &&
|
||||
((PropertyDescriptor) memberDescriptor).isConst() || hasJvmFieldAnnotation(memberDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -550,7 +541,7 @@ public class AsmUtil {
|
||||
if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
genInvertBoolean(v);
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -689,28 +680,17 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DeclarationDescriptor container = propertyDescriptor.getContainingDeclaration();
|
||||
return isNonCompanionObject(container) ||
|
||||
isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ||
|
||||
(isCompanionObject(container) && isInterface(container.getContainingDeclaration()));
|
||||
}
|
||||
|
||||
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
|
||||
isObject(propertyDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
|
||||
public static int getVisibilityForBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
if (isDelegate || isExtensionProperty) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
else {
|
||||
return areBothAccessorDefault(propertyDescriptor)
|
||||
return propertyDescriptor.isLateInit() || isConstOrHasJvmFieldAnnotation(propertyDescriptor)
|
||||
? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor))
|
||||
: ACC_PRIVATE;
|
||||
}
|
||||
@@ -726,27 +706,10 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
|
||||
return !propertyDescriptor.isVar()
|
||||
&& !isExtensionProperty
|
||||
return propertyDescriptor.isConst()
|
||||
&& isCompanionObject(propertyContainer) && isInterface(propertyContainer.getContainingDeclaration())
|
||||
&& areBothAccessorDefault(propertyDescriptor)
|
||||
&& getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
|
||||
DeclarationDescriptor containingClass = companionObject.getContainingDeclaration();
|
||||
return isCompanionObject(companionObject) && (isClass(containingClass) || isEnumClass(containingClass));
|
||||
}
|
||||
|
||||
private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return isAccessorWithEmptyBody(propertyDescriptor.getGetter())
|
||||
&& (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter()));
|
||||
}
|
||||
|
||||
private static boolean isAccessorWithEmptyBody(@Nullable PropertyAccessorDescriptor accessorDescriptor) {
|
||||
return accessorDescriptor == null || !accessorDescriptor.hasBody();
|
||||
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
|
||||
}
|
||||
|
||||
public static Type comparisonOperandType(Type left, Type right) {
|
||||
@@ -822,24 +785,25 @@ public class AsmUtil {
|
||||
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull GenerationState state) {
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(KOTLIN_SYNTHETIC_CLASS), true);
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
JvmCodegenUtil.writeModuleName(av, state);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
public static void writeAnnotationData(
|
||||
@NotNull AnnotationVisitor av,
|
||||
@NotNull DescriptorSerializer serializer,
|
||||
@NotNull MessageLite message
|
||||
@NotNull MessageLite message,
|
||||
boolean old
|
||||
) {
|
||||
byte[] bytes = serializer.serialize(message);
|
||||
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
AnnotationVisitor data = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME);
|
||||
AnnotationVisitor data = av.visitArray(old ? JvmAnnotationNames.DATA_FIELD_NAME : JvmAnnotationNames.METADATA_DATA_FIELD_NAME);
|
||||
for (String string : BitEncoding.encodeBytes(bytes)) {
|
||||
data.visit(null, string);
|
||||
}
|
||||
data.visitEnd();
|
||||
AnnotationVisitor strings = av.visitArray(JvmAnnotationNames.STRINGS_FIELD_NAME);
|
||||
AnnotationVisitor strings = av.visitArray(
|
||||
old ? JvmAnnotationNames.STRINGS_FIELD_NAME : JvmAnnotationNames.METADATA_STRINGS_FIELD_NAME
|
||||
);
|
||||
for (String string : ((JvmStringTable) serializer.getStringTable()).getStrings()) {
|
||||
strings.visit(null, string);
|
||||
}
|
||||
@@ -851,13 +815,6 @@ public class AsmUtil {
|
||||
return asmTypeByFqNameWithoutInnerClasses(fqName).getDescriptor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String shortNameByAsmType(@NotNull Type type) {
|
||||
String internalName = type.getInternalName();
|
||||
int lastSlash = internalName.lastIndexOf('/');
|
||||
return lastSlash < 0 ? internalName : internalName.substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
|
||||
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));
|
||||
|
||||
@@ -147,8 +147,8 @@ open class BranchedValue(
|
||||
}, IFEQ)
|
||||
}
|
||||
|
||||
public fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
|
||||
if (operandType.getSort() == Type.OBJECT)
|
||||
fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
|
||||
if (operandType.sort == Type.OBJECT)
|
||||
ObjectCompare(opToken, operandType, left, right)
|
||||
else
|
||||
NumberCompare(opToken, operandType, left, right)
|
||||
|
||||
@@ -51,15 +51,15 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DefaultCallMask generate(
|
||||
public DefaultCallArgs generate(
|
||||
@NotNull List<? extends ResolvedValueArgument> valueArgumentsByIndex,
|
||||
@NotNull List<? extends ResolvedValueArgument> valueArgs
|
||||
) {
|
||||
boolean shouldMarkLineNumbers = this.codegen.isShouldMarkLineNumbers();
|
||||
this.codegen.setShouldMarkLineNumbers(false);
|
||||
DefaultCallMask masks = super.generate(valueArgumentsByIndex, valueArgs);
|
||||
DefaultCallArgs defaultArgs = super.generate(valueArgumentsByIndex, valueArgs);
|
||||
this.codegen.setShouldMarkLineNumbers(shouldMarkLineNumbers);
|
||||
return masks;
|
||||
return defaultArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,10 +75,9 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
|
||||
@Override
|
||||
protected void generateDefault(int i, @NotNull DefaultValueArgument argument) {
|
||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
||||
Type type = valueParameterTypes.get(i);
|
||||
pushDefaultValueOnStack(type, codegen.v);
|
||||
callGenerator.afterParameterPut(type, null, parameter, i);
|
||||
callGenerator.afterParameterPut(type, null, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,11 +85,11 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
||||
Type type = valueParameterTypes.get(i);
|
||||
codegen.genVarargs(argument, parameter.getType());
|
||||
callGenerator.afterParameterPut(type, null, parameter, i);
|
||||
callGenerator.afterParameterPut(type, null, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List actualArgsWithDeclIndex) {
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex) {
|
||||
callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ abstract class CallGenerator {
|
||||
override fun afterParameterPut(
|
||||
type: Type,
|
||||
stackValue: StackValue?,
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
parameterIndex: Int) {
|
||||
|
||||
}
|
||||
@@ -70,7 +69,7 @@ abstract class CallGenerator {
|
||||
}
|
||||
|
||||
override fun putValueIfNeeded(
|
||||
valueParameterDescriptor: ValueParameterDescriptor?, parameterType: Type, value: StackValue) {
|
||||
parameterType: Type, value: StackValue) {
|
||||
value.put(value.type, codegen.v)
|
||||
}
|
||||
|
||||
@@ -113,7 +112,6 @@ abstract class CallGenerator {
|
||||
abstract fun afterParameterPut(
|
||||
type: Type,
|
||||
stackValue: StackValue?,
|
||||
valueParameterDescriptor: ValueParameterDescriptor,
|
||||
parameterIndex: Int)
|
||||
|
||||
abstract fun genValueAndPut(
|
||||
@@ -123,7 +121,6 @@ abstract class CallGenerator {
|
||||
parameterIndex: Int)
|
||||
|
||||
abstract fun putValueIfNeeded(
|
||||
valueParameterDescriptor: ValueParameterDescriptor?,
|
||||
parameterType: Type,
|
||||
value: StackValue)
|
||||
|
||||
|
||||
@@ -20,32 +20,32 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
public interface Callable {
|
||||
public val owner: Type
|
||||
interface Callable {
|
||||
val owner: Type
|
||||
|
||||
public val dispatchReceiverType: Type?
|
||||
val dispatchReceiverType: Type?
|
||||
|
||||
public val extensionReceiverType: Type?
|
||||
val extensionReceiverType: Type?
|
||||
|
||||
public val generateCalleeType: Type?
|
||||
val generateCalleeType: Type?
|
||||
|
||||
public val valueParameterTypes: List<Type>
|
||||
val valueParameterTypes: List<Type>
|
||||
|
||||
public val parameterTypes: Array<Type>
|
||||
val parameterTypes: Array<Type>
|
||||
|
||||
public val returnType: Type
|
||||
val returnType: Type
|
||||
|
||||
public fun genInvokeInstruction(v: InstructionAdapter)
|
||||
fun genInvokeInstruction(v: InstructionAdapter)
|
||||
|
||||
public fun isStaticCall(): Boolean
|
||||
fun isStaticCall(): Boolean
|
||||
|
||||
public fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
|
||||
fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
|
||||
return StackValue.functionCall(returnType) {
|
||||
codegen.invokeMethodWithArguments(this, resolvedCall, receiver)
|
||||
}
|
||||
}
|
||||
|
||||
public fun afterReceiverGeneration(v: InstructionAdapter) {
|
||||
fun afterReceiverGeneration(v: InstructionAdapter) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import org.jetbrains.org.objectweb.asm.util.Printer
|
||||
|
||||
public class CallableMethod(
|
||||
class CallableMethod(
|
||||
override val owner: Type,
|
||||
private val defaultImplOwner: Type?,
|
||||
private val defaultMethodDesc: String,
|
||||
@@ -37,48 +37,47 @@ public class CallableMethod(
|
||||
override val extensionReceiverType: Type?,
|
||||
override val generateCalleeType: Type?
|
||||
) : Callable {
|
||||
public fun getValueParameters(): List<JvmMethodParameterSignature> =
|
||||
signature.getValueParameters()
|
||||
fun getValueParameters(): List<JvmMethodParameterSignature> =
|
||||
signature.valueParameters
|
||||
|
||||
override val valueParameterTypes: List<Type>
|
||||
get() = signature.getValueParameters().filter { it.getKind() == JvmMethodParameterKind.VALUE }.map { it.getAsmType() }
|
||||
get() = signature.valueParameters.filter { it.kind == JvmMethodParameterKind.VALUE }.map { it.asmType }
|
||||
|
||||
public fun getAsmMethod(): Method =
|
||||
signature.getAsmMethod()
|
||||
fun getAsmMethod(): Method =
|
||||
signature.asmMethod
|
||||
|
||||
override val parameterTypes: Array<Type>
|
||||
get() = getAsmMethod().getArgumentTypes()
|
||||
get() = getAsmMethod().argumentTypes
|
||||
|
||||
|
||||
public override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor())
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
v.visitMethodInsn(invokeOpcode, owner.internalName, getAsmMethod().name, getAsmMethod().descriptor)
|
||||
}
|
||||
|
||||
public fun genInvokeDefaultInstruction(v: InstructionAdapter) {
|
||||
fun genInvokeDefaultInstruction(v: InstructionAdapter) {
|
||||
if (defaultImplOwner == null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
val method = getAsmMethod()
|
||||
|
||||
if ("<init>".equals(method.getName())) {
|
||||
v.aconst(null)
|
||||
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", defaultMethodDesc, false)
|
||||
if ("<init>".equals(method.name)) {
|
||||
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.internalName, "<init>", defaultMethodDesc, false)
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(),
|
||||
method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
|
||||
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.internalName,
|
||||
method.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
|
||||
|
||||
StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v)
|
||||
}
|
||||
}
|
||||
|
||||
override val returnType: Type
|
||||
get() = signature.getReturnType()
|
||||
get() = signature.returnType
|
||||
|
||||
override fun isStaticCall(): Boolean =
|
||||
invokeOpcode == INVOKESTATIC
|
||||
|
||||
override fun toString(): String =
|
||||
"${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature"
|
||||
"${Printer.OPCODES[invokeOpcode]} ${owner.internalName}.$signature"
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -51,11 +52,19 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
List<KtObjectDeclaration> companions = new ArrayList<KtObjectDeclaration>();
|
||||
if (kind != OwnerKind.DEFAULT_IMPLS) {
|
||||
//generate nested classes first and only then generate class body. It necessary to access to nested CodegenContexts
|
||||
for (KtDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (shouldProcessFirst(declaration)) {
|
||||
generateDeclaration(declaration);
|
||||
//Generate companions after class body generation (need to record all synthetic accessors)
|
||||
if (declaration instanceof KtObjectDeclaration && ((KtObjectDeclaration) declaration).isCompanion()) {
|
||||
companions.add((KtObjectDeclaration) declaration);
|
||||
CodegenUtilKt.populateCompanionBackingFieldNamesToOuterContextIfNeeded((KtObjectDeclaration) declaration, context, state);
|
||||
}
|
||||
else {
|
||||
generateDeclaration(declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +75,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
}
|
||||
}
|
||||
|
||||
generatePrimaryConstructorProperties();
|
||||
generateConstructors();
|
||||
generateDefaultImplsIfNeeded();
|
||||
|
||||
for (KtObjectDeclaration companion : companions) {
|
||||
generateDeclaration(companion);
|
||||
}
|
||||
|
||||
if (!DescriptorUtils.isInterface(descriptor)) {
|
||||
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
|
||||
if (memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
@@ -88,8 +105,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void generateConstructors() {
|
||||
|
||||
}
|
||||
|
||||
protected void generateDefaultImplsIfNeeded() {
|
||||
|
||||
generatePrimaryConstructorProperties();
|
||||
}
|
||||
|
||||
private static boolean shouldProcessFirst(KtDeclaration declaration) {
|
||||
|
||||
@@ -22,14 +22,14 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -123,7 +123,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
try {
|
||||
ByteArrayOutputStream moduleMapping = new ByteArrayOutputStream(4096);
|
||||
DataOutputStream dataOutStream = new DataOutputStream(moduleMapping);
|
||||
int[] version = JvmAbi.VERSION.toArray();
|
||||
int[] version = JvmMetadataVersion.INSTANCE.toArray();
|
||||
dataOutStream.writeInt(version.length);
|
||||
for (int number : version) {
|
||||
dataOutStream.writeInt(number);
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
public abstract class ClassNameCollectionClassBuilderFactory(
|
||||
abstract class ClassNameCollectionClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
@@ -46,7 +47,6 @@ import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.kotlin.utils.FunctionsKt;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -60,7 +60,7 @@ import java.util.List;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.ExpressionCodegen.generateClassLiteralReference;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeAbiVersion;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
@@ -212,7 +212,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
this.constructor = generateConstructor();
|
||||
|
||||
if (isConst(closure)) {
|
||||
generateConstInstance(asmType, asmType, FunctionsKt.<InstructionAdapter>doNothing());
|
||||
generateConstInstance(asmType, asmType);
|
||||
}
|
||||
|
||||
genClosureFields(closure, v, typeMapper);
|
||||
@@ -222,16 +222,22 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
protected void generateKotlinAnnotation() {
|
||||
writeKotlinSyntheticClassAnnotation(v, state);
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
DescriptorSerializer.createForLambda(
|
||||
new JvmSerializerExtension(v.getSerializationBindings(), typeMapper, state.getUseTypeTableInSerializer())
|
||||
);
|
||||
final DescriptorSerializer serializer =
|
||||
DescriptorSerializer.createForLambda(new JvmSerializerExtension(v.getSerializationBindings(), state));
|
||||
|
||||
ProtoBuf.Function functionProto = serializer.functionProto(funDescriptor).build();
|
||||
final ProtoBuf.Function functionProto = serializer.functionProto(funDescriptor).build();
|
||||
|
||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.SYNTHETIC_CLASS, new Function1<AnnotationVisitor, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(AnnotationVisitor av) {
|
||||
writeAnnotationData(av, serializer, functionProto, false);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FUNCTION), true);
|
||||
writeAnnotationData(av, serializer, functionProto);
|
||||
writeModuleName(av, state);
|
||||
writeAbiVersion(av);
|
||||
writeAnnotationData(av, serializer, functionProto, true);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
@@ -259,13 +265,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
|
||||
}
|
||||
|
||||
if (functionReferenceTarget != null) {
|
||||
if (!"true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.callable.references"))) {
|
||||
v.invokestatic(REFLECTION, "function", Type.getMethodDescriptor(K_FUNCTION, FUNCTION_REFERENCE), false);
|
||||
}
|
||||
}
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
public class CodegenFileClassesProvider : JvmFileClassesProvider {
|
||||
override public fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
|
||||
class CodegenFileClassesProvider : JvmFileClassesProvider {
|
||||
override fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
|
||||
JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
||||
}
|
||||
@@ -65,14 +65,14 @@ class CollectionStubMethodGenerator(
|
||||
val (child, typeParameters) = createSyntheticSubclass()
|
||||
// If the original class has any type parameters, we copied them and now we need to substitute types of the newly created type
|
||||
// parameters as arguments for the type parameters of the original class
|
||||
val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.getDefaultType()) })
|
||||
val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.defaultType) })
|
||||
|
||||
// Now we need to determine the arguments which should be substituted for the MutableCollection super class. To do that,
|
||||
// we look for type arguments which were substituted in the inheritance of the original class from Collection and use them
|
||||
// to construct the needed MutableCollection type. Since getAllSupertypes() may return several types which correspond to the
|
||||
// Collection class descriptor, we find the most specific one (which is guaranteed to exist by front-end)
|
||||
val readOnlyCollectionType = TypeUtils.getAllSupertypes(parentType).findMostSpecificTypeForClass(readOnlyClass)
|
||||
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.getArguments())
|
||||
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.arguments)
|
||||
|
||||
child.addSupertype(parentType)
|
||||
child.addSupertype(mutableCollectionType)
|
||||
@@ -81,10 +81,10 @@ class CollectionStubMethodGenerator(
|
||||
// Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub
|
||||
// or save its descriptor to generate all the needed bridges
|
||||
for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) {
|
||||
if (method.getModality() == Modality.ABSTRACT) {
|
||||
if (method.modality == Modality.ABSTRACT) {
|
||||
// If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already
|
||||
// present in the bytecode (abstract) and we don't want a duplicate signature error
|
||||
if (method.findOverriddenFromDirectSuperClass(descriptor)?.getKind() == DECLARATION) continue
|
||||
if (method.findOverriddenFromDirectSuperClass(descriptor)?.kind == DECLARATION) continue
|
||||
|
||||
// Otherwise we can safely generate the stub with the substituted signature
|
||||
val signature = method.signature()
|
||||
@@ -160,18 +160,18 @@ class CollectionStubMethodGenerator(
|
||||
|
||||
val collectionClasses = with(descriptor.builtIns) {
|
||||
listOf(
|
||||
pair(getCollection(), getMutableCollection()),
|
||||
pair(getSet(), getMutableSet()),
|
||||
pair(getList(), getMutableList()),
|
||||
pair(getMap(), getMutableMap()),
|
||||
pair(getMapEntry(), getMutableMapEntry()),
|
||||
pair(getIterable(), getMutableIterable()),
|
||||
pair(getIterator(), getMutableIterator()),
|
||||
pair(getListIterator(), getMutableListIterator())
|
||||
pair(collection, mutableCollection),
|
||||
pair(set, mutableSet),
|
||||
pair(list, mutableList),
|
||||
pair(map, mutableMap),
|
||||
pair(mapEntry, mutableMapEntry),
|
||||
pair(iterable, mutableIterable),
|
||||
pair(iterator, mutableIterator),
|
||||
pair(listIterator, mutableListIterator)
|
||||
)
|
||||
}
|
||||
|
||||
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.getDefaultType()).classes().toHashSet()
|
||||
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.defaultType).classes().toHashSet()
|
||||
|
||||
val ourSuperCollectionClasses = collectionClasses.filter { pair ->
|
||||
pair.readOnlyClass in allSuperClasses && pair.mutableClass !in allSuperClasses
|
||||
@@ -180,13 +180,13 @@ class CollectionStubMethodGenerator(
|
||||
|
||||
// Filter out built-in classes which are overridden by other built-in classes in the list, to avoid duplicating methods.
|
||||
val redundantClasses = ourSuperCollectionClasses.flatMapTo(HashSet<ClassDescriptor>()) { pair ->
|
||||
pair.readOnlyClass.getTypeConstructor().getSupertypes().classes()
|
||||
pair.readOnlyClass.typeConstructor.supertypes.classes()
|
||||
}
|
||||
return ourSuperCollectionClasses.filter { klass -> klass.readOnlyClass !in redundantClasses }
|
||||
}
|
||||
|
||||
private fun Collection<KotlinType>.classes(): Collection<ClassDescriptor> =
|
||||
this.map { it.getConstructor().getDeclarationDescriptor() as ClassDescriptor }
|
||||
this.map { it.constructor.declarationDescriptor as ClassDescriptor }
|
||||
|
||||
private fun findFakeOverridesForMethodsFromMutableCollection(
|
||||
klass: ClassDescriptor,
|
||||
@@ -212,9 +212,9 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun Collection<KotlinType>.findMostSpecificTypeForClass(klass: ClassDescriptor): KotlinType {
|
||||
val types = this.filter { it.getConstructor().getDeclarationDescriptor() == klass }
|
||||
val types = this.filter { it.constructor.declarationDescriptor == klass }
|
||||
if (types.isEmpty()) error("No supertype of $klass in $this")
|
||||
if (types.size() == 1) return types.first()
|
||||
if (types.size == 1) return types.first()
|
||||
// Find the first type in the list such that it's a subtype of every other type in that list
|
||||
return types.first { type ->
|
||||
types.all { other -> KotlinTypeChecker.DEFAULT.isSubtypeOf(type, other) }
|
||||
@@ -222,19 +222,19 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> {
|
||||
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), ClassKind.CLASS, false,
|
||||
Name.special("<synthetic inheritor of ${descriptor.getName()}>"), descriptor.getSource())
|
||||
child.setModality(Modality.FINAL)
|
||||
child.setVisibility(Visibilities.PUBLIC)
|
||||
val typeParameters = descriptor.getTypeConstructor().getParameters()
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
|
||||
val child = MutableClassDescriptor(descriptor.containingDeclaration, ClassKind.CLASS, false,
|
||||
Name.special("<synthetic inheritor of ${descriptor.name}>"), descriptor.source)
|
||||
child.modality = Modality.FINAL
|
||||
child.visibility = Visibilities.PUBLIC
|
||||
val typeParameters = descriptor.typeConstructor.parameters
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
|
||||
child.setTypeParameterDescriptors(typeParameters)
|
||||
return Pair(child, newTypeParameters)
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(classDescriptor: ClassDescriptor): FunctionDescriptor? {
|
||||
return this.getOverriddenDescriptors().firstOrNull { it.getContainingDeclaration() == classDescriptor }
|
||||
return this.overriddenDescriptors.firstOrNull { it.containingDeclaration == classDescriptor }
|
||||
}
|
||||
|
||||
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType {
|
||||
@@ -246,13 +246,13 @@ class CollectionStubMethodGenerator(
|
||||
private fun generateMethodStub(signature: JvmMethodSignature, synthetic: Boolean) {
|
||||
// TODO: investigate if it makes sense to generate abstract stubs in traits
|
||||
var access = ACC_PUBLIC
|
||||
if (descriptor.getKind() == ClassKind.INTERFACE) access = access or ACC_ABSTRACT
|
||||
if (descriptor.kind == ClassKind.INTERFACE) access = access or ACC_ABSTRACT
|
||||
if (synthetic) access = access or ACC_SYNTHETIC
|
||||
|
||||
val asmMethod = signature.getAsmMethod()
|
||||
val genericSignature = if (synthetic) null else signature.getGenericsSignature()
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.getName(), asmMethod.getDescriptor(), genericSignature, null)
|
||||
if (descriptor.getKind() != ClassKind.INTERFACE) {
|
||||
val asmMethod = signature.asmMethod
|
||||
val genericSignature = if (synthetic) null else signature.genericsSignature
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.name, asmMethod.descriptor, genericSignature, null)
|
||||
if (descriptor.kind != ClassKind.INTERFACE) {
|
||||
mv.visitCode()
|
||||
AsmUtil.genThrow(InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection")
|
||||
FunctionCodegen.endVisit(mv, "built-in stub for $signature", null)
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.util.*
|
||||
|
||||
class DefaultCallMask(val size: Int) {
|
||||
class DefaultCallArgs(val size: Int) {
|
||||
|
||||
val bits: BitSet = BitSet(size)
|
||||
|
||||
@@ -50,10 +51,15 @@ class DefaultCallMask(val size: Int) {
|
||||
return masks
|
||||
}
|
||||
|
||||
public fun generateOnStackIfNeeded(callGenerator: CallGenerator): Boolean {
|
||||
fun generateOnStackIfNeeded(callGenerator: CallGenerator, isConstructor: Boolean): Boolean {
|
||||
val toInts = toInts()
|
||||
for (mask in toInts) {
|
||||
callGenerator.putValueIfNeeded(null, Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE))
|
||||
if (!toInts.isEmpty()) {
|
||||
for (mask in toInts) {
|
||||
callGenerator.putValueIfNeeded(Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE))
|
||||
}
|
||||
|
||||
val parameterType = if (isConstructor) AsmTypes.DEFAULT_CONSTRUCTOR_MARKER else AsmTypes.OBJECT_TYPE
|
||||
callGenerator.putValueIfNeeded(parameterType, StackValue.constant(null, parameterType))
|
||||
}
|
||||
return toInts.isNotEmpty();
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
* Generates Java overloads for functions and constructors that have the default
|
||||
* parameter values substituted.
|
||||
*/
|
||||
public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
/**
|
||||
* If all of the parameters of the specified constructor declare default values,
|
||||
* generates a no-argument constructor that passes default values for all arguments.
|
||||
@@ -118,19 +118,19 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
val typeMapper = state.typeMapper
|
||||
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
|
||||
val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0)
|
||||
val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount)
|
||||
val remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount)
|
||||
val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters)
|
||||
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
|
||||
signature.getAsmMethod().getName(),
|
||||
signature.getAsmMethod().getDescriptor(),
|
||||
signature.getGenericsSignature(),
|
||||
signature.asmMethod.name,
|
||||
signature.asmMethod.descriptor,
|
||||
signature.genericsSignature,
|
||||
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper))
|
||||
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.getReturnType())
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.returnType)
|
||||
|
||||
remainingParameters.withIndex().forEach {
|
||||
val annotationCodegen = AnnotationCodegen.forParameter(it.index, mv, typeMapper)
|
||||
annotationCodegen.genAnnotations(it.value, signature.getValueParameters()[it.index].getAsmType())
|
||||
annotationCodegen.genAnnotations(it.value, signature.valueParameters[it.index].asmType)
|
||||
}
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) {
|
||||
@@ -148,14 +148,14 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
v.load(thisIndex, methodOwner) // Load this on stack
|
||||
}
|
||||
else {
|
||||
val delegateOwner = delegateFunctionDescriptor.getContainingDeclaration()
|
||||
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject()) {
|
||||
val delegateOwner = delegateFunctionDescriptor.containingDeclaration
|
||||
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject) {
|
||||
val singletonValue = StackValue.singleton(delegateOwner, typeMapper)
|
||||
singletonValue.put(singletonValue.type, v);
|
||||
}
|
||||
}
|
||||
|
||||
val receiver = functionDescriptor.getExtensionReceiverParameter()
|
||||
val receiver = functionDescriptor.extensionReceiverParameter
|
||||
if (receiver != null) {
|
||||
val receiverType = typeMapper.mapType(receiver)
|
||||
val receiverIndex = frameMap.enter(receiver, receiverType)
|
||||
@@ -167,8 +167,8 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
|
||||
var mask = 0
|
||||
val masks = arrayListOf<Int>()
|
||||
for (parameterDescriptor in functionDescriptor.getValueParameters()) {
|
||||
val paramType = typeMapper.mapType(parameterDescriptor.getType())
|
||||
for (parameterDescriptor in functionDescriptor.valueParameters) {
|
||||
val paramType = typeMapper.mapType(parameterDescriptor.type)
|
||||
if (parameterDescriptor in remainingParameters) {
|
||||
val index = frameMap.getIndex(parameterDescriptor)
|
||||
StackValue.local(index, paramType).put(paramType, v)
|
||||
@@ -184,50 +184,50 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
}
|
||||
}
|
||||
masks.add(mask)
|
||||
|
||||
for (m in masks) {
|
||||
v.iconst(m)
|
||||
}
|
||||
|
||||
// constructors with default arguments has last synthetic argument of specific type
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
v.aconst(null)
|
||||
}
|
||||
// for default constructors: just marks default constructor (see DEFAULT_CONSTRUCTOR_MARKER)
|
||||
// for default methods: contains MethodHandle for super calls ('null' cause not super call)
|
||||
v.aconst(null)
|
||||
|
||||
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
v.invokespecial(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false)
|
||||
v.invokespecial(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
}
|
||||
else {
|
||||
v.invokestatic(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false)
|
||||
v.invokestatic(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
}
|
||||
v.areturn(signature.getReturnType())
|
||||
v.areturn(signature.returnType)
|
||||
FunctionCodegen.endVisit(mv, null, methodElement)
|
||||
}
|
||||
|
||||
private fun getRemainingParameters(functionDescriptor: FunctionDescriptor,
|
||||
substituteCount: Int): List<ValueParameterDescriptor> {
|
||||
var remainingCount = functionDescriptor.countDefaultParameters() - substituteCount
|
||||
return functionDescriptor.getValueParameters().filter { !it.declaresDefaultValue() || --remainingCount >= 0 }
|
||||
return functionDescriptor.valueParameters.filter { !it.declaresDefaultValue() || --remainingCount >= 0 }
|
||||
}
|
||||
|
||||
private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: KtClassOrObject): Boolean {
|
||||
val classDescriptor = constructorDescriptor.getContainingDeclaration()
|
||||
if (classDescriptor.getKind() != ClassKind.CLASS) return false
|
||||
val classDescriptor = constructorDescriptor.containingDeclaration
|
||||
if (classDescriptor.kind != ClassKind.CLASS) return false
|
||||
|
||||
if (classOrObject.isLocal()) return false
|
||||
|
||||
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
||||
|
||||
if (Visibilities.isPrivate(classDescriptor.getVisibility()) || Visibilities.isPrivate(constructorDescriptor.getVisibility()))
|
||||
if (Visibilities.isPrivate(classDescriptor.visibility) || Visibilities.isPrivate(constructorDescriptor.visibility))
|
||||
return false
|
||||
|
||||
if (constructorDescriptor.getValueParameters().isEmpty()) return false
|
||||
if (constructorDescriptor.valueParameters.isEmpty()) return false
|
||||
if (classOrObject is KtClass && hasSecondaryConstructorsWithNoParameters(classOrObject)) return false
|
||||
|
||||
return constructorDescriptor.getValueParameters().all { it.declaresDefaultValue() }
|
||||
return constructorDescriptor.valueParameters.all { it.declaresDefaultValue() }
|
||||
}
|
||||
|
||||
private fun hasSecondaryConstructorsWithNoParameters(klass: KtClass) =
|
||||
klass.getSecondaryConstructors().any { it.getValueParameters().isEmpty() }
|
||||
klass.getSecondaryConstructors().any { it.valueParameters.isEmpty() }
|
||||
|
||||
}
|
||||
|
||||
@@ -25,18 +25,18 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
public abstract class DelegatingClassBuilderFactory(
|
||||
abstract class DelegatingClassBuilderFactory(
|
||||
protected val delegate: ClassBuilderFactory
|
||||
|
||||
) : ClassBuilderFactory by delegate {
|
||||
|
||||
abstract override fun newClassBuilder(origin: JvmDeclarationOrigin): DelegatingClassBuilder
|
||||
|
||||
public override fun asBytes(builder: ClassBuilder?): ByteArray? {
|
||||
override fun asBytes(builder: ClassBuilder?): ByteArray? {
|
||||
return delegate.asBytes((builder as DelegatingClassBuilder).getDelegate())
|
||||
}
|
||||
|
||||
public override fun asText(builder: ClassBuilder?): String? {
|
||||
override fun asText(builder: ClassBuilder?): String? {
|
||||
return delegate.asText((builder as DelegatingClassBuilder).getDelegate())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.Pair;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,7 +40,6 @@ import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -54,10 +54,10 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesKt;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
@@ -93,15 +93,13 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.couldUseDirectAccessToProperty;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -481,7 +479,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
markLineNumber(expression, isStatement);
|
||||
v.mark(end);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -669,7 +667,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
});
|
||||
}
|
||||
else {
|
||||
KtMultiDeclaration multiParameter = forExpression.getMultiParameter();
|
||||
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
|
||||
assert multiParameter != null;
|
||||
|
||||
// E tmp<e> = tmp<iterator>.next()
|
||||
@@ -687,15 +685,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
assignToLoopParameter();
|
||||
|
||||
if (forExpression.getLoopParameter() == null) {
|
||||
KtMultiDeclaration multiParameter = forExpression.getMultiParameter();
|
||||
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
|
||||
assert multiParameter != null;
|
||||
|
||||
generateMultiVariables(multiParameter.getEntries());
|
||||
}
|
||||
}
|
||||
|
||||
private void generateMultiVariables(List<KtMultiDeclarationEntry> entries) {
|
||||
for (KtMultiDeclarationEntry variableDeclaration : entries) {
|
||||
private void generateMultiVariables(List<KtDestructuringDeclarationEntry> entries) {
|
||||
for (KtDestructuringDeclarationEntry variableDeclaration : entries) {
|
||||
final VariableDescriptor componentDescriptor = bindingContext.get(VARIABLE, variableDeclaration);
|
||||
|
||||
@SuppressWarnings("ConstantConditions") final Type componentAsmType = asmType(componentDescriptor.getReturnType());
|
||||
@@ -1067,7 +1065,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type asmLoopRangeType = asmType(loopRangeType);
|
||||
|
||||
Collection<PropertyDescriptor> incrementProp =
|
||||
loopRangeType.getMemberScope().getContributedVariables(Name.identifier("increment"), NoLookupLocation.FROM_BACKEND);
|
||||
loopRangeType.getMemberScope().getContributedVariables(Name.identifier("step"), NoLookupLocation.FROM_BACKEND);
|
||||
assert incrementProp.size() == 1 : loopRangeType + " " + incrementProp.size();
|
||||
incrementType = asmType(incrementProp.iterator().next().getType());
|
||||
|
||||
@@ -1295,7 +1293,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1332,7 +1330,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression, StackValue receiver) {
|
||||
public StackValue visitLambdaExpression(@NotNull KtLambdaExpression expression, StackValue receiver) {
|
||||
if (Boolean.TRUE.equals(bindingContext.get(BLOCK, expression))) {
|
||||
return gen(expression.getFunctionLiteral().getBodyExpression());
|
||||
}
|
||||
@@ -1434,7 +1432,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
JvmMethodSignature constructor = typeMapper.mapSignature(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
|
||||
v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor(), false);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1552,7 +1550,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
|
||||
task.fun(value);
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1569,9 +1567,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
|
||||
private void putDescriptorIntoFrameMap(@NotNull KtElement statement) {
|
||||
if (statement instanceof KtMultiDeclaration) {
|
||||
KtMultiDeclaration multiDeclaration = (KtMultiDeclaration) statement;
|
||||
for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
if (statement instanceof KtDestructuringDeclaration) {
|
||||
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
|
||||
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
putLocalVariableIntoFrameMap(entry);
|
||||
}
|
||||
}
|
||||
@@ -1609,9 +1607,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull Label blockEnd,
|
||||
@NotNull List<Function<StackValue, Void>> leaveTasks
|
||||
) {
|
||||
if (statement instanceof KtMultiDeclaration) {
|
||||
KtMultiDeclaration multiDeclaration = (KtMultiDeclaration) statement;
|
||||
for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
if (statement instanceof KtDestructuringDeclaration) {
|
||||
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
|
||||
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
|
||||
addLeaveTaskToRemoveLocalVariableFromFrameMap(entry, blockEnd, leaveTasks);
|
||||
}
|
||||
}
|
||||
@@ -2072,7 +2070,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
if (getter != null) {
|
||||
Call call = bindingContext.get(DELEGATED_PROPERTY_CALL, getter);
|
||||
return call != null ? ((ReceiverValue) call.getExplicitReceiver()).getType() : null;
|
||||
if (call != null) {
|
||||
assert call.getExplicitReceiver() != null : "No explicit receiver for call:" + call;
|
||||
return ((ReceiverValue) call.getExplicitReceiver()).getType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -2116,11 +2117,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
|
||||
boolean isBackingFieldInClassCompanion = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
if (isBackingFieldInClassCompanion && forceField) {
|
||||
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
|
||||
}
|
||||
else if (syntheticBackingField && context.getParentContext().getContextDescriptor() != containingDeclaration) {
|
||||
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {
|
||||
fieldAccessorKind = FieldAccessorKind.FIELD_FROM_LOCAL;
|
||||
}
|
||||
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
|
||||
@@ -2140,7 +2141,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
|
||||
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
|
||||
if (!skipPropertyAccessors) {
|
||||
//noinspection ConstantConditions
|
||||
@@ -2161,18 +2162,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
|
||||
if (isSuper && !isJvmInterface(containingDeclaration)) {
|
||||
CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor;
|
||||
if (c != context.getParentContext()) {
|
||||
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor, superCallTarget);
|
||||
}
|
||||
}
|
||||
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget);
|
||||
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
|
||||
|
||||
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
|
||||
if (getter != null && !hasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
if (getter != null && !isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
callableGetter = typeMapper.mapToCallableMethod(getter, isSuper);
|
||||
}
|
||||
}
|
||||
@@ -2181,7 +2176,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (setter != null &&
|
||||
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context) &&
|
||||
!hasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
!isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
|
||||
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
|
||||
}
|
||||
}
|
||||
@@ -2251,8 +2246,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
final SamType samType = bindingContext.get(SAM_VALUE, probablyParenthesizedExpression);
|
||||
if (samType == null || expression == null) return null;
|
||||
|
||||
if (expression instanceof KtFunctionLiteralExpression) {
|
||||
return genClosure(((KtFunctionLiteralExpression) expression).getFunctionLiteral(), samType);
|
||||
if (expression instanceof KtLambdaExpression) {
|
||||
return genClosure(((KtLambdaExpression) expression).getFunctionLiteral(), samType);
|
||||
}
|
||||
|
||||
if (expression instanceof KtNamedFunction) {
|
||||
@@ -2300,22 +2295,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
descriptor = originalIfSamAdapter;
|
||||
}
|
||||
// $default method is not private, so you need no accessor to call it
|
||||
return usesDefaultArguments(resolvedCall)
|
||||
return CallUtilKt.usesDefaultArguments(resolvedCall)
|
||||
? descriptor
|
||||
: context.accessibleDescriptor(descriptor, getSuperCallTarget(resolvedCall.getCall()));
|
||||
}
|
||||
|
||||
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
|
||||
if (valueArguments == null) return false;
|
||||
|
||||
for (ResolvedValueArgument argument : valueArguments) {
|
||||
if (argument instanceof DefaultValueArgument) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue invokeFunction(@NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
|
||||
return invokeFunction(resolvedCall.getCall(), resolvedCall, receiver);
|
||||
@@ -2325,15 +2309,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
|
||||
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
|
||||
ClassDescriptor superCallTarget = getSuperCallTarget(call);
|
||||
boolean superCall = superCallTarget != null;
|
||||
|
||||
if (superCall && !isJvmInterface(fd.getContainingDeclaration())) {
|
||||
CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + fd;
|
||||
if (c != context.getParentContext()) {
|
||||
fd = (FunctionDescriptor) c.getAccessor(fd, superCallTarget);
|
||||
}
|
||||
}
|
||||
fd = context.getAccessorForSuperCallIfNeeded(fd, superCallTarget);
|
||||
|
||||
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
|
||||
if (!codegenExtensions.isEmpty()) {
|
||||
@@ -2344,7 +2321,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
Callable callable = resolveToCallable(fd, superCall, resolvedCall);
|
||||
Callable callable = resolveToCallable(fd, superCallTarget != null, resolvedCall);
|
||||
|
||||
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
|
||||
}
|
||||
@@ -2401,7 +2378,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull CallGenerator callGenerator,
|
||||
@NotNull ArgumentGenerator argumentGenerator
|
||||
) {
|
||||
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
|
||||
boolean isConstructor = resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor;
|
||||
if (!isConstructor) { // otherwise already
|
||||
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
|
||||
receiver.put(receiver.type, v);
|
||||
callableMethod.afterReceiverGeneration(v);
|
||||
@@ -2412,7 +2390,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
|
||||
assert valueArguments != null : "Failed to arrange value arguments by index: " + resolvedCall.getResultingDescriptor();
|
||||
|
||||
DefaultCallMask masks =
|
||||
DefaultCallArgs defaultArgs =
|
||||
argumentGenerator.generate(valueArguments, new ArrayList<ResolvedValueArgument>(resolvedCall.getValueArguments().values()));
|
||||
|
||||
if (tailRecursionCodegen.isTailRecursion(resolvedCall)) {
|
||||
@@ -2420,26 +2398,32 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return;
|
||||
}
|
||||
|
||||
boolean defaultMaskWasGenerated = masks.generateOnStackIfNeeded(callGenerator);
|
||||
boolean defaultMaskWasGenerated = defaultArgs.generateOnStackIfNeeded(callGenerator, isConstructor);
|
||||
|
||||
// Extra constructor marker argument
|
||||
if (callableMethod instanceof CallableMethod) {
|
||||
List<JvmMethodParameterSignature> callableParameters = ((CallableMethod) callableMethod).getValueParameters();
|
||||
for (JvmMethodParameterSignature parameter: callableParameters) {
|
||||
if (parameter.getKind() == JvmMethodParameterKind.CONSTRUCTOR_MARKER) {
|
||||
callGenerator.putValueIfNeeded(null, parameter.getAsmType(), StackValue.constant(null, parameter.getAsmType()));
|
||||
callGenerator.putValueIfNeeded(parameter.getAsmType(), StackValue.constant(null, parameter.getAsmType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
||||
|
||||
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
v.aconst(null);
|
||||
v.athrow();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected CallGenerator getOrCreateCallGenerator(
|
||||
private CallGenerator getOrCreateCallGenerator(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@Nullable KtElement callElement,
|
||||
@Nullable ReifiedTypeParameterMappings reifiedTypeParameterMappings
|
||||
@Nullable TypeParameterMappings typeParameterMappings
|
||||
) {
|
||||
if (callElement == null) return defaultCallGenerator;
|
||||
|
||||
@@ -2451,25 +2435,25 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (!isInline) return defaultCallGenerator;
|
||||
|
||||
SimpleFunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((SimpleFunctionDescriptor) descriptor.getOriginal());
|
||||
return new InlineCodegen(this, state, original, callElement, reifiedTypeParameterMappings);
|
||||
return new InlineCodegen(this, state, original, callElement, typeParameterMappings);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CallGenerator getOrCreateCallGenerator(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
|
||||
protected CallGenerator getOrCreateCallGeneratorForDefaultImplBody(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
|
||||
return getOrCreateCallGenerator(descriptor, function, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
|
||||
ReifiedTypeParameterMappings mappings = new ReifiedTypeParameterMappings();
|
||||
TypeParameterMappings mappings = new TypeParameterMappings();
|
||||
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
||||
TypeParameterDescriptor key = entry.getKey();
|
||||
if (!key.isReified()) continue;
|
||||
|
||||
KotlinType type = entry.getValue();
|
||||
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
||||
if (parameterDescriptor == null) {
|
||||
KotlinType type = TypeUtils.uncaptureTypeForInlineMapping(entry.getValue());
|
||||
|
||||
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||
if (typeParameterAndReificationArgument == null) {
|
||||
// type is not generic
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
|
||||
Type asmType = typeMapper.mapTypeParameter(type, signatureWriter);
|
||||
@@ -2478,14 +2462,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
key.getName().getIdentifier(),
|
||||
type,
|
||||
asmType,
|
||||
signatureWriter.toString()
|
||||
);
|
||||
signatureWriter.toString(),
|
||||
key.isReified());
|
||||
}
|
||||
else {
|
||||
mappings.addParameterMappingToNewParameter(
|
||||
key.getName().getIdentifier(),
|
||||
parameterDescriptor.getName().getIdentifier()
|
||||
);
|
||||
mappings.addParameterMappingForFurtherReification(
|
||||
key.getName().getIdentifier(), type,
|
||||
typeParameterAndReificationArgument.getSecond(), key.isReified());
|
||||
}
|
||||
}
|
||||
return getOrCreateCallGenerator(
|
||||
@@ -2493,8 +2476,26 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static Pair<TypeParameterDescriptor, ReificationArgument> extractReificationArgument(@NotNull KotlinType type) {
|
||||
int arrayDepth = 0;
|
||||
boolean isNullable = type.isMarkedNullable();
|
||||
while (KotlinBuiltIns.isArray(type)) {
|
||||
arrayDepth++;
|
||||
type = type.getArguments().get(0).getType();
|
||||
}
|
||||
|
||||
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
||||
if (parameterDescriptor == null) return null;
|
||||
|
||||
return new Pair<TypeParameterDescriptor, ReificationArgument>(
|
||||
parameterDescriptor,
|
||||
new ReificationArgument(parameterDescriptor.getName().asString(), isNullable, arrayDepth));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue generateReceiverValue(@NotNull ReceiverValue receiverValue, boolean isSuper) {
|
||||
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
|
||||
if (receiverValue instanceof ImplicitClassReceiver) {
|
||||
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
|
||||
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
|
||||
@@ -2746,19 +2747,17 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
|
||||
if (variableDescriptor != null) {
|
||||
return generatePropertyReference(expression, variableDescriptor, (VariableDescriptor) resolvedCall.getResultingDescriptor(),
|
||||
resolvedCall.getDispatchReceiver());
|
||||
return generatePropertyReference(expression, variableDescriptor, resolvedCall);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue generatePropertyReference(
|
||||
private StackValue generatePropertyReference(
|
||||
@NotNull KtElement element,
|
||||
@NotNull VariableDescriptor variableDescriptor,
|
||||
@NotNull VariableDescriptor target,
|
||||
@NotNull ReceiverValue dispatchReceiver
|
||||
@NotNull ResolvedCall<?> resolvedCall
|
||||
) {
|
||||
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
|
||||
|
||||
@@ -2770,7 +2769,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
|
||||
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
|
||||
element, classBuilder, classDescriptor, target, dispatchReceiver
|
||||
element, classBuilder, resolvedCall
|
||||
);
|
||||
codegen.generate();
|
||||
|
||||
@@ -2795,13 +2794,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
|
||||
assert codegen != null :
|
||||
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
|
||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
|
||||
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
|
||||
}
|
||||
|
||||
putJavaLangClassInstance(v, classAsmType);
|
||||
wrapJavaClassIntoKClass(v);
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3260,7 +3259,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
value.store(StackValue.onStack(storeType), v, true);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3276,7 +3275,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitMultiDeclaration(@NotNull KtMultiDeclaration multiDeclaration, StackValue receiver) {
|
||||
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
|
||||
KtExpression initializer = multiDeclaration.getInitializer();
|
||||
if (initializer == null) return StackValue.none();
|
||||
|
||||
@@ -3293,7 +3292,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.store(tempVarIndex, initializerAsmType);
|
||||
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
|
||||
|
||||
for (KtMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
|
||||
for (KtDestructuringDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration);
|
||||
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
|
||||
Call call = makeFakeCall(initializerAsReceiver);
|
||||
@@ -3385,7 +3384,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructor, false);
|
||||
invokeMethodWithArguments(method, resolvedCall, StackValue.none());
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3401,7 +3400,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
gen(sizeExpression, Type.INT_TYPE);
|
||||
newArrayInstruction(arrayType);
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3409,9 +3408,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public void newArrayInstruction(@NotNull KotlinType arrayType) {
|
||||
if (KotlinBuiltIns.isArray(arrayType)) {
|
||||
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
|
||||
putReifierMarkerIfTypeIsReifiedParameter(
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
elementJetType,
|
||||
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
|
||||
ReifiedTypeInliner.OperationKind.NEW_ARRAY
|
||||
);
|
||||
v.newarray(boxType(asmType(elementJetType)));
|
||||
}
|
||||
@@ -3478,10 +3477,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
|
||||
assert resolvedCall != null : "couldn't find resolved call: " + expression.getText();
|
||||
|
||||
ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(
|
||||
this, defaultCallGenerator, resolvedCall.getResultingDescriptor().getValueParameters(), callable.getValueParameterTypes()
|
||||
);
|
||||
|
||||
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
|
||||
assert valueArguments != null : "Failed to arrange value arguments by index: " + operationDescriptor;
|
||||
|
||||
@@ -3492,7 +3487,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
return new StackValue.CollectionElementReceiver(
|
||||
callable, receiver, resolvedGetCall, resolvedSetCall, isGetter, this, argumentGenerator, valueArguments
|
||||
callable, receiver, resolvedGetCall, resolvedSetCall, isGetter, this, valueArguments
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3640,7 +3635,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
if (finallyBlock != null) {
|
||||
blockStackElements.pop();
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3688,28 +3683,19 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
StackValue.putUnitInstance(v);
|
||||
}
|
||||
|
||||
if (opToken != KtTokens.AS_SAFE) {
|
||||
if (!TypeUtils.isNullableType(rightType)) {
|
||||
v.dup();
|
||||
Label nonnull = new Label();
|
||||
v.ifnonnull(nonnull);
|
||||
genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " +
|
||||
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(rightType));
|
||||
v.mark(nonnull);
|
||||
}
|
||||
}
|
||||
else {
|
||||
v.dup();
|
||||
generateInstanceOfInstruction(rightType);
|
||||
Label ok = new Label();
|
||||
v.ifne(ok);
|
||||
v.pop();
|
||||
v.aconst(null);
|
||||
v.mark(ok);
|
||||
boolean safeAs = opToken == KtTokens.AS_SAFE;
|
||||
Type type = boxType(asmType(rightType));
|
||||
if (TypeUtils.isReifiedTypeParameter(rightType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightType,
|
||||
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
|
||||
: ReifiedTypeInliner.OperationKind.AS);
|
||||
v.checkcast(type);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
generateCheckCastInstruction(rightType, opToken == KtTokens.AS_SAFE);
|
||||
return Unit.INSTANCE$;
|
||||
CodegenUtilKt.generateAsCast(v, rightType, type, safeAs);
|
||||
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3747,11 +3733,11 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
private StackValue generateIsCheck(StackValue expressionToMatch, KtTypeReference typeReference, boolean negated) {
|
||||
KotlinType jetType = bindingContext.get(TYPE, typeReference);
|
||||
markStartLineNumber(typeReference);
|
||||
StackValue value = generateInstanceOf(expressionToMatch, jetType, false);
|
||||
StackValue value = generateIsCheck(expressionToMatch, jetType, false);
|
||||
return negated ? StackValue.not(value) : value;
|
||||
}
|
||||
|
||||
private StackValue generateInstanceOf(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
|
||||
private StackValue generateIsCheck(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
@@ -3759,46 +3745,35 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
generateInstanceOfInstruction(kotlinType);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
Type type = boxType(asmType(kotlinType));
|
||||
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
|
||||
v.instanceOf(type);
|
||||
return null;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateIsCheck(v, kotlinType, type);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void generateInstanceOfInstruction(@NotNull KotlinType jetType) {
|
||||
Type type = boxType(asmType(jetType));
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME);
|
||||
TypeIntrinsics.instanceOf(v, jetType, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generateCheckCastInstruction(@NotNull KotlinType jetType, boolean safeAs) {
|
||||
Type type = boxType(asmType(jetType));
|
||||
putReifierMarkerIfTypeIsReifiedParameter(jetType,
|
||||
safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME
|
||||
: ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
|
||||
TypeIntrinsics.checkcast(v, jetType, type, safeAs);
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull KotlinType type, @NotNull String markerMethodName) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
||||
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
|
||||
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
|
||||
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
|
||||
) {
|
||||
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
|
||||
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeParameterAndReificationArgument.getFirst();
|
||||
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
|
||||
parentCodegen.getReifiedTypeParametersUsages().
|
||||
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
|
||||
}
|
||||
|
||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
|
||||
v.iconst(operationKind.getId());
|
||||
v.visitLdcInsn(typeParameterAndReificationArgument.getSecond().asString());
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.REIFIED_OPERATION_MARKER_METHOD_NAME,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.getType(String.class)), false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3821,11 +3796,12 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return StackValue.operation(resultType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
SwitchCodegen switchCodegen =
|
||||
SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, ExpressionCodegen.this);
|
||||
SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(
|
||||
expression, isStatement, isExhaustive(expression, isStatement), ExpressionCodegen.this
|
||||
);
|
||||
if (switchCodegen != null) {
|
||||
switchCodegen.generate();
|
||||
return Unit.INSTANCE$;
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;
|
||||
@@ -3868,9 +3844,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
if (!hasElse && nextCondition != null) {
|
||||
v.mark(nextCondition);
|
||||
if (!isStatement) {
|
||||
putUnitInstanceOntoStackForNonExhaustiveWhen(expression);
|
||||
}
|
||||
putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
|
||||
}
|
||||
|
||||
markLineNumber(expression, isStatement);
|
||||
@@ -3883,14 +3857,24 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isExhaustive(@NotNull KtWhenExpression whenExpression, boolean isStatement) {
|
||||
if (isStatement) {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
else {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
}
|
||||
|
||||
public void putUnitInstanceOntoStackForNonExhaustiveWhen(
|
||||
@NotNull KtWhenExpression expression
|
||||
@NotNull KtWhenExpression whenExpression,
|
||||
boolean isStatement
|
||||
) {
|
||||
if (Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, expression))) {
|
||||
if (isExhaustive(whenExpression, isStatement)) {
|
||||
// when() is supposed to be exhaustive
|
||||
genThrow(v, "kotlin/NoWhenBranchMatchedException", null);
|
||||
}
|
||||
else {
|
||||
else if (!isStatement) {
|
||||
// non-exhaustive when() with no else -> Unit must be expected
|
||||
StackValue.putUnitInstance(v);
|
||||
}
|
||||
|
||||
@@ -33,17 +33,12 @@ public class FieldInfo {
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
|
||||
return createForSingleton(classDescriptor, typeMapper, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) {
|
||||
if (!classDescriptor.getKind().isSingleton() || DescriptorUtils.isEnumEntry(classDescriptor)) {
|
||||
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
|
||||
}
|
||||
|
||||
if (isNonCompanionObject(classDescriptor) || COMPANION_OBJECT_MAPPING.hasMappingToObject(classDescriptor)) {
|
||||
return createSingletonViaInstance(classDescriptor, typeMapper, oldSingleton);
|
||||
return createSingletonViaInstance(classDescriptor, typeMapper);
|
||||
}
|
||||
else {
|
||||
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
||||
@@ -56,11 +51,10 @@ public class FieldInfo {
|
||||
@NotNull
|
||||
public static FieldInfo createSingletonViaInstance(
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
boolean oldSingleton
|
||||
@NotNull JetTypeMapper typeMapper
|
||||
) {
|
||||
Type type = typeMapper.mapType(classDescriptor);
|
||||
return new FieldInfo(type, type, oldSingleton ? JvmAbi.DEPRECATED_INSTANCE_FIELD : JvmAbi.INSTANCE_FIELD, true);
|
||||
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -47,7 +47,7 @@ public class FrameMap {
|
||||
myVarSizes.remove(descriptor);
|
||||
int oldIndex = myVarIndex.remove(descriptor);
|
||||
if (oldIndex != myMaxIndex) {
|
||||
throw new IllegalStateException("descriptor can be left only if it is last");
|
||||
throw new IllegalStateException("Descriptor can be left only if it is last: " + descriptor);
|
||||
}
|
||||
return oldIndex;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -29,7 +28,6 @@ import org.jetbrains.kotlin.backend.common.bridges.Bridge;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics;
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
@@ -40,7 +38,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeKt;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -60,10 +57,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
|
||||
@@ -77,11 +71,12 @@ import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -161,7 +156,7 @@ public class FunctionCodegen {
|
||||
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
|
||||
boolean isNative = NativeKt.hasNativeAnnotation(functionDescriptor);
|
||||
|
||||
if (isNative && owner instanceof DelegatingFacadeContext) {
|
||||
if (isNative && owner instanceof MultifileClassFacadeContext) {
|
||||
// Native methods are only defined in facades and do not need package part implementations
|
||||
return;
|
||||
}
|
||||
@@ -172,10 +167,6 @@ public class FunctionCodegen {
|
||||
jvmSignature.getGenericsSignature(),
|
||||
getThrownExceptions(functionDescriptor, typeMapper));
|
||||
|
||||
String implClassName = CodegenContextUtil.getImplementationClassShortName(owner);
|
||||
if (implClassName != null) {
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, functionDescriptor, implClassName);
|
||||
}
|
||||
if (CodegenContextUtil.isImplClassOwner(owner)) {
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
|
||||
}
|
||||
@@ -221,8 +212,6 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
endVisit(mv, null, origin.getElement());
|
||||
|
||||
methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, bindingContext);
|
||||
}
|
||||
|
||||
private void generateMethodAnnotations(
|
||||
@@ -239,22 +228,6 @@ public class FunctionCodegen {
|
||||
else {
|
||||
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType());
|
||||
}
|
||||
|
||||
writePackageFacadeMethodAnnotationsIfNeeded(mv);
|
||||
}
|
||||
|
||||
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
|
||||
if (owner instanceof PackageFacadeContext) {
|
||||
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
|
||||
Type delegateToClassType = packageFacadeContext.getPublicFacadeType();
|
||||
if (delegateToClassType != null) {
|
||||
String className = delegateToClassType.getClassName();
|
||||
AnnotationVisitor
|
||||
av = mv.visitAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_DELEGATED_METHOD), true);
|
||||
av.visit(JvmAnnotationNames.IMPLEMENTATION_CLASS_NAME_FIELD_NAME, className);
|
||||
av.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateParameterAnnotations(
|
||||
@@ -275,9 +248,6 @@ public class FunctionCodegen {
|
||||
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
ValueParameterDescriptor parameter = iterator.next();
|
||||
if (parameter.getIndex() != i) {
|
||||
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
|
||||
}
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper);
|
||||
|
||||
if (functionDescriptor instanceof PropertySetterDescriptor) {
|
||||
@@ -366,18 +336,18 @@ public class FunctionCodegen {
|
||||
int functionFakeIndex = -1;
|
||||
int lambdaFakeIndex = -1;
|
||||
|
||||
if (context.getParentContext() instanceof DelegatingFacadeContext) {
|
||||
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
|
||||
if (context.getParentContext() instanceof MultifileClassFacadeContext) {
|
||||
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else {
|
||||
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
|
||||
functionDescriptor));
|
||||
if (context.isInlineFunction()) {
|
||||
if (context.isInlineMethodContext()) {
|
||||
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
if (context.isInliningLambda()) {
|
||||
if (context instanceof InlineLambdaContext) {
|
||||
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
@@ -398,7 +368,7 @@ public class FunctionCodegen {
|
||||
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
|
||||
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind());
|
||||
|
||||
if (context.isInlineFunction() && functionFakeIndex != -1) {
|
||||
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
|
||||
mv.visitLocalVariable(
|
||||
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
|
||||
Type.INT_TYPE.getDescriptor(), null,
|
||||
@@ -406,7 +376,7 @@ public class FunctionCodegen {
|
||||
functionFakeIndex);
|
||||
}
|
||||
|
||||
if (context.isInliningLambda() && thisType != null && lambdaFakeIndex != -1) {
|
||||
if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
|
||||
String name = thisType.getClassName();
|
||||
int indexOfLambdaOrdinal = name.lastIndexOf("$");
|
||||
if (indexOfLambdaOrdinal > 0) {
|
||||
@@ -470,9 +440,9 @@ public class FunctionCodegen {
|
||||
private static void generateFacadeDelegateMethodBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull DelegatingFacadeContext context
|
||||
@NotNull MultifileClassFacadeContext context
|
||||
) {
|
||||
generateDelegateToMethodBody(true, mv, asmMethod, context.getDelegateToClassType().getInternalName());
|
||||
generateDelegateToMethodBody(true, mv, asmMethod, context.getFilePartType().getInternalName());
|
||||
}
|
||||
|
||||
private static void generateDelegateToMethodBody(
|
||||
@@ -555,7 +525,7 @@ public class FunctionCodegen {
|
||||
// If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges
|
||||
if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return;
|
||||
|
||||
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor) != null;
|
||||
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
|
||||
|
||||
Set<Bridge<Method>> bridgesToGenerate;
|
||||
if (!isSpecial) {
|
||||
@@ -589,7 +559,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
|
||||
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor);
|
||||
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
|
||||
assert overridden != null;
|
||||
|
||||
Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
|
||||
@@ -695,9 +665,9 @@ public class FunctionCodegen {
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
if (this.owner instanceof DelegatingFacadeContext) {
|
||||
if (this.owner instanceof MultifileClassFacadeContext) {
|
||||
mv.visitCode();
|
||||
generateFacadeDelegateMethodBody(mv, defaultMethod, (DelegatingFacadeContext) this.owner);
|
||||
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
|
||||
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
|
||||
}
|
||||
else {
|
||||
@@ -705,6 +675,15 @@ public class FunctionCodegen {
|
||||
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen);
|
||||
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
|
||||
}
|
||||
|
||||
generateOldDefaultForFun(defaultMethod,
|
||||
JvmDeclarationOriginKt.Synthetic(function, functionDescriptor),
|
||||
flags,
|
||||
getThrownExceptions(functionDescriptor, typeMapper),
|
||||
(owner.getContextKind() == OwnerKind.DEFAULT_IMPLS ?
|
||||
typeMapper.mapDefaultImpls((ClassDescriptor) functionDescriptor.getContainingDeclaration()) :
|
||||
typeMapper.mapImplementationOwner(functionDescriptor)).getInternalName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,7 +703,7 @@ public class FunctionCodegen {
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
|
||||
|
||||
CallGenerator generator = codegen.getOrCreateCallGenerator(functionDescriptor, function);
|
||||
CallGenerator generator = codegen.getOrCreateCallGeneratorForDefaultImplBody(functionDescriptor, function);
|
||||
|
||||
loadExplicitArgumentsOnStack(OBJECT_TYPE, isStatic, signature, generator);
|
||||
|
||||
@@ -759,7 +738,7 @@ public class FunctionCodegen {
|
||||
iv.mark(loadArg);
|
||||
}
|
||||
|
||||
generator.putValueIfNeeded(parameterDescriptor, type, StackValue.local(parameterIndex, type));
|
||||
generator.putValueIfNeeded(type, StackValue.local(parameterIndex, type));
|
||||
}
|
||||
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
|
||||
@@ -769,6 +748,38 @@ public class FunctionCodegen {
|
||||
iv.areturn(signature.getReturnType());
|
||||
}
|
||||
|
||||
private void generateOldDefaultForFun(
|
||||
Method newDefaultMethod,
|
||||
JvmDeclarationOrigin origin,
|
||||
int flags,
|
||||
String[] exceptions,
|
||||
String owner
|
||||
) {
|
||||
if ("<init>".equals(newDefaultMethod.getName())) {
|
||||
return;
|
||||
}
|
||||
String oldSignature = newDefaultMethod.getDescriptor().replaceFirst("Ljava/lang/Object;\\)", ")");
|
||||
MethodVisitor mv = v.newMethod(
|
||||
origin,
|
||||
flags,
|
||||
newDefaultMethod.getName(),
|
||||
oldSignature,
|
||||
null,
|
||||
exceptions
|
||||
);
|
||||
mv.visitCode();
|
||||
int index = 0;
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
for (Type type: Type.getArgumentTypes(oldSignature)) {
|
||||
iv.load(index, type);
|
||||
index += type.getSize();
|
||||
}
|
||||
iv.aconst(null);
|
||||
iv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, newDefaultMethod.getName(), newDefaultMethod.getDescriptor(), false);
|
||||
iv.areturn(newDefaultMethod.getReturnType());
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FrameMap createFrameMap(
|
||||
@NotNull GenerationState state,
|
||||
@@ -808,14 +819,14 @@ public class FunctionCodegen {
|
||||
) {
|
||||
int var = 0;
|
||||
if (!isStatic) {
|
||||
callGenerator.putValueIfNeeded(null, ownerType, StackValue.local(var, ownerType));
|
||||
callGenerator.putValueIfNeeded(ownerType, StackValue.local(var, ownerType));
|
||||
var += ownerType.getSize();
|
||||
}
|
||||
|
||||
for (JvmMethodParameterSignature parameterSignature : signature.getValueParameters()) {
|
||||
if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) {
|
||||
Type type = parameterSignature.getAsmType();
|
||||
callGenerator.putValueIfNeeded(null, type, StackValue.local(var, type));
|
||||
callGenerator.putValueIfNeeded(type, StackValue.local(var, type));
|
||||
var += type.getSize();
|
||||
}
|
||||
}
|
||||
@@ -911,13 +922,7 @@ public class FunctionCodegen {
|
||||
iv.ifnonnull(afterBarrier);
|
||||
}
|
||||
else {
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateParameterType));
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterType));
|
||||
iv.ifne(afterBarrier);
|
||||
}
|
||||
|
||||
@@ -949,7 +954,7 @@ public class FunctionCodegen {
|
||||
@NotNull MethodContext context,
|
||||
@NotNull MemberCodegen<?> parentCodegen
|
||||
) {
|
||||
Method delegateToMethod = typeMapper.mapSignature(delegatedTo).getAsmMethod();
|
||||
Method delegateToMethod = typeMapper.mapToCallableMethod(delegatedTo, /* superCall = */ false).getAsmMethod();
|
||||
Method delegateMethod = typeMapper.mapSignature(delegateFunction).getAsmMethod();
|
||||
|
||||
Type[] argTypes = delegateMethod.getArgumentTypes();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -36,8 +36,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
|
||||
public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<FunctionDescriptor> {
|
||||
private final ResolvedCall<?> resolvedCall;
|
||||
private final FunctionDescriptor referencedFunction;
|
||||
@@ -82,13 +80,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
@Override
|
||||
public ReceiverValue getExtensionReceiver() {
|
||||
return extensionReceiver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
@Override
|
||||
public ReceiverValue getDispatchReceiver() {
|
||||
return dispatchReceiver;
|
||||
@@ -119,7 +117,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
}
|
||||
else {
|
||||
Call call = CallMaker.makeCall(fakeExpression, NO_RECEIVER, null, fakeExpression, fakeArguments);
|
||||
Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
|
||||
result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
|
||||
}
|
||||
|
||||
@@ -157,13 +155,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
private ReceiverValue computeAndSaveReceiver(
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@Nullable ReceiverParameterDescriptor receiver
|
||||
) {
|
||||
if (receiver == null) return NO_RECEIVER;
|
||||
if (receiver == null) return null;
|
||||
|
||||
KtExpression receiverExpression = KtPsiFactoryKt
|
||||
.KtPsiFactory(state.getProject()).createExpression("callableReferenceFakeReceiver");
|
||||
|
||||
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
@@ -43,6 +43,8 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -62,8 +64,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
@@ -74,6 +76,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||
@@ -98,6 +101,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private List<PropertyAndDefaultValue> companionObjectPropertiesToCopy;
|
||||
|
||||
private final DelegationFieldsInfo delegationFieldsInfo;
|
||||
|
||||
private final List<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>> additionalTasks =
|
||||
new ArrayList<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>>();
|
||||
|
||||
@@ -112,6 +117,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
super(aClass, context, v, state, parentCodegen);
|
||||
this.classAsmType = typeMapper.mapClass(descriptor);
|
||||
this.isLocal = isLocal;
|
||||
delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -227,8 +233,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateBody() {
|
||||
super.generateBody();
|
||||
protected void generateDefaultImplsIfNeeded() {
|
||||
if (isInterface(descriptor) && !isLocal) {
|
||||
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
|
||||
ClassBuilder defaultImplsBuilder =
|
||||
@@ -237,31 +242,29 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
CodegenContext parentContext = context.getParentContext();
|
||||
assert parentContext != null : "Parent context of interface declaration should not be null";
|
||||
|
||||
ClassContext defaultImplsContext = parentContext.intoClass(descriptor, OwnerKind.DEFAULT_IMPLS, state);
|
||||
ClassContext defaultImplsContext = parentContext.intoDefaultImplsClass(descriptor, (ClassContext) context, state);
|
||||
new InterfaceImplBodyCodegen(myClass, defaultImplsContext, defaultImplsBuilder, state, this).generate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateKotlinAnnotation() {
|
||||
if (!isTopLevelOrInnerClass(descriptor)) {
|
||||
AnnotationVisitor av = v.getVisitor().visitAnnotation(
|
||||
asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true
|
||||
);
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
|
||||
av.visitEnd();
|
||||
}
|
||||
final DescriptorSerializer serializer =
|
||||
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(
|
||||
v.getSerializationBindings(), typeMapper, state.getUseTypeTableInSerializer()
|
||||
));
|
||||
final ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
||||
|
||||
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.CLASS, new Function1<AnnotationVisitor, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(AnnotationVisitor av) {
|
||||
writeAnnotationData(av, serializer, classProto, false);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS), true);
|
||||
writeAnnotationData(av, serializer, classProto);
|
||||
writeModuleName(av, state);
|
||||
writeAbiVersion(av);
|
||||
writeAnnotationData(av, serializer, classProto, true);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
@@ -277,25 +280,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<String, String> KOTLIN_MARKER_INTERFACES = new HashMap<String, String>();
|
||||
private static final Map<FqName, String> KOTLIN_MARKER_INTERFACES = new HashMap<FqName, String>();
|
||||
static {
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterator", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterable", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.Collection", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.List", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.ListIterator", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.Set", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.Map", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.Map.Entry", "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.iterator, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.iterable, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.collection, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.list, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.listIterator, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.set, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.map, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mapEntry, "kotlin/jvm/internal/markers/KMappedMarker");
|
||||
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableIterator", "kotlin/jvm/internal/markers/KMutableIterator");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableIterable", "kotlin/jvm/internal/markers/KMutableIterable");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableCollection", "kotlin/jvm/internal/markers/KMutableCollection");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableList", "kotlin/jvm/internal/markers/KMutableList");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableListIterator", "kotlin/jvm/internal/markers/KMutableListIterator");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableSet", "kotlin/jvm/internal/markers/KMutableSet");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableMap", "kotlin/jvm/internal/markers/KMutableMap");
|
||||
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableMap.MutableEntry", "kotlin/jvm/internal/markers/KMutableMap$Entry");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableIterator, "kotlin/jvm/internal/markers/KMutableIterator");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableIterable, "kotlin/jvm/internal/markers/KMutableIterable");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableCollection, "kotlin/jvm/internal/markers/KMutableCollection");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableList, "kotlin/jvm/internal/markers/KMutableList");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableListIterator, "kotlin/jvm/internal/markers/KMutableListIterator");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableSet, "kotlin/jvm/internal/markers/KMutableSet");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableMap, "kotlin/jvm/internal/markers/KMutableMap");
|
||||
KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableMapEntry, "kotlin/jvm/internal/markers/KMutableMap$Entry");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -325,7 +328,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
String jvmInterfaceInternalName = jvmInterfaceType.getInternalName();
|
||||
superInterfaces.add(jvmInterfaceInternalName);
|
||||
|
||||
String kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).asString();
|
||||
FqName kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).toSafe();
|
||||
String kotlinMarkerInterfaceInternalName = KOTLIN_MARKER_INTERFACES.get(kotlinInterfaceName);
|
||||
if (kotlinMarkerInterfaceInternalName != null) {
|
||||
kotlinMarkerInterfaces.add(kotlinMarkerInterfaceInternalName);
|
||||
@@ -371,7 +374,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
generateCompanionObjectBackingFieldCopies();
|
||||
|
||||
DelegationFieldsInfo delegationFieldsInfo = getDelegationFieldsInfo(myClass.getDelegationSpecifiers());
|
||||
generateTraitMethods();
|
||||
|
||||
generateDelegates(delegationFieldsInfo);
|
||||
|
||||
if (!isInterface(descriptor) || kind == OwnerKind.DEFAULT_IMPLS) {
|
||||
generateSyntheticAccessors();
|
||||
}
|
||||
|
||||
generateEnumMethods();
|
||||
|
||||
generateFunctionsForDataClasses();
|
||||
|
||||
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
|
||||
|
||||
generateToArray();
|
||||
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
|
||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateConstructors() {
|
||||
try {
|
||||
lookupConstructorExpressionsInClosureIfPresent();
|
||||
generatePrimaryConstructor(delegationFieldsInfo);
|
||||
@@ -388,26 +415,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
catch (RuntimeException e) {
|
||||
throw new RuntimeException("Error generating constructors of class " + myClass.getName() + " with kind " + kind, e);
|
||||
}
|
||||
|
||||
generateTraitMethods();
|
||||
|
||||
generateDelegates(delegationFieldsInfo);
|
||||
|
||||
generateSyntheticAccessors();
|
||||
|
||||
generateEnumMethods();
|
||||
|
||||
generateFunctionsForDataClasses();
|
||||
|
||||
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
|
||||
|
||||
generateToArray();
|
||||
|
||||
genClosureFields(context.closure, v, typeMapper);
|
||||
|
||||
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
|
||||
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGenericToArrayPresent() {
|
||||
@@ -834,22 +841,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateFieldForSingleton() {
|
||||
if (isEnumEntry(descriptor)) return;
|
||||
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) return;
|
||||
|
||||
boolean isCompanionObject = isCompanionObject(descriptor);
|
||||
if (isNonCompanionObject(descriptor) || isCompanionObject) {
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.Field field = StackValue.singletonViaInstance(descriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL | (isCompanionObject ? ACC_DEPRECATED : 0),
|
||||
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
|
||||
field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.Field oldField = StackValue.oldSingleton(descriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_DEPRECATED, oldField.name, oldField.type.getDescriptor(), null, null);
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
// Invoke the object constructor but ignore the result because INSTANCE$ will be initialized in the first line of <init>
|
||||
// Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of <init>
|
||||
InstructionAdapter v = createOrGetClInitCodegen().v;
|
||||
markLineNumberForElement(element, v);
|
||||
v.anew(classAsmType);
|
||||
@@ -868,12 +869,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
|
||||
if (!isCompanionObjectWithBackingFieldsInOuter(companionObjectDescriptor)) {
|
||||
generateCompanionObjectInitializer(companionObjectDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateCompanionObjectBackingFieldCopies() {
|
||||
@@ -883,7 +878,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
PropertyDescriptor property = info.descriptor;
|
||||
|
||||
Type type = typeMapper.mapType(property);
|
||||
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (property.isConst() ? 0 : ACC_DEPRECATED);
|
||||
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC;
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
|
||||
modifiers, context.getFieldName(property, false),
|
||||
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
|
||||
@@ -925,13 +920,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
//TODO: uncomment when DEPRECATED INSTANCE is removed
|
||||
//FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
|
||||
// CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
|
||||
//);
|
||||
//generateMethodCallTo(constructor, null, codegen.v);
|
||||
//StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
|
||||
StackValue.singleton(companionObject, typeMapper).store(StackValue.singletonViaInstance(companionObject, typeMapper), codegen.v, true);
|
||||
|
||||
FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
|
||||
CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
|
||||
);
|
||||
generateMethodCallTo(constructor, null, codegen.v);
|
||||
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
|
||||
StackValue.singleton(companionObject, typeMapper).store(instance, codegen.v, true);
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
|
||||
@@ -958,10 +953,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass);
|
||||
|
||||
if (isCompanionObject(descriptor)) {
|
||||
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSecondaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
|
||||
@@ -1005,16 +996,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor,
|
||||
getDelegationConstructorCall(bindingContext, constructorDescriptor));
|
||||
|
||||
if (isObject(descriptor)) {
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.singletonViaInstance(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
|
||||
if (isNonCompanionObject(descriptor)) {
|
||||
StackValue.oldSingleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
|
||||
}
|
||||
}
|
||||
|
||||
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatorByExpressionSpecifier) specifier, fieldsInfo);
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatedSuperTypeEntry) specifier, fieldsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,9 +1021,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
curParam++;
|
||||
}
|
||||
|
||||
if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||
if (isCompanionObject(descriptor)) {
|
||||
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||
parentCodegen.generateCompanionObjectInitializer(descriptor);
|
||||
}
|
||||
|
||||
if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||
generateInitializers(new Function0<ExpressionCodegen>() {
|
||||
@Override
|
||||
public ExpressionCodegen invoke() {
|
||||
@@ -1153,41 +1145,41 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return StackValue.field(type, classAsmType, name, false, StackValue.none());
|
||||
}
|
||||
}
|
||||
private final Map<KtDelegatorByExpressionSpecifier, Field> fields = new HashMap<KtDelegatorByExpressionSpecifier, Field>();
|
||||
private final Map<KtDelegatedSuperTypeEntry, Field> fields = new HashMap<KtDelegatedSuperTypeEntry, Field>();
|
||||
|
||||
@NotNull
|
||||
public Field getInfo(KtDelegatorByExpressionSpecifier specifier) {
|
||||
public Field getInfo(KtDelegatedSuperTypeEntry specifier) {
|
||||
return fields.get(specifier);
|
||||
}
|
||||
|
||||
private void addField(KtDelegatorByExpressionSpecifier specifier, PropertyDescriptor propertyDescriptor) {
|
||||
private void addField(KtDelegatedSuperTypeEntry specifier, PropertyDescriptor propertyDescriptor) {
|
||||
fields.put(specifier,
|
||||
new Field(typeMapper.mapType(propertyDescriptor), propertyDescriptor.getName().asString(), false));
|
||||
}
|
||||
|
||||
private void addField(KtDelegatorByExpressionSpecifier specifier, Type type, String name) {
|
||||
private void addField(KtDelegatedSuperTypeEntry specifier, Type type, String name) {
|
||||
fields.put(specifier, new Field(type, name, true));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtDelegationSpecifier> delegationSpecifiers) {
|
||||
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtSuperTypeListEntry> delegationSpecifiers) {
|
||||
DelegationFieldsInfo result = new DelegationFieldsInfo();
|
||||
int n = 0;
|
||||
for (KtDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
KtExpression expression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||
for (KtSuperTypeListEntry specifier : delegationSpecifiers) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
|
||||
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext);
|
||||
|
||||
|
||||
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
|
||||
result.addField((KtDelegatorByExpressionSpecifier) specifier, propertyDescriptor);
|
||||
result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor);
|
||||
}
|
||||
else {
|
||||
KotlinType expressionType = expression != null ? bindingContext.getType(expression) : null;
|
||||
Type asmType =
|
||||
expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(getSuperClass(specifier));
|
||||
result.addField((KtDelegatorByExpressionSpecifier) specifier, asmType, "$delegate_" + n);
|
||||
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, "$delegate_" + n);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
@@ -1196,14 +1188,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassDescriptor getSuperClass(@NotNull KtDelegationSpecifier specifier) {
|
||||
return CodegenUtil.getSuperClassByDelegationSpecifier(specifier, bindingContext);
|
||||
private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) {
|
||||
return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
|
||||
}
|
||||
|
||||
private void genCallToDelegatorByExpressionSpecifier(
|
||||
InstructionAdapter iv,
|
||||
ExpressionCodegen codegen,
|
||||
KtDelegatorByExpressionSpecifier specifier,
|
||||
KtDelegatedSuperTypeEntry specifier,
|
||||
DelegationFieldsInfo fieldsInfo
|
||||
) {
|
||||
KtExpression expression = specifier.getDelegateExpression();
|
||||
@@ -1248,7 +1240,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void lookupReceiver(@NotNull ReceiverValue value) {
|
||||
private void lookupReceiver(@Nullable ReceiverValue value) {
|
||||
if (value instanceof ImplicitReceiver) {
|
||||
if (value instanceof ExtensionReceiver) {
|
||||
ReceiverParameterDescriptor parameter =
|
||||
@@ -1303,9 +1295,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
KtExpression delegateExpression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
|
||||
assert delegateExpression != null;
|
||||
delegateExpression.accept(visitor);
|
||||
}
|
||||
@@ -1331,7 +1323,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
private void generateTraitMethods() {
|
||||
if (isInterface(descriptor)) return;
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getTraitMethods(descriptor).entrySet()) {
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor traitFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!(traitFun instanceof JavaCallableMemberDescriptor)) {
|
||||
@@ -1559,7 +1551,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List args) {
|
||||
protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> args) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1571,7 +1563,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
for (KtEnumEntry enumEntry : enumEntries) {
|
||||
ClassDescriptor descriptor = getNotNull(bindingContext, BindingContext.CLASS, enumEntry);
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL,
|
||||
int isDeprecated = KotlinBuiltIns.isDeprecated(descriptor) ? ACC_DEPRECATED : 0;
|
||||
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL | isDeprecated,
|
||||
descriptor.getName().asString(), classAsmType.getDescriptor(), null, null);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(descriptor, null);
|
||||
}
|
||||
@@ -1619,7 +1612,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.aconst(enumEntry.getName());
|
||||
iv.iconst(ordinal);
|
||||
|
||||
List<KtDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
|
||||
List<KtSuperTypeListEntry> delegationSpecifiers = enumEntry.getSuperTypeListEntries();
|
||||
if (delegationSpecifiers.size() == 1 && !enumEntryNeedSubclass(bindingContext, enumEntry)) {
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(delegationSpecifiers.get(0), bindingContext);
|
||||
|
||||
@@ -1637,11 +1630,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateDelegates(DelegationFieldsInfo delegationFieldsInfo) {
|
||||
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
|
||||
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatorByExpressionSpecifier) specifier);
|
||||
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
|
||||
if (specifier instanceof KtDelegatedSuperTypeEntry) {
|
||||
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatedSuperTypeEntry) specifier);
|
||||
generateDelegateField(field);
|
||||
KtExpression delegateExpression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
|
||||
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
|
||||
KotlinType delegateExpressionType = delegateExpression != null ? bindingContext.getType(delegateExpression) : null;
|
||||
generateDelegates(getSuperClass(specifier), delegateExpressionType, field);
|
||||
}
|
||||
|
||||
@@ -23,29 +23,29 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
|
||||
val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>()
|
||||
|
||||
public fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
|
||||
fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
|
||||
//null call for default method inlining
|
||||
if (call != null) {
|
||||
val callElement = call.getCall().getCallElement()
|
||||
val callElement = call.call.callElement
|
||||
if (processingFunctions.contains(callElement)) {
|
||||
val cycle = processingFunctions.asSequence().dropWhile { it.getKey() != callElement }
|
||||
val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement }
|
||||
cycle.forEach {
|
||||
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.getKey(), it.getValue()))
|
||||
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.key, it.value))
|
||||
}
|
||||
return false
|
||||
}
|
||||
processingFunctions.put(callElement, call.getResultingDescriptor().getOriginal())
|
||||
processingFunctions.put(callElement, call.resultingDescriptor.original)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public fun exitFromInliningOf(call: ResolvedCall<*>?) {
|
||||
fun exitFromInliningOf(call: ResolvedCall<*>?) {
|
||||
if (call != null) {
|
||||
val callElement = call.getCall().getCallElement()
|
||||
val callElement = call.call.callElement
|
||||
processingFunctions.remove(callElement)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ 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.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_INTERFACE_DEFAULT_IMPLS
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
@@ -39,7 +37,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import java.util.*
|
||||
|
||||
public class InterfaceImplBodyCodegen(
|
||||
class InterfaceImplBodyCodegen(
|
||||
aClass: KtClassOrObject,
|
||||
context: ClassContext,
|
||||
v: ClassBuilder,
|
||||
@@ -51,11 +49,11 @@ public class InterfaceImplBodyCodegen(
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(
|
||||
myClass, V1_6, ACC_PUBLIC or ACC_FINAL,
|
||||
myClass, V1_6, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
v.visitSource(myClass.getContainingFile().getName(), null)
|
||||
v.visitSource(myClass.containingFile.name, null)
|
||||
}
|
||||
|
||||
override fun classForInnerClassRecord(): ClassDescriptor? {
|
||||
@@ -63,19 +61,19 @@ public class InterfaceImplBodyCodegen(
|
||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||
val classDescriptorImpl = ClassDescriptorImpl(
|
||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||
Modality.FINAL, Collections.emptyList(), SourceElement.NO_SOURCE)
|
||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE)
|
||||
|
||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||
return classDescriptorImpl
|
||||
}
|
||||
|
||||
override fun generateSyntheticParts() {
|
||||
for (memberDescriptor in descriptor.getDefaultType().getMemberScope().getContributedDescriptors()) {
|
||||
for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
|
||||
if (memberDescriptor !is CallableMemberDescriptor) continue
|
||||
|
||||
if (memberDescriptor.getKind().isReal()) continue
|
||||
if (memberDescriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) continue
|
||||
if (memberDescriptor.getModality() == Modality.ABSTRACT) continue
|
||||
if (memberDescriptor.kind.isReal) continue
|
||||
if (memberDescriptor.visibility == Visibilities.INVISIBLE_FAKE) continue
|
||||
if (memberDescriptor.modality == Modality.ABSTRACT) continue
|
||||
|
||||
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
|
||||
|
||||
@@ -83,7 +81,7 @@ public class InterfaceImplBodyCodegen(
|
||||
if (implementation is JavaMethodDescriptor) continue
|
||||
|
||||
// We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body
|
||||
val copy = memberDescriptor.copy(memberDescriptor.getContainingDeclaration(), Modality.OPEN, memberDescriptor.getVisibility(),
|
||||
val copy = memberDescriptor.copy(memberDescriptor.containingDeclaration, Modality.OPEN, memberDescriptor.visibility,
|
||||
CallableMemberDescriptor.Kind.DECLARATION, true)
|
||||
|
||||
if (memberDescriptor is FunctionDescriptor) {
|
||||
@@ -91,18 +89,20 @@ public class InterfaceImplBodyCodegen(
|
||||
}
|
||||
else if (memberDescriptor is PropertyDescriptor) {
|
||||
implementation as PropertyDescriptor
|
||||
val getter = (copy as PropertyDescriptor).getGetter()
|
||||
val implGetter = implementation.getGetter()
|
||||
val getter = (copy as PropertyDescriptor).getter
|
||||
val implGetter = implementation.getter
|
||||
if (getter != null && implGetter != null) {
|
||||
generateDelegationToSuperTraitImpl(getter, implGetter)
|
||||
}
|
||||
val setter = copy.getSetter()
|
||||
val implSetter = implementation.getSetter()
|
||||
val setter = copy.setter
|
||||
val implSetter = implementation.setter
|
||||
if (setter != null && implSetter != null) {
|
||||
generateDelegationToSuperTraitImpl(setter, implSetter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateSyntheticAccessors()
|
||||
}
|
||||
|
||||
private fun generateDelegationToSuperTraitImpl(descriptor: FunctionDescriptor, implementation: FunctionDescriptor) {
|
||||
@@ -119,10 +119,10 @@ public class InterfaceImplBodyCodegen(
|
||||
val iv = codegen.v
|
||||
|
||||
val method = typeMapper.mapToCallableMethod(delegateTo, true)
|
||||
val myParameters = signature.getValueParameters()
|
||||
val myParameters = signature.valueParameters
|
||||
val calleeParameters = method.getValueParameters()
|
||||
|
||||
if (myParameters.size() != calleeParameters.size()) {
|
||||
if (myParameters.size != calleeParameters.size) {
|
||||
throw AssertionError(
|
||||
"Method from super interface has a different signature.\n" +
|
||||
"This method:\n%s\n%s\n%s\nSuper method:\n%s\n%s\n%s".format(
|
||||
@@ -134,14 +134,14 @@ public class InterfaceImplBodyCodegen(
|
||||
var k = 0
|
||||
val it = calleeParameters.iterator()
|
||||
for (parameter in myParameters) {
|
||||
val type = parameter.getAsmType()
|
||||
StackValue.local(k, type).put(it.next().getAsmType(), iv)
|
||||
k += type.getSize()
|
||||
val type = parameter.asmType
|
||||
StackValue.local(k, type).put(it.next().asmType, iv)
|
||||
k += type.size
|
||||
}
|
||||
|
||||
method.genInvokeInstruction(iv)
|
||||
StackValue.coerce(method.returnType, signature.getReturnType(), iv)
|
||||
iv.areturn(signature.getReturnType())
|
||||
StackValue.coerce(method.returnType, signature.returnType, iv)
|
||||
iv.areturn(signature.returnType)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -149,10 +149,9 @@ public class InterfaceImplBodyCodegen(
|
||||
override fun generateKotlinAnnotation() {
|
||||
(v as InterfaceImplClassBuilder).stopCounting()
|
||||
|
||||
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
|
||||
av.visitEnd()
|
||||
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
|
||||
|
||||
writeSyntheticClassMetadata(v);
|
||||
}
|
||||
|
||||
override fun done() {
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.StringsKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
@@ -28,11 +28,10 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.FacadePartWithSourceFile;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.RootContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
@@ -50,6 +49,7 @@ import java.io.File;
|
||||
|
||||
import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT;
|
||||
import static org.jetbrains.kotlin.descriptors.Modality.FINAL;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
|
||||
public class JvmCodegenUtil {
|
||||
|
||||
@@ -130,16 +130,21 @@ public class JvmCodegenUtil {
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean isConstOrHasJvmFieldAnnotation(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return propertyDescriptor.isConst() || hasJvmFieldAnnotation(propertyDescriptor);
|
||||
}
|
||||
|
||||
public static boolean couldUseDirectAccessToProperty(
|
||||
@NotNull PropertyDescriptor property,
|
||||
boolean forGetter,
|
||||
boolean isDelegated,
|
||||
@NotNull MethodContext context
|
||||
@NotNull MethodContext contextBeforeInline
|
||||
) {
|
||||
if (JetTypeMapper.isAccessor(property)) return false;
|
||||
|
||||
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();
|
||||
// Inline functions can't use direct access because a field may not be visible at the call site
|
||||
if (context.isInlineFunction()) {
|
||||
if (context.isInlineMethodContext()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,7 +169,7 @@ public class JvmCodegenUtil {
|
||||
return Visibilities.isPrivate(property.getVisibility()) || accessor.getModality() == FINAL;
|
||||
}
|
||||
|
||||
private static boolean isDebuggerContext(@NotNull MethodContext context) {
|
||||
private static boolean isDebuggerContext(@NotNull CodegenContext context) {
|
||||
KtFile file = DescriptorToSourceUtils.getContainingFile(context.getContextDescriptor());
|
||||
return file != null && CodeFragmentUtilKt.getSuppressDiagnosticsInDebugMode(file);
|
||||
}
|
||||
@@ -217,16 +222,6 @@ public class JvmCodegenUtil {
|
||||
}
|
||||
|
||||
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
|
||||
|
||||
// TODO: drop after some time
|
||||
av.visit(JvmAnnotationNames.OLD_ABI_VERSION_FIELD_NAME, 32);
|
||||
}
|
||||
|
||||
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {
|
||||
String name = state.getModuleName();
|
||||
if (!name.equals(JvmAbi.DEFAULT_MODULE_NAME)) {
|
||||
av.visit(JvmAnnotationNames.MODULE_NAME_FIELD_NAME, name);
|
||||
}
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmMetadataVersion.INSTANCE.toArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class JvmRuntimeTypes {
|
||||
|
||||
public JvmRuntimeTypes() {
|
||||
ModuleDescriptorImpl module = TargetPlatformKt.createModule(
|
||||
JvmPlatform.INSTANCE$,
|
||||
JvmPlatform.INSTANCE,
|
||||
Name.special("<jvm functions impl>"),
|
||||
LockBasedStorageManager.NO_LOCKS
|
||||
);
|
||||
|
||||
@@ -79,15 +79,14 @@ class JvmStaticGenerator(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
public fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
|
||||
@JvmStatic fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor
|
||||
val copies = CodegenUtil.copyFunctions(
|
||||
memberDescriptor,
|
||||
memberDescriptor,
|
||||
descriptor.getContainingDeclaration().getContainingDeclaration(),
|
||||
descriptor.getModality(),
|
||||
descriptor.getVisibility(),
|
||||
descriptor.containingDeclaration.containingDeclaration,
|
||||
descriptor.modality,
|
||||
descriptor.visibility,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
false
|
||||
)
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
@@ -46,8 +44,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
||||
@@ -65,8 +61,7 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlag
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
|
||||
@@ -281,7 +276,8 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
|
||||
protected void writeOuterClassAndEnclosingMethod() {
|
||||
CodegenContext context = this.context.getParentContext();
|
||||
while (context instanceof MethodContext && ((MethodContext) context).isInliningLambda()) {
|
||||
|
||||
while (context instanceof InlineLambdaContext) {
|
||||
// If this is a lambda which will be inlined, skip its MethodContext and enclosing ClosureContext
|
||||
//noinspection ConstantConditions
|
||||
context = context.getParentContext().getParentContext();
|
||||
@@ -306,7 +302,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
if (outermost instanceof ClassContext) {
|
||||
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
|
||||
}
|
||||
else if (outermost instanceof DelegatingFacadeContext || outermost instanceof DelegatingToPartContext) {
|
||||
else if (outermost instanceof MultifileClassFacadeContext || outermost instanceof DelegatingToPartContext) {
|
||||
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
|
||||
if (implementationOwnerType != null) {
|
||||
return implementationOwnerType;
|
||||
@@ -499,37 +495,23 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
iv.dup();
|
||||
iv.iconst(i);
|
||||
|
||||
StackValue value;
|
||||
// TODO: remove this option and always generate PropertyReferenceNImpl creation
|
||||
if ("true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.delegated.properties"))) {
|
||||
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
|
||||
(property.getExtensionReceiverParameter() != null ? 1 : 0);
|
||||
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
||||
iv.anew(implType);
|
||||
iv.dup();
|
||||
// TODO: generate the container once and save to a local field instead
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||
iv.aconst(property.getName().asString());
|
||||
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
|
||||
iv.invokespecial(
|
||||
implType.getInternalName(), "<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
|
||||
);
|
||||
value = StackValue.onStack(implType);
|
||||
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
|
||||
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
|
||||
}
|
||||
else {
|
||||
ReceiverParameterDescriptor dispatchReceiver = property.getDispatchReceiverParameter();
|
||||
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
|
||||
(property.getExtensionReceiverParameter() != null ? 1 : 0);
|
||||
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
||||
iv.anew(implType);
|
||||
iv.dup();
|
||||
// TODO: generate the container once and save to a local field instead (KT-10495)
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||
iv.aconst(property.getName().asString());
|
||||
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
|
||||
iv.invokespecial(
|
||||
implType.getInternalName(), "<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
|
||||
);
|
||||
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
|
||||
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
value = createOrGetClInitCodegen().generatePropertyReference(
|
||||
delegatedProperties.get(i).getDelegate(), property, property,
|
||||
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : ReceiverValue.NO_RECEIVER
|
||||
);
|
||||
}
|
||||
|
||||
value.put(K_PROPERTY_TYPE, iv);
|
||||
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
|
||||
|
||||
iv.astore(K_PROPERTY_TYPE);
|
||||
}
|
||||
@@ -568,20 +550,17 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
return sourceMapper;
|
||||
}
|
||||
|
||||
protected void generateConstInstance(
|
||||
@NotNull Type thisAsmType,
|
||||
@NotNull Type fieldAsmType,
|
||||
@NotNull Function1<InstructionAdapter, Unit> initialization
|
||||
) {
|
||||
v.newField(JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor(),
|
||||
null, null);
|
||||
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
|
||||
v.newField(
|
||||
JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
|
||||
fieldAsmType.getDescriptor(), null, null
|
||||
);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
InstructionAdapter iv = createOrGetClInitCodegen().v;
|
||||
iv.anew(thisAsmType);
|
||||
iv.dup();
|
||||
iv.invokespecial(thisAsmType.getInternalName(), "<init>", "()V", false);
|
||||
initialization.invoke(iv);
|
||||
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
|
||||
}
|
||||
}
|
||||
@@ -622,7 +601,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
|
||||
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
boolean forceField = (JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
!isCompanionObject(accessor.getContainingDeclaration())) ||
|
||||
syntheticBackingField ||
|
||||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
|
||||
@@ -673,7 +652,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateMethodCallTo(
|
||||
protected StackValue generateMethodCallTo(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@Nullable FunctionDescriptor accessorDescriptor,
|
||||
@NotNull InstructionAdapter iv
|
||||
@@ -684,7 +663,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
|
||||
);
|
||||
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor);
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) && !isInterface(functionDescriptor.getContainingDeclaration());
|
||||
int reg = hasDispatchReceiver ? 1 : 0;
|
||||
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
||||
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
@@ -38,6 +39,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
@@ -47,14 +49,16 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.*
|
||||
|
||||
public class MultifileClassCodegen(
|
||||
class MultifileClassCodegen(
|
||||
private val state: GenerationState,
|
||||
public val files: Collection<KtFile>,
|
||||
val files: Collection<KtFile>,
|
||||
private val facadeFqName: FqName
|
||||
) {
|
||||
private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName)
|
||||
@@ -72,7 +76,7 @@ public class MultifileClassCodegen(
|
||||
private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) =
|
||||
compiledPackageFragment.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CALLABLES, MemberScope.ALL_NAME_FILTER).filterIsInstance<DeserializedCallableMemberDescriptor>()
|
||||
|
||||
public val packageParts = PackageParts(facadeFqName.parent().asString())
|
||||
val packageParts = PackageParts(facadeFqName.parent().asString())
|
||||
|
||||
private val classBuilder = ClassBuilderOnDemand {
|
||||
val originFile = files.firstOrNull()
|
||||
@@ -86,16 +90,22 @@ public class MultifileClassCodegen(
|
||||
|
||||
val singleSourceFile = if (previouslyCompiledCallables.isNotEmpty()) null else filesWithCallables.singleOrNull()
|
||||
|
||||
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES,
|
||||
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6,
|
||||
if (state.generateOpenMultifileClasses) OPEN_FACADE_CLASS_ATTRIBUTES else FACADE_CLASS_ATTRIBUTES,
|
||||
facadeClassType.internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY)
|
||||
if (singleSourceFile != null) {
|
||||
classBuilder.visitSource(singleSourceFile.name, null)
|
||||
}
|
||||
|
||||
if (state.generateOpenMultifileClasses) {
|
||||
generateMultifileFacadeClassConstructor(classBuilder, originFile)
|
||||
}
|
||||
|
||||
classBuilder
|
||||
}
|
||||
|
||||
public fun generate(errorHandler: CompilationErrorHandler) {
|
||||
fun generate(errorHandler: CompilationErrorHandler) {
|
||||
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
|
||||
val partFqNames = arrayListOf<FqName>()
|
||||
|
||||
@@ -144,10 +154,20 @@ public class MultifileClassCodegen(
|
||||
writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames)
|
||||
}
|
||||
|
||||
public fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
|
||||
fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
|
||||
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null)
|
||||
}
|
||||
|
||||
|
||||
private fun generateMultifileFacadeClassConstructor(classBuilder: ClassBuilder, originFile: KtFile?) {
|
||||
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null)
|
||||
val v = InstructionAdapter(mv)
|
||||
v.load(0, facadeClassType)
|
||||
v.invokespecial("java/lang/Object", "<init>", "()V", false)
|
||||
v.visitInsn(Opcodes.RETURN)
|
||||
FunctionCodegen.endVisit(v, "multifile class constructor", originFile)
|
||||
}
|
||||
|
||||
private fun generatePart(
|
||||
file: KtFile,
|
||||
generateCallableMemberTasks: MutableMap<CallableMemberDescriptor, () -> Unit>,
|
||||
@@ -253,17 +273,23 @@ public class MultifileClassCodegen(
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) return
|
||||
if (files.any { it.isScript }) return
|
||||
|
||||
val partInternalNames = partFqNames.map(AsmUtil::internalNameByFqNameWithoutInnerClasses).sorted()
|
||||
|
||||
fun writePartNames(av: AnnotationVisitor, fieldName: String) {
|
||||
val arv = av.visitArray(fieldName)
|
||||
for (internalName in partInternalNames) {
|
||||
arv.visit(null, internalName)
|
||||
}
|
||||
arv.visitEnd()
|
||||
}
|
||||
|
||||
writeKotlinMetadata(classBuilder, KotlinClassHeader.Kind.MULTIFILE_CLASS) { av ->
|
||||
writePartNames(av, JvmAnnotationNames.METADATA_DATA_FIELD_NAME)
|
||||
}
|
||||
|
||||
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
|
||||
JvmCodegenUtil.writeAbiVersion(av)
|
||||
JvmCodegenUtil.writeModuleName(av, state)
|
||||
|
||||
val partInternalNames = partFqNames.map { JvmClassName.byFqNameWithoutInnerClasses(it).internalName }.sorted()
|
||||
val arv = av.visitArray(JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
|
||||
for (internalName in partInternalNames) {
|
||||
arv.visit(null, internalName)
|
||||
}
|
||||
arv.visitEnd()
|
||||
|
||||
writePartNames(av, JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
|
||||
av.visitEnd()
|
||||
}
|
||||
|
||||
@@ -274,12 +300,13 @@ public class MultifileClassCodegen(
|
||||
override fun generateKotlinAnnotation() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
public fun done() {
|
||||
fun done() {
|
||||
classBuilder.done()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL
|
||||
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER
|
||||
private val OPEN_FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_SUPER
|
||||
|
||||
private fun getOnlyPackageFragment(packageFqName: FqName, files: Collection<KtFile>, bindingContext: BindingContext): PackageFragmentDescriptor? {
|
||||
val fragments = SmartList<PackageFragmentDescriptor>()
|
||||
@@ -293,7 +320,7 @@ public class MultifileClassCodegen(
|
||||
fragments.add(fragment)
|
||||
}
|
||||
}
|
||||
if (fragments.size() > 1) {
|
||||
if (fragments.size > 1) {
|
||||
throw IllegalStateException("More than one package fragment, files: $files | fragments: $fragments")
|
||||
}
|
||||
return fragments.firstOrNull()
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
@@ -31,7 +32,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.util.*
|
||||
|
||||
public class MultifileClassPartCodegen(
|
||||
class MultifileClassPartCodegen(
|
||||
v: ClassBuilder,
|
||||
file: KtFile,
|
||||
private val filePartType: Type,
|
||||
@@ -46,7 +47,7 @@ public class MultifileClassPartCodegen(
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(element, Opcodes.V1_6,
|
||||
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC,
|
||||
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC or Opcodes.ACC_SUPER,
|
||||
filePartType.internalName,
|
||||
null,
|
||||
"java/lang/Object",
|
||||
@@ -83,15 +84,17 @@ public class MultifileClassPartCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
val bindings = v.serializationBindings
|
||||
|
||||
val serializer = DescriptorSerializer.createTopLevel(
|
||||
JvmSerializerExtension(bindings, state.typeMapper, state.useTypeTableInSerializer)
|
||||
)
|
||||
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(v.serializationBindings, state))
|
||||
val packageProto = serializer.packagePartProto(members).build()
|
||||
|
||||
writeKotlinMetadata(v, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART) { av ->
|
||||
AsmUtil.writeAnnotationData(av, serializer, packageProto, false)
|
||||
av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
|
||||
}
|
||||
|
||||
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS_PART), true)
|
||||
AsmUtil.writeAnnotationData(av, serializer, packageProto)
|
||||
JvmCodegenUtil.writeAbiVersion(av)
|
||||
AsmUtil.writeAnnotationData(av, serializer, packageProto, true)
|
||||
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
|
||||
av.visitEnd()
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
|
||||
this.typeConstructor = TypeConstructorImpl.createForClass(
|
||||
this,
|
||||
Annotations.Companion.getEMPTY(),
|
||||
!getModality().isOverridable(),
|
||||
ModalityKt.isFinalClass(this),
|
||||
getName().asString(),
|
||||
typeParameters,
|
||||
supertypes
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
@@ -43,7 +45,7 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.writeAnnotationData;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeModuleName;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.writeAbiVersion;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
@@ -63,7 +65,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
@Override
|
||||
protected void generateDeclaration() {
|
||||
v.defineClass(element, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
|
||||
packagePartType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
@@ -119,16 +121,21 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
}
|
||||
}
|
||||
|
||||
JvmSerializationBindings bindings = v.getSerializationBindings();
|
||||
final DescriptorSerializer serializer =
|
||||
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
|
||||
final ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
|
||||
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(
|
||||
bindings, state.getTypeMapper(), state.getUseTypeTableInSerializer()
|
||||
));
|
||||
ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
|
||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.FILE_FACADE, new Function1<AnnotationVisitor, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(AnnotationVisitor av) {
|
||||
writeAnnotationData(av, serializer, packageProto, false);
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
|
||||
writeAnnotationData(av, serializer, packageProto);
|
||||
writeModuleName(av, state);
|
||||
writeAbiVersion(av);
|
||||
writeAnnotationData(av, serializer, packageProto, true);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -54,10 +54,14 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -97,7 +101,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
|
||||
assert context instanceof DelegatingFacadeContext : "should be called only for generating facade: " + context;
|
||||
assert context instanceof MultifileClassFacadeContext : "should be called only for generating facade: " + context;
|
||||
gen(null, deserializedProperty, null, null);
|
||||
}
|
||||
|
||||
@@ -110,11 +114,6 @@ public class PropertyCodegen {
|
||||
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
|
||||
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
||||
|
||||
String implClassName = CodegenContextUtil.getImplementationClassShortName(context);
|
||||
if (implClassName != null) {
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, implClassName);
|
||||
}
|
||||
|
||||
if (CodegenContextUtil.isImplClassOwner(context)) {
|
||||
assert declaration != null : "Declaration is null for different context: " + context;
|
||||
|
||||
@@ -127,22 +126,22 @@ public class PropertyCodegen {
|
||||
if (isAccessorNeeded(declaration, descriptor, setter)) {
|
||||
generateSetter(declaration, descriptor, setter);
|
||||
}
|
||||
|
||||
context.recordSyntheticAccessorIfNeeded(descriptor, bindingContext);
|
||||
}
|
||||
|
||||
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
|
||||
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
||||
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
|
||||
|
||||
AnnotationSplitter annotationSplitter =
|
||||
AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
|
||||
descriptor.getAnnotations(),
|
||||
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField));
|
||||
AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField, hasDelegate));
|
||||
|
||||
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
||||
Annotations delegateAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD);
|
||||
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
||||
|
||||
generateBackingField(declaration, descriptor, fieldAnnotations);
|
||||
generateBackingField(declaration, descriptor, fieldAnnotations, delegateAnnotations);
|
||||
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
|
||||
}
|
||||
|
||||
@@ -157,7 +156,7 @@ public class PropertyCodegen {
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable KtPropertyAccessor accessor
|
||||
) {
|
||||
if (hasJvmFieldAnnotation(descriptor)) return false;
|
||||
if (isConstOrHasJvmFieldAnnotation(descriptor)) return false;
|
||||
|
||||
boolean isDefaultAccessor = accessor == null || !accessor.hasBody();
|
||||
|
||||
@@ -231,17 +230,18 @@ public class PropertyCodegen {
|
||||
private boolean generateBackingField(
|
||||
@NotNull KtNamedDeclaration p,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull Annotations annotations
|
||||
@NotNull Annotations backingFieldAnnotations,
|
||||
@NotNull Annotations delegateAnnotations
|
||||
) {
|
||||
if (isJvmInterface(descriptor.getContainingDeclaration()) || kind == OwnerKind.DEFAULT_IMPLS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p instanceof KtProperty && ((KtProperty) p).hasDelegate()) {
|
||||
generatePropertyDelegateAccess((KtProperty) p, descriptor, annotations);
|
||||
generatePropertyDelegateAccess((KtProperty) p, descriptor, delegateAnnotations);
|
||||
}
|
||||
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
||||
generateBackingFieldAccess(p, descriptor, annotations);
|
||||
generateBackingFieldAccess(p, descriptor, backingFieldAnnotations);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -267,10 +267,6 @@ public class PropertyCodegen {
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitEnd();
|
||||
}
|
||||
else {
|
||||
Type tImplType = typeMapper.mapDefaultImpls((ClassDescriptor) context.getContextDescriptor());
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, shortNameByAsmType(tImplType));
|
||||
}
|
||||
|
||||
if (kind != OwnerKind.DEFAULT_IMPLS) {
|
||||
v.getSerializationBindings().put(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor, new Method(name, desc));
|
||||
@@ -309,46 +305,17 @@ public class PropertyCodegen {
|
||||
|
||||
ClassBuilder builder = v;
|
||||
|
||||
boolean hasJvmFieldAnnotation = hasJvmFieldAnnotation(propertyDescriptor);
|
||||
|
||||
FieldOwnerContext backingFieldContext = context;
|
||||
boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst();
|
||||
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
modifiers |= ACC_STATIC;
|
||||
|
||||
if (takeVisibilityFromDescriptor) {
|
||||
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
|
||||
}
|
||||
else if (hasJvmFieldAnnotation && !isDelegate) {
|
||||
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
|
||||
}
|
||||
else {
|
||||
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
|
||||
}
|
||||
|
||||
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
builder = codegen.v;
|
||||
backingFieldContext = codegen.context;
|
||||
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
|
||||
}
|
||||
|
||||
if (isObject(propertyDescriptor.getContainingDeclaration()) &&
|
||||
!hasJvmFieldAnnotation &&
|
||||
!propertyDescriptor.isConst() &&
|
||||
(modifiers & ACC_PRIVATE) == 0) {
|
||||
modifiers |= ACC_DEPRECATED;
|
||||
}
|
||||
}
|
||||
else if (takeVisibilityFromDescriptor) {
|
||||
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
|
||||
}
|
||||
else if (!isDelegate && hasJvmFieldAnnotation) {
|
||||
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
|
||||
}
|
||||
else {
|
||||
modifiers |= ACC_PRIVATE;
|
||||
}
|
||||
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
||||
|
||||
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
|
||||
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||
@@ -363,7 +330,8 @@ public class PropertyCodegen {
|
||||
typeMapper.mapFieldSignature(jetType, propertyDescriptor), defaultValue);
|
||||
|
||||
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(
|
||||
fieldAnnotated, type, isDelegate ? AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD : AnnotationUseSiteTarget.FIELD);
|
||||
}
|
||||
|
||||
private void generatePropertyDelegateAccess(KtProperty p, PropertyDescriptor propertyDescriptor, Annotations annotations) {
|
||||
|
||||
@@ -28,31 +28,30 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
public class PropertyReferenceCodegen(
|
||||
class PropertyReferenceCodegen(
|
||||
state: GenerationState,
|
||||
parentCodegen: MemberCodegen<*>,
|
||||
context: ClassContext,
|
||||
expression: KtElement,
|
||||
classBuilder: ClassBuilder,
|
||||
private val classDescriptor: ClassDescriptor,
|
||||
private val target: VariableDescriptor,
|
||||
dispatchReceiver: ReceiverValue
|
||||
resolvedCall: ResolvedCall<*>
|
||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||
private val classDescriptor = context.contextDescriptor
|
||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||
|
||||
private val dispatchReceiverType = if (dispatchReceiver.exists()) dispatchReceiver.type else null
|
||||
|
||||
private val target = resolvedCall.resultingDescriptor as VariableDescriptor
|
||||
private val dispatchReceiverType = resolvedCall.dispatchReceiver?.type
|
||||
private val extensionReceiverType = target.extensionReceiverParameter?.type
|
||||
|
||||
private val receiverCount =
|
||||
@@ -69,26 +68,22 @@ public class PropertyReferenceCodegen(
|
||||
element,
|
||||
V1_6,
|
||||
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor),
|
||||
asmType.getInternalName(),
|
||||
asmType.internalName,
|
||||
null,
|
||||
superAsmType.getInternalName(),
|
||||
superAsmType.internalName,
|
||||
emptyArray()
|
||||
)
|
||||
|
||||
v.visitSource(element.getContainingFile().getName(), null)
|
||||
v.visitSource(element.containingFile.name, null)
|
||||
}
|
||||
|
||||
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
|
||||
override fun generateBody() {
|
||||
generateConstInstance(asmType, wrapperMethod.getReturnType()) { iv ->
|
||||
if (!"true".equals(System.getProperty("kotlin.jvm.optimize.callable.references"), ignoreCase = true)) {
|
||||
iv.invokestatic(REFLECTION, wrapperMethod.getName(), wrapperMethod.getDescriptor(), false)
|
||||
}
|
||||
}
|
||||
generateConstInstance(asmType, wrapperMethod.returnType)
|
||||
|
||||
generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) {
|
||||
load(0, OBJECT_TYPE)
|
||||
invokespecial(superAsmType.getInternalName(), "<init>", "()V", false)
|
||||
invokespecial(superAsmType.internalName, "<init>", "()V", false)
|
||||
}
|
||||
|
||||
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
|
||||
@@ -96,7 +91,7 @@ public class PropertyReferenceCodegen(
|
||||
}
|
||||
|
||||
generateMethod("property reference getName", ACC_PUBLIC, method("getName", JAVA_STRING_TYPE)) {
|
||||
aconst(target.getName().asString())
|
||||
aconst(target.name.asString())
|
||||
}
|
||||
|
||||
generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) {
|
||||
@@ -113,11 +108,11 @@ public class PropertyReferenceCodegen(
|
||||
// return type and value parameter types. However, it's created only to be able to use
|
||||
// ExpressionCodegen#intermediateValueForProperty, which is poorly coupled with everything else.
|
||||
val fakeDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(method.getName()), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(method.name), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
fakeDescriptor.initialize(null, classDescriptor.getThisAsReceiverParameter(), emptyList(), emptyList(),
|
||||
classDescriptor.builtIns.getAnyType(), Modality.OPEN, Visibilities.PUBLIC)
|
||||
fakeDescriptor.initialize(null, classDescriptor.thisAsReceiverParameter, emptyList(), emptyList(),
|
||||
classDescriptor.builtIns.anyType, Modality.OPEN, Visibilities.PUBLIC)
|
||||
|
||||
val fakeCodegen = ExpressionCodegen(
|
||||
this, FrameMap(), OBJECT_TYPE, context.intoFunction(fakeDescriptor), state, this@PropertyReferenceCodegen
|
||||
@@ -152,24 +147,26 @@ public class PropertyReferenceCodegen(
|
||||
}
|
||||
|
||||
private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) {
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.getName(), method.getDescriptor(), null, null)
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.name, method.descriptor, null, null)
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.FULL) {
|
||||
val iv = InstructionAdapter(mv)
|
||||
iv.visitCode()
|
||||
iv.generate()
|
||||
iv.areturn(method.getReturnType())
|
||||
iv.areturn(method.returnType)
|
||||
FunctionCodegen.endVisit(mv, debugString, element)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateKotlinAnnotation() {
|
||||
writeKotlinSyntheticClassAnnotation(v, state)
|
||||
|
||||
writeSyntheticClassMetadata(v)
|
||||
}
|
||||
|
||||
public fun putInstanceOnStack(): StackValue =
|
||||
StackValue.operation(wrapperMethod.getReturnType()) { iv ->
|
||||
iv.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, wrapperMethod.getReturnType().getDescriptor())
|
||||
fun putInstanceOnStack(): StackValue =
|
||||
StackValue.operation(wrapperMethod.returnType) { iv ->
|
||||
iv.getstatic(asmType.internalName, JvmAbi.INSTANCE_FIELD, wrapperMethod.returnType.descriptor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor;
|
||||
|
||||
public class RangeCodegenUtil {
|
||||
@@ -53,8 +53,8 @@ public class RangeCodegenUtil {
|
||||
ImmutableMap.Builder<FqName, PrimitiveType> rangeBuilder = ImmutableMap.builder();
|
||||
ImmutableMap.Builder<FqName, PrimitiveType> progressionBuilder = ImmutableMap.builder();
|
||||
for (PrimitiveType primitiveType : supportedRangeTypes()) {
|
||||
FqName rangeClassFqName = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Range"));
|
||||
FqName progressionClassFqName = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Progression"));
|
||||
FqName rangeClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Range"));
|
||||
FqName progressionClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Progression"));
|
||||
rangeBuilder.put(rangeClassFqName, primitiveType);
|
||||
progressionBuilder.put(progressionClassFqName, primitiveType);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ public class SamWrapperCodegen {
|
||||
samType.getJavaClassDescriptor().getContainingDeclaration(),
|
||||
fqName.shortName(),
|
||||
Modality.FINAL,
|
||||
ClassKind.CLASS,
|
||||
Collections.singleton(samType.getType()),
|
||||
SourceElement.NO_SOURCE
|
||||
);
|
||||
@@ -85,7 +86,7 @@ public class SamWrapperCodegen {
|
||||
ClassBuilder cv = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), asmType, file);
|
||||
cv.defineClass(file,
|
||||
V1_6,
|
||||
ACC_FINAL,
|
||||
ACC_FINAL | ACC_SUPER,
|
||||
asmType.getInternalName(),
|
||||
null,
|
||||
OBJECT_TYPE.getInternalName(),
|
||||
@@ -95,6 +96,8 @@ public class SamWrapperCodegen {
|
||||
|
||||
writeKotlinSyntheticClassAnnotation(cv, state);
|
||||
|
||||
WriteAnnotationUtilKt.writeSyntheticClassMetadata(cv);
|
||||
|
||||
// e.g. ASM type for Function2
|
||||
Type functionAsmType = typeMapper.mapType(functionType);
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
||||
|
||||
v.defineClass(scriptDeclaration,
|
||||
V1_6,
|
||||
ACC_PUBLIC,
|
||||
ACC_PUBLIC | ACC_SUPER,
|
||||
classType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
public abstract class SignatureCollectingClassBuilderFactory(
|
||||
abstract class SignatureCollectingClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public abstract class SignatureCollectingClassBuilderFactory(
|
||||
|
||||
override fun done() {
|
||||
for ((signature, elementsAndDescriptors) in signatures.entrySet()) {
|
||||
if (elementsAndDescriptors.size() == 1) continue // no clash
|
||||
if (elementsAndDescriptors.size == 1) continue // no clash
|
||||
handleClashingSignatures(ConflictingJvmDeclarationsData(
|
||||
classInternalName,
|
||||
classCreatedFor,
|
||||
|
||||
@@ -22,19 +22,19 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
|
||||
data public class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
|
||||
data class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
|
||||
|
||||
companion object {
|
||||
fun createInfo(element: KtElement?, internalClassName: String): SourceInfo {
|
||||
assert(element != null) { "Couldn't create source mapper for null element " + internalClassName }
|
||||
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.getContainingFile(), true)
|
||||
assert(lineNumbers != null) { "Couldn't extract line count in " + element.getContainingFile() }
|
||||
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.containingFile, true)
|
||||
assert(lineNumbers != null) { "Couldn't extract line count in " + element.containingFile }
|
||||
|
||||
//TODO hack condition for package parts cleaning
|
||||
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
|
||||
val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
|
||||
|
||||
return SourceInfo(element.getContainingKtFile().getName(), cleanedClassFqName, lineNumbers!!)
|
||||
return SourceInfo(element.getContainingKtFile().name, cleanedClassFqName, lineNumbers!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import kotlin.ArraysKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
|
||||
@@ -45,6 +47,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -502,19 +505,19 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
ReceiverValue callExtensionReceiver = (ReceiverValue) resolvedCall.getExtensionReceiver();
|
||||
if (callDispatchReceiver.exists() || callExtensionReceiver.exists()
|
||||
if (callDispatchReceiver != null || callExtensionReceiver != null
|
||||
|| isLocalFunCall(callableMethod) || isCallToMemberObjectImportedByName(resolvedCall)) {
|
||||
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
|
||||
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
|
||||
if (descriptor.getOriginal() instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
callDispatchReceiver = callExtensionReceiver;
|
||||
callExtensionReceiver = ReceiverValue.NO_RECEIVER;
|
||||
callExtensionReceiver = null;
|
||||
dispatchReceiverParameter = extensionReceiverParameter;
|
||||
extensionReceiverParameter = null;
|
||||
}
|
||||
|
||||
boolean hasExtensionReceiver = callExtensionReceiver.exists();
|
||||
boolean hasExtensionReceiver = callExtensionReceiver != null;
|
||||
StackValue dispatchReceiver = platformStaticCallIfPresent(
|
||||
genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, callDispatchReceiver, false),
|
||||
descriptor
|
||||
@@ -532,11 +535,11 @@ public abstract class StackValue {
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull ResolvedCall resolvedCall,
|
||||
@Nullable Callable callableMethod,
|
||||
ReceiverValue receiverValue,
|
||||
@Nullable ReceiverValue receiverValue,
|
||||
boolean isExtension
|
||||
) {
|
||||
if (receiver == none()) {
|
||||
if (receiverValue.exists()) {
|
||||
if (receiverValue != null) {
|
||||
return codegen.generateReceiverValue(receiverValue, false);
|
||||
}
|
||||
else if (isLocalFunCall(callableMethod) && !isExtension) {
|
||||
@@ -548,7 +551,7 @@ public abstract class StackValue {
|
||||
return singleton(((ImportedFromObjectCallableDescriptor) resolvedCall.getResultingDescriptor()).getContainingObject(), codegen.typeMapper);
|
||||
}
|
||||
}
|
||||
else if (receiverValue.exists()) {
|
||||
else if (receiverValue != null) {
|
||||
return receiver;
|
||||
}
|
||||
return none();
|
||||
@@ -597,11 +600,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
public static Field singletonViaInstance(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper, false), none());
|
||||
}
|
||||
|
||||
public static Field oldSingleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
|
||||
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true), none());
|
||||
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper), none());
|
||||
}
|
||||
|
||||
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
|
||||
@@ -770,13 +769,14 @@ public abstract class StackValue {
|
||||
private final Callable callable;
|
||||
private final boolean isGetter;
|
||||
private final ExpressionCodegen codegen;
|
||||
private final ArgumentGenerator argumentGenerator;
|
||||
private final List<ResolvedValueArgument> valueArguments;
|
||||
private final FrameMap frame;
|
||||
private final StackValue receiver;
|
||||
private final ResolvedCall<FunctionDescriptor> resolvedGetCall;
|
||||
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
|
||||
private DefaultCallMask mask;
|
||||
private DefaultCallArgs defaultArgs;
|
||||
private CallGenerator callGenerator;
|
||||
boolean isComplexOperationWithDup;
|
||||
|
||||
public CollectionElementReceiver(
|
||||
@NotNull Callable callable,
|
||||
@@ -785,7 +785,6 @@ public abstract class StackValue {
|
||||
ResolvedCall<FunctionDescriptor> resolvedSetCall,
|
||||
boolean isGetter,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
ArgumentGenerator argumentGenerator,
|
||||
List<ResolvedValueArgument> valueArguments
|
||||
) {
|
||||
super(OBJECT_TYPE);
|
||||
@@ -795,7 +794,6 @@ public abstract class StackValue {
|
||||
this.receiver = receiver;
|
||||
this.resolvedGetCall = resolvedGetCall;
|
||||
this.resolvedSetCall = resolvedSetCall;
|
||||
this.argumentGenerator = argumentGenerator;
|
||||
this.valueArguments = valueArguments;
|
||||
this.codegen = codegen;
|
||||
this.frame = codegen.myFrameMap;
|
||||
@@ -805,8 +803,25 @@ public abstract class StackValue {
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
ResolvedCall<?> call = isGetter ? resolvedGetCall : resolvedSetCall;
|
||||
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, callable);
|
||||
ArgumentGenerator generator = createArgumentGenerator();
|
||||
newReceiver.put(newReceiver.type, v);
|
||||
mask = argumentGenerator.generate(valueArguments, valueArguments);
|
||||
callGenerator.putHiddenParams();
|
||||
|
||||
defaultArgs = generator.generate(valueArguments, valueArguments);
|
||||
}
|
||||
|
||||
private ArgumentGenerator createArgumentGenerator() {
|
||||
assert callGenerator == null :
|
||||
"'putSelector' and 'createArgumentGenerator' methods should be called once for CollectionElementReceiver: " + callable;
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
|
||||
assert resolvedCall != null : "Resolved call should be non-null: " + callable;
|
||||
callGenerator =
|
||||
!isComplexOperationWithDup ? codegen.getOrCreateCallGenerator(resolvedCall) : codegen.defaultCallGenerator;
|
||||
return new CallBasedArgumentGenerator(
|
||||
codegen,
|
||||
callGenerator,
|
||||
resolvedCall.getResultingDescriptor().getValueParameters(), callable.getValueParameterTypes()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -834,7 +849,7 @@ public abstract class StackValue {
|
||||
|
||||
ReceiverValue receiverParameter = (ReceiverValue) resolvedGetCall.getExtensionReceiver();
|
||||
int receiverIndex = -1;
|
||||
if (receiverParameter.exists()) {
|
||||
if (receiverParameter != null) {
|
||||
Type type = codegen.typeMapper.mapType(receiverParameter.getType());
|
||||
receiverIndex = frame.enterTemp(type);
|
||||
v.store(receiverIndex, type);
|
||||
@@ -842,7 +857,7 @@ public abstract class StackValue {
|
||||
|
||||
ReceiverValue dispatchReceiver = resolvedGetCall.getDispatchReceiver();
|
||||
int thisIndex = -1;
|
||||
if (dispatchReceiver.exists()) {
|
||||
if (dispatchReceiver != null) {
|
||||
thisIndex = frame.enterTemp(OBJECT_TYPE);
|
||||
v.store(thisIndex, OBJECT_TYPE);
|
||||
}
|
||||
@@ -863,14 +878,14 @@ public abstract class StackValue {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
if (resolvedSetCall.getDispatchReceiver().exists()) {
|
||||
if (resolvedSetCall.getExtensionReceiver().exists()) {
|
||||
if (resolvedSetCall.getDispatchReceiver() != null) {
|
||||
if (resolvedSetCall.getExtensionReceiver() != null) {
|
||||
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, v);
|
||||
}
|
||||
v.load(realReceiverIndex, realReceiverType);
|
||||
}
|
||||
else {
|
||||
if (resolvedSetCall.getExtensionReceiver().exists()) {
|
||||
if (resolvedSetCall.getExtensionReceiver() != null) {
|
||||
v.load(realReceiverIndex, realReceiverType);
|
||||
}
|
||||
else {
|
||||
@@ -934,14 +949,22 @@ public abstract class StackValue {
|
||||
if (getter == null) {
|
||||
throw new UnsupportedOperationException("no getter specified");
|
||||
}
|
||||
CallGenerator callGenerator = codegen.defaultCallGenerator;
|
||||
CallGenerator callGenerator = getCallGenerator();
|
||||
callGenerator.genCall(getter, resolvedGetCall, genDefaultMaskIfPresent(callGenerator), codegen);
|
||||
coerceTo(type, v);
|
||||
}
|
||||
|
||||
private boolean genDefaultMaskIfPresent(CallGenerator callGenerator) {
|
||||
DefaultCallMask mask = ((CollectionElementReceiver) receiver).mask;
|
||||
return mask.generateOnStackIfNeeded(callGenerator);
|
||||
DefaultCallArgs defaultArgs = ((CollectionElementReceiver) receiver).defaultArgs;
|
||||
return defaultArgs.generateOnStackIfNeeded(callGenerator, true);
|
||||
}
|
||||
|
||||
private CallGenerator getCallGenerator() {
|
||||
CallGenerator generator = ((CollectionElementReceiver) receiver).callGenerator;
|
||||
assert generator != null :
|
||||
"CollectionElementReceiver should be putted on stack before CollectionElement:" +
|
||||
" getCall = " + resolvedGetCall + ", setCall = " + resolvedSetCall;
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -970,8 +993,8 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
if (call.getDispatchReceiver().exists()) {
|
||||
if (call.getExtensionReceiver().exists()) {
|
||||
if (call.getDispatchReceiver() != null) {
|
||||
if (call.getExtensionReceiver() != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -993,8 +1016,13 @@ public abstract class StackValue {
|
||||
|
||||
Type lastParameterType = ArraysKt.last(setter.getParameterTypes());
|
||||
coerce(topOfStackType, lastParameterType, v);
|
||||
//*Convention setter couldn't have default parameters, just getter can have it at last positions
|
||||
|
||||
getCallGenerator().afterParameterPut(lastParameterType, StackValue.onStack(lastParameterType),
|
||||
CollectionsKt.getLastIndex(setter.getValueParameterTypes()));
|
||||
|
||||
//Convention setter couldn't have default parameters, just getter can have it at last positions
|
||||
//We should remove default parameters of getter from stack*/
|
||||
//Note that it works only for non-inline case
|
||||
CollectionElementReceiver collectionElementReceiver = (CollectionElementReceiver) receiver;
|
||||
if (collectionElementReceiver.isGetter) {
|
||||
List<ResolvedValueArgument> arguments = collectionElementReceiver.valueArguments;
|
||||
@@ -1009,7 +1037,7 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
codegen.defaultCallGenerator.genCall(setter, resolvedSetCall, false, codegen);
|
||||
getCallGenerator().genCall(setter, resolvedSetCall, false, codegen);
|
||||
Type returnType = setter.getReturnType();
|
||||
if (returnType != Type.VOID_TYPE) {
|
||||
pop(v, returnType);
|
||||
@@ -1090,6 +1118,12 @@ public abstract class StackValue {
|
||||
else {
|
||||
getter.genInvokeInstruction(v);
|
||||
coerce(getter.getReturnType(), type, v);
|
||||
|
||||
KotlinType returnType = descriptor.getReturnType();
|
||||
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
|
||||
v.aconst(null);
|
||||
v.athrow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1134,6 +1168,11 @@ public abstract class StackValue {
|
||||
else {
|
||||
coerce(topOfStackType, ArraysKt.last(setter.getParameterTypes()), v);
|
||||
setter.genInvokeInstruction(v);
|
||||
|
||||
Type returnType = setter.getReturnType();
|
||||
if (returnType != Type.VOID_TYPE) {
|
||||
pop(v, returnType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1525,6 +1564,11 @@ public abstract class StackValue {
|
||||
super(value.type, value.receiver.canHaveSideEffects());
|
||||
this.originalValueWithReceiver = value;
|
||||
this.isReadOperations = isReadOperations;
|
||||
if (value instanceof CollectionElement) {
|
||||
if (value.receiver instanceof CollectionElementReceiver) {
|
||||
((CollectionElementReceiver) value.receiver).isComplexOperationWithDup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ class CoercionValue(
|
||||
}
|
||||
|
||||
|
||||
public class StackValueWithLeaveTask(
|
||||
class StackValueWithLeaveTask(
|
||||
val stackValue: StackValue,
|
||||
val leaveTasks: (StackValue) -> Unit
|
||||
) : StackValue(stackValue.type) {
|
||||
|
||||
@@ -22,15 +22,15 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
public interface WrappedAnnotated : Annotated {
|
||||
public val originalAnnotated: Annotated
|
||||
interface WrappedAnnotated : Annotated {
|
||||
val originalAnnotated: Annotated
|
||||
}
|
||||
|
||||
public class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated {
|
||||
class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated {
|
||||
override fun getAnnotations() = actual
|
||||
}
|
||||
|
||||
public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
|
||||
class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
|
||||
private val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
|
||||
|
||||
override fun getAnnotations() = annotations
|
||||
@@ -52,4 +52,4 @@ public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotate
|
||||
}
|
||||
}
|
||||
|
||||
public class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)
|
||||
class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)
|
||||
@@ -98,6 +98,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
correctContainerForLambda(callableDescriptor, element),
|
||||
Name.special("<closure-" + simpleName + ">"),
|
||||
Modality.FINAL,
|
||||
ClassKind.CLASS,
|
||||
supertypes,
|
||||
KotlinSourceElementKt.toSourceElement(element)
|
||||
);
|
||||
@@ -128,7 +129,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
if (element instanceof KtObjectDeclaration &&
|
||||
element.getParent() instanceof KtObjectLiteralExpression &&
|
||||
child instanceof KtDelegationSpecifierList) {
|
||||
child instanceof KtSuperTypeList) {
|
||||
// If we're passing an anonymous object's super call, it means "container" is ConstructorDescriptor of that object.
|
||||
// To reach outer context, we should call getContainingDeclaration() twice
|
||||
// TODO: this is probably not entirely correct, mostly because DECLARATION_TO_DESCRIPTOR can return null
|
||||
@@ -177,7 +178,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
@Override
|
||||
public void visitEnumEntry(@NotNull KtEnumEntry enumEntry) {
|
||||
if (enumEntry.getDeclarations().isEmpty()) {
|
||||
for (KtDelegationSpecifier specifier : enumEntry.getDelegationSpecifiers()) {
|
||||
for (KtSuperTypeListEntry specifier : enumEntry.getSuperTypeListEntries()) {
|
||||
specifier.accept(this);
|
||||
}
|
||||
return;
|
||||
@@ -247,7 +248,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
String name = inventAnonymousClassName();
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
KtDelegationSpecifierList delegationSpecifierList = object.getDelegationSpecifierList();
|
||||
KtSuperTypeList delegationSpecifierList = object.getSuperTypeList();
|
||||
if (delegationSpecifierList != null) {
|
||||
delegationSpecifierList.accept(this);
|
||||
}
|
||||
@@ -263,8 +264,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression) {
|
||||
KtFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
||||
public void visitLambdaExpression(@NotNull KtLambdaExpression lambdaExpression) {
|
||||
KtFunctionLiteral functionLiteral = lambdaExpression.getFunctionLiteral();
|
||||
FunctionDescriptor functionDescriptor =
|
||||
(FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, functionLiteral);
|
||||
// working around a problem with shallow analysis
|
||||
@@ -277,7 +278,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
classStack.push(classDescriptor);
|
||||
nameStack.push(name);
|
||||
super.visitFunctionLiteralExpression(expression);
|
||||
super.visitLambdaExpression(lambdaExpression);
|
||||
nameStack.pop();
|
||||
classStack.pop();
|
||||
}
|
||||
@@ -431,8 +432,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDelegationToSuperCallSpecifier(@NotNull KtDelegatorToSuperCall call) {
|
||||
super.visitDelegationToSuperCallSpecifier(call);
|
||||
public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
|
||||
super.visitSuperTypeCallEntry(call);
|
||||
checkSamCall(call);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ public final class PsiCodegenPredictor {
|
||||
// TODO: Method won't work for declarations inside companion objects
|
||||
// TODO: Method won't give correct class name for traits implementations
|
||||
|
||||
if (declaration instanceof KtPropertyAccessor) {
|
||||
return getPredefinedJvmInternalName(((KtPropertyAccessor) declaration).getProperty(), fileClassesProvider);
|
||||
}
|
||||
KtDeclaration parentDeclaration = KtStubbedPsiUtil.getContainingDeclaration(declaration);
|
||||
|
||||
String parentInternalName;
|
||||
@@ -73,8 +76,8 @@ public final class PsiCodegenPredictor {
|
||||
else {
|
||||
KtFile containingFile = declaration.getContainingKtFile();
|
||||
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
Name name = ((KtNamedFunction) declaration).getNameAsName();
|
||||
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) {
|
||||
Name name = ((KtNamedDeclaration) declaration).getNameAsName();
|
||||
return name == null ? null : FileClasses.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmDescriptor
|
||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -43,15 +43,14 @@ class BridgeForBuiltinSpecial<Signature>(
|
||||
)
|
||||
|
||||
object BuiltinSpecialBridgesUtil {
|
||||
@JvmStatic
|
||||
public fun <Signature> generateBridgesForBuiltinSpecial(
|
||||
@JvmStatic fun <Signature> generateBridgesForBuiltinSpecial(
|
||||
function: FunctionDescriptor,
|
||||
signatureByDescriptor: (FunctionDescriptor) -> Signature
|
||||
): Set<BridgeForBuiltinSpecial<Signature>> {
|
||||
|
||||
val functionHandle = DescriptorBasedFunctionHandle(function)
|
||||
val fake = !functionHandle.isDeclaration
|
||||
val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmDescriptor()!!
|
||||
val overriddenBuiltin = function.getOverriddenBuiltinReflectingJvmDescriptor()!!
|
||||
|
||||
val reachableDeclarations = findAllReachableDeclarations(function)
|
||||
|
||||
@@ -93,13 +92,12 @@ object BuiltinSpecialBridgesUtil {
|
||||
return bridges
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
|
||||
@JvmStatic fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
|
||||
signatureByDescriptor: (FunctionDescriptor) -> Signature
|
||||
): Boolean {
|
||||
if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false
|
||||
|
||||
val builtin = getOverriddenBuiltinWithDifferentJvmDescriptor()!!
|
||||
val builtin = getOverriddenBuiltinReflectingJvmDescriptor()!!
|
||||
return signatureByDescriptor(this) == signatureByDescriptor(builtin)
|
||||
}
|
||||
}
|
||||
@@ -134,7 +132,7 @@ private fun <Signature> needGenerateSpecialBridge(
|
||||
|| originalOverridden.containingDeclaration is JavaClassDescriptor
|
||||
|| DescriptorUtils.isInterface(originalOverridden.containingDeclaration)) return@firstOverridden false
|
||||
|
||||
val overriddenSpecial = originalOverridden.getOverriddenBuiltinWithDifferentJvmDescriptor()?.original ?: return@firstOverridden false
|
||||
val overriddenSpecial = originalOverridden.getOverriddenBuiltinReflectingJvmDescriptor()?.original ?: return@firstOverridden false
|
||||
|
||||
signatureByDescriptor(originalOverridden) != signatureByDescriptor(overriddenSpecial)
|
||||
} != null) return false
|
||||
@@ -143,7 +141,7 @@ private fun <Signature> needGenerateSpecialBridge(
|
||||
&& signatureByDescriptor(it) == overriddenBuiltinSignature }
|
||||
}
|
||||
|
||||
public fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
|
||||
fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
|
||||
element: KtElement,
|
||||
bindingContext: BindingContext
|
||||
): Boolean {
|
||||
|
||||
@@ -47,7 +47,7 @@ private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<Pa
|
||||
mapping.findPackageParts(qualifier)?.run { parts.remove(name) }
|
||||
}
|
||||
|
||||
return (this + mapping.packageFqName2Parts.values())
|
||||
return (this + mapping.packageFqName2Parts.values)
|
||||
.groupBy { it.packageFqName }
|
||||
.map {
|
||||
val (packageFqName, packageParts) = it
|
||||
|
||||
@@ -17,17 +17,29 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
fun generateIsCheck(
|
||||
v: InstructionAdapter,
|
||||
type: KotlinType,
|
||||
generateInstanceOfInstruction: (InstructionAdapter) -> Unit
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type
|
||||
) {
|
||||
if (type.isMarkedNullable) {
|
||||
if (TypeUtils.isNullableType(kotlinType)) {
|
||||
val nope = Label()
|
||||
val end = Label()
|
||||
|
||||
@@ -36,7 +48,8 @@ fun generateIsCheck(
|
||||
|
||||
ifnull(nope)
|
||||
|
||||
generateInstanceOfInstruction(this)
|
||||
TypeIntrinsics.instanceOf(this, kotlinType, asmType)
|
||||
|
||||
goTo(end)
|
||||
|
||||
mark(nope)
|
||||
@@ -47,10 +60,69 @@ fun generateIsCheck(
|
||||
}
|
||||
}
|
||||
else {
|
||||
generateInstanceOfInstruction(v)
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
}
|
||||
}
|
||||
|
||||
fun generateAsCast(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
isSafe: Boolean
|
||||
) {
|
||||
if (!isSafe) {
|
||||
if (!TypeUtils.isNullableType(kotlinType)) {
|
||||
generateNullCheckForNonSafeAs(v, kotlinType)
|
||||
}
|
||||
}
|
||||
else {
|
||||
with(v) {
|
||||
dup()
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
val ok = Label()
|
||||
ifne(ok)
|
||||
pop()
|
||||
aconst(null)
|
||||
mark(ok)
|
||||
}
|
||||
}
|
||||
|
||||
public fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
|
||||
TypeIntrinsics.checkcast(v, kotlinType, asmType, isSafe)
|
||||
}
|
||||
|
||||
private fun generateNullCheckForNonSafeAs(
|
||||
v: InstructionAdapter,
|
||||
type: KotlinType
|
||||
) {
|
||||
with(v) {
|
||||
dup()
|
||||
val nonnull = Label()
|
||||
ifnonnull(nonnull)
|
||||
AsmUtil.genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
|
||||
mark(nonnull)
|
||||
}
|
||||
}
|
||||
|
||||
fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
|
||||
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }
|
||||
|
||||
fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) {
|
||||
val descriptor = state.bindingContext.get(BindingContext.CLASS, companion)
|
||||
|
||||
if (descriptor == null || ErrorUtils.isError(descriptor)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
||||
return
|
||||
}
|
||||
val properties = companion.declarations.filterIsInstance<KtProperty>()
|
||||
|
||||
properties.forEach {
|
||||
val variableDescriptor = state.bindingContext.get(BindingContext.VARIABLE, it)
|
||||
if (variableDescriptor is PropertyDescriptor) {
|
||||
outerContext.getFieldName(variableDescriptor, it.hasDelegate())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.context;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ReadOnly;
|
||||
import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -27,8 +28,8 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.storage.NullableLazyValue;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
@@ -37,7 +38,7 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.NEED_SYNTHETIC_ACCESSOR;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
|
||||
@@ -267,6 +268,10 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return new MultifileClassFacadeContext(descriptor, this, multifileClassType, filePartType);
|
||||
}
|
||||
|
||||
public ClassContext intoDefaultImplsClass(ClassDescriptor descriptor, ClassContext interfaceContext, GenerationState state) {
|
||||
return new DefaultImplsClassContext(state.getTypeMapper(), descriptor, OwnerKind.DEFAULT_IMPLS, this, null, interfaceContext);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) {
|
||||
if (descriptor.isCompanionObject()) {
|
||||
@@ -279,11 +284,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
ClassContext classContext = new ClassContext(state.getTypeMapper(), descriptor, kind, this, null);
|
||||
|
||||
//We can't call descriptor.getCompanionObjectDescriptor() on light class generation
|
||||
// because it triggers companion light class generation via putting it to BindingContext.CLASS
|
||||
// (so MemberCodegen doesn't skip it in genClassOrObject).
|
||||
if (state.getTypeMapper().getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES &&
|
||||
descriptor.getCompanionObjectDescriptor() != null) {
|
||||
if (descriptor.getCompanionObjectDescriptor() != null) {
|
||||
//We need to create companion object context ahead of time
|
||||
// because otherwise we can't generate synthetic accessor for private members in companion object
|
||||
classContext.intoClass(descriptor.getCompanionObjectDescriptor(), OwnerKind.IMPLEMENTATION, state);
|
||||
@@ -298,12 +299,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
@NotNull
|
||||
public MethodContext intoFunction(FunctionDescriptor descriptor) {
|
||||
return new MethodContext(descriptor, getContextKind(), this, null, false);
|
||||
return new MethodContext(descriptor, getContextKind(), this, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor) {
|
||||
return new MethodContext(descriptor, getContextKind(), this, null, true);
|
||||
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor, boolean isCrossInline) {
|
||||
return new InlineLambdaContext(descriptor, getContextKind(), this, null, isCrossInline);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -365,11 +366,24 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
private <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallTarget);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessorForSuperCallIfNeeded(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
if (superCallTarget != null && !isJvmInterface(descriptor.getContainingDeclaration())) {
|
||||
CodegenContext afterInline = getFirstCrossInlineOrNonInlineContext();
|
||||
CodegenContext c = afterInline.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + descriptor;
|
||||
if (c != afterInline.getParentContext()) {
|
||||
return (D) c.getAccessor(descriptor, superCallTarget);
|
||||
}
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessor(
|
||||
@NotNull D possiblySubstitutedDescriptor,
|
||||
@@ -502,32 +516,27 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ReadOnly
|
||||
public Collection<? extends AccessorForCallableDescriptor<?>> getAccessors() {
|
||||
return accessors == null ? Collections.<AccessorForCallableDescriptor<CallableMemberDescriptor>>emptySet() : accessors.values();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D accessibleDescriptor(
|
||||
@NotNull D descriptor,
|
||||
@Nullable ClassDescriptor superCallTarget
|
||||
) {
|
||||
CodegenContext properContext = getFirstCrossInlineOrNonInlineContext();
|
||||
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
|
||||
boolean isInliningContext = isInlineMethodContext();
|
||||
boolean isInliningContext = properContext.isInlineMethodContext();
|
||||
if (!isInliningContext && (
|
||||
!hasThisDescriptor() ||
|
||||
enclosing == getThisDescriptor() ||
|
||||
enclosing == getClassOrPackageParentContext().getContextDescriptor())) {
|
||||
!properContext.hasThisDescriptor() ||
|
||||
enclosing == properContext.getThisDescriptor() ||
|
||||
enclosing == properContext.getClassOrPackageParentContext().getContextDescriptor())) {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
return accessibleDescriptorIfNeeded(descriptor, superCallTarget, isInliningContext);
|
||||
}
|
||||
|
||||
public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
|
||||
if (hasThisDescriptor() && Boolean.TRUE.equals(bindingContext.get(NEED_SYNTHETIC_ACCESSOR, descriptor))) {
|
||||
// Not a super call because neither constructors nor private members can be targets of super calls
|
||||
accessibleDescriptorIfNeeded(descriptor, /* superCallTarget = */ null, false);
|
||||
}
|
||||
return (D) properContext.accessibleDescriptorIfNeeded(descriptor, superCallTarget, isInliningContext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -601,6 +610,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
boolean withinInline,
|
||||
boolean isSuperCall
|
||||
) {
|
||||
if (AnnotationUtilKt.isInlineOnly(unwrappedDescriptor)) return false;
|
||||
|
||||
return isSuperCall && withinInline ||
|
||||
(accessFlag & ACC_PRIVATE) != 0 ||
|
||||
((accessFlag & ACC_PROTECTED) != 0 &&
|
||||
@@ -632,7 +643,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CodegenContext findChildContext(@NotNull DeclarationDescriptor child) {
|
||||
protected CodegenContext findChildContext(@NotNull DeclarationDescriptor child) {
|
||||
return childContexts == null ? null : childContexts.get(child);
|
||||
}
|
||||
|
||||
@@ -640,18 +651,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return value instanceof StackValue.Field && ((StackValue.Field) value).isStaticPut;
|
||||
}
|
||||
|
||||
private boolean isInsideInliningContext() {
|
||||
CodegenContext current = this;
|
||||
while (current != null) {
|
||||
if (current instanceof MethodContext && ((MethodContext) current).isInlineFunction()) {
|
||||
return true;
|
||||
}
|
||||
current = current.getParentContext();
|
||||
}
|
||||
public boolean isInlineMethodContext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInlineMethodContext() {
|
||||
return this instanceof MethodContext && ((MethodContext) this).isInlineFunction();
|
||||
@NotNull
|
||||
public CodegenContext getFirstCrossInlineOrNonInlineContext() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,24 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.context
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
|
||||
public object CodegenContextUtil {
|
||||
@JvmStatic
|
||||
public fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
|
||||
object CodegenContextUtil {
|
||||
@JvmStatic fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
|
||||
when (owner) {
|
||||
is DelegatingFacadeContext -> owner.delegateToClassType
|
||||
is MultifileClassFacadeContext -> owner.filePartType
|
||||
is DelegatingToPartContext -> owner.implementationOwnerClassType
|
||||
else -> null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun getImplementationClassShortName(owner: CodegenContext<*>): String? =
|
||||
getImplementationOwnerClassType(owner)?.let { AsmUtil.shortNameByAsmType(it) }
|
||||
|
||||
@JvmStatic
|
||||
public fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
|
||||
owner !is DelegatingFacadeContext
|
||||
}
|
||||
@JvmStatic fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
|
||||
owner !is MultifileClassFacadeContext
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ConstructorContext extends MethodContext {
|
||||
@NotNull CodegenContext parent,
|
||||
@Nullable MutableClosure closure
|
||||
) {
|
||||
super(contextDescriptor, kind, parent, closure, false);
|
||||
super(contextDescriptor, kind, parent, closure);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user