mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-14 15:52:18 +00:00
Compare commits
725 Commits
igotti/com
...
1.0.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bff511f24 | ||
|
|
3392fbf512 | ||
|
|
69d824099f | ||
|
|
a7fac37bc0 | ||
|
|
e5151113ad | ||
|
|
e203ee4889 | ||
|
|
c02ecf63f6 | ||
|
|
b69f87c7df | ||
|
|
6a8439611d | ||
|
|
90d306a954 | ||
|
|
a82716ce89 | ||
|
|
52a81bf01f | ||
|
|
ca94d1ba23 | ||
|
|
c8d123ee53 | ||
|
|
87a44f31d3 | ||
|
|
10a429abf0 | ||
|
|
d99035e27d | ||
|
|
b0a275095f | ||
|
|
3be06cea65 | ||
|
|
e87a0bd9be | ||
|
|
61bc0ec6e7 | ||
|
|
194aea8cdb | ||
|
|
a1d9a25107 | ||
|
|
cceeaeb431 | ||
|
|
fa144b0ce2 | ||
|
|
dfebdafc2a | ||
|
|
35050f4e0f | ||
|
|
2b87f8ebe3 | ||
|
|
95239e59c0 | ||
|
|
68d0d84f50 | ||
|
|
81a8e6a699 | ||
|
|
4ec4914504 | ||
|
|
6274c6b7c5 | ||
|
|
dc90ec9740 | ||
|
|
f4486beb19 | ||
|
|
e8050656ad | ||
|
|
2b6f07563c | ||
|
|
a841f87142 | ||
|
|
4441323b45 | ||
|
|
4a0a440a7d | ||
|
|
1912783f94 | ||
|
|
3373d544de | ||
|
|
a5a5fe5d50 | ||
|
|
d9584d2788 | ||
|
|
2ea3980e78 | ||
|
|
28b9d3e835 | ||
|
|
911afee1a6 | ||
|
|
84ca283411 | ||
|
|
29e450e5fe | ||
|
|
9ba8ecd368 | ||
|
|
7d6466dafd | ||
|
|
8989ccc110 | ||
|
|
e23029d26b | ||
|
|
3274cc586e | ||
|
|
1039545f25 | ||
|
|
2d15e7851d | ||
|
|
18b21e292c | ||
|
|
e1ebaae077 | ||
|
|
2f57c48873 | ||
|
|
bfb1a1ecb5 | ||
|
|
6a61dddc33 | ||
|
|
3c4009305d | ||
|
|
797a36a73f | ||
|
|
9c39ec682e | ||
|
|
ee985e623a | ||
|
|
0d5e4ee98e | ||
|
|
a95f890e27 | ||
|
|
54f060ba1b | ||
|
|
b9c6f546b0 | ||
|
|
d2ff82073c | ||
|
|
2b694c9f31 | ||
|
|
2ef3d7eeae | ||
|
|
a8b88b64dd | ||
|
|
aedbc79c75 | ||
|
|
706f61295f | ||
|
|
2866497203 | ||
|
|
b48c039165 | ||
|
|
43eb65fe0f | ||
|
|
b83a58b16b | ||
|
|
99a95f7988 | ||
|
|
cfdb98558a | ||
|
|
4940d3ba12 | ||
|
|
710564805c | ||
|
|
b34ee4ebb8 | ||
|
|
c0db8e0c0b | ||
|
|
2744309af1 | ||
|
|
b54b0daf0a | ||
|
|
cdedf1dfed | ||
|
|
80f5852eb4 | ||
|
|
cb8fe96435 | ||
|
|
4e2d35ae8b | ||
|
|
2ff53e67d9 | ||
|
|
876a07fdcc | ||
|
|
cd5974075e | ||
|
|
571eead43a | ||
|
|
185db4c4d5 | ||
|
|
0819f2c1f4 | ||
|
|
c411141e82 | ||
|
|
8df023dec1 | ||
|
|
619dccc80e | ||
|
|
b1a0b07357 | ||
|
|
af4f5f603e | ||
|
|
49d8daa376 | ||
|
|
8b3ec4c4b8 | ||
|
|
754e97815a | ||
|
|
25e8704d32 | ||
|
|
4f41cdd771 | ||
|
|
b639f71fb8 | ||
|
|
2f70b2f52c | ||
|
|
94d4b3f336 | ||
|
|
d4116b54ac | ||
|
|
886cf21cc9 | ||
|
|
4d44e1553c | ||
|
|
6967711c52 | ||
|
|
9f3b7003e3 | ||
|
|
9ca81d5b56 | ||
|
|
942f6d45cd | ||
|
|
0936bf7256 | ||
|
|
7df72775b7 | ||
|
|
df1231d75f | ||
|
|
6eb5a5100d | ||
|
|
99b24227ce | ||
|
|
ffa04e11a8 | ||
|
|
31e8fe51a6 | ||
|
|
7cc6b9b910 | ||
|
|
ed23aa9bc0 | ||
|
|
b09b5a9a28 | ||
|
|
a084c1d395 | ||
|
|
af1b26b993 | ||
|
|
00d8c26160 | ||
|
|
21a32408cf | ||
|
|
3321e904b3 | ||
|
|
5e85e85a29 | ||
|
|
765bd44207 | ||
|
|
a77f4dfb8e | ||
|
|
c3e38dd594 | ||
|
|
21952a64d3 | ||
|
|
602b19bf90 | ||
|
|
6804bd6985 | ||
|
|
2044bc9f94 | ||
|
|
0aa70fc3b5 | ||
|
|
6356957bfb | ||
|
|
9a50a0b4b9 | ||
|
|
2eaaf9c14a | ||
|
|
9a17999750 | ||
|
|
7d501714a3 | ||
|
|
761116563d | ||
|
|
f2e5d4b699 | ||
|
|
2db7562920 | ||
|
|
7e2865f500 | ||
|
|
8069aca614 | ||
|
|
4dbac59c6e | ||
|
|
32ee3f2934 | ||
|
|
b2851cdba8 | ||
|
|
7c9a94d674 | ||
|
|
cc90e80794 | ||
|
|
fad9a9decb | ||
|
|
3c88ac45f6 | ||
|
|
cd460987dc | ||
|
|
9c80f87794 | ||
|
|
477b1cf151 | ||
|
|
53e6139def | ||
|
|
0c6602ab84 | ||
|
|
ca66f1f29b | ||
|
|
e195ae2516 | ||
|
|
ac8c749af8 | ||
|
|
15b39f7427 | ||
|
|
2e38fbd274 | ||
|
|
e923f2ed42 | ||
|
|
2ffad4b5fa | ||
|
|
18d6427ff2 | ||
|
|
9fa7e0bc96 | ||
|
|
d4f28855d5 | ||
|
|
c0f6cee914 | ||
|
|
e2c2f8e684 | ||
|
|
6003dda5e5 | ||
|
|
d6894e07b1 | ||
|
|
873795ff54 | ||
|
|
d035645a8c | ||
|
|
dfa286394b | ||
|
|
3c963b040e | ||
|
|
f36180c33d | ||
|
|
1b226d1d7a | ||
|
|
66530e5e7a | ||
|
|
96f704c348 | ||
|
|
06032d33d4 | ||
|
|
4eeea9b960 | ||
|
|
dcf42e2e4a | ||
|
|
ce3e98c8bf | ||
|
|
17b8bac308 | ||
|
|
86a836432a | ||
|
|
bea86db6b5 | ||
|
|
9eff617bea | ||
|
|
822071aecf | ||
|
|
3731e170e4 | ||
|
|
aab4d9e8e2 | ||
|
|
85a89cb80b | ||
|
|
1164dec297 | ||
|
|
ff82155f93 | ||
|
|
35bc25577a | ||
|
|
30ba7689db | ||
|
|
2319ef2d8d | ||
|
|
4526678cb4 | ||
|
|
f4538bc3a6 | ||
|
|
2475dc5151 | ||
|
|
388dadcf6d | ||
|
|
33a1efc624 | ||
|
|
28ada3bf30 | ||
|
|
0b1a2194cb | ||
|
|
b35dd6b026 | ||
|
|
a9830b2d28 | ||
|
|
18913925d9 | ||
|
|
dcdf0cc33e | ||
|
|
3af211275b | ||
|
|
de1ff80486 | ||
|
|
3eb80015c7 | ||
|
|
2205227f47 | ||
|
|
4b77ee5feb | ||
|
|
6d21c3d145 | ||
|
|
23b7bb8fba | ||
|
|
f03816ef1b | ||
|
|
cb696b31ce | ||
|
|
2ae4d2a2fb | ||
|
|
470600c2ef | ||
|
|
cddcf025b5 | ||
|
|
51015965f2 | ||
|
|
37dc0aeeac | ||
|
|
2179ee82a9 | ||
|
|
696475e6bf | ||
|
|
dbc54e2c52 | ||
|
|
5c78acc38c | ||
|
|
dd4c370c57 | ||
|
|
421ea3b0c5 | ||
|
|
f6ad3d92f5 | ||
|
|
5675b8b4f6 | ||
|
|
87d07924da | ||
|
|
e45e3dd652 | ||
|
|
0f1e21cdf8 | ||
|
|
5ad50f837a | ||
|
|
3cb1a71b75 | ||
|
|
2166547123 | ||
|
|
0936839410 | ||
|
|
c0d094b1e3 | ||
|
|
654700694a | ||
|
|
e7b7628f6c | ||
|
|
a304ffd0c9 | ||
|
|
b983312d0a | ||
|
|
53ce2d0446 | ||
|
|
3e19c09d57 | ||
|
|
2b6ddb1608 | ||
|
|
54f59fdc3d | ||
|
|
2486da41d8 | ||
|
|
2ab89ea65c | ||
|
|
dda6330be8 | ||
|
|
78f4f20080 | ||
|
|
00ce8b3fc1 | ||
|
|
78d62b2985 | ||
|
|
909bc0161c | ||
|
|
34dfadd278 | ||
|
|
e8a92150b4 | ||
|
|
a72d63a8c9 | ||
|
|
72f6f9b5d7 | ||
|
|
2224702216 | ||
|
|
ac32cd83c1 | ||
|
|
07ea37022a | ||
|
|
f74bd75dfa | ||
|
|
a7074fe7a8 | ||
|
|
cacbd4c553 | ||
|
|
a475da5256 | ||
|
|
5d63e2346f | ||
|
|
713fdcd409 | ||
|
|
82a7fc6c29 | ||
|
|
52a97a0b19 | ||
|
|
1938b436a1 | ||
|
|
c70cfd28ca | ||
|
|
67db7ab151 | ||
|
|
7a76e4e38b | ||
|
|
03040a71f3 | ||
|
|
4c7e596897 | ||
|
|
60fb5c7f29 | ||
|
|
b9d630c7ac | ||
|
|
0b6adb5c1e | ||
|
|
e57427a246 | ||
|
|
d48294e8c7 | ||
|
|
944a4446ff | ||
|
|
022ef6410d | ||
|
|
3951b6f719 | ||
|
|
96e2deab25 | ||
|
|
5872aeb375 | ||
|
|
74f7e9f955 | ||
|
|
caf87fbab2 | ||
|
|
782f4bffbf | ||
|
|
a020870de3 | ||
|
|
bff1963f9e | ||
|
|
1bcc173e36 | ||
|
|
9b59d0de7a | ||
|
|
1124fddb9e | ||
|
|
55b158f7d5 | ||
|
|
d6addc4ea5 | ||
|
|
743ee4f278 | ||
|
|
e14efcebc0 | ||
|
|
886de1d9bf | ||
|
|
cee494eaf9 | ||
|
|
560b7c5be3 | ||
|
|
9717eb5172 | ||
|
|
0d97f96b0e | ||
|
|
bfbde9042d | ||
|
|
d07b0fcb8d | ||
|
|
452932b55c | ||
|
|
dd6da009d9 | ||
|
|
461fdad5df | ||
|
|
b2f428d5b6 | ||
|
|
6c9cdd82d3 | ||
|
|
37d76c4866 | ||
|
|
6806b0813a | ||
|
|
56a8ea3492 | ||
|
|
195acce366 | ||
|
|
b5ee06be1f | ||
|
|
efbecc9fb2 | ||
|
|
fa3a7f056a | ||
|
|
833cf8267f | ||
|
|
ad6f2de8a1 | ||
|
|
97228e5ac4 | ||
|
|
bf3ada0592 | ||
|
|
db2fa0fbdf | ||
|
|
3db9871a13 | ||
|
|
84b573d1ea | ||
|
|
b043906395 | ||
|
|
f59bf2d8ef | ||
|
|
0b44a90823 | ||
|
|
8233c5d458 | ||
|
|
89059bda04 | ||
|
|
c19dbefe1b | ||
|
|
c07350227e | ||
|
|
c2cf56b137 | ||
|
|
6e967b1e0b | ||
|
|
e9fe329415 | ||
|
|
7131238c86 | ||
|
|
7ae2ab8437 | ||
|
|
4be84d8d4c | ||
|
|
caf0184e2f | ||
|
|
6e5dd83b67 | ||
|
|
90be470172 | ||
|
|
6c5a3b7734 | ||
|
|
f493a42d27 | ||
|
|
95d022c38d | ||
|
|
4ef75eb110 | ||
|
|
7f1674ee50 | ||
|
|
a48d4dc9be | ||
|
|
ab23195d54 | ||
|
|
407405f305 | ||
|
|
abb7c4a13a | ||
|
|
890ef8c952 | ||
|
|
6dcdd7f8a3 | ||
|
|
6e19b7dc30 | ||
|
|
93b7e84ee8 | ||
|
|
9542fd3e7c | ||
|
|
44fbae0530 | ||
|
|
bc0d7cf64e | ||
|
|
e26410a307 | ||
|
|
9da5de9271 | ||
|
|
f3fad4ad07 | ||
|
|
2898fce39d | ||
|
|
522df6f1f8 | ||
|
|
2aae0a1a7d | ||
|
|
4e5e2ae08e | ||
|
|
f86e01fca8 | ||
|
|
709aa92bd8 | ||
|
|
76bf4a71e7 | ||
|
|
4f771fdb55 | ||
|
|
3b4069c996 | ||
|
|
bd1d4034fd | ||
|
|
18636e6ae7 | ||
|
|
4d6a69011e | ||
|
|
b1d84bc89b | ||
|
|
40509366b8 | ||
|
|
4de95d5abf | ||
|
|
e6fd73c500 | ||
|
|
eccbb499fe | ||
|
|
613e5b1968 | ||
|
|
9e10893462 | ||
|
|
dbe179ebde | ||
|
|
0d129f9d10 | ||
|
|
0745f2e4bf | ||
|
|
81ef3c5684 | ||
|
|
daad2a529c | ||
|
|
01717e8f8c | ||
|
|
ff389f99a3 | ||
|
|
89910692d0 | ||
|
|
1bd0c54bd6 | ||
|
|
2a7c0db825 | ||
|
|
c0ca947cbb | ||
|
|
ac8afae2e0 | ||
|
|
e3aa5d183f | ||
|
|
cc9adf15e1 | ||
|
|
192a8edbee | ||
|
|
d40f851e52 | ||
|
|
2a9805f77c | ||
|
|
eaef198878 | ||
|
|
d553327c7e | ||
|
|
366be38453 | ||
|
|
88cb987558 | ||
|
|
1dad7f1625 | ||
|
|
ffbd6b41a7 | ||
|
|
cf01144fa9 | ||
|
|
97f2b0df3e | ||
|
|
4fc3c6b41f | ||
|
|
fcf19b9db4 | ||
|
|
38bcacd988 | ||
|
|
a37e7a782b | ||
|
|
413ab743cd | ||
|
|
92c3b1f570 | ||
|
|
543ae45eec | ||
|
|
69156f22fb | ||
|
|
305fe89d30 | ||
|
|
6be6726b5d | ||
|
|
23ce84721c | ||
|
|
5000772ddc | ||
|
|
f197ee5363 | ||
|
|
695e20a48e | ||
|
|
0ad6a3802b | ||
|
|
bf1e2bd0dd | ||
|
|
20a7f83915 | ||
|
|
fa2e925ed7 | ||
|
|
d262e462bb | ||
|
|
02fa66fbaa | ||
|
|
c081d0b9a9 | ||
|
|
9085175fb3 | ||
|
|
d4b17dbdfa | ||
|
|
bde4b943fe | ||
|
|
6b8a54b230 | ||
|
|
15c09c483e | ||
|
|
4ba9433187 | ||
|
|
b5d89c549c | ||
|
|
a796b66e05 | ||
|
|
64fa595716 | ||
|
|
ec78ab5ffa | ||
|
|
b75677cccd | ||
|
|
fdf15407ea | ||
|
|
827b74fc06 | ||
|
|
06c6234561 | ||
|
|
fdbf6f10e8 | ||
|
|
38d7a357fc | ||
|
|
2b6b7181e1 | ||
|
|
5117bf1184 | ||
|
|
e64649fb0a | ||
|
|
167dd1a927 | ||
|
|
f9722393dc | ||
|
|
bef65e4283 | ||
|
|
dcaf6dcef5 | ||
|
|
0cc3f4be3d | ||
|
|
5f8220c937 | ||
|
|
385d335042 | ||
|
|
571f31c743 | ||
|
|
626e6657d9 | ||
|
|
fb5390a738 | ||
|
|
a4176b0cbb | ||
|
|
d93d4dc38a | ||
|
|
4f6317694e | ||
|
|
4f6f3879c6 | ||
|
|
eb84b61b69 | ||
|
|
0e0dbb25b5 | ||
|
|
dd740b6e6b | ||
|
|
7e359015d6 | ||
|
|
1714b1c092 | ||
|
|
cc7f7103be | ||
|
|
4fc118b20a | ||
|
|
5427d81aa7 | ||
|
|
b151a5f6e8 | ||
|
|
73afad23b3 | ||
|
|
d4b27e2649 | ||
|
|
f1131da000 | ||
|
|
73a9c1568f | ||
|
|
529777fa0b | ||
|
|
79b1764554 | ||
|
|
b80115be88 | ||
|
|
3d0d002bd6 | ||
|
|
f1c7b50814 | ||
|
|
4d35991a1c | ||
|
|
c23e8713a4 | ||
|
|
518a030fe5 | ||
|
|
2255bde6e1 | ||
|
|
2c7714e5d9 | ||
|
|
6c4223ee44 | ||
|
|
55c7c37da4 | ||
|
|
0ad6c8cefe | ||
|
|
4e5e6c0b46 | ||
|
|
51c49eba48 | ||
|
|
5113cb2935 | ||
|
|
42ba9cf03f | ||
|
|
28089434ad | ||
|
|
1726a31c6b | ||
|
|
b5523e32e2 | ||
|
|
3e9da49c2f | ||
|
|
aaae96bba6 | ||
|
|
c452dd0491 | ||
|
|
93ed1705b9 | ||
|
|
28c7244901 | ||
|
|
0f88682587 | ||
|
|
c5b1256960 | ||
|
|
c79731dbee | ||
|
|
4ffa2eaf39 | ||
|
|
b3ccdbc626 | ||
|
|
3200a17c51 | ||
|
|
7be9805c3d | ||
|
|
d214e347ea | ||
|
|
395d359c7f | ||
|
|
046bb7348c | ||
|
|
3ee5272011 | ||
|
|
e8e33b2636 | ||
|
|
47bb721097 | ||
|
|
ed7197e519 | ||
|
|
c3a9007ac3 | ||
|
|
343192c2ae | ||
|
|
d2fc64ff56 | ||
|
|
ee5b01be5c | ||
|
|
d062b478bd | ||
|
|
761d171de1 | ||
|
|
c3d4772e1e | ||
|
|
2245fdc9d5 | ||
|
|
2f7e4b0e2a | ||
|
|
89a54a9982 | ||
|
|
c88d6150e1 | ||
|
|
968d4ce680 | ||
|
|
a35f80c6c1 | ||
|
|
9932fcfdb8 | ||
|
|
83edb851e3 | ||
|
|
9e10127828 | ||
|
|
a0a6d1ee85 | ||
|
|
926634ab10 | ||
|
|
31d0e08515 | ||
|
|
4437222d01 | ||
|
|
0d1050d395 | ||
|
|
031c1353b7 | ||
|
|
dc99fee4b4 | ||
|
|
302ef0adac | ||
|
|
37c14137e2 | ||
|
|
388a323105 | ||
|
|
e9716ee88d | ||
|
|
25734f92be | ||
|
|
32ca38de8c | ||
|
|
832497773b | ||
|
|
c1153eda3a | ||
|
|
7c3e8ae54a | ||
|
|
0b93ac51b5 | ||
|
|
5fd5be6e1b | ||
|
|
a4ea7d3b2e | ||
|
|
2ba6808559 | ||
|
|
156ca8227b | ||
|
|
077ec0289d | ||
|
|
b6b924d4e1 | ||
|
|
16c391f9bd | ||
|
|
70e567a09d | ||
|
|
294f5cf98d | ||
|
|
3e9f302cf6 | ||
|
|
a450fbb18a | ||
|
|
e634881f96 | ||
|
|
ad71747116 | ||
|
|
1f0b71abac | ||
|
|
3a1e15f5c2 | ||
|
|
44596b3723 | ||
|
|
4e30143f51 | ||
|
|
db5a0fe4dc | ||
|
|
1b1306d372 | ||
|
|
ac2ab49e8f | ||
|
|
5c61b5dd17 | ||
|
|
5941f40444 | ||
|
|
bca15e24ce | ||
|
|
81a15d9327 | ||
|
|
b01fe77ba2 | ||
|
|
f99e01018e | ||
|
|
393befe4fa | ||
|
|
4d9d11cbfb | ||
|
|
c8356fb261 | ||
|
|
2938092be6 | ||
|
|
ed099857c0 | ||
|
|
e5b4eb5c19 | ||
|
|
3239c191fb | ||
|
|
6a6bff90e8 | ||
|
|
0a410dbbf2 | ||
|
|
ea6ddd7aa6 | ||
|
|
23cfb1d9f9 | ||
|
|
9295c87845 | ||
|
|
cd3a11c9e2 | ||
|
|
99f31b66c3 | ||
|
|
d9c3ef655e | ||
|
|
a9220dd4d8 | ||
|
|
6e75886a3d | ||
|
|
fbab016ba7 | ||
|
|
d6d2189344 | ||
|
|
c6e18ef0d5 | ||
|
|
ab3fca5b64 | ||
|
|
aedd3f2d53 | ||
|
|
01a32f6318 | ||
|
|
09c5214181 | ||
|
|
c243a99947 | ||
|
|
88ab4724e4 | ||
|
|
e975106995 | ||
|
|
f44891c367 | ||
|
|
e940963dd2 | ||
|
|
eed4b1f2df | ||
|
|
b8179d9548 | ||
|
|
a7b06aabaf | ||
|
|
0677294afa | ||
|
|
aaf18f7b7c | ||
|
|
42baad25fd | ||
|
|
2122a30d41 | ||
|
|
ad6638da29 | ||
|
|
2aad39e41c | ||
|
|
5af22ecd3b | ||
|
|
d7625532be | ||
|
|
73e53d8cf0 | ||
|
|
56191cf988 | ||
|
|
fff9783879 | ||
|
|
e06eb6976e | ||
|
|
e8a89c1060 | ||
|
|
780fef14bf | ||
|
|
a9bcde41d1 | ||
|
|
f54ce18402 | ||
|
|
d3baf847bf | ||
|
|
1f24f8ef75 | ||
|
|
3fbee04549 | ||
|
|
5203f0f852 | ||
|
|
99d3ae396d | ||
|
|
a62fac14a9 | ||
|
|
5fb178426c | ||
|
|
3093d958b3 | ||
|
|
a3f7e0c769 | ||
|
|
f3b9ba2f06 | ||
|
|
e15b36e141 | ||
|
|
efb6bbde69 | ||
|
|
65ddf8a2c9 | ||
|
|
eab688f5c1 | ||
|
|
bf77b1dc40 | ||
|
|
7d7aa9ff05 | ||
|
|
21a21c55b7 | ||
|
|
5f4d716f5e | ||
|
|
64f7009480 | ||
|
|
2a7814b2bb | ||
|
|
40e901f46e | ||
|
|
3b187abbe1 | ||
|
|
3b9dcc11b2 | ||
|
|
3b29421f6f | ||
|
|
9c9b64efea | ||
|
|
51de23f66f | ||
|
|
97c1fedf38 | ||
|
|
6e7388737a | ||
|
|
2c77a23943 | ||
|
|
6858ec13de | ||
|
|
c6194d925c | ||
|
|
853200aa98 | ||
|
|
9f63317900 | ||
|
|
ce84e168d1 | ||
|
|
d506346db3 | ||
|
|
17cfee37b9 | ||
|
|
3cd9bb9f86 | ||
|
|
0ff15c38a3 | ||
|
|
831469f4d9 | ||
|
|
f7b212b449 | ||
|
|
3d3b061c31 | ||
|
|
6f874e6dbc | ||
|
|
f60cc2a2f7 | ||
|
|
f9bc1b8c3b | ||
|
|
73be96e304 | ||
|
|
42ec16c32f | ||
|
|
247e435752 | ||
|
|
fd21f5ee80 | ||
|
|
0644a54883 | ||
|
|
6117b822ab | ||
|
|
6270ed81bf | ||
|
|
249180f9f0 | ||
|
|
93f8c711af | ||
|
|
1f5a861402 | ||
|
|
1a2c67cb4b | ||
|
|
45daf1f42b | ||
|
|
65985b184f | ||
|
|
ec113ac691 | ||
|
|
31a57190e0 | ||
|
|
adad2ef5fe | ||
|
|
5e8f91bd2a | ||
|
|
b49693f30f | ||
|
|
5f826b7ff4 | ||
|
|
c50c111fdf | ||
|
|
b20aa6e5bd | ||
|
|
4927d6cce2 | ||
|
|
693ea83924 | ||
|
|
4ed3befa71 | ||
|
|
82b26e009a | ||
|
|
5814197257 | ||
|
|
4e4f7438f1 | ||
|
|
faf758ffdd | ||
|
|
cd5c533351 | ||
|
|
1ad77837cf | ||
|
|
82c331d03d | ||
|
|
97330a72cd | ||
|
|
c04153910f | ||
|
|
6ae2d28cf5 | ||
|
|
e104817ed1 | ||
|
|
e402b82f00 | ||
|
|
88ad4bb956 | ||
|
|
e9b1476112 | ||
|
|
4ea9332892 | ||
|
|
a19fc430cd | ||
|
|
c914583a7a | ||
|
|
fcfa0b0297 | ||
|
|
9fde765e22 | ||
|
|
437e5e98cc | ||
|
|
2aeea4ef0e | ||
|
|
d0304a251e | ||
|
|
7d2698473d | ||
|
|
51ab247bc5 | ||
|
|
ff83391e97 | ||
|
|
3c97ae4c5c | ||
|
|
917a8f09db | ||
|
|
a523fd3742 | ||
|
|
fe2b7d6060 | ||
|
|
ce5e02bd20 | ||
|
|
212bb21e7c | ||
|
|
ea22c0f891 | ||
|
|
a0e2193383 | ||
|
|
711ae62ed2 | ||
|
|
f5df3b7d7e | ||
|
|
77a0fb4e01 | ||
|
|
cd8305b07a | ||
|
|
cfaa68317a |
4
.idea/artifacts/KotlinPlugin.xml
generated
4
.idea/artifacts/KotlinPlugin.xml
generated
@@ -38,6 +38,7 @@
|
||||
<element id="module-output" name="ide-common" />
|
||||
<element id="file-copy" path="$PROJECT_DIR$/resources/kotlinManifest.properties" />
|
||||
<element id="module-output" name="idea-android" />
|
||||
<element id="module-output" name="idea-android-output-parser" />
|
||||
<element id="module-output" name="js.serializer" />
|
||||
<element id="module-output" name="serialization" />
|
||||
<element id="module-output" name="idea-completion" />
|
||||
@@ -47,8 +48,11 @@
|
||||
<element id="module-output" name="idea-repl" />
|
||||
<element id="module-output" name="idea-live-templates" />
|
||||
<element id="module-output" name="resolution" />
|
||||
<element id="module-output" name="plugin-api" />
|
||||
<element id="module-output" name="idea-ultimate" />
|
||||
<element id="module-output" name="formatter" />
|
||||
<element id="module-output" name="idea-maven" />
|
||||
<element id="extracted-dir" path="$PROJECT_DIR$/dependencies/protobuf-2.5.0.jar" path-in-jar="/" />
|
||||
</element>
|
||||
<element id="library" level="project" name="javax.inject" />
|
||||
<element id="directory" name="jps">
|
||||
|
||||
8
.idea/dictionaries/Alexey_Sedunov.xml
generated
Normal file
8
.idea/dictionaries/Alexey_Sedunov.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="Alexey.Sedunov">
|
||||
<words>
|
||||
<w>inplace</w>
|
||||
<w>renamer</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
1
.idea/libraries/android_plugin.xml
generated
1
.idea/libraries/android_plugin.xml
generated
@@ -6,6 +6,7 @@
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib" />
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib/jps" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/android-common.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
|
||||
11
.idea/libraries/java_decompiler_plugin.xml
generated
Normal file
11
.idea/libraries/java_decompiler_plugin.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
<component name="libraryTable">
|
||||
<library name="java-decompiler-plugin">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/java-decompiler/lib/java-decompiler.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
3
.idea/libraries/jps.xml
generated
3
.idea/libraries/jps.xml
generated
@@ -8,7 +8,6 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/protobuf-java-2.5.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/antLayout/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/src" />
|
||||
@@ -24,4 +23,4 @@
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/jps" recursive="false" />
|
||||
</library>
|
||||
</component>
|
||||
</component>
|
||||
4
.idea/libraries/protobuf_java.xml
generated
4
.idea/libraries/protobuf_java.xml
generated
@@ -4,11 +4,11 @@
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/protobuf-2.5.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/protobuf-2.5.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/protobuf-java-2.5.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/protobuf-2.5.0-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -49,7 +49,7 @@
|
||||
<component name="ProjectResources">
|
||||
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="SuppressABINotification">
|
||||
|
||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -41,10 +41,12 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" filepath="$PROJECT_DIR$/idea/idea-analysis/idea-analysis.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" filepath="$PROJECT_DIR$/idea/idea-android/idea-android-output-parser/idea-android-output-parser.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" filepath="$PROJECT_DIR$/idea/idea-completion/idea-completion.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" filepath="$PROJECT_DIR$/idea/idea-maven/idea-maven.iml" group="ide" />
|
||||
<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" />
|
||||
|
||||
2
.idea/scopes/IDE.xml
generated
2
.idea/scopes/IDE.xml
generated
@@ -1,3 +1,3 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="IDE" pattern="file[idea]:src/*/||file[idea]:testData/*/||file[ide-common]:src/*/||file[idea-analysis]:src/*/||file[idea-android]:src/*/||file[idea-completion]:src/*/||file[idea-completion]:testData/*/||file[idea-core]:src/*/||file[idea-jps-common]:/*/||file[idea-live-templates]:/*/||file[idea-live-templates]:testData/*/||file[idea-repl]:/*/" />
|
||||
<scope name="IDE" pattern="file[idea]:src/*/||file[idea]:testData/*/||file[ide-common]:src/*/||file[idea-analysis]:src/*/||file[idea-android]:src/*/||file[idea-completion]:src/*/||file[idea-completion]:testData/*/||file[idea-core]:src/*/||file[idea-jps-common]:/*/||file[idea-live-templates]:/*/||file[idea-live-templates]:testData/*/||file[idea-repl]:/*/||src[idea-android-output-parser]:*..*" />
|
||||
</component>
|
||||
478
ChangeLog.md
478
ChangeLog.md
@@ -1,47 +1,458 @@
|
||||
# CHANGELOG
|
||||
|
||||
<!-- Find: ([^\[/])(KT-\d+) -->
|
||||
<!-- Replace: $1[$2](https://youtrack.jetbrains.com/issue/$2) -->
|
||||
|
||||
## 1.1
|
||||
<!-- Find: ([^\`/\[])(KT-\d+) -->
|
||||
<!-- Replace: $1[`$2`](https://youtrack.jetbrains.com/issue/$2) -->
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Compiler
|
||||
|
||||
#### Analysis & diagnostics
|
||||
|
||||
- Combination of `open` and `override` is no longer a warning
|
||||
- [`KT-4829`](https://youtrack.jetbrains.com/issue/KT-4829) Equal conditions in `when` is now a warning
|
||||
- [`KT-6611`](https://youtrack.jetbrains.com/issue/KT-6611) "This cast can never succeed" warning is no longer reported for `Foo<T> as Foo<Any>`
|
||||
- [`KT-7174`](https://youtrack.jetbrains.com/issue/KT-7174) Declaring members with the same signature as non-overridable methods from Java classes (like Object.wait/notify) is now an error (when targeting JVM)
|
||||
- [`KT-12302`](https://youtrack.jetbrains.com/issue/KT-12302) `abstract` modifier for a member of interface is no longer a warning
|
||||
- [`KT-12452`](https://youtrack.jetbrains.com/issue/KT-12452) `open` modifier for a member of interface without implementation is now a warning
|
||||
- [`KT-11111`](https://youtrack.jetbrains.com/issue/KT-11111) Overriding by inline function is now a warning, overriding by a function with reified type parameter is an error
|
||||
- [`KT-12337`](https://youtrack.jetbrains.com/issue/KT-12337) Reference to a property with invisible setter now has KProperty type (as opposed to KMutableProperty)
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-4285`](https://youtrack.jetbrains.com/issue/KT-4285) No warning for a non-tail call when the method inherits default arguments from superclass
|
||||
- [`KT-4764`](https://youtrack.jetbrains.com/issue/KT-4764) Spurious "Variable must be initialized" in try/catch/finally
|
||||
- [`KT-6665`](https://youtrack.jetbrains.com/issue/KT-6665) Unresolved reference leads to marking subsequent code unreachable
|
||||
- [`KT-9597`](https://youtrack.jetbrains.com/issue/KT-9597) NullPointerException during resolution of complicated star projections
|
||||
- [`KT-11750`](https://youtrack.jetbrains.com/issue/KT-11750) Exceptions when creating various entries with the name "name" in enums
|
||||
- [`KT-11998`](https://youtrack.jetbrains.com/issue/KT-11998) Smart cast to not-null is not performed on a boolean property in `if` condition
|
||||
- [`KT-10648`](https://youtrack.jetbrains.com/issue/KT-10648) Exhaustiveness check does not work when sealed class hierarchy contains intermediate sealed classes
|
||||
- [`KT-10717`](https://youtrack.jetbrains.com/issue/KT-10717) Type inference for lambda with local return
|
||||
- [`KT-11266`](https://youtrack.jetbrains.com/issue/KT-11266) Fixed "Empty intersection of types" internal compiler error for some cases
|
||||
- [`KT-11857`](https://youtrack.jetbrains.com/issue/KT-11857) Fix visibility check for dynamic members within protected method (when targeting JS)
|
||||
- [`KT-12589`](https://youtrack.jetbrains.com/issue/KT-12589) Improved "`infix` modifier is inapplicable" diagnostic message
|
||||
- [`KT-11679`](https://youtrack.jetbrains.com/issue/KT-11679) Erroneous call with argument causes Throwable at ResolvedCallImpl.getArgumentMapping()
|
||||
- [`KT-12623`](https://youtrack.jetbrains.com/issue/KT-12623) Fix ISE on malformed code
|
||||
|
||||
#### JVM code generation
|
||||
|
||||
- [`KT-5075`](https://youtrack.jetbrains.com/issue/KT-5075) Optimize array/collection indices usage in `for` loop
|
||||
- [`KT-11116`](https://youtrack.jetbrains.com/issue/KT-11116) Optimize coercion to Unit, POP operations are backward-propagated
|
||||
|
||||
###### Issues fixed
|
||||
- [`KT-11499`](https://youtrack.jetbrains.com/issue/KT-11499) Compiler crashes with "Incompatible stack heights"
|
||||
- [`KT-11943`](https://youtrack.jetbrains.com/issue/KT-11943) CompilationException with extension property of KClass
|
||||
- [`KT-12125`](https://youtrack.jetbrains.com/issue/KT-12125) Wrong increment/decrement on Byte/Char/Short.MAX_VALUE/MIN_VALUE
|
||||
- [`KT-12192`](https://youtrack.jetbrains.com/issue/KT-12192) Exhaustiveness check isn't generated for when expression returning Unit
|
||||
- [`KT-12200`](https://youtrack.jetbrains.com/issue/KT-12200) Erroneously optimized away assignment to a property initialized to zero
|
||||
- [`KT-12582`](https://youtrack.jetbrains.com/issue/KT-12582) "VerifyError: Bad local variable type" caused by explicit loop variable type
|
||||
- [`KT-12708`](https://youtrack.jetbrains.com/issue/KT-12708) Bridge method not generated when data class implements interface with copy() method
|
||||
- [`KT-12106`](https://youtrack.jetbrains.com/issue/KT-12106) import static of reified companion object method throws IllegalAccessError
|
||||
|
||||
#### Performance
|
||||
|
||||
- Reduced number of IO operation when loading kotlin compiled classes
|
||||
|
||||
#### Сompiler options
|
||||
|
||||
- Allow to specify version of Kotlin language for source compatibility with older releases.
|
||||
- CLI: `-language-version` command line option
|
||||
- Maven: `languageVersion` configuration parameter, linked with `kotlin.compiler.languageVersion` property
|
||||
- Gradle: `kotlinOptions.languageVersion` property in task configuration
|
||||
- Allow to specify which java runtime target version to generate bytecode for.
|
||||
- CLI: `-jvm-target` command line option
|
||||
- Maven: `jvmTarget` configuration parameter, linked with `kotlin.compiler.jvmTarget` property
|
||||
- Gradle: `kotlinOptions.jvmTarget` property in task configuration
|
||||
- Allow to specify path to JDK to resolve classes from.
|
||||
- CLI: `-jdk-home` command line option
|
||||
- Maven: `jdkHome` configuration parameter, linked with `kotlin.compiler.jdkHome` property
|
||||
- Gradle: `kotlinOptions.jdkHome` property in task configuration
|
||||
|
||||
### Standard Library
|
||||
|
||||
- Improve documentation (including [`KT-11632`](https://youtrack.jetbrains.com/issue/KT-11632))
|
||||
- List iteration used in collection operations is performed with an indexed loop when the list supports `RandomAccess` and the operation isn't inlined
|
||||
|
||||
### IDE
|
||||
|
||||
New features:
|
||||
#### Completion
|
||||
|
||||
###### New features
|
||||
|
||||
- Smart completion after `by` and `in`
|
||||
- Improved completion in bodies of overridden members (when no type is specified)
|
||||
- Improved presentation of completion items for property accessors
|
||||
- Fixed keyword completion after `try` in assignment expression
|
||||
- [`KT-8527`](https://youtrack.jetbrains.com/issue/KT-8527) Include non-imported declarations on the first completion
|
||||
- [`KT-12068`](https://youtrack.jetbrains.com/issue/KT-12068) Special completion item for "[]" get-operator access
|
||||
- [`KT-12080`](https://youtrack.jetbrains.com/issue/KT-12080) Parameter names are now higher up in completion list
|
||||
|
||||
###### Issues fixed
|
||||
- Fixed enum members being present in completion as static members
|
||||
- Fixed QuickDoc not working for properties generated for java classes
|
||||
- [`KT-9166`](https://youtrack.jetbrains.com/issue/KT-9166) Code completion does not work for synthetic java properties on typing "g"
|
||||
- [`KT-11609`](https://youtrack.jetbrains.com/issue/KT-11609) No named arguments completion should be after dot
|
||||
- [`KT-11633`](https://youtrack.jetbrains.com/issue/KT-11633) Wrong indentation after completing a statement in data class
|
||||
- [`KT-11680`](https://youtrack.jetbrains.com/issue/KT-11680) Code completion of label for existing return with value inserts redundant whitespace
|
||||
- [`KT-11784`](https://youtrack.jetbrains.com/issue/KT-11784) Completion for `if` statement should add parentheses automatically
|
||||
- [`KT-11890`](https://youtrack.jetbrains.com/issue/KT-11890) Completion for callable references does not propose static Java members
|
||||
- [`KT-11912`](https://youtrack.jetbrains.com/issue/KT-11912) String interpolation is not converted to ${} form when accessing this.property
|
||||
- [`KT-11957`](https://youtrack.jetbrains.com/issue/KT-11957) No `catch` and `finally` keywords in completion
|
||||
- [`KT-12103`](https://youtrack.jetbrains.com/issue/KT-12103) Smart completion for nested SAM-adapter produces short unresolved name
|
||||
- [`KT-12138`](https://youtrack.jetbrains.com/issue/KT-12138) Do not show "::error" in smart completion when any function type accepting one argument is expected
|
||||
- [`KT-12150`](https://youtrack.jetbrains.com/issue/KT-12150) Smart completion suggests to compare non-nullable with null
|
||||
- [`KT-12124`](https://youtrack.jetbrains.com/issue/KT-12124) No code completion for a java property in a specific position
|
||||
- [`KT-12299`](https://youtrack.jetbrains.com/issue/KT-12299) Completion: incorrect priority of property foo over method getFoo in Kotlin-only code
|
||||
- [`KT-12328`](https://youtrack.jetbrains.com/issue/KT-12328) Qualified function name inserted when typing before `if`
|
||||
- [`KT-12427`](https://youtrack.jetbrains.com/issue/KT-12427) Completion doesn't work for "@receiver:" annotation target
|
||||
- [`KT-12447`](https://youtrack.jetbrains.com/issue/KT-12447) Don't use CompletionProgressIndicator in Kotlin plugin
|
||||
- [`KT-12669`](https://youtrack.jetbrains.com/issue/KT-12669) Completion should show variant with `()` when there is default lambda
|
||||
- [`KT-12369`](https://youtrack.jetbrains.com/issue/KT-12369) Pressing dot after class name should not cause insertion of constructor call
|
||||
|
||||
#### Spring support
|
||||
|
||||
###### New features
|
||||
|
||||
- [`KT-11692`](https://youtrack.jetbrains.com/issue/KT-11692) Support Spring model diagrams for Kotlin classes
|
||||
- [`KT-12079`](https://youtrack.jetbrains.com/issue/KT-12079) Support "Autowired members defined in invalid Spring bean" inspection on Kotlin declarations
|
||||
- [`KT-12092`](https://youtrack.jetbrains.com/issue/KT-12092) Implement bean references in @Qualifier annotations
|
||||
- [`KT-12135`](https://youtrack.jetbrains.com/issue/KT-12135) Automatically configure components based on `basePackageClasses` attribute of @ComponentScan
|
||||
- [`KT-12136`](https://youtrack.jetbrains.com/issue/KT-12136) Implement package references inside of string literals
|
||||
- [`KT-12139`](https://youtrack.jetbrains.com/issue/KT-12139) Support Spring configurations linked via @Import annotation
|
||||
- [`KT-12278`](https://youtrack.jetbrains.com/issue/KT-12278) Implement Spring @Autowired inspection
|
||||
- [`KT-12465`](https://youtrack.jetbrains.com/issue/KT-12465) Implement Spring @ComponentScan inspection
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-12091`](https://youtrack.jetbrains.com/issue/KT-12091) Fixed unstable behavior of Spring line markers
|
||||
- [`KT-12096`](https://youtrack.jetbrains.com/issue/KT-12096) Fixed rename of custom-named beans specified with Kotlin annotation
|
||||
- [`KT-12117`](https://youtrack.jetbrains.com/issue/KT-12117) Group Kotlin classes from the same file in the Choose Bean dialog
|
||||
- [`KT-12120`](https://youtrack.jetbrains.com/issue/KT-12120) Show autowiring candidates line markers for @Autowired-annotated constructors and constructor parameters
|
||||
- [`KT-12122`](https://youtrack.jetbrains.com/issue/KT-12122) Fixed line marker popup on functions with @Qualifier-annotated parameters
|
||||
- [`KT-12143`](https://youtrack.jetbrains.com/issue/KT-12143) Fixed "Spring Facet Code Configuration (Kotlin)" inspection description
|
||||
- [`KT-12147`](https://youtrack.jetbrains.com/issue/KT-12147) Fixed exception on analyzing object declaration with @Component annotation
|
||||
- [`KT-12148`](https://youtrack.jetbrains.com/issue/KT-12148) Warn about object declarations annotated with Spring `@Configuration`/`@Component`/etc.
|
||||
- [`KT-12363`](https://youtrack.jetbrains.com/issue/KT-12363) Fixed "Autowired members defined in invalid Spring bean (Kotlin)" inspection description
|
||||
- [`KT-12366`](https://youtrack.jetbrains.com/issue/KT-12366) Fixed exception on analyzing class declaration upon annotation typing
|
||||
- [`KT-12384`](https://youtrack.jetbrains.com/issue/KT-12384) Fixed bean references in factory method calls
|
||||
|
||||
#### Intention actions, inspections and quickfixes
|
||||
|
||||
###### New features
|
||||
|
||||
- New icon for "New -> Kotlin Activity" action
|
||||
- "Change visibility on exposure" and "Make visible" fixes now support all possible visibilities
|
||||
- [`KT-8477`](https://youtrack.jetbrains.com/issue/KT-8477) New inspection "Can be primary constructor property" with quick-fix
|
||||
- [`KT-5010`](https://youtrack.jetbrains.com/issue/KT-5010) "Redundant semicolon" inspection with quickfix
|
||||
- [`KT-9757`](https://youtrack.jetbrains.com/issue/KT-9757) Quickfix for "Unused lambda expression" warning
|
||||
- [`KT-10844`](https://youtrack.jetbrains.com/issue/KT-10844) Quick fix to add crossinline modifier
|
||||
- [`KT-11090`](https://youtrack.jetbrains.com/issue/KT-11090) "Add variance modifiers to type parameters" inspection
|
||||
- [`KT-11255`](https://youtrack.jetbrains.com/issue/KT-11255) Move Element Left/Right actions
|
||||
- [`KT-11450`](https://youtrack.jetbrains.com/issue/KT-11450) "Modality is redundant" inspection
|
||||
- [`KT-11523`](https://youtrack.jetbrains.com/issue/KT-11523) "Add @JvmOverloads annotation" intention
|
||||
- [`KT-11768`](https://youtrack.jetbrains.com/issue/KT-11768) "Introduce local variable" intention
|
||||
- [`KT-11806`](https://youtrack.jetbrains.com/issue/KT-11806) Quick-fix to increase visibility for invisible member
|
||||
- [`KT-11807`](https://youtrack.jetbrains.com/issue/KT-11807) Use function body template when generating overriding functions with default body
|
||||
- [`KT-11864`](https://youtrack.jetbrains.com/issue/KT-11864) Suggest "Create function/secondary constructor" quick fix on argument type mismatch
|
||||
- [`KT-11876`](https://youtrack.jetbrains.com/issue/KT-11876) Quickfix for "Extension function type is not allowed as supertype" error
|
||||
- [`KT-11920`](https://youtrack.jetbrains.com/issue/KT-11920) "Increase visibility" and "Decrease visibility" quickfixes for exposed visibility errors
|
||||
- [`KT-12089`](https://youtrack.jetbrains.com/issue/KT-12089) Quickfix "Make primary constructor parameter a property"
|
||||
- [`KT-12121`](https://youtrack.jetbrains.com/issue/KT-12121) "Add `toString()` call" quickfix
|
||||
- [`KT-11104`](https://youtrack.jetbrains.com/issue/KT-11104) New quickfixes for nullability problems: "Surround with null check" and "Wrap with safe let call"
|
||||
- [`KT-12310`](https://youtrack.jetbrains.com/issue/KT-12310) New inspection "Member has platform type" with quickfix
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- Fixed "Convert property initializer getter" intention being available inside lambda initializer
|
||||
- Improved message for "Can be declared as `val`" inspection
|
||||
- [`KT-3797`](https://youtrack.jetbrains.com/issue/KT-3797) Quickfix to make a function abstract should not be offered for object members
|
||||
- [`KT-11866`](https://youtrack.jetbrains.com/issue/KT-11866) Suggest "Create secondary constructor" when constructors exist but are not applicable
|
||||
- [`KT-11482`](https://youtrack.jetbrains.com/issue/KT-11482) Fixed exception in "Move to companion object" intention
|
||||
- [`KT-11483`](https://youtrack.jetbrains.com/issue/KT-11483) Pass implicit receiver as argument when moving member function to companion object
|
||||
- [`KT-11512`](https://youtrack.jetbrains.com/issue/KT-11512) Allow choosing any source root in "Move file to directory" intention
|
||||
- [`KT-10950`](https://youtrack.jetbrains.com/issue/KT-10950) Keep original file package name when moving top-level declarations to separate file (provided it's not ambiguous)
|
||||
- [`KT-10174`](https://youtrack.jetbrains.com/issue/KT-10174) Optimize imports after applying "Move declaration to separate file" intention
|
||||
- [`KT-11764`](https://youtrack.jetbrains.com/issue/KT-11764) Intention "Replace with a `forEach` function call should replace `continue` with `return@forEach`
|
||||
- [`KT-11724`](https://youtrack.jetbrains.com/issue/KT-11724) False suggestion to replace with compound assignment
|
||||
- [`KT-11805`](https://youtrack.jetbrains.com/issue/KT-11805) Invert if-condition intention breaks code in case of end of line comment
|
||||
- [`KT-11811`](https://youtrack.jetbrains.com/issue/KT-11811) "Make protected" intention for a val declared in parameters of constructor
|
||||
- [`KT-11710`](https://youtrack.jetbrains.com/issue/KT-11710) "Replace `if` with elvis operator": incorrect code generated for `if` expression
|
||||
- [`KT-11849`](https://youtrack.jetbrains.com/issue/KT-11849) Replace explicit parameter with `it` changes the meaning of code because of the shadowing
|
||||
- [`KT-11870`](https://youtrack.jetbrains.com/issue/KT-11870) "Replace with Elvis" refactoring doesn't change the variable type from T? to T
|
||||
- [`KT-12069`](https://youtrack.jetbrains.com/issue/KT-12069) Specify language for all Kotlin code inspections
|
||||
- [`KT-11366`](https://youtrack.jetbrains.com/issue/KT-11366) "object `Companion` is never used" warning in intellij
|
||||
- [`KT-11275`](https://youtrack.jetbrains.com/issue/KT-11275) Inconsistent behaviour of "move lambda argument out of parentheses" intention action when using lambda calls with function arguments without parentheses
|
||||
- [`KT-11594`](https://youtrack.jetbrains.com/issue/KT-11594) "Add non-null asserted (!!) call" applied to unsafe cast to nullable type causes AE at KtPsiFactory.createExpression()
|
||||
- [`KT-11982`](https://youtrack.jetbrains.com/issue/KT-11982) False "Redundant final modifier" reported
|
||||
- [`KT-12040`](https://youtrack.jetbrains.com/issue/KT-12040) "Replace when with if" produce invalid code for first entry which has comment
|
||||
- [`KT-12204`](https://youtrack.jetbrains.com/issue/KT-12204) "Use classpath of module" option in existing Kotlin run configuration may be changed when a new run configuration is created
|
||||
- [`KT-10635`](https://youtrack.jetbrains.com/issue/KT-10635) Don't mark private writeObject and readObject methods of Serializable classes as unused
|
||||
- [`KT-11466`](https://youtrack.jetbrains.com/issue/KT-11466) "Make abstract" quick fix applies to outer class of object with accidentally abstract function
|
||||
- [`KT-11120`](https://youtrack.jetbrains.com/issue/KT-11120) Constructor parameter/field reported as unused symbol even if it have `used` annotation
|
||||
- [`KT-11974`](https://youtrack.jetbrains.com/issue/KT-11974) Invert if-condition intention loses comments
|
||||
- [`KT-10812`](https://youtrack.jetbrains.com/issue/KT-10812) Globally unused constructors are not marked as such
|
||||
- [`KT-11320`](https://youtrack.jetbrains.com/issue/KT-11320) Don't mark @BeforeClass (JUnit4) annotated functions as unused
|
||||
- [`KT-12267`](https://youtrack.jetbrains.com/issue/KT-12267) "Change type" quick fix converts to Int for Long literal
|
||||
- [`KT-11949`](https://youtrack.jetbrains.com/issue/KT-11949) Various problems fixed with "Constructor parameter is never used as a property" inspection
|
||||
- [`KT-11716`](https://youtrack.jetbrains.com/issue/KT-11716) "Simply `for` using destructuring declaration" intention: incorrect behavior for data classes
|
||||
- [`KT-12145`](https://youtrack.jetbrains.com/issue/KT-12145) "Simplify `for` using destructuring declaration" should work even when no variables declared inside loop
|
||||
- [`KT-11933`](https://youtrack.jetbrains.com/issue/KT-11933) Entities used only by alias are marked as unused
|
||||
- [`KT-12193`](https://youtrack.jetbrains.com/issue/KT-12193) Convert to block body isn't equivalent for when expressions returning Unit
|
||||
- [`KT-10779`](https://youtrack.jetbrains.com/issue/KT-10779) Simplify `for` using destructing declaration: intention / inspection quick fix is available only when all variables are used
|
||||
- [`KT-11281`](https://youtrack.jetbrains.com/issue/KT-11281) Fix exception on applying "Convert to class" intention to Java interface with Kotlin inheritor(s)
|
||||
- [`KT-12285`](https://youtrack.jetbrains.com/issue/KT-12285) Fix exception on test class generation
|
||||
- [`KT-12502`](https://youtrack.jetbrains.com/issue/KT-12502) Convert to expression body should be forbidden for non-exhaustive when returning Unit
|
||||
- [`KT-12260`](https://youtrack.jetbrains.com/issue/KT-12260) ISE while replacing an operator with safe call
|
||||
- [`KT-12649`](https://youtrack.jetbrains.com/issue/KT-12649) "Convert if to when" intention incorrectly deletes code
|
||||
- [`KT-12671`](https://youtrack.jetbrains.com/issue/KT-12671) "Shot type" action: "Type is unknown" error on an invoked expression
|
||||
- [`KT-12284`](https://youtrack.jetbrains.com/issue/KT-12284) Too wide applicability range for "Add braces to else" intention
|
||||
- [`KT-11975`](https://youtrack.jetbrains.com/issue/KT-11975) "Invert if-condition" intention does not simplify `is` expression
|
||||
- [`KT-12437`](https://youtrack.jetbrains.com/issue/KT-12437) "Replace explicit parameter" intention is suggested for parameter of inner lambda in presence of `it` from outer lambda
|
||||
- [`KT-12290`](https://youtrack.jetbrains.com/issue/KT-12290) Navigate to the generated declaration when using "Implement abstract member" intention
|
||||
- [`KT-12376`](https://youtrack.jetbrains.com/issue/KT-12376) Don't show "Package directive doesn't match file location" in injected code
|
||||
- [`KT-12777`](https://youtrack.jetbrains.com/issue/KT-12777) Fix exception in "Create class" quickfix applied to unresolved references in type arguments
|
||||
|
||||
#### Language injection
|
||||
|
||||
- [KT-11768](https://youtrack.jetbrains.com/issue/KT-11768) Implement "Introduce local variable" intention
|
||||
- [KT-11692](https://youtrack.jetbrains.com/issue/KT-11692) Support Spring model diagrams for Kotlin classes
|
||||
- [KT-11574](https://youtrack.jetbrains.com/issue/KT-11574) Support predefined Java positions for language injection
|
||||
- [KT-2428](https://youtrack.jetbrains.com/issue/KT-11574) Support basic use-cases of language injection for expressions marked with @Language annotation
|
||||
- Add comment or @Language annotation after "Inject language or reference" intention automatically
|
||||
- Apply injection for the literals in property initializer through property usages
|
||||
- [KT-11807](https://youtrack.jetbrains.com/issue/KT-11807) Use function body template when generating overriding functions with default body
|
||||
- Enable injection from Java or Kotlin function declaration by annotating parameter with @Language annotation
|
||||
- [`KT-2428`](https://youtrack.jetbrains.com/issue/KT-2428) Support basic use-cases of language injection for expressions marked with @Language annotation
|
||||
- [`KT-11574`](https://youtrack.jetbrains.com/issue/KT-11574) Support predefined Java positions for language injection
|
||||
- [`KT-11472`](https://youtrack.jetbrains.com/issue/KT-11472) Add comment or @Language annotation after "Inject language or reference" intention automatically
|
||||
|
||||
Issues fixed:
|
||||
#### Refactorings
|
||||
|
||||
- [KT-11145](https://youtrack.jetbrains.com/issue/KT-11145) Use progress indicator when searching usages in Introduce Parameter
|
||||
- [KT-11155](https://youtrack.jetbrains.com/issue/KT-11155) Allow running multiple Kotlin classes as well as running mixtures of Kotlin and Java classes
|
||||
- [KT-11495](https://youtrack.jetbrains.com/issue/KT-11495) Show recursion line markers for extension function calls with different receiver
|
||||
- [KT-11659](https://youtrack.jetbrains.com/issue/KT-11659) Generate abstract overrides for Any members inside of Kotlin interfaces
|
||||
- [KT-11866](https://youtrack.jetbrains.com/issue/KT-11866) Suggest "Create secondary constructor" when constructors exist but are not applicable
|
||||
- [KT-11908](https://youtrack.jetbrains.com/issue/KT-11866) Allow properties with custom setters to be used in generated equals/hashCode/toString
|
||||
- [KT-11845](https://youtrack.jetbrains.com/issue/KT-11845) Fixed exception on attempt to find derived classes
|
||||
- [KT-11736](https://youtrack.jetbrains.com/issue/KT-11736) Fixed searching of Java usages for @JvmStatic properties and @JvmStatic @JvmOverloads functions
|
||||
- [KT-8817](https://youtrack.jetbrains.com/issue/KT-8817) Fixed rename of Java getters/setters through synthetic property references in Kotlin
|
||||
- [KT-11617](https://youtrack.jetbrains.com/issue/KT-11617) Fixed title of Introduce Parameter declaration chooser
|
||||
- [KT-11817](https://youtrack.jetbrains.com/issue/KT-11817) Fixed rename of Kotlin enum constants through Java references
|
||||
- [KT-11816](https://youtrack.jetbrains.com/issue/KT-11816) Fixed usages search for Safe Delete on simple enum entries
|
||||
- [KT-11282](https://youtrack.jetbrains.com/issue/KT-11282) Delete interface reference from super-type list when applying Safe Delete to Java interface
|
||||
- [KT-11967](https://youtrack.jetbrains.com/issue/KT-11967) Fix Find Usages/Rename for parameter references in XML files
|
||||
###### New features
|
||||
- [`KT-6372`](https://youtrack.jetbrains.com/issue/KT-6372) Add name suggestions to Rename dialog
|
||||
- [`KT-7851`](https://youtrack.jetbrains.com/issue/KT-7851) Respect naming conventions in automatic variable rename
|
||||
- [`KT-8044`](https://youtrack.jetbrains.com/issue/KT-8044), [`KT-9432`](https://youtrack.jetbrains.com/issue/KT-9432) Support @JvmName annotation in rename refactoring
|
||||
- [`KT-8512`](https://youtrack.jetbrains.com/issue/KT-8512) Support "Rename tests" options in Rename dialog
|
||||
- [`KT-9168`](https://youtrack.jetbrains.com/issue/KT-9168) Support rename of synthetic properties
|
||||
- [`KT-10578`](https://youtrack.jetbrains.com/issue/KT-10578) Support automatic test renaming for facade files
|
||||
- [`KT-12657`](https://youtrack.jetbrains.com/issue/KT-12657) Rename implicit usages of annotation method `value`
|
||||
- [`KT-12759`](https://youtrack.jetbrains.com/issue/KT-12759) Suggest renaming both property accessors with matching @JvmName when renaming one of them from Java
|
||||
|
||||
###### Issues fixed
|
||||
- [`KT-4791`](https://youtrack.jetbrains.com/issue/KT-4791) Rename overridden property and all its accessors on attempt to rename overriding accessor in Java code
|
||||
- [`KT-6363`](https://youtrack.jetbrains.com/issue/KT-6363) Do not rename ambiguous references in import directives
|
||||
- [`KT-6663`](https://youtrack.jetbrains.com/issue/KT-6663) Fixed rename of ambiguous import reference to class/function when some referenced declarations are not changed
|
||||
- [`KT-8510`](https://youtrack.jetbrains.com/issue/KT-8510) Preserve "Search in comments and strings" and "Search for text occurrences" settings in Rename dialog
|
||||
- [`KT-8541`](https://youtrack.jetbrains.com/issue/KT-8541), [`KT-8786`](https://youtrack.jetbrains.com/issue/KT-8786) Do now show 'Rename overloads' options if target function has no overloads
|
||||
- [`KT-8544`](https://youtrack.jetbrains.com/issue/KT-8544) Show more detailed description in Rename dialog
|
||||
- [`KT-8562`](https://youtrack.jetbrains.com/issue/KT-8562) Show conflicts dialog on attempt of redeclaration
|
||||
- [`KT-8611`](https://youtrack.jetbrains.com/issue/KT-8732) Qualify class references to resolve rename conflicts when possible
|
||||
- [`KT-8732`](https://youtrack.jetbrains.com/issue/KT-8732) Implement Rename conflict analysis and fixes for properties/parameters
|
||||
- [`KT-8860`](https://youtrack.jetbrains.com/issue/KT-8860) Allow renaming class by constructor delegation call referencing primary constructor
|
||||
- [`KT-8892`](https://youtrack.jetbrains.com/issue/KT-8892) Suggest renaming base declarations on overriding members in object literals
|
||||
- [`KT-9156`](https://youtrack.jetbrains.com/issue/KT-9156) Quote non-identifier names in Kotlin references
|
||||
- [`KT-9157`](https://youtrack.jetbrains.com/issue/KT-9157) Fixed in-place rename of Kotlin expression referring Java declaration
|
||||
- [`KT-9241`](https://youtrack.jetbrains.com/issue/KT-9241) Do not replace Java references to synthetic component functions when renaming constructor parameter
|
||||
- [`KT-9435`](https://youtrack.jetbrains.com/issue/KT-9435) Process property accessor usages (Java) in comments and string literals
|
||||
- [`KT-9444`](https://youtrack.jetbrains.com/issue/KT-9444) Rename dialog: Allow typing any identifier without backquotes
|
||||
- [`KT-9446`](https://youtrack.jetbrains.com/issue/KT-9446) Copy default parameter values to overriding function which is renamed while its base function is not
|
||||
- [`KT-9649`](https://youtrack.jetbrains.com/issue/KT-9649) Constraint search scope of parameter declared in a private member
|
||||
- [`KT-10033`](https://youtrack.jetbrains.com/issue/KT-10033) Qualify references to members of enum companions in case of conflict with enum entries
|
||||
- [`KT-10713`](https://youtrack.jetbrains.com/issue/KT-10713) Skip read-only declarations when renaming parameters
|
||||
- [`KT-10687`](https://youtrack.jetbrains.com/issue/KT-10687) Qualify property references to avoid shadowing by parameters
|
||||
- [`KT-11903`](https://youtrack.jetbrains.com/issue/KT-11903) Update references to facade class when renaming file via matching top-level class
|
||||
- [`KT-12411`](https://youtrack.jetbrains.com/issue/KT-12411) Fix package name quotation in Move refactoring
|
||||
- [`KT-12543`](https://youtrack.jetbrains.com/issue/KT-12543) Qualify property references with `this` to avoid renaming conflicts
|
||||
- [`KT-12732`](https://youtrack.jetbrains.com/issue/KT-12732) Copy default parameter values to overriding function which is renamed by Java reference while its base function is unchanged
|
||||
- [`KT-12747`](https://youtrack.jetbrains.com/issue/KT-12747) Fix exception on file copy
|
||||
|
||||
#### Java to Kotlin converter
|
||||
|
||||
###### New features
|
||||
|
||||
- [`KT-4727`](https://youtrack.jetbrains.com/issue/KT-4727) Convert Java code copied from browser or other sources
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-11952`](https://youtrack.jetbrains.com/issue/KT-11952) Assertion failed in PropertyDetectionCache.get on conversion of access to Java constant of anonymous type
|
||||
- [`KT-12046`](https://youtrack.jetbrains.com/issue/KT-12046) Recursive property setter
|
||||
- [`KT-12039`](https://youtrack.jetbrains.com/issue/KT-12039) Static imports converted missing ".Companion"
|
||||
- [`KT-12054`](https://youtrack.jetbrains.com/issue/KT-12054) Wrong conversion of `instanceof` checks with raw types
|
||||
- [`KT-12045`](https://youtrack.jetbrains.com/issue/KT-12045) Convert `Object()` to `Any()`
|
||||
|
||||
#### Android Lint
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-12015`](https://youtrack.jetbrains.com/issue/KT-12015) False positive for Bundle.getInt()
|
||||
- [`KT-12023`](https://youtrack.jetbrains.com/issue/KT-12023) "minSdk" lint check doesn't work for `as`/`is`
|
||||
- [`KT-12674`](https://youtrack.jetbrains.com/issue/KT-12674) "Calling new methods on older versions" errors for inlined constants
|
||||
- [`KT-12681`](https://youtrack.jetbrains.com/issue/KT-12681) Running lint from main menu: diagnostics reported for java source files only
|
||||
- [`KT-12173`](https://youtrack.jetbrains.com/issue/KT-12173) False positive for "Toast created but not shown" inside SAM adapter
|
||||
- [`KT-12895`](https://youtrack.jetbrains.com/issue/KT-12895) NoSuchMethodError thrown when saving a Kotlin file
|
||||
|
||||
#### KDoc
|
||||
|
||||
###### New features
|
||||
- Support for @receiver tag
|
||||
|
||||
###### Issues fixed
|
||||
- Rendering of `_` and `*` standalone characters
|
||||
- Rendering of code blocks
|
||||
- [`KT-9933`](https://youtrack.jetbrains.com/issue/KT-9933) Indentation in code fragments is not preserved
|
||||
- [`KT-10998`](https://youtrack.jetbrains.com/issue/KT-10998) Spaces around links are missing in return block
|
||||
- [`KT-11791`](https://youtrack.jetbrains.com/issue/KT-11791) Markdown links rendering
|
||||
- [`KT-12001`](https://youtrack.jetbrains.com/issue/KT-12001) Allow use of `@param` to document type parameter
|
||||
|
||||
#### Maven support
|
||||
|
||||
###### New features
|
||||
- Inspections that check that kotlin IDEA plugin, kotlin Maven plugin and kotlin stdlib are of the same version
|
||||
- [`KT-11643`](https://youtrack.jetbrains.com/issue/KT-11643) Inspections and intentions to fix erroneously configured Maven pom file
|
||||
- [`KT-11701`](https://youtrack.jetbrains.com/issue/KT-11701) "Add Maven Dependency quick fix" in Kotlin source files
|
||||
- [`KT-11743`](https://youtrack.jetbrains.com/issue/KT-11743) Intention to replace kotlin-test with kotlin-test-junit
|
||||
|
||||
###### Issues fixed
|
||||
- [`KT-9492`](https://youtrack.jetbrains.com/issue/KT-9492) Configuring multiple Maven Modules
|
||||
- [`KT-11642`](https://youtrack.jetbrains.com/issue/KT-11642) Kotlin Maven configurator tags order
|
||||
- [`KT-11436`](https://youtrack.jetbrains.com/issue/KT-11436) "Choose Configurator" control opens dialogs with inconsistent modality (linux)
|
||||
- [`KT-11731`](https://youtrack.jetbrains.com/issue/KT-11731) Default maven integration doesn't include documentation
|
||||
- [`KT-12568`](https://youtrack.jetbrains.com/issue/KT-12568) Execution configuration: file path completion works only in some sub-elements of <sourceDirs>
|
||||
- [`KT-12558`](https://youtrack.jetbrains.com/issue/KT-12558) Configure Kotlin in Project: "Undo" should revert changes in all poms
|
||||
- [`KT-12512`](https://youtrack.jetbrains.com/issue/KT-12512) "Different IDE and Maven plugin version" inspection is being invoked for non-tracked pom.xml files
|
||||
|
||||
#### Debugger
|
||||
|
||||
###### New features
|
||||
- [`KT-11438`](https://youtrack.jetbrains.com/issue/KT-11438) Support navigation from stacktrace to inline function call site
|
||||
|
||||
###### Issues fixed
|
||||
- Do not step into inline lambda argument during step over inside inline function body
|
||||
- Fix step over for inline argument with non-local return
|
||||
- [`KT-12067`](https://youtrack.jetbrains.com/issue/KT-12067) Deadlock in Kotlin debugger is fixed
|
||||
- [`KT-12232`](https://youtrack.jetbrains.com/issue/KT-12232) No code completion in Evaluate Expression and Throwable at CodeCompletionHandlerBase.invokeCompletion()
|
||||
- [`KT-12137`](https://youtrack.jetbrains.com/issue/KT-12137) Evaluate expression: code completion/intention actions allows to use symbols from modules that are not referenced
|
||||
- [`KT-12206`](https://youtrack.jetbrains.com/issue/KT-12206) NoSuchFieldError in Evaluate Expression on a property of a derived class
|
||||
- [`KT-12678`](https://youtrack.jetbrains.com/issue/KT-12678) NoSuchFieldError in Evaluate Expression on accessing delegated property defined in other module
|
||||
- [`KT-12773`](https://youtrack.jetbrains.com/issue/KT-12773) Fix debugging for Kotlin JS projects
|
||||
|
||||
#### Formatter
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-12035`](https://youtrack.jetbrains.com/issue/KT-12035) Spaces around `as`
|
||||
- [`KT-12018`](https://youtrack.jetbrains.com/issue/KT-12018) Spaces between function name and arguments in infix calls
|
||||
- [`KT-11961`](https://youtrack.jetbrains.com/issue/KT-11961) Spaces before angle bracket in method definition
|
||||
- [`KT-12175`](https://youtrack.jetbrains.com/issue/KT-12175) Don't enforce empty line between secondary constructors without body
|
||||
- [`KT-12548`](https://youtrack.jetbrains.com/issue/KT-12548) Spaces around `is` keyword
|
||||
- [`KT-12446`](https://youtrack.jetbrains.com/issue/KT-12446) Spaces before class type parameters
|
||||
- [`KT-12634`](https://youtrack.jetbrains.com/issue/KT-12634) Spaces between method name and parenthesis in method call
|
||||
- [`KT-10680`](https://youtrack.jetbrains.com/issue/KT-10680) Spaces around `in` keyword
|
||||
- [`KT-12791`](https://youtrack.jetbrains.com/issue/KT-12791) Spaces between curly brace and expression inside string template
|
||||
- [`KT-12781`](https://youtrack.jetbrains.com/issue/KT-12781) Spaces between annotation and expression
|
||||
- [`KT-12689`](https://youtrack.jetbrains.com/issue/KT-12689) Spaces around semicolons
|
||||
- [`KT-12714`](https://youtrack.jetbrains.com/issue/KT-12714) Spaces around parentheses in enum elements
|
||||
|
||||
#### Other
|
||||
|
||||
###### New features
|
||||
|
||||
- Added "Decompile" button to Kotlin bytecode toolwindow
|
||||
- Added Kotlin "Tips of the day"
|
||||
- Added "Kotlin 1.1 EAP" to "Configure Kotlin Plugin updates"
|
||||
- [`KT-2919`](https://youtrack.jetbrains.com/issue/KT-2919) Constructor calls are no longer highlighted as classes
|
||||
- [`KT-6540`](https://youtrack.jetbrains.com/issue/KT-6540) Infix function calls are now highlighted as regular function calls
|
||||
- [`KT-9410`](https://youtrack.jetbrains.com/issue/KT-9410) Annotations in Kotlin are now highlighted with the same color as in Java by default
|
||||
- [`KT-11465`](https://youtrack.jetbrains.com/issue/KT-11465) Type parameters in Kotlin are now highlighted with the same color as in Java by default
|
||||
- [`KT-11657`](https://youtrack.jetbrains.com/issue/KT-11657) Allow viewing decompiled Java source code for Kotlin-compiled classes
|
||||
- [`KT-11704`](https://youtrack.jetbrains.com/issue/KT-11704) Support file path references inside of Kotlin string literals
|
||||
- [`KT-12076`](https://youtrack.jetbrains.com/issue/KT-12076) Kotlin Plugin update check: always display installed version number
|
||||
- [`KT-11814`](https://youtrack.jetbrains.com/issue/KT-11814) New icon for kotlin annotation classes
|
||||
- [`KT-12735`](https://youtrack.jetbrains.com/issue/KT-12735) Convert JavaDoc to KDoc when overriding Java class member in Kotlin
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-5960`](https://youtrack.jetbrains.com/issue/KT-5960) Can't find usages for Java methods used from Kotlin by call convention
|
||||
- [`KT-8362`](https://youtrack.jetbrains.com/issue/KT-8362) "New Kotlin file": Keywords should be escaped in package name
|
||||
- [`KT-8682`](https://youtrack.jetbrains.com/issue/KT-8682) Respect "Copy JavaDoc" option in the "Override/Implement Members..." dialog
|
||||
- [`KT-8817`](https://youtrack.jetbrains.com/issue/KT-8817) Fixed rename of Java getters/setters through synthetic property references in Kotlin
|
||||
- [`KT-9399`](https://youtrack.jetbrains.com/issue/KT-9399) Find Usages omits Kotlin annotation parameter usage in Java source
|
||||
- [`KT-9797`](https://youtrack.jetbrains.com/issue/KT-9797) "Kotlin Bytecode" toolwindow breaks after closing
|
||||
- [`KT-11145`](https://youtrack.jetbrains.com/issue/KT-11145) Use progress indicator when searching usages in Introduce Parameter
|
||||
- [`KT-11155`](https://youtrack.jetbrains.com/issue/KT-11155) Allow running multiple Kotlin classes as well as running mixtures of Kotlin and Java classes
|
||||
- [`KT-11495`](https://youtrack.jetbrains.com/issue/KT-11495) Show recursion line markers for extension function calls with different receiver
|
||||
- [`KT-11659`](https://youtrack.jetbrains.com/issue/KT-11659) Generate abstract overrides for Any members inside of Kotlin interfaces
|
||||
- [`KT-12070`](https://youtrack.jetbrains.com/issue/KT-12070) Add empty line in error message of Maven and Gradle configuration
|
||||
- [`KT-11908`](https://youtrack.jetbrains.com/issue/KT-11908) Allow properties with custom setters to be used in generated equals/hashCode/toString
|
||||
- [`KT-11617`](https://youtrack.jetbrains.com/issue/KT-11617) Fixed title of Introduce Parameter declaration chooser
|
||||
- [`KT-11817`](https://youtrack.jetbrains.com/issue/KT-11817) Fixed rename of Kotlin enum constants through Java references
|
||||
- [`KT-11816`](https://youtrack.jetbrains.com/issue/KT-11816) Fixed usages search for Safe Delete on simple enum entries
|
||||
- [`KT-11282`](https://youtrack.jetbrains.com/issue/KT-11282) Delete interface reference from super-type list when applying Safe Delete to Java interface
|
||||
- [`KT-11967`](https://youtrack.jetbrains.com/issue/KT-11967) Fix Find Usages/Rename for parameter references in XML files
|
||||
- [`KT-10770`](https://youtrack.jetbrains.com/issue/KT-10770) "Optimize imports" will not keep import if a type is only referenced by kdoc
|
||||
- [`KT-11955`](https://youtrack.jetbrains.com/issue/KT-11955) Copy/Paste inserts fully qualified name when copying function with overloads
|
||||
- [`KT-12436`](https://youtrack.jetbrains.com/issue/KT-12436) "Replace explicit parameter with it": java.lang.Exception at BaseRefactoringProcessor.run()
|
||||
- [`KT-12440`](https://youtrack.jetbrains.com/issue/KT-12440) Removing unused parameter results in Exception "Refactorings should not be started inside write action"
|
||||
- [`KT-12006`](https://youtrack.jetbrains.com/issue/KT-12006) getLanguageLevel is slow for Kotlin light classes
|
||||
- [`KT-12026`](https://youtrack.jetbrains.com/issue/KT-12026) "Constant expression required" in Java for const Kotlin values
|
||||
- [`KT-12259`](https://youtrack.jetbrains.com/issue/KT-12259) ClassCastException in light classes while trying to create generic property
|
||||
- [`KT-12289`](https://youtrack.jetbrains.com/issue/KT-12289) Remove unnecessary `?` from `serr` live template
|
||||
- [`KT-12110`](https://youtrack.jetbrains.com/issue/KT-12110) Map help button of the Compiler - Kotlin page
|
||||
- [`KT-12075`](https://youtrack.jetbrains.com/issue/KT-12075) Kotlin Plugin update check: make dumbaware
|
||||
- [`KT-10255`](https://youtrack.jetbrains.com/issue/KT-10255) call BuildManager.clearState(project) in apply() method of Kotlin Compiler Settings configurable
|
||||
- [`KT-11841`](https://youtrack.jetbrains.com/issue/KT-11841) New Project / Module wizard, Gradle: pure Kotlin module is created without `repositories` call in build.gradle
|
||||
- [`KT-11095`](https://youtrack.jetbrains.com/issue/KT-11095) Java cannot infer generic return type of Kotlin function (with java 8 language level)
|
||||
- [`KT-12090`](https://youtrack.jetbrains.com/issue/KT-12090) Intellij/Kotlin plugin does not handle generic return type of static method defined in Kotlin, called from Java
|
||||
- [`KT-12206`](https://youtrack.jetbrains.com/issue/KT-12206) Fix NoSuchFieldError on accessing base property without backing field in evaluate expression
|
||||
- [`KT-12516`](https://youtrack.jetbrains.com/issue/KT-12516) File Structure: Kotlin annotation classes have Java annotation icons
|
||||
- [`KT-11328`](https://youtrack.jetbrains.com/issue/KT-11328) "New Kotlin class": generates packages when fully qualified name is specified
|
||||
- [`KT-11778`](https://youtrack.jetbrains.com/issue/KT-11778) Exception in Lombok plugin: Rewrite at slice FUNCTION
|
||||
- [`KT-11708`](https://youtrack.jetbrains.com/issue/KT-11708) "Go to declaration" doesn't work on a call to function with SAM conversion on a derived type
|
||||
- [`KT-12381`](https://youtrack.jetbrains.com/issue/KT-12381) Prefer not-nullable return type when overriding Java method without nullability annotation
|
||||
- [`KT-12647`](https://youtrack.jetbrains.com/issue/KT-12647) Performance improvement for test-related line markers
|
||||
- [`KT-12526`](https://youtrack.jetbrains.com/issue/KT-12526) Kotlin intentions increase PSI modification counts from isAvailable, even in daemon threads
|
||||
|
||||
### Reflection
|
||||
|
||||
###### Issues fixed
|
||||
- [`KT-11531`](https://youtrack.jetbrains.com/issue/KT-11531) Optimize "KCallable.name"
|
||||
- [`KT-10771`](https://youtrack.jetbrains.com/issue/KT-10771) Reflection on Function objects does not support lambdas with generic return type
|
||||
- [`KT-11824`](https://youtrack.jetbrains.com/issue/KT-11824) Reflection inconsistency between member property and accessor
|
||||
|
||||
### JS
|
||||
|
||||
- Improve performance of maps and sets
|
||||
|
||||
###### Issues fixed
|
||||
- [`KT-6942`](https://youtrack.jetbrains.com/issue/KT-6942) Generate structural equality check (i.e. `Any.equals`) instead of referential check (===) value equality patterns in `when`
|
||||
- [`KT-7228`](https://youtrack.jetbrains.com/issue/KT-7228) Wrong AbstractList signature
|
||||
- [`KT-8299`](https://youtrack.jetbrains.com/issue/KT-8299) Wrong access to private member in autogenerated code in data class
|
||||
- [`KT-11346`](https://youtrack.jetbrains.com/issue/KT-11346) Reified functions like `filterIsInstance` are now available in JS Standard Library
|
||||
- [`KT-12305`](https://youtrack.jetbrains.com/issue/KT-12305) Incorrect translation of `vararg` in `@native` functions
|
||||
- [`KT-12254`](https://youtrack.jetbrains.com/issue/KT-12254) JsEmptyExpression in initializer when compiling code like `val x = throw Exception()`
|
||||
- [`KT-11960`](https://youtrack.jetbrains.com/issue/KT-11960) Wrong code generated when a method of a local class calls constructor of the class
|
||||
- [`KT-10931`](https://youtrack.jetbrains.com/issue/KT-10931) Incorrect inlining of library method with optional parameters
|
||||
- [`KT-12417`](https://youtrack.jetbrains.com/issue/KT-12417) Wrong check cast generated for KMutableProperty
|
||||
|
||||
### Tools
|
||||
|
||||
###### New features
|
||||
|
||||
- [`KT-11839`](https://youtrack.jetbrains.com/issue/KT-11839) Maven goal to execute kotlin script
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- KAPT: fix error when using enum constructors with parameters
|
||||
- Various problems with gradle 2.2 fixed: [`KT-12478`](https://youtrack.jetbrains.com/issue/KT-12478), [`KT-12406`](https://youtrack.jetbrains.com/issue/KT-12406), [`KT-12478`](https://youtrack.jetbrains.com/issue/KT-12478)
|
||||
- [`KT-12595`](https://youtrack.jetbrains.com/issue/KT-12595) JPS: Fixed com.intellij.util.io.MappingFailedException: Cannot map buffer
|
||||
- [`KT-11166`](https://youtrack.jetbrains.com/issue/KT-11166) Gradle: Unable to access internal classes from test code within the same module
|
||||
- [`KT-12352`](https://youtrack.jetbrains.com/issue/KT-12352) KAPT: Fix "Classpath entry points to a non-existent location" warnings
|
||||
- [`KT-12074`](https://youtrack.jetbrains.com/issue/KT-12074) Building Kotlin maven projects using a parent pom will silently fail
|
||||
- [`KT-11770`](https://youtrack.jetbrains.com/issue/KT-11770) Warning "RuntimeException: Could not find installation home path" when using Gradle Incremental Compilation
|
||||
- [`KT-10969`](https://youtrack.jetbrains.com/issue/KT-10969) Android extensions: NullPointerException when finding view in Fragment
|
||||
- [`KT-11885`](https://youtrack.jetbrains.com/issue/KT-11885) Gradle/Android: Unresolved reference "kotlinx" when classpath dependency is defined in root build.gradle
|
||||
- [`KT-12786`](https://youtrack.jetbrains.com/issue/KT-12786) Deprecation warning with Gradle 2.14
|
||||
|
||||
## 1.0.2-1
|
||||
|
||||
- [KT-12159](https://youtrack.jetbrains.com/issue/KT-12159), [KT-12406](https://youtrack.jetbrains.com/issue/KT-12406), [KT-12431](https://youtrack.jetbrains.com/issue/KT-12431), [KT-12478](https://youtrack.jetbrains.com/issue/KT-12478) Support Android Studio 2.2
|
||||
- [KT-11770](https://youtrack.jetbrains.com/issue/KT-11770) Fix warning "RuntimeException: Could not find installation home path" when using incremental compilation in Gradle
|
||||
- [KT-12436](https://youtrack.jetbrains.com/issue/KT-12436), [KT-12440](https://youtrack.jetbrains.com/issue/KT-12440) Fix multiple exceptions during refactorings in IDEA 2016.2 EAP
|
||||
- [KT-12015](https://youtrack.jetbrains.com/issue/KT-12015), [KT-12047](https://youtrack.jetbrains.com/issue/KT-12047), [KT-12387](https://youtrack.jetbrains.com/issue/KT-12387) Fix multiple issues in Kotlin Lint checks
|
||||
|
||||
## 1.0.2
|
||||
|
||||
@@ -82,6 +493,7 @@ Issues fixed:
|
||||
- [KT-5429](https://youtrack.jetbrains.com/issue/KT-5429) Write nullability annotations on extension receiver parameters
|
||||
- [KT-11347](https://youtrack.jetbrains.com/issue/KT-11347) Preserve source file and line number of call site when inlining certain standard library functions
|
||||
- [KT-11677](https://youtrack.jetbrains.com/issue/KT-11677) Write correct generic signatures for local classes in inlined lambdas
|
||||
- [KT-12127](https://youtrack.jetbrains.com/issue/KT-12127) Do not write unnecessary generic signature for property delegate backing field
|
||||
- Fix multiple issues leading to exceptions or bad bytecode being generated: [KT-11034](https://youtrack.jetbrains.com/issue/KT-11034), [KT-11519](https://youtrack.jetbrains.com/issue/KT-11519), [KT-11117](https://youtrack.jetbrains.com/issue/KT-11117), [KT-11479](https://youtrack.jetbrains.com/issue/KT-11479)
|
||||
|
||||
#### Java interoperability
|
||||
@@ -135,9 +547,15 @@ Issues fixed:
|
||||
- [KT-11030](https://youtrack.jetbrains.com/issue/KT-11030) Support local classes
|
||||
- [KT-7819](https://youtrack.jetbrains.com/issue/KT-7819) Support non-local returns in local lambdas
|
||||
- [KT-6912](https://youtrack.jetbrains.com/issue/KT-6912) Safe calls (`x?.let { it }`) are now inlined
|
||||
- [KT-2670](https://youtrack.jetbrains.com/issue/KT-2670) Support unsafe casts (`as`)
|
||||
- [KT-7016](https://youtrack.jetbrains.com/issue/KT-7016), [KT-8012](https://youtrack.jetbrains.com/issue/KT-8012) Fix `is`-checks for reified type parameters
|
||||
- [KT-7038](https://youtrack.jetbrains.com/issue/KT-7038) Avoid unwanted side effects on `is`-checks for nullable types
|
||||
- [KT-10614](https://youtrack.jetbrains.com/issue/KT-10614) Copy array on vararg call with spread operator
|
||||
- [KT-10785](https://youtrack.jetbrains.com/issue/KT-10785) Correctly translate property names and receiver instances in assignment operations
|
||||
- [KT-11611](https://youtrack.jetbrains.com/issue/KT-11611) Fix translation of default value of secondary constructor's functional parameter
|
||||
- [KT-11100](https://youtrack.jetbrains.com/issue/KT-11100) Fix generation of `invoke` on objects and companion objects
|
||||
- [KT-11823](https://youtrack.jetbrains.com/issue/KT-11823) Fix capturing of outer class' `this` in inner's lambdas
|
||||
- [KT-11996](https://youtrack.jetbrains.com/issue/KT-11996) Fix translation of a call to a private member of an outer class from an inner class which is a subtype of the outer class
|
||||
- [KT-10667](https://youtrack.jetbrains.com/issue/KT-10667) Support inheritance from nested built-in types such as Map.Entry
|
||||
- [KT-7480](https://youtrack.jetbrains.com/issue/KT-7480) Remove declarations of LinkedList, SortedSet, TreeSet, Enumeration
|
||||
- [KT-3064](https://youtrack.jetbrains.com/issue/KT-3064) Implement `CharSequence.repeat`
|
||||
@@ -193,11 +611,12 @@ Issues fixed:
|
||||
- [KT-11295](https://youtrack.jetbrains.com/issue/KT-11295) "Convert string to template" intention: fix exception on certain code
|
||||
- [KT-10750](https://youtrack.jetbrains.com/issue/KT-10750), [KT-11424](https://youtrack.jetbrains.com/issue/KT-11424) "Convert if to when" intention now detects effectively else branches in subsequent code and performs more accurate comment handling
|
||||
- Configure Kotlin: show only changed files in the notification "Kotlin not configured", restore all changed files in undo action
|
||||
- [KT-11556](https://youtrack.jetbrains.com/issue/KT-11556) Do not show "Kotlin not configured" for Kotlin JS projects
|
||||
- [KT-11593](https://youtrack.jetbrains.com/issue/KT-11593) Fix "Configure Kotlin" action for Gradle projects in IDEA 2016
|
||||
- [KT-11077](https://youtrack.jetbrains.com/issue/KT-11077) Use new built-in definition file format (`.kotlin_builtins` files)
|
||||
- [KT-5728](https://youtrack.jetbrains.com/issue/KT-5728) Remove closing curly brace in a string template when opening one is deleted
|
||||
- [KT-10883](https://youtrack.jetbrains.com/issue/KT-10883) "Explicit get or set call" quick fix: do not move caret too far away
|
||||
- [KT-5717](https://youtrack.jetbrains.com/issue/KT-5717) "Replace 'when' with 'if'": do not lose comments
|
||||
- [KT-5717](https://youtrack.jetbrains.com/issue/KT-5717) "Replace `when` with `if`": do not lose comments
|
||||
- [KT-10797](https://youtrack.jetbrains.com/issue/KT-10797) "Replace with operator" intention is not available anymore for non-`operator` functions
|
||||
- [KT-11529](https://youtrack.jetbrains.com/issue/KT-11529) Highlighting range for unresolved annotation name does not include `@` now
|
||||
- [KT-11178](https://youtrack.jetbrains.com/issue/KT-11178) Don't show "Change type arguments" fix when there's nothing to change
|
||||
@@ -208,7 +627,8 @@ Issues fixed:
|
||||
- [KT-11720](https://youtrack.jetbrains.com/issue/KT-11720) Fixed renaming of Kotlin beans through SpEL references
|
||||
- [KT-11719](https://youtrack.jetbrains.com/issue/KT-11719) Fixed renaming of Kotlin parameters references in XML files
|
||||
- [KT-11736](https://youtrack.jetbrains.com/issue/KT-11736) Fixed searching of Java usages for @JvmStatic properties and @JvmStatic @JvmOverloads functions
|
||||
- Fix several issues leading to exceptions: [KT-11579](https://youtrack.jetbrains.com/issue/KT-11579), [KT-11580](https://youtrack.jetbrains.com/issue/KT-11580), [KT-11777](https://youtrack.jetbrains.com/issue/KT-11777), [KT-11868](https://youtrack.jetbrains.com/issue/KT-11868), [KT-11845](https://youtrack.jetbrains.com/issue/KT-11845)
|
||||
- [KT-11862](https://youtrack.jetbrains.com/issue/KT-11862) Fixed bogus warnings about unresolved types in the Change Signature dialog
|
||||
- Fix several issues leading to exceptions: [KT-11579](https://youtrack.jetbrains.com/issue/KT-11579), [KT-11580](https://youtrack.jetbrains.com/issue/KT-11580), [KT-11777](https://youtrack.jetbrains.com/issue/KT-11777), [KT-11868](https://youtrack.jetbrains.com/issue/KT-11868), [KT-11845](https://youtrack.jetbrains.com/issue/KT-11845), [KT-11486](https://youtrack.jetbrains.com/issue/KT-11486)
|
||||
- Fixed NoSuchFieldException in Kotlin module settings on IDEA Ultimate
|
||||
|
||||
#### Debugger
|
||||
@@ -271,6 +691,8 @@ Issues fixed:
|
||||
- [KT-8487](https://youtrack.jetbrains.com/issue/KT-8487) Experimental support for incremental compilation with project property `kotlin.incremental`
|
||||
- [KT-11350](https://youtrack.jetbrains.com/issue/KT-11350) Fixed a bug causing Java rebuild when both Java and Kotlin are up-to-date
|
||||
- [KT-10507](https://youtrack.jetbrains.com/issue/KT-10507) Fix IllegalArgumentException "Missing extension point" on parallel builds
|
||||
- [KT-10932](https://youtrack.jetbrains.com/issue/KT-10932) Prevent compile tasks from running when nothing changes
|
||||
- [KT-11993](https://youtrack.jetbrains.com/issue/KT-11993) Fix NoSuchMethodError on access to internal members in production from tests (IDEA 2016+)
|
||||
|
||||
## 1.0.1-2
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.google.protobuf.MessageLite
|
||||
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.io.BooleanDataDescriptor
|
||||
@@ -33,6 +32,7 @@ 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.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
@@ -122,6 +122,11 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
}
|
||||
|
||||
// used in gradle
|
||||
@Suppress("unused")
|
||||
fun classesBySources(sources: Iterable<File>): Iterable<JvmClassName> =
|
||||
sources.flatMap { sourceToClassesMap[it] }
|
||||
|
||||
fun getSubtypesOf(className: FqName): Sequence<FqName> =
|
||||
subtypesMap[className].asSequence()
|
||||
|
||||
@@ -641,12 +646,12 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
|
||||
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)
|
||||
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
|
||||
val inlineFunctions = inlineFunctionsJvmNames(header)
|
||||
if (inlineFunctions.isEmpty()) return emptyMap()
|
||||
|
||||
val result = HashMap<String, Long>()
|
||||
|
||||
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)
|
||||
@@ -669,7 +674,7 @@ open class IncrementalCacheImpl<Target>(
|
||||
}
|
||||
|
||||
fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean): CompilationResult {
|
||||
return put(kotlinClass.className, getInlineFunctionsMap(kotlinClass.fileContents), isPackage)
|
||||
return put(kotlinClass.className, getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents), isPackage)
|
||||
}
|
||||
|
||||
private fun put(className: JvmClassName, newMap: Map<String, Long>, isPackage: Boolean): CompilationResult {
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.google.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
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.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.Deserialization
|
||||
|
||||
@@ -16,13 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental.testingUtils
|
||||
|
||||
import com.google.common.collect.Sets
|
||||
import com.google.common.hash.Hashing
|
||||
import com.google.common.io.Files
|
||||
import com.google.protobuf.ExtensionRegistry
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistry
|
||||
import org.jetbrains.kotlin.serialization.DebugProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||
import org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf
|
||||
@@ -36,6 +33,7 @@ import java.io.File
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.util.*
|
||||
import java.util.zip.CRC32
|
||||
import kotlin.comparisons.compareBy
|
||||
|
||||
// Set this to true if you want to dump all bytecode (test will fail in this case)
|
||||
@@ -45,7 +43,7 @@ fun assertEqualDirectories(expected: File, actual: File, forgiveExtraFiles: Bool
|
||||
val pathsInExpected = getAllRelativePaths(expected)
|
||||
val pathsInActual = getAllRelativePaths(actual)
|
||||
|
||||
val commonPaths = Sets.intersection(pathsInExpected, pathsInActual)
|
||||
val commonPaths = pathsInExpected.intersect(pathsInActual)
|
||||
val changedPaths = commonPaths
|
||||
.filter { DUMP_ALL || !Arrays.equals(File(expected, it).readBytes(), File(actual, it).readBytes()) }
|
||||
.sorted()
|
||||
@@ -71,7 +69,11 @@ fun assertEqualDirectories(expected: File, actual: File, forgiveExtraFiles: Bool
|
||||
Assert.assertEquals(expectedString, actualString)
|
||||
}
|
||||
|
||||
private fun File.hash() = Files.hash(this, Hashing.crc32())
|
||||
private fun File.checksumString(): String {
|
||||
val crc32 = CRC32()
|
||||
crc32.update(this.readBytes())
|
||||
return java.lang.Long.toHexString(crc32.value)
|
||||
}
|
||||
|
||||
private fun getDirectoryString(dir: File, interestingPaths: List<String>): String {
|
||||
val buf = StringBuilder()
|
||||
@@ -93,7 +95,7 @@ private fun getDirectoryString(dir: File, interestingPaths: List<String>): Strin
|
||||
}
|
||||
}
|
||||
else {
|
||||
p.println(child.name, " ", child.hash())
|
||||
p.println(child.name, " ", child.checksumString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ package org.jetbrains.kotlin.serialization;
|
||||
public final class DebugExtOptionsProtoBuf {
|
||||
private DebugExtOptionsProtoBuf() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry) {
|
||||
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.skipInComparison);
|
||||
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.nameIdInTable);
|
||||
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.fqNameIdInTable);
|
||||
@@ -17,9 +17,9 @@ public final class DebugExtOptionsProtoBuf {
|
||||
* <code>extend .google.protobuf.FieldOptions { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
com.google.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> skipInComparison = com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> skipInComparison = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Boolean.class,
|
||||
null);
|
||||
@@ -28,9 +28,9 @@ public final class DebugExtOptionsProtoBuf {
|
||||
* <code>extend .google.protobuf.FieldOptions { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
com.google.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> nameIdInTable = com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> nameIdInTable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Boolean.class,
|
||||
null);
|
||||
@@ -39,9 +39,9 @@ public final class DebugExtOptionsProtoBuf {
|
||||
* <code>extend .google.protobuf.FieldOptions { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
com.google.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> fqNameIdInTable = com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> fqNameIdInTable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Boolean.class,
|
||||
null);
|
||||
@@ -50,18 +50,18 @@ public final class DebugExtOptionsProtoBuf {
|
||||
* <code>extend .google.protobuf.FieldOptions { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
com.google.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> stringIdInTable = com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.DescriptorProtos.FieldOptions,
|
||||
java.lang.Boolean> stringIdInTable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Boolean.class,
|
||||
null);
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
public static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
private static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
@@ -74,12 +74,12 @@ public final class DebugExtOptionsProtoBuf {
|
||||
":<\n\023fq_name_id_in_table\022\035.google.protobu" +
|
||||
"f.FieldOptions\030\322\206\003 \001(\010:;\n\022string_id_in_t" +
|
||||
"able\022\035.google.protobuf.FieldOptions\030\323\206\003 " +
|
||||
"\001(\010B\034B\027DebugExtOptionsProtoBuf\210\001\000"
|
||||
"\001(\010B\031B\027DebugExtOptionsProtoBuf"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public org.jetbrains.kotlin.protobuf.ExtensionRegistry assignDescriptors(
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
skipInComparison.internalInit(descriptor.getExtensions().get(0));
|
||||
nameIdInTable.internalInit(descriptor.getExtensions().get(1));
|
||||
@@ -88,12 +88,12 @@ public final class DebugExtOptionsProtoBuf {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
com.google.protobuf.DescriptorProtos.getDescriptor(),
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor[] {
|
||||
org.jetbrains.kotlin.protobuf.DescriptorProtos.getDescriptor(),
|
||||
}, assigner);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ package org.jetbrains.kotlin.serialization.builtins;
|
||||
public final class DebugBuiltInsProtoBuf {
|
||||
private DebugBuiltInsProtoBuf() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry) {
|
||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.packageFqName);
|
||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.classAnnotation);
|
||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.constructorAnnotation);
|
||||
@@ -19,7 +19,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
registry.add(org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.typeParameterAnnotation);
|
||||
}
|
||||
public interface BuiltInsOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
extends org.jetbrains.kotlin.protobuf.MessageOrBuilder {
|
||||
|
||||
// optional .org.jetbrains.kotlin.serialization.StringTable strings = 1;
|
||||
/**
|
||||
@@ -92,14 +92,14 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* Protobuf type {@code org.jetbrains.kotlin.serialization.builtins.BuiltIns}
|
||||
*/
|
||||
public static final class BuiltIns extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
implements BuiltInsOrBuilder {
|
||||
// Use BuiltIns.newBuilder() to construct.
|
||||
private BuiltIns(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
private BuiltIns(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.unknownFields = builder.getUnknownFields();
|
||||
}
|
||||
private BuiltIns(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
private BuiltIns(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
|
||||
private static final BuiltIns defaultInstance;
|
||||
public static BuiltIns getDefaultInstance() {
|
||||
@@ -110,20 +110,20 @@ public final class DebugBuiltInsProtoBuf {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
private final com.google.protobuf.UnknownFieldSet unknownFields;
|
||||
private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
|
||||
@java.lang.Override
|
||||
public final com.google.protobuf.UnknownFieldSet
|
||||
public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private BuiltIns(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
initFields();
|
||||
int mutable_bitField0_ = 0;
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||
org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
@@ -188,10 +188,10 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||
throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
|
||||
e.getMessage()).setUnfinishedMessage(this);
|
||||
} finally {
|
||||
if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
@@ -201,30 +201,30 @@ public final class DebugBuiltInsProtoBuf {
|
||||
makeExtensionsImmutable();
|
||||
}
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns.class, org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns.Builder.class);
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Parser<BuiltIns> PARSER =
|
||||
new com.google.protobuf.AbstractParser<BuiltIns>() {
|
||||
public static org.jetbrains.kotlin.protobuf.Parser<BuiltIns> PARSER =
|
||||
new org.jetbrains.kotlin.protobuf.AbstractParser<BuiltIns>() {
|
||||
public BuiltIns parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return new BuiltIns(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
@java.lang.Override
|
||||
public com.google.protobuf.Parser<BuiltIns> getParserForType() {
|
||||
public org.jetbrains.kotlin.protobuf.Parser<BuiltIns> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
@@ -389,19 +389,19 @@ public final class DebugBuiltInsProtoBuf {
|
||||
|
||||
size = 0;
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeMessageSize(1, strings_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeMessageSize(2, qualifiedNames_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeMessageSize(3, package_);
|
||||
}
|
||||
for (int i = 0; i < class_.size(); i++) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeMessageSize(4, class_.get(i));
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
@@ -417,24 +417,24 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ByteString data)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ByteString data,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(java.io.InputStream input)
|
||||
@@ -443,7 +443,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
@@ -453,18 +453,18 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
@@ -478,7 +478,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
|
||||
@java.lang.Override
|
||||
protected Builder newBuilderForType(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
@@ -486,14 +486,14 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* Protobuf type {@code org.jetbrains.kotlin.serialization.builtins.BuiltIns}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder>
|
||||
implements org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltInsOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
@@ -506,12 +506,12 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
|
||||
private Builder(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
getStringsFieldBuilder();
|
||||
getQualifiedNamesFieldBuilder();
|
||||
getPackageFieldBuilder();
|
||||
@@ -555,7 +555,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
return create().mergeFrom(buildPartial());
|
||||
}
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_descriptor;
|
||||
}
|
||||
@@ -614,7 +614,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
|
||||
if (other instanceof org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns) {
|
||||
return mergeFrom((org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns)other);
|
||||
} else {
|
||||
@@ -653,7 +653,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
class_ = other.class_;
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
classBuilder_ =
|
||||
com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
|
||||
getClassFieldBuilder() : null;
|
||||
} else {
|
||||
classBuilder_.addAllMessages(other.class_);
|
||||
@@ -687,13 +687,13 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (org.jetbrains.kotlin.serialization.builtins.DebugBuiltInsProtoBuf.BuiltIns) e.getUnfinishedMessage();
|
||||
throw e;
|
||||
} finally {
|
||||
@@ -707,7 +707,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
|
||||
// optional .org.jetbrains.kotlin.serialization.StringTable strings = 1;
|
||||
private org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable strings_ = org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable.getDefaultInstance();
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable, org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTableOrBuilder> stringsBuilder_;
|
||||
/**
|
||||
* <code>optional .org.jetbrains.kotlin.serialization.StringTable strings = 1;</code>
|
||||
@@ -808,11 +808,11 @@ public final class DebugBuiltInsProtoBuf {
|
||||
/**
|
||||
* <code>optional .org.jetbrains.kotlin.serialization.StringTable strings = 1;</code>
|
||||
*/
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable, org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTableOrBuilder>
|
||||
getStringsFieldBuilder() {
|
||||
if (stringsBuilder_ == null) {
|
||||
stringsBuilder_ = new com.google.protobuf.SingleFieldBuilder<
|
||||
stringsBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable, org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTable.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.StringTableOrBuilder>(
|
||||
strings_,
|
||||
getParentForChildren(),
|
||||
@@ -824,7 +824,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
|
||||
// optional .org.jetbrains.kotlin.serialization.QualifiedNameTable qualified_names = 2;
|
||||
private org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable qualifiedNames_ = org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable.getDefaultInstance();
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable, org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTableOrBuilder> qualifiedNamesBuilder_;
|
||||
/**
|
||||
* <code>optional .org.jetbrains.kotlin.serialization.QualifiedNameTable qualified_names = 2;</code>
|
||||
@@ -925,11 +925,11 @@ public final class DebugBuiltInsProtoBuf {
|
||||
/**
|
||||
* <code>optional .org.jetbrains.kotlin.serialization.QualifiedNameTable qualified_names = 2;</code>
|
||||
*/
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable, org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTableOrBuilder>
|
||||
getQualifiedNamesFieldBuilder() {
|
||||
if (qualifiedNamesBuilder_ == null) {
|
||||
qualifiedNamesBuilder_ = new com.google.protobuf.SingleFieldBuilder<
|
||||
qualifiedNamesBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable, org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTable.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.QualifiedNameTableOrBuilder>(
|
||||
qualifiedNames_,
|
||||
getParentForChildren(),
|
||||
@@ -941,7 +941,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
|
||||
// optional .org.jetbrains.kotlin.serialization.Package package = 3;
|
||||
private org.jetbrains.kotlin.serialization.DebugProtoBuf.Package package_ = org.jetbrains.kotlin.serialization.DebugProtoBuf.Package.getDefaultInstance();
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package, org.jetbrains.kotlin.serialization.DebugProtoBuf.Package.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.PackageOrBuilder> packageBuilder_;
|
||||
/**
|
||||
* <code>optional .org.jetbrains.kotlin.serialization.Package package = 3;</code>
|
||||
@@ -1042,11 +1042,11 @@ public final class DebugBuiltInsProtoBuf {
|
||||
/**
|
||||
* <code>optional .org.jetbrains.kotlin.serialization.Package package = 3;</code>
|
||||
*/
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package, org.jetbrains.kotlin.serialization.DebugProtoBuf.Package.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.PackageOrBuilder>
|
||||
getPackageFieldBuilder() {
|
||||
if (packageBuilder_ == null) {
|
||||
packageBuilder_ = new com.google.protobuf.SingleFieldBuilder<
|
||||
packageBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package, org.jetbrains.kotlin.serialization.DebugProtoBuf.Package.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.PackageOrBuilder>(
|
||||
package_,
|
||||
getParentForChildren(),
|
||||
@@ -1066,7 +1066,7 @@ public final class DebugBuiltInsProtoBuf {
|
||||
}
|
||||
}
|
||||
|
||||
private com.google.protobuf.RepeatedFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Class.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.ClassOrBuilder> classBuilder_;
|
||||
|
||||
/**
|
||||
@@ -1281,11 +1281,11 @@ public final class DebugBuiltInsProtoBuf {
|
||||
getClassBuilderList() {
|
||||
return getClassFieldBuilder().getBuilderList();
|
||||
}
|
||||
private com.google.protobuf.RepeatedFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Class.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.ClassOrBuilder>
|
||||
getClassFieldBuilder() {
|
||||
if (classBuilder_ == null) {
|
||||
classBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
|
||||
classBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class, org.jetbrains.kotlin.serialization.DebugProtoBuf.Class.Builder, org.jetbrains.kotlin.serialization.DebugProtoBuf.ClassOrBuilder>(
|
||||
class_,
|
||||
((bitField0_ & 0x00000008) == 0x00000008),
|
||||
@@ -1312,9 +1312,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package,
|
||||
java.lang.Integer> packageFqName = com.google.protobuf.GeneratedMessage
|
||||
java.lang.Integer> packageFqName = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Integer.class,
|
||||
null);
|
||||
@@ -1323,9 +1323,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> classAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> classAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1334,9 +1334,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Constructor { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Constructor,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> constructorAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> constructorAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1345,9 +1345,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Function { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Function,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> functionAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> functionAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1356,9 +1356,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Property { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> propertyAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> propertyAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1367,9 +1367,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Property { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value> compileTimeValue = com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value> compileTimeValue = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.Argument.Value.getDefaultInstance());
|
||||
@@ -1378,9 +1378,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.EnumEntry { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.EnumEntry,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> enumEntryAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> enumEntryAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1389,9 +1389,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.ValueParameter { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.ValueParameter,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> parameterAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> parameterAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1400,9 +1400,9 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Type { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Type,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> typeAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> typeAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
@@ -1411,23 +1411,23 @@ public final class DebugBuiltInsProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.TypeParameter { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
com.google.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.TypeParameter,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> typeParameterAnnotation = com.google.protobuf.GeneratedMessage
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation>> typeParameterAnnotation = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Annotation.getDefaultInstance());
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
private static org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_descriptor;
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
public static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
private static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
@@ -1474,15 +1474,15 @@ public final class DebugBuiltInsProtoBuf {
|
||||
"etbrains.kotlin.serialization.Annotation" +
|
||||
"B\027B\025DebugBuiltInsProtoBuf"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public org.jetbrains.kotlin.protobuf.ExtensionRegistry assignDescriptors(
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_org_jetbrains_kotlin_serialization_builtins_BuiltIns_descriptor,
|
||||
new java.lang.String[] { "Strings", "QualifiedNames", "Package", "Class", });
|
||||
packageFqName.internalInit(descriptor.getExtensions().get(0));
|
||||
@@ -1498,12 +1498,12 @@ public final class DebugBuiltInsProtoBuf {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor[] {
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.getDescriptor(),
|
||||
}, assigner);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,10 +6,10 @@ package org.jetbrains.kotlin.serialization.jvm;
|
||||
public final class DebugJvmPackageTable {
|
||||
private DebugJvmPackageTable() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry) {
|
||||
}
|
||||
public interface PackageTableOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
extends org.jetbrains.kotlin.protobuf.MessageOrBuilder {
|
||||
|
||||
// repeated .org.jetbrains.kotlin.serialization.jvm.PackageParts package_parts = 1;
|
||||
/**
|
||||
@@ -40,14 +40,14 @@ public final class DebugJvmPackageTable {
|
||||
* Protobuf type {@code org.jetbrains.kotlin.serialization.jvm.PackageTable}
|
||||
*/
|
||||
public static final class PackageTable extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
implements PackageTableOrBuilder {
|
||||
// Use PackageTable.newBuilder() to construct.
|
||||
private PackageTable(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
private PackageTable(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.unknownFields = builder.getUnknownFields();
|
||||
}
|
||||
private PackageTable(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
private PackageTable(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
|
||||
private static final PackageTable defaultInstance;
|
||||
public static PackageTable getDefaultInstance() {
|
||||
@@ -58,20 +58,20 @@ public final class DebugJvmPackageTable {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
private final com.google.protobuf.UnknownFieldSet unknownFields;
|
||||
private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
|
||||
@java.lang.Override
|
||||
public final com.google.protobuf.UnknownFieldSet
|
||||
public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private PackageTable(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
initFields();
|
||||
int mutable_bitField0_ = 0;
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||
org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
@@ -97,10 +97,10 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||
throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
|
||||
e.getMessage()).setUnfinishedMessage(this);
|
||||
} finally {
|
||||
if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
@@ -110,30 +110,30 @@ public final class DebugJvmPackageTable {
|
||||
makeExtensionsImmutable();
|
||||
}
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable.class, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable.Builder.class);
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Parser<PackageTable> PARSER =
|
||||
new com.google.protobuf.AbstractParser<PackageTable>() {
|
||||
public static org.jetbrains.kotlin.protobuf.Parser<PackageTable> PARSER =
|
||||
new org.jetbrains.kotlin.protobuf.AbstractParser<PackageTable>() {
|
||||
public PackageTable parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return new PackageTable(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
@java.lang.Override
|
||||
public com.google.protobuf.Parser<PackageTable> getParserForType() {
|
||||
public org.jetbrains.kotlin.protobuf.Parser<PackageTable> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public final class DebugJvmPackageTable {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
for (int i = 0; i < packageParts_.size(); i++) {
|
||||
@@ -207,7 +207,7 @@ public final class DebugJvmPackageTable {
|
||||
|
||||
size = 0;
|
||||
for (int i = 0; i < packageParts_.size(); i++) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeMessageSize(1, packageParts_.get(i));
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
@@ -223,24 +223,24 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ByteString data)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ByteString data,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(java.io.InputStream input)
|
||||
@@ -249,7 +249,7 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
@@ -259,18 +259,18 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ public final class DebugJvmPackageTable {
|
||||
|
||||
@java.lang.Override
|
||||
protected Builder newBuilderForType(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
@@ -292,14 +292,14 @@ public final class DebugJvmPackageTable {
|
||||
* Protobuf type {@code org.jetbrains.kotlin.serialization.jvm.PackageTable}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder>
|
||||
implements org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTableOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
@@ -312,12 +312,12 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
private Builder(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
getPackagePartsFieldBuilder();
|
||||
}
|
||||
}
|
||||
@@ -340,7 +340,7 @@ public final class DebugJvmPackageTable {
|
||||
return create().mergeFrom(buildPartial());
|
||||
}
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_descriptor;
|
||||
}
|
||||
@@ -373,7 +373,7 @@ public final class DebugJvmPackageTable {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
|
||||
if (other instanceof org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable) {
|
||||
return mergeFrom((org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable)other);
|
||||
} else {
|
||||
@@ -403,7 +403,7 @@ public final class DebugJvmPackageTable {
|
||||
packageParts_ = other.packageParts_;
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
packagePartsBuilder_ =
|
||||
com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
|
||||
getPackagePartsFieldBuilder() : null;
|
||||
} else {
|
||||
packagePartsBuilder_.addAllMessages(other.packageParts_);
|
||||
@@ -425,13 +425,13 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageTable) e.getUnfinishedMessage();
|
||||
throw e;
|
||||
} finally {
|
||||
@@ -453,7 +453,7 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
}
|
||||
|
||||
private com.google.protobuf.RepeatedFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts.Builder, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackagePartsOrBuilder> packagePartsBuilder_;
|
||||
|
||||
/**
|
||||
@@ -668,11 +668,11 @@ public final class DebugJvmPackageTable {
|
||||
getPackagePartsBuilderList() {
|
||||
return getPackagePartsFieldBuilder().getBuilderList();
|
||||
}
|
||||
private com.google.protobuf.RepeatedFieldBuilder<
|
||||
private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts.Builder, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackagePartsOrBuilder>
|
||||
getPackagePartsFieldBuilder() {
|
||||
if (packagePartsBuilder_ == null) {
|
||||
packagePartsBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
|
||||
packagePartsBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts.Builder, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackagePartsOrBuilder>(
|
||||
packageParts_,
|
||||
((bitField0_ & 0x00000001) == 0x00000001),
|
||||
@@ -695,7 +695,7 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
public interface PackagePartsOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
extends org.jetbrains.kotlin.protobuf.MessageOrBuilder {
|
||||
|
||||
// required string package_fq_name = 1;
|
||||
/**
|
||||
@@ -709,7 +709,7 @@ public final class DebugJvmPackageTable {
|
||||
/**
|
||||
* <code>required string package_fq_name = 1;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
org.jetbrains.kotlin.protobuf.ByteString
|
||||
getPackageFqNameBytes();
|
||||
|
||||
// repeated string class_name = 2;
|
||||
@@ -729,21 +729,21 @@ public final class DebugJvmPackageTable {
|
||||
/**
|
||||
* <code>repeated string class_name = 2;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
org.jetbrains.kotlin.protobuf.ByteString
|
||||
getClassNameBytes(int index);
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code org.jetbrains.kotlin.serialization.jvm.PackageParts}
|
||||
*/
|
||||
public static final class PackageParts extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
implements PackagePartsOrBuilder {
|
||||
// Use PackageParts.newBuilder() to construct.
|
||||
private PackageParts(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
private PackageParts(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.unknownFields = builder.getUnknownFields();
|
||||
}
|
||||
private PackageParts(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
private PackageParts(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
|
||||
private static final PackageParts defaultInstance;
|
||||
public static PackageParts getDefaultInstance() {
|
||||
@@ -754,20 +754,20 @@ public final class DebugJvmPackageTable {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
private final com.google.protobuf.UnknownFieldSet unknownFields;
|
||||
private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
|
||||
@java.lang.Override
|
||||
public final com.google.protobuf.UnknownFieldSet
|
||||
public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private PackageParts(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
initFields();
|
||||
int mutable_bitField0_ = 0;
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||
org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
@@ -790,7 +790,7 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
case 18: {
|
||||
if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
className_ = new com.google.protobuf.LazyStringArrayList();
|
||||
className_ = new org.jetbrains.kotlin.protobuf.LazyStringArrayList();
|
||||
mutable_bitField0_ |= 0x00000002;
|
||||
}
|
||||
className_.add(input.readBytes());
|
||||
@@ -798,43 +798,43 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||
throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
|
||||
e.getMessage()).setUnfinishedMessage(this);
|
||||
} finally {
|
||||
if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
className_ = new com.google.protobuf.UnmodifiableLazyStringList(className_);
|
||||
className_ = new org.jetbrains.kotlin.protobuf.UnmodifiableLazyStringList(className_);
|
||||
}
|
||||
this.unknownFields = unknownFields.build();
|
||||
makeExtensionsImmutable();
|
||||
}
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts.class, org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts.Builder.class);
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Parser<PackageParts> PARSER =
|
||||
new com.google.protobuf.AbstractParser<PackageParts>() {
|
||||
public static org.jetbrains.kotlin.protobuf.Parser<PackageParts> PARSER =
|
||||
new org.jetbrains.kotlin.protobuf.AbstractParser<PackageParts>() {
|
||||
public PackageParts parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return new PackageParts(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
@java.lang.Override
|
||||
public com.google.protobuf.Parser<PackageParts> getParserForType() {
|
||||
public org.jetbrains.kotlin.protobuf.Parser<PackageParts> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@@ -856,8 +856,8 @@ public final class DebugJvmPackageTable {
|
||||
if (ref instanceof java.lang.String) {
|
||||
return (java.lang.String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
org.jetbrains.kotlin.protobuf.ByteString bs =
|
||||
(org.jetbrains.kotlin.protobuf.ByteString) ref;
|
||||
java.lang.String s = bs.toStringUtf8();
|
||||
if (bs.isValidUtf8()) {
|
||||
packageFqName_ = s;
|
||||
@@ -868,23 +868,23 @@ public final class DebugJvmPackageTable {
|
||||
/**
|
||||
* <code>required string package_fq_name = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
public org.jetbrains.kotlin.protobuf.ByteString
|
||||
getPackageFqNameBytes() {
|
||||
java.lang.Object ref = packageFqName_;
|
||||
if (ref instanceof java.lang.String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
org.jetbrains.kotlin.protobuf.ByteString b =
|
||||
org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
packageFqName_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
return (org.jetbrains.kotlin.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
// repeated string class_name = 2;
|
||||
public static final int CLASS_NAME_FIELD_NUMBER = 2;
|
||||
private com.google.protobuf.LazyStringList className_;
|
||||
private org.jetbrains.kotlin.protobuf.LazyStringList className_;
|
||||
/**
|
||||
* <code>repeated string class_name = 2;</code>
|
||||
*/
|
||||
@@ -907,14 +907,14 @@ public final class DebugJvmPackageTable {
|
||||
/**
|
||||
* <code>repeated string class_name = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
public org.jetbrains.kotlin.protobuf.ByteString
|
||||
getClassNameBytes(int index) {
|
||||
return className_.getByteString(index);
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
packageFqName_ = "";
|
||||
className_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
className_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
@@ -929,7 +929,7 @@ public final class DebugJvmPackageTable {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
@@ -948,13 +948,13 @@ public final class DebugJvmPackageTable {
|
||||
|
||||
size = 0;
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, getPackageFqNameBytes());
|
||||
}
|
||||
{
|
||||
int dataSize = 0;
|
||||
for (int i = 0; i < className_.size(); i++) {
|
||||
dataSize += com.google.protobuf.CodedOutputStream
|
||||
dataSize += org.jetbrains.kotlin.protobuf.CodedOutputStream
|
||||
.computeBytesSizeNoTag(className_.getByteString(i));
|
||||
}
|
||||
size += dataSize;
|
||||
@@ -973,24 +973,24 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ByteString data)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ByteString data,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(java.io.InputStream input)
|
||||
@@ -999,7 +999,7 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
@@ -1009,18 +1009,18 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
@@ -1034,7 +1034,7 @@ public final class DebugJvmPackageTable {
|
||||
|
||||
@java.lang.Override
|
||||
protected Builder newBuilderForType(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
@@ -1042,14 +1042,14 @@ public final class DebugJvmPackageTable {
|
||||
* Protobuf type {@code org.jetbrains.kotlin.serialization.jvm.PackageParts}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder>
|
||||
implements org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackagePartsOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
@@ -1062,12 +1062,12 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
private Builder(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
}
|
||||
}
|
||||
private static Builder create() {
|
||||
@@ -1078,7 +1078,7 @@ public final class DebugJvmPackageTable {
|
||||
super.clear();
|
||||
packageFqName_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
className_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
className_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
return this;
|
||||
}
|
||||
@@ -1087,7 +1087,7 @@ public final class DebugJvmPackageTable {
|
||||
return create().mergeFrom(buildPartial());
|
||||
}
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_descriptor;
|
||||
}
|
||||
@@ -1113,7 +1113,7 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
result.packageFqName_ = packageFqName_;
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
className_ = new com.google.protobuf.UnmodifiableLazyStringList(
|
||||
className_ = new org.jetbrains.kotlin.protobuf.UnmodifiableLazyStringList(
|
||||
className_);
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
}
|
||||
@@ -1123,7 +1123,7 @@ public final class DebugJvmPackageTable {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
|
||||
if (other instanceof org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts) {
|
||||
return mergeFrom((org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts)other);
|
||||
} else {
|
||||
@@ -1162,13 +1162,13 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
org.jetbrains.kotlin.protobuf.CodedInputStream input,
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (org.jetbrains.kotlin.serialization.jvm.DebugJvmPackageTable.PackageParts) e.getUnfinishedMessage();
|
||||
throw e;
|
||||
} finally {
|
||||
@@ -1194,7 +1194,7 @@ public final class DebugJvmPackageTable {
|
||||
public java.lang.String getPackageFqName() {
|
||||
java.lang.Object ref = packageFqName_;
|
||||
if (!(ref instanceof java.lang.String)) {
|
||||
java.lang.String s = ((com.google.protobuf.ByteString) ref)
|
||||
java.lang.String s = ((org.jetbrains.kotlin.protobuf.ByteString) ref)
|
||||
.toStringUtf8();
|
||||
packageFqName_ = s;
|
||||
return s;
|
||||
@@ -1205,17 +1205,17 @@ public final class DebugJvmPackageTable {
|
||||
/**
|
||||
* <code>required string package_fq_name = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
public org.jetbrains.kotlin.protobuf.ByteString
|
||||
getPackageFqNameBytes() {
|
||||
java.lang.Object ref = packageFqName_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
org.jetbrains.kotlin.protobuf.ByteString b =
|
||||
org.jetbrains.kotlin.protobuf.ByteString.copyFromUtf8(
|
||||
(java.lang.String) ref);
|
||||
packageFqName_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
return (org.jetbrains.kotlin.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
@@ -1244,7 +1244,7 @@ public final class DebugJvmPackageTable {
|
||||
* <code>required string package_fq_name = 1;</code>
|
||||
*/
|
||||
public Builder setPackageFqNameBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
org.jetbrains.kotlin.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@@ -1255,10 +1255,10 @@ public final class DebugJvmPackageTable {
|
||||
}
|
||||
|
||||
// repeated string class_name = 2;
|
||||
private com.google.protobuf.LazyStringList className_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
private org.jetbrains.kotlin.protobuf.LazyStringList className_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
|
||||
private void ensureClassNameIsMutable() {
|
||||
if (!((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
className_ = new com.google.protobuf.LazyStringArrayList(className_);
|
||||
className_ = new org.jetbrains.kotlin.protobuf.LazyStringArrayList(className_);
|
||||
bitField0_ |= 0x00000002;
|
||||
}
|
||||
}
|
||||
@@ -1284,7 +1284,7 @@ public final class DebugJvmPackageTable {
|
||||
/**
|
||||
* <code>repeated string class_name = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
public org.jetbrains.kotlin.protobuf.ByteString
|
||||
getClassNameBytes(int index) {
|
||||
return className_.getByteString(index);
|
||||
}
|
||||
@@ -1328,7 +1328,7 @@ public final class DebugJvmPackageTable {
|
||||
* <code>repeated string class_name = 2;</code>
|
||||
*/
|
||||
public Builder clearClassName() {
|
||||
className_ = com.google.protobuf.LazyStringArrayList.EMPTY;
|
||||
className_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
onChanged();
|
||||
return this;
|
||||
@@ -1337,7 +1337,7 @@ public final class DebugJvmPackageTable {
|
||||
* <code>repeated string class_name = 2;</code>
|
||||
*/
|
||||
public Builder addClassNameBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
org.jetbrains.kotlin.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@@ -1358,22 +1358,22 @@ public final class DebugJvmPackageTable {
|
||||
// @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.jvm.PackageParts)
|
||||
}
|
||||
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
private static org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_descriptor;
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_fieldAccessorTable;
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
private static org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_descriptor;
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
public static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
private static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
@@ -1386,31 +1386,31 @@ public final class DebugJvmPackageTable {
|
||||
"\nclass_name\030\002 \003(\tB\026B\024DebugJvmPackageTabl" +
|
||||
"e"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public org.jetbrains.kotlin.protobuf.ExtensionRegistry assignDescriptors(
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageTable_descriptor,
|
||||
new java.lang.String[] { "PackageParts", });
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_descriptor =
|
||||
getDescriptor().getMessageTypes().get(1);
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_PackageParts_descriptor,
|
||||
new java.lang.String[] { "PackageFqName", "ClassName", });
|
||||
return null;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor[] {
|
||||
}, assigner);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
28
build.xml
28
build.xml
@@ -24,7 +24,7 @@
|
||||
<property name="build.number" value="snapshot"/>
|
||||
<property name="bootstrap.build.no.tests" value="false"/>
|
||||
<property name="idea.sdk" value="${basedir}/ideaSDK"/>
|
||||
<property name="protobuf.jar" value="${idea.sdk}/lib/protobuf-2.5.0.jar"/>
|
||||
<property name="protobuf.jar" value="${basedir}/dependencies/protobuf-2.5.0.jar"/>
|
||||
<property name="protobuf-lite.jar" value="${basedir}/dependencies/protobuf-2.5.0-lite.jar"/>
|
||||
<property name="javax.inject.jar" value="${basedir}/lib/javax.inject.jar"/>
|
||||
|
||||
@@ -489,6 +489,13 @@
|
||||
<attribute name="compress" default="true"/>
|
||||
|
||||
<sequential>
|
||||
<local name="idea.core.uberjar.exists"/>
|
||||
<available file="${dependencies.dir}/idea/idea-core-all.jar" property="idea.core.uberjar.exists"/>
|
||||
<!-- TODO: move this jar creation to update_dependencies.xml eventually -->
|
||||
<jar jarfile="${dependencies.dir}/idea/idea-core-all.jar" unless:true="${idea.core.uberjar.exists}">
|
||||
<zipgroupfileset dir="${idea.sdk}/core" includes="*.jar" excludes="util.jar"/>
|
||||
</jar>
|
||||
|
||||
<jar jarfile="@{jarfile}" compress="@{compress}" duplicate="preserve">
|
||||
<fileset dir="${output}/classes/compiler"/>
|
||||
<fileset dir="${output}/builtins">
|
||||
@@ -507,7 +514,7 @@
|
||||
</fileset>
|
||||
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
|
||||
<zipfileset src="${dependencies.dir}/idea/idea-core-all.jar" excludes="META-INF/INDEX.LIST"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-platform.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/oromatcher.jar"/>
|
||||
<zipfileset src="${idea.sdk}/jps/jps-model.jar"/>
|
||||
@@ -655,38 +662,40 @@
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="kotlin-build-common-test" depends="kotlin-build-common,kotlin-test">
|
||||
<target name="kotlin-build-common-test">
|
||||
<cleandir dir="${output}/classes/kotlin-build-common-test"/>
|
||||
|
||||
<javac2 destdir="${output}/classes/kotlin-build-common-test" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin modulename="kotlin-build-common"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src path="build-common/test"/>
|
||||
<classpath>
|
||||
<pathelement path="${bootstrap.runtime}"/>
|
||||
<pathelement path="${bootstrap.reflect}"/>
|
||||
<pathelement path="${bootstrap.kotlin.test}"/>
|
||||
<pathelement path="${protobuf.jar}"/>
|
||||
<pathelement path="${idea.sdk}/lib/junit-4.12.jar"/>
|
||||
<pathelement path="${idea.sdk}/lib/guava-17.0.jar"/>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-build-common.jar"/>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
<pathelement path="${protobuf.jar}"/>
|
||||
</classpath>
|
||||
</javac2>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-build-common-test.jar">
|
||||
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
|
||||
|
||||
<jarjar jarfile="${kotlin-home}/lib/kotlin-build-common-test.jar">
|
||||
<fileset dir="${output}/classes/kotlin-build-common-test"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
<zipfileset src="${protobuf.jar}"/>
|
||||
<rule pattern="com.intellij.**" result="org.jetbrains.kotlin.com.intellij.@1"/>
|
||||
|
||||
<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.common}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</jarjar>
|
||||
</target>
|
||||
|
||||
<target name="daemon-client">
|
||||
@@ -998,7 +1007,6 @@
|
||||
<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>
|
||||
|
||||
|
||||
@@ -1,43 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="GEN_FOLDER_RELATIVE_PATH_APT" value="/gen" />
|
||||
<option name="GEN_FOLDER_RELATIVE_PATH_AIDL" value="/gen" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/assets" />
|
||||
<option name="LIBS_FOLDER_RELATIVE_PATH" value="/libs" />
|
||||
<option name="USE_CUSTOM_APK_RESOURCE_FOLDER" value="false" />
|
||||
<option name="CUSTOM_APK_RESOURCE_FOLDER" value="" />
|
||||
<option name="USE_CUSTOM_COMPILER_MANIFEST" value="false" />
|
||||
<option name="CUSTOM_COMPILER_MANIFEST" value="" />
|
||||
<option name="APK_PATH" value="" />
|
||||
<option name="LIBRARY_PROJECT" value="false" />
|
||||
<option name="RUN_PROCESS_RESOURCES_MAVEN_TASK" value="true" />
|
||||
<option name="GENERATE_UNSIGNED_APK" value="false" />
|
||||
<option name="CUSTOM_DEBUG_KEYSTORE_PATH" value="" />
|
||||
<option name="PACK_TEST_CODE" value="false" />
|
||||
<option name="RUN_PROGUARD" value="false" />
|
||||
<option name="PROGUARD_CFG_PATH" value="/proguard-project.txt" />
|
||||
<resOverlayFolders>
|
||||
<path>/res-overlay</path>
|
||||
</resOverlayFolders>
|
||||
<includeSystemProguardFile>true</includeSystemProguardFile>
|
||||
<includeAssetsFromLibraries>false</includeAssetsFromLibraries>
|
||||
<additionalNativeLibs />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<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$/gen" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android 2.3.3 Platform" jdkType="Android SDK" />
|
||||
<module version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
74
compiler/android-tests/android-module/build.gradle
Normal file
74
compiler/android-tests/android-module/build.gradle
Normal file
@@ -0,0 +1,74 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 19
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.jetbrains.kotlin.android.tests"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 19
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testApplicationId "org.jetbrains.kotlin.android.tests.gradle"
|
||||
testInstrumentationRunner "android.test.InstrumentationTestRunner"
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java {
|
||||
srcDirs = ['src']
|
||||
}
|
||||
res.srcDirs = ['res']
|
||||
}
|
||||
androidTest {
|
||||
java {
|
||||
srcDirs = ['src']
|
||||
}
|
||||
}
|
||||
}
|
||||
packagingOptions { exclude 'META-INF/build.txt' }
|
||||
|
||||
//TODO run under java 6, cause there is error on implicit 'stream' import in 'asWithMutable' test
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
incremental = false
|
||||
}
|
||||
|
||||
dexOptions {
|
||||
dexInProcess false
|
||||
javaMaxHeapSize "600m"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
androidTestCompile 'junit:junit:4.12'
|
||||
}
|
||||
@@ -8,5 +8,5 @@
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
#sdk.dir=compiler/android-tests/android-module/android-sdk/android-sdk-windows
|
||||
#sdk.dir.relative=android-sdk/android-sdk-windows
|
||||
sdk.dir=../../../android.tests.dependencies/android-sdk
|
||||
|
||||
|
||||
@@ -22,11 +22,8 @@ import java.lang.reflect.Method;
|
||||
|
||||
public class AbstractCodegenTestCaseOnAndroid extends TestCase {
|
||||
|
||||
protected void invokeBoxMethod(String filePath, String expectedResult) throws Exception {
|
||||
protected void invokeBoxMethod(Class clazz, String filePath, String expectedResult) throws Exception {
|
||||
try {
|
||||
String simpelName = filePath.substring(filePath.lastIndexOf("/") + 1);
|
||||
String packageName = filePath.replaceAll("\\\\|-|\\.|/", "_");
|
||||
Class clazz = Class.forName(packageName + "." + getPackageClassName(simpelName));
|
||||
Method method = clazz.getMethod("box");
|
||||
assertEquals(expectedResult, method.invoke(null));
|
||||
}
|
||||
@@ -34,8 +31,4 @@ public class AbstractCodegenTestCaseOnAndroid extends TestCase {
|
||||
throw new RuntimeException("File: " + filePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPackageClassName(String fileName) {
|
||||
return Character.toUpperCase(fileName.charAt(0)) + fileName.substring(1).replaceAll("\\.kt", "Kt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
<orderEntry type="library" name="idea-full" level="project" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="descriptor.loader.java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="frontend.java" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -19,25 +19,27 @@ package org.jetbrains.kotlin.android.tests;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.android.tests.ant.AntRunner;
|
||||
import org.jetbrains.kotlin.android.tests.download.SDKDownloader;
|
||||
import org.jetbrains.kotlin.android.tests.emulator.Emulator;
|
||||
import org.jetbrains.kotlin.android.tests.gradle.GradleRunner;
|
||||
import org.jetbrains.kotlin.android.tests.run.PermissionManager;
|
||||
import org.junit.Assert;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CodegenTestsOnAndroidRunner {
|
||||
private static final Pattern ERROR_IN_TEST_OUTPUT_PATTERN =
|
||||
Pattern.compile("([\\s]+at .*| Caused .*| java.lang.RuntimeException: File: .*|[\\s]+\\.\\.\\. .* more| Error in .*)");
|
||||
private static final Pattern NUMBER_OF_TESTS_IF_FAILED = Pattern.compile("Tests run: ([0-9]*), Failures: ([0-9]*), Errors: ([0-9]*)");
|
||||
private static final Pattern NUMBER_OF_TESTS_OK = Pattern.compile(" OK \\(([0-9]*) tests\\)");
|
||||
|
||||
private final PathManager pathManager;
|
||||
|
||||
@@ -53,123 +55,22 @@ public class CodegenTestsOnAndroidRunner {
|
||||
TestSuite suite = new TestSuite("MySuite");
|
||||
|
||||
String resultOutput = runTests();
|
||||
if (resultOutput == null) return suite;
|
||||
|
||||
//Fix problem with exception parsing cause 'at' pattern
|
||||
resultOutput = resultOutput.replaceAll("\\[checkenv\\] Installed at", "[checkenv] Installed_at");
|
||||
|
||||
// Test name -> stackTrace
|
||||
Map<String, String> resultMap = parseOutputForFailedTests(resultOutput);
|
||||
final Statistics statistics;
|
||||
|
||||
// If map is empty => there are no failed tests
|
||||
if (resultMap.isEmpty()) {
|
||||
statistics = parseOutputForTestsNumberIfTestsPassed(resultOutput);
|
||||
String reportFolder = pathManager.getTmpFolder() + "/build/outputs/androidTest-results/connected";
|
||||
try {
|
||||
List<TestCase> testCases = parseSingleReportInFolder(reportFolder);
|
||||
for (TestCase aCase : testCases) {
|
||||
suite.addTest(aCase);
|
||||
}
|
||||
Assert.assertNotEquals("There is no test results in report", 0, testCases.size());
|
||||
}
|
||||
else {
|
||||
statistics = parseOutputForTestsNumberIfThereIsFailedTests(resultOutput);
|
||||
|
||||
for (final Map.Entry<String, String> entry : resultMap.entrySet()) {
|
||||
|
||||
suite.addTest(new TestCase("run") {
|
||||
@Override
|
||||
public String getName() {
|
||||
return entry.getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
Assert.fail(entry.getValue() + "See more information in log above.");
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("Can't parse test results in " + reportFolder +"\n" + resultOutput);
|
||||
}
|
||||
|
||||
Assert.assertNotNull("Cannot parse number of failed tests from final line", statistics);
|
||||
Assert.assertEquals("Number of stackTraces != failed tests on the final line", resultMap.size(),
|
||||
statistics.failed + statistics.errors);
|
||||
|
||||
suite.addTest(new TestCase("run") {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "testAll: Total: " + statistics.total + ", Failures: " + statistics.failed + ", Errors: " + statistics.errors;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
Assert.assertTrue(true);
|
||||
}
|
||||
});
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Output example:
|
||||
[exec] Error in testKt344:
|
||||
[exec] java.lang.RuntimeException: File: compiler\testData\codegen\box\regressions\kt344.kt
|
||||
[exec] at org.jetbrains.kotlin.android.tests.AbstractCodegenTestCaseOnAndroid.invokeBoxMethod(AbstractCodegenTestCaseOnAndroid.java:38)
|
||||
[exec] at org.jetbrains.kotlin.android.tests.CodegenTestCaseOnAndroid.testKt344(CodegenTestCaseOnAndroid.java:595)
|
||||
[exec] at java.lang.reflect.Method.invokeNative(Native Method)
|
||||
[exec] at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
|
||||
[exec] Caused by: java.lang.reflect.InvocationTargetException
|
||||
[exec] at java.lang.reflect.Method.invokeNative(Native Method)
|
||||
[exec] at org.jetbrains.kotlin.android.tests.AbstractCodegenTestCaseOnAndroid.invokeBoxMethod(AbstractCodegenTestCaseOnAndroid.java:35)
|
||||
[exec] ... 13 more
|
||||
[exec] Caused by: java.lang.VerifyError: compiler_testData_codegen_box_regressions_kt344_kt.Compiler_testData_codegen_box_regressions_kt344_ktPackage$t6$foo$1
|
||||
[exec] at compiler_testData_codegen_box_regressions_kt344_kt.Compiler_testData_codegen_box_regressions_kt344_ktPackage.t6(dummy.kt:94)
|
||||
[exec] at compiler_testData_codegen_box_regressions_kt344_kt.Compiler_testData_codegen_box_regressions_kt344_ktPackage.box(dummy.kt:185)
|
||||
[exec] ... 16 more
|
||||
[exec] ...............
|
||||
[exec] Error in testKt529:
|
||||
*/
|
||||
private static Map<String, String> parseOutputForFailedTests(@NotNull String output) {
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String failedTestNamePrefix = " Error in ";
|
||||
String lastFailedTestName = "";
|
||||
Matcher matcher = ERROR_IN_TEST_OUTPUT_PATTERN.matcher(output);
|
||||
while (matcher.find()) {
|
||||
String groupValue = matcher.group();
|
||||
if (groupValue.startsWith(failedTestNamePrefix)) {
|
||||
if (builder.length() > 0) {
|
||||
result.put(lastFailedTestName, builder.toString());
|
||||
builder.delete(0, builder.length());
|
||||
}
|
||||
lastFailedTestName = groupValue.substring(failedTestNamePrefix.length());
|
||||
}
|
||||
builder.append(groupValue);
|
||||
builder.append("\n");
|
||||
}
|
||||
if (builder.length() > 0) {
|
||||
result.put(lastFailedTestName, builder.toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//[exec] Tests run: 225, Failures: 0, Errors: 2
|
||||
@Nullable
|
||||
private static Statistics parseOutputForTestsNumberIfThereIsFailedTests(String output) {
|
||||
Matcher matcher = NUMBER_OF_TESTS_IF_FAILED.matcher(output);
|
||||
if (matcher.find()) {
|
||||
return new Statistics(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)),
|
||||
Integer.parseInt(matcher.group(3)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//[exec] OK (223 tests)
|
||||
@Nullable
|
||||
private static Statistics parseOutputForTestsNumberIfTestsPassed(String output) {
|
||||
Matcher matcher = NUMBER_OF_TESTS_OK.matcher(output);
|
||||
if (matcher.find()) {
|
||||
return new Statistics(Integer.parseInt(matcher.group(1)), 0, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String runTests() {
|
||||
File rootForAndroidDependencies = new File(pathManager.getDependenciesRoot());
|
||||
@@ -178,27 +79,27 @@ public class CodegenTestsOnAndroidRunner {
|
||||
}
|
||||
|
||||
SDKDownloader downloader = new SDKDownloader(pathManager);
|
||||
Emulator emulator = new Emulator(pathManager, Emulator.ARM);
|
||||
AntRunner antRunner = new AntRunner(pathManager);
|
||||
downloader.downloadAll();
|
||||
downloader.unzipAll();
|
||||
PermissionManager.setPermissions(pathManager);
|
||||
|
||||
AntRunner antRunner = new AntRunner(pathManager);
|
||||
antRunner.packLibraries();
|
||||
Emulator emulator = new Emulator(pathManager, Emulator.ARM);
|
||||
GradleRunner gradleRunner = new GradleRunner(pathManager);
|
||||
gradleRunner.clean();
|
||||
gradleRunner.build();
|
||||
|
||||
emulator.createEmulator();
|
||||
|
||||
String platformPrefixProperty = System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, "Idea");
|
||||
|
||||
try {
|
||||
PermissionManager.setPermissions(pathManager);
|
||||
|
||||
antRunner.packLibraries();
|
||||
|
||||
emulator.createEmulator();
|
||||
emulator.startEmulator();
|
||||
|
||||
try {
|
||||
emulator.waitEmulatorStart();
|
||||
antRunner.cleanOutput();
|
||||
antRunner.compileSources();
|
||||
antRunner.installApplicationOnEmulator();
|
||||
return antRunner.runTestsOnEmulator();
|
||||
//runTestsViaAdb(emulator, gradleRunner);
|
||||
return gradleRunner.connectedDebugAndroidTest();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
@@ -223,15 +124,55 @@ public class CodegenTestsOnAndroidRunner {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Statistics {
|
||||
public final int total;
|
||||
public final int errors;
|
||||
public final int failed;
|
||||
private String runTestsViaAdb(Emulator emulator, GradleRunner gradleRunner) {
|
||||
gradleRunner.installDebugAndroidTest();
|
||||
String result = emulator.runTestsViaAdb();
|
||||
System.out.println(result);
|
||||
gradleRunner.uninstallDebugAndroidTest();
|
||||
return result;
|
||||
}
|
||||
|
||||
private Statistics(int total, int failed, int errors) {
|
||||
this.total = total;
|
||||
this.failed = failed;
|
||||
this.errors = errors;
|
||||
private static List<TestCase> parseSingleReportInFolder(String reportFolder) throws
|
||||
IOException,
|
||||
SAXException,
|
||||
ParserConfigurationException {
|
||||
File folder = new File(reportFolder);
|
||||
File[] files = folder.listFiles();
|
||||
assert files != null;
|
||||
assert files.length == 1;
|
||||
File reportFile = files[0];
|
||||
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
Document doc = dBuilder.parse(reportFile);
|
||||
Element root = doc.getDocumentElement();
|
||||
NodeList testCases = root.getElementsByTagName("testcase");
|
||||
List<TestCase> result = new ArrayList(testCases.getLength());
|
||||
|
||||
for (int i = 0; i < testCases.getLength(); i++) {
|
||||
Element item = (Element) testCases.item(i);
|
||||
final NodeList failure = item.getElementsByTagName("failure");
|
||||
String name = item.getAttribute("name");
|
||||
String clazz = item.getAttribute("classname");
|
||||
|
||||
if (failure.getLength() == 0) {
|
||||
result.add(new TestCase(name) {
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
result.add(new TestCase(name) {
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
Assert.fail(failure.item(0).getTextContent());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,10 @@ public class PathManager {
|
||||
return rootFolder + "/android.tests.dependencies";
|
||||
}
|
||||
|
||||
public String getGradleBinFolder() {
|
||||
return getDependenciesRoot() + "/gradle-2.12/bin";
|
||||
}
|
||||
|
||||
public String getRootForDownload() {
|
||||
return getDependenciesRoot() + "/download";
|
||||
}
|
||||
|
||||
@@ -34,13 +34,15 @@ public class SDKDownloader {
|
||||
private final String platformToolsZipPath;
|
||||
private final String skdToolsZipPath;
|
||||
private final String buildToolsZipPath;
|
||||
private final String gradleZipPath;
|
||||
|
||||
private final PathManager pathManager;
|
||||
|
||||
private static final String PLATFORM_TOOLS = "23.1.0";
|
||||
//NOTE: PLATFORM_TOOLS 23.1.0 requires only 64 bit build agents
|
||||
private static final String PLATFORM_TOOLS = "23.0.1";
|
||||
private static final String SDK_TOOLS = "25.1.1";
|
||||
public static final String BUILD_TOOLS = "23.0.3";
|
||||
private static final int ANDROID_VERSION = 16;
|
||||
private static final int ANDROID_VERSION = 19;
|
||||
|
||||
|
||||
public SDKDownloader(PathManager pathManager) {
|
||||
@@ -51,27 +53,32 @@ public class SDKDownloader {
|
||||
platformToolsZipPath = pathManager.getRootForDownload() + "/platform-tools.zip";
|
||||
skdToolsZipPath = pathManager.getRootForDownload() + "/tools.zip";
|
||||
buildToolsZipPath = pathManager.getRootForDownload() + "/build-tools.zip";
|
||||
gradleZipPath = pathManager.getRootForDownload() + "/gradle.zip";
|
||||
}
|
||||
|
||||
public void downloadPlatform() {
|
||||
download("http://dl-ssl.google.com/android/repository/android-" + ANDROID_VERSION + "_r05.zip", platformZipPath); //Same for all platforms
|
||||
download("https://dl-ssl.google.com/android/repository/android-" + ANDROID_VERSION + "_r04.zip", platformZipPath); //Same for all platforms
|
||||
}
|
||||
|
||||
private void downloadAbi() {
|
||||
download("http://dl.google.com/android/repository/sys-img/android/sysimg_armv7a-" + ANDROID_VERSION + "_r04.zip", armImage); //Same for all platforms
|
||||
download("https://dl.google.com/android/repository/sys-img/android/sysimg_x86-" + ANDROID_VERSION + "_r02.zip", x86Image); //Same for all platforms
|
||||
download("https://dl.google.com/android/repository/sys-img/android/sysimg_armv7a-" + ANDROID_VERSION + "_r03.zip", armImage); //Same for all platforms
|
||||
download("https://dl.google.com/android/repository/sys-img/android/sysimg_x86-" + ANDROID_VERSION + "_r03.zip", x86Image); //Same for all platforms
|
||||
}
|
||||
|
||||
public void downloadPlatformTools() {
|
||||
download(getDownloadUrl("http://dl-ssl.google.com/android/repository/platform-tools_r" + PLATFORM_TOOLS), platformToolsZipPath);
|
||||
download(getDownloadUrl("https://dl-ssl.google.com/android/repository/platform-tools_r" + PLATFORM_TOOLS), platformToolsZipPath);
|
||||
}
|
||||
|
||||
public void downloadSdkTools() {
|
||||
download(getDownloadUrl("http://dl.google.com/android/repository/tools_r" + SDK_TOOLS), skdToolsZipPath);
|
||||
download(getDownloadUrl("https://dl.google.com/android/repository/tools_r" + SDK_TOOLS), skdToolsZipPath);
|
||||
}
|
||||
|
||||
public void downloadBuildTools() {
|
||||
download(getDownloadUrl("http://dl.google.com/android/repository/build-tools_r" + BUILD_TOOLS), buildToolsZipPath);
|
||||
download(getDownloadUrl("https://dl.google.com/android/repository/build-tools_r" + BUILD_TOOLS), buildToolsZipPath);
|
||||
}
|
||||
|
||||
public void downloadGradle() {
|
||||
download("https://services.gradle.org/distributions/gradle-2.12-bin.zip", gradleZipPath);
|
||||
}
|
||||
|
||||
private static String getDownloadUrl(String prefix) {
|
||||
@@ -97,17 +104,23 @@ public class SDKDownloader {
|
||||
downloadPlatform();
|
||||
downloadPlatformTools();
|
||||
downloadBuildTools();
|
||||
downloadGradle();
|
||||
}
|
||||
|
||||
|
||||
public void unzipAll() {
|
||||
String androidSdkRoot = pathManager.getAndroidSdkRoot();
|
||||
unzip(platformZipPath, pathManager.getPlatformFolderInAndroidSdk());
|
||||
unzip(armImage, androidSdkRoot + "/system-images/android-" + ANDROID_VERSION + "/");
|
||||
unzip(x86Image, androidSdkRoot + "/system-images/android-" + ANDROID_VERSION + "/");
|
||||
new File(pathManager.getPlatformFolderInAndroidSdk() + "/android-4.4.2").renameTo(new File(pathManager.getPlatformFolderInAndroidSdk() + "/android-" + ANDROID_VERSION));
|
||||
|
||||
unzip(armImage, androidSdkRoot + "/system-images/android-" + ANDROID_VERSION + "/default/");
|
||||
unzip(x86Image, androidSdkRoot + "/system-images/android-" + ANDROID_VERSION + "/default/");
|
||||
|
||||
unzip(platformToolsZipPath, androidSdkRoot);
|
||||
unzip(skdToolsZipPath, androidSdkRoot);
|
||||
|
||||
unzip(gradleZipPath, pathManager.getDependenciesRoot());
|
||||
|
||||
//BUILD TOOLS
|
||||
String buildTools = androidSdkRoot + "/build-tools/";
|
||||
String buildToolsFolder = buildTools + BUILD_TOOLS + "/";
|
||||
@@ -123,6 +136,7 @@ public class SDKDownloader {
|
||||
delete(buildToolsZipPath);
|
||||
delete(armImage);
|
||||
delete(x86Image);
|
||||
delete(gradleZipPath);
|
||||
}
|
||||
|
||||
private static void download(String urlString, String output) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.android.tests.OutputUtils;
|
||||
import org.jetbrains.kotlin.android.tests.PathManager;
|
||||
import org.jetbrains.kotlin.android.tests.run.RunResult;
|
||||
import org.jetbrains.kotlin.android.tests.run.RunUtils;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -123,7 +124,7 @@ public class Emulator {
|
||||
GeneralCommandLine commandLine = createAdbCommand();
|
||||
commandLine.addParameter("start-server");
|
||||
System.out.println("Start adb server...");
|
||||
OutputUtils.checkResult(RunUtils.execute(commandLine));
|
||||
OutputUtils.checkResult(RunUtils.execute(new RunUtils.RunSettings(commandLine, null, true, "ADB START:", true)));
|
||||
}
|
||||
|
||||
public void startEmulator() {
|
||||
@@ -138,13 +139,38 @@ public class Emulator {
|
||||
commandLine.addParameter("logcat");
|
||||
commandLine.addParameter("-v");
|
||||
commandLine.addParameter("time");
|
||||
commandLine.addParameter("*:I");
|
||||
commandLine.addParameter("-s");
|
||||
commandLine.addParameter("dalvikvm:W");
|
||||
commandLine.addParameter("TestRunner:I");
|
||||
RunUtils.executeOnSeparateThread(new RunUtils.RunSettings(commandLine, null, false, "LOGCAT: ", true));
|
||||
}
|
||||
|
||||
public void waitEmulatorStart() {
|
||||
System.out.println("Waiting for emulator start...");
|
||||
OutputUtils.checkResult(RunUtils.execute(getWaitCommand()));
|
||||
GeneralCommandLine bootCheckCommand = createAdbCommand();
|
||||
bootCheckCommand.addParameter("shell");
|
||||
bootCheckCommand.addParameter("getprop");
|
||||
bootCheckCommand.addParameter("sys.boot_completed");
|
||||
int counter = 0;
|
||||
RunResult execute = RunUtils.execute(bootCheckCommand);
|
||||
while (counter < 12) {
|
||||
String output = execute.getOutput();
|
||||
if (output.trim().endsWith("1")) {
|
||||
System.out.println("Emulator fully booted!");
|
||||
return;
|
||||
}
|
||||
System.out.println("Waiting for emulator boot (" + counter + ")...");
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
counter++;
|
||||
execute = RunUtils.execute(bootCheckCommand);
|
||||
}
|
||||
Assert.fail("Can't find booted emulator: " + execute.getOutput());
|
||||
}
|
||||
|
||||
public void stopEmulator() {
|
||||
@@ -212,6 +238,15 @@ public class Emulator {
|
||||
}
|
||||
}
|
||||
|
||||
public String runTestsViaAdb() {
|
||||
System.out.println("Running tests via adb...");
|
||||
GeneralCommandLine adbCommand = createAdbCommand();
|
||||
//adb shell am instrument -w -r org.jetbrains.kotlin.android.tests/android.test.InstrumentationTestRunner
|
||||
adbCommand.addParameters("shell", "am", "instrument", "-w", "-r", "org.jetbrains.kotlin.android.tests/android.test.InstrumentationTestRunner");
|
||||
RunResult execute = RunUtils.execute(adbCommand);
|
||||
return execute.getOutput();
|
||||
}
|
||||
|
||||
private void stopRedundantEmulators(PathManager pathManager) {
|
||||
GeneralCommandLine commandLineForListOfDevices = createAdbCommand();
|
||||
commandLineForListOfDevices.addParameter("devices");
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.android.tests.gradle;
|
||||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import org.jetbrains.kotlin.android.tests.OutputUtils;
|
||||
import org.jetbrains.kotlin.android.tests.PathManager;
|
||||
import org.jetbrains.kotlin.android.tests.run.RunResult;
|
||||
import org.jetbrains.kotlin.android.tests.run.RunUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GradleRunner {
|
||||
private final List<String> listOfCommands;
|
||||
|
||||
public GradleRunner(PathManager pathManager) {
|
||||
listOfCommands = new ArrayList<String>();
|
||||
String cmdName = SystemInfo.isWindows ? "gradle.bat" : "gradle";
|
||||
listOfCommands.add(pathManager.getGradleBinFolder() + "/" + cmdName);
|
||||
listOfCommands.add("--build-file");
|
||||
listOfCommands.add(pathManager.getTmpFolder() + "/build.gradle");
|
||||
}
|
||||
|
||||
|
||||
public void clean() {
|
||||
System.out.println("Building gradle project...");
|
||||
RunResult result = RunUtils.execute(generateCommandLine("clean"));
|
||||
OutputUtils.checkResult(result);
|
||||
}
|
||||
|
||||
public void build() {
|
||||
System.out.println("Building gradle project...");
|
||||
RunResult result = RunUtils.execute(generateCommandLine("build"));
|
||||
OutputUtils.checkResult(result);
|
||||
}
|
||||
|
||||
public void installDebugAndroidTest() {
|
||||
System.out.println("Install tests...");
|
||||
OutputUtils.checkResult(RunUtils.execute(generateCommandLine("installDebug")));
|
||||
OutputUtils.checkResult(RunUtils.execute(generateCommandLine("installDebugAndroidTest")));
|
||||
}
|
||||
|
||||
public void uninstallDebugAndroidTest() {
|
||||
System.out.println("Uninstall tests...");
|
||||
RunUtils.execute(generateCommandLine("uninstallDebugAndroidTest"));
|
||||
RunUtils.execute(generateCommandLine("uninstallDebug"));
|
||||
}
|
||||
|
||||
public String connectedDebugAndroidTest() {
|
||||
System.out.println("Starting tests...");
|
||||
RunResult result = RunUtils.execute(generateCommandLine("connectedAndroidTest"));
|
||||
return result.getOutput();
|
||||
}
|
||||
|
||||
private GeneralCommandLine generateCommandLine(String taskName) {
|
||||
GeneralCommandLine commandLine = new GeneralCommandLine(listOfCommands);
|
||||
commandLine.addParameter(taskName);
|
||||
return commandLine;
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,10 @@ public class PermissionManager {
|
||||
if (!SystemInfo.isWindows) {
|
||||
RunUtils.execute(generateChmodCmd(pathManager.getAntBinDirectory() + "/ant"));
|
||||
setExecPermissionForSimpleNamedFiles(new File(pathManager.getToolsFolderInAndroidSdk()));
|
||||
setExecPermissionForSimpleNamedFiles(new File(pathManager.getToolsFolderInAndroidSdk() + "/bin64"));
|
||||
setExecPermissionForSimpleNamedFiles(new File(pathManager.getBuildToolsFolderInAndroidSdk() + "/" + SDKDownloader.BUILD_TOOLS));
|
||||
setExecPermissionForSimpleNamedFiles(new File(pathManager.getPlatformToolsFolderInAndroidSdk()));
|
||||
RunUtils.execute(generateChmodCmd(pathManager.getGradleBinFolder() + "/gradle"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import junit.framework.TestSuite;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AndroidRunner extends TestSuite {
|
||||
|
||||
@@ -42,7 +44,8 @@ public class AndroidRunner extends TestSuite {
|
||||
PathManager pathManager = getPathManager();
|
||||
|
||||
FileUtil.copyDir(new File(pathManager.getAndroidModuleRoot()), new File(pathManager.getTmpFolder()));
|
||||
|
||||
writeAndroidSkdToLocalProperties();
|
||||
|
||||
CodegenTestsOnAndroidGenerator.generate(pathManager);
|
||||
|
||||
System.out.println("Run tests on android...");
|
||||
@@ -55,4 +58,15 @@ public class AndroidRunner extends TestSuite {
|
||||
// Clear tmp folder where we run android tests
|
||||
FileUtil.delete(new File(pathManager.getTmpFolder()));
|
||||
}
|
||||
|
||||
private static void writeAndroidSkdToLocalProperties() throws IOException {
|
||||
System.out.println("Writing android sdk to local.properties: " + pathManager.getAndroidSdkRoot());
|
||||
File file = new File(pathManager.getTmpFolder() + "/local.properties");
|
||||
FileWriter fw = new FileWriter(file);
|
||||
try {
|
||||
fw.write("sdk.dir=" + pathManager.getAndroidSdkRoot());
|
||||
} finally {
|
||||
fw.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.android.tests
|
||||
|
||||
import com.intellij.openapi.util.Ref
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
import java.util.regex.Pattern
|
||||
|
||||
private val FILE_NAME_ANNOTATIONS = arrayOf("@file:JvmName", "@file:kotlin.jvm.JvmName")
|
||||
|
||||
private val packagePattern = Pattern.compile("(?m)^\\s*package[ |\t]+([\\w|\\.]*)")
|
||||
|
||||
private val importPattern = Pattern.compile("import[ |\t]([\\w|]*\\.)")
|
||||
|
||||
internal fun genFiles(file: File, fileContent: String, filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter): FqName? {
|
||||
val testFiles = createTestFiles(file, fileContent)
|
||||
if (testFiles.filter { it.name.endsWith(".java") }.isNotEmpty()) {
|
||||
//TODO support java files
|
||||
return null;
|
||||
}
|
||||
val ktFiles = testFiles.filter { it.name.endsWith(".kt") }
|
||||
if (ktFiles.isEmpty()) return null
|
||||
|
||||
val newPackagePrefix = file.path.replace("\\\\|-|\\.|/".toRegex(), "_")
|
||||
val oldPackage = Ref<FqName>()
|
||||
val isSingle = testFiles.size == 1
|
||||
val resultFiles = testFiles.map {
|
||||
val fileName = if (isSingle) it.name else file.name.substringBeforeLast(".kt") + "/" + it.name
|
||||
TestClassInfo(
|
||||
fileName,
|
||||
changePackage(newPackagePrefix, it.content, oldPackage),
|
||||
oldPackage.get(),
|
||||
getGeneratedClassName(File(fileName), it.content, newPackagePrefix, oldPackage.get())
|
||||
)
|
||||
}
|
||||
|
||||
/*replace all Class.forName*/
|
||||
resultFiles.forEach {
|
||||
file ->
|
||||
file.content = resultFiles.fold(file.content) { r, param ->
|
||||
patchClassForName(param.newClassId, param.oldPackage, r)
|
||||
}
|
||||
}
|
||||
|
||||
/*patch imports and self imports*/
|
||||
resultFiles.forEach {
|
||||
file ->
|
||||
file.content = resultFiles.fold(file.content) { r, param ->
|
||||
r.patchImports(param.oldPackage, param.newPackage)
|
||||
}.patchSelfImports(file.newPackage)
|
||||
}
|
||||
|
||||
resultFiles.forEach { resultFile -> filesHolder.addFile(resultFile.name, resultFile.content) }
|
||||
|
||||
val boxFiles = resultFiles.filter { hasBoxMethod(it.content) }
|
||||
if (boxFiles.size != 1) {
|
||||
println("Several box methods in $file")
|
||||
}
|
||||
return boxFiles.last().newClassId
|
||||
}
|
||||
|
||||
|
||||
private fun createTestFiles(file: File, expectedText: String): List<CodegenTestCase.TestFile> {
|
||||
val files = KotlinTestUtils.createTestFiles(file.name, expectedText, object : KotlinTestUtils.TestFileFactoryNoModules<CodegenTestCase.TestFile>() {
|
||||
override fun create(fileName: String, text: String, directives: Map<String, String>): CodegenTestCase.TestFile {
|
||||
return CodegenTestCase.TestFile(fileName, text)
|
||||
}
|
||||
})
|
||||
return files
|
||||
}
|
||||
|
||||
private fun hasBoxMethod(text: String): Boolean {
|
||||
return text.contains("fun box()")
|
||||
}
|
||||
|
||||
class TestClassInfo(val name: String, var content: String, val oldPackage: FqName, val newClassId: FqName) {
|
||||
val newPackage = newClassId.parent()
|
||||
}
|
||||
|
||||
|
||||
private fun changePackage(newPackagePrefix: String, text: String, oldPackage: Ref<FqName>): String {
|
||||
val matcher = packagePattern.matcher(text)
|
||||
if (matcher.find()) {
|
||||
val oldPackageName = matcher.toMatchResult().group(1)
|
||||
oldPackage.set(FqName(oldPackageName))
|
||||
return matcher.replaceAll("package $newPackagePrefix.$oldPackageName")
|
||||
}
|
||||
else {
|
||||
oldPackage.set(FqName.ROOT)
|
||||
val packageDirective = "package $newPackagePrefix;\n"
|
||||
if (text.contains("@file:")) {
|
||||
val index = text.lastIndexOf("@file:")
|
||||
val packageDirectiveIndex = text.indexOf("\n", index)
|
||||
return text.substring(0, packageDirectiveIndex + 1) + packageDirective + text.substring(packageDirectiveIndex + 1)
|
||||
}
|
||||
else {
|
||||
return packageDirective + text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getGeneratedClassName(file: File, text: String, newPackagePrefix: String, oldPackage: FqName): FqName {
|
||||
//TODO support multifile facades
|
||||
var packageFqName = FqName(newPackagePrefix)
|
||||
if (!oldPackage.isRoot) {
|
||||
packageFqName = packageFqName.child(Name.identifier(oldPackage.asString()))
|
||||
}
|
||||
for (annotation in FILE_NAME_ANNOTATIONS) {
|
||||
if (text.contains(annotation)) {
|
||||
val indexOf = text.indexOf(annotation)
|
||||
val annotationParameter = text.substring(text.indexOf("(\"", indexOf) + 2, text.indexOf("\")", indexOf))
|
||||
return packageFqName.child(Name.identifier(annotationParameter))
|
||||
}
|
||||
}
|
||||
|
||||
return PackagePartClassUtils.getPackagePartFqName(packageFqName, file.name)
|
||||
}
|
||||
|
||||
private fun patchClassForName(className: FqName, oldPackage: FqName, text: String): String {
|
||||
return text.replace(("Class\\.forName\\(\"" + oldPackage.child(className.shortName()).asString() + "\"\\)").toRegex(), "Class.forName(\"" + className.asString() + "\")")
|
||||
}
|
||||
|
||||
private fun String.patchImports(oldPackage: FqName, newPackage: FqName): String {
|
||||
if (oldPackage.isRoot) return this
|
||||
|
||||
return this.replace(("import\\s+" + oldPackage.asString()).toRegex(), "import " + newPackage.asString())
|
||||
}
|
||||
|
||||
|
||||
private fun String.patchSelfImports(newPackage: FqName): String {
|
||||
var newText = this;
|
||||
val matcher = importPattern.matcher(this)
|
||||
while (matcher.find()) {
|
||||
val possibleSelfImport = matcher.toMatchResult().group(1)
|
||||
val classOrObjectPattern = Pattern.compile("[\\s|^](class|object)\\s$possibleSelfImport[\\s|\\(|{|;|:]")
|
||||
if (classOrObjectPattern.matcher(newText).find()) {
|
||||
newText = newText.replace("import " + possibleSelfImport, "import " + newPackage.child(Name.identifier(possibleSelfImport)).asString())
|
||||
}
|
||||
}
|
||||
return newText
|
||||
}
|
||||
@@ -29,8 +29,11 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.codegen.CodegenTestFiles;
|
||||
import org.jetbrains.kotlin.codegen.GenerationUtils;
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
@@ -43,8 +46,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
|
||||
@@ -55,7 +56,7 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
private static final String baseTestClassName = "AbstractCodegenTestCaseOnAndroid";
|
||||
private static final String generatorName = "CodegenTestsOnAndroidGenerator";
|
||||
|
||||
private final Pattern packagePattern = Pattern.compile("package (.*)");
|
||||
private static int MODULE_INDEX = 1;
|
||||
|
||||
private final List<String> generatedTestNames = Lists.newArrayList();
|
||||
|
||||
@@ -113,7 +114,7 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
p.println("public class ", testClassName, " extends ", baseTestClassName, " {");
|
||||
p.pushIndent();
|
||||
|
||||
generateTestMethodsForDirectories(p, new File("compiler/testData/codegen/box"));
|
||||
generateTestMethodsForDirectories(p, new File("compiler/testData/codegen/box"), new File("compiler/testData/codegen/boxInline"));
|
||||
|
||||
p.popIndent();
|
||||
p.println("}");
|
||||
@@ -124,27 +125,31 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
}
|
||||
|
||||
private void generateTestMethodsForDirectories(Printer p, File... dirs) throws IOException {
|
||||
FilesWriter holderMock = new FilesWriter(false);
|
||||
FilesWriter holderFull = new FilesWriter(true);
|
||||
FilesWriter holderMock = new FilesWriter(false, false);
|
||||
FilesWriter holderFull = new FilesWriter(true, false);
|
||||
FilesWriter holderInheritMFP = new FilesWriter(true, true);
|
||||
|
||||
for (File dir : dirs) {
|
||||
File[] files = dir.listFiles();
|
||||
Assert.assertNotNull("Folder with testData is empty: " + dir.getAbsolutePath(), files);
|
||||
processFiles(p, files, holderFull, holderMock);
|
||||
processFiles(p, files, holderFull, holderMock, holderInheritMFP);
|
||||
}
|
||||
|
||||
holderFull.writeFilesOnDisk();
|
||||
holderMock.writeFilesOnDisk();
|
||||
holderInheritMFP.writeFilesOnDisk();
|
||||
}
|
||||
|
||||
private class FilesWriter {
|
||||
class FilesWriter {
|
||||
private final boolean isFullJdkAndRuntime;
|
||||
private boolean inheritMultifileParts;
|
||||
|
||||
public List<KtFile> files = new ArrayList<KtFile>();
|
||||
private KotlinCoreEnvironment environment;
|
||||
|
||||
private FilesWriter(boolean isFullJdkAndRuntime) {
|
||||
private FilesWriter(boolean isFullJdkAndRuntime, boolean inheritMultifileParts) {
|
||||
this.isFullJdkAndRuntime = isFullJdkAndRuntime;
|
||||
this.inheritMultifileParts = inheritMultifileParts;
|
||||
environment = createEnvironment(isFullJdkAndRuntime);
|
||||
}
|
||||
|
||||
@@ -152,7 +157,7 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
return isFullJdkAndRuntime ?
|
||||
KotlinTestUtils.createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(
|
||||
myTestRootDisposable, ConfigurationKind.ALL, TestJdkKind.FULL_JDK
|
||||
) :
|
||||
) :
|
||||
KotlinTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(myTestRootDisposable, ConfigurationKind.JDK_ONLY);
|
||||
}
|
||||
|
||||
@@ -172,18 +177,35 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
environment = createEnvironment(isFullJdkAndRuntime);
|
||||
}
|
||||
|
||||
public void addFile(String name, String content) {
|
||||
try {
|
||||
files.add(CodegenTestFiles.create(name, content, environment.getProject()).getPsiFile());
|
||||
} catch (Throwable e) {
|
||||
new RuntimeException("Problem during creating file " + name + ": \n" + content, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeFiles(List<KtFile> filesToCompile) {
|
||||
if (filesToCompile.isEmpty()) return;
|
||||
|
||||
System.out.println("Generating " + filesToCompile.size() + " files" + (isFullJdkAndRuntime
|
||||
? " (full jdk and runtime)" : "") + "...");
|
||||
System.out.println("Generating " + filesToCompile.size() + " files" +
|
||||
(inheritMultifileParts
|
||||
? " (JVM.INHERIT_MULTIFILE_PARTS)"
|
||||
: isFullJdkAndRuntime ? " (full jdk and runtime)" : "") + "...");
|
||||
OutputFileCollection outputFiles;
|
||||
try {
|
||||
//hack to pass module name
|
||||
CompilerConfiguration configuration = environment.getConfiguration().copy();
|
||||
configuration.put(JVMConfigurationKeys.MODULE_NAME, "android-module-" + MODULE_INDEX++);
|
||||
if (inheritMultifileParts) {
|
||||
configuration.put(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, true);
|
||||
}
|
||||
configuration.setReadOnly(true);
|
||||
outputFiles = GenerationUtils.compileManyFilesGetGenerationStateForTest(
|
||||
filesToCompile.iterator().next().getProject(),
|
||||
filesToCompile,
|
||||
new JvmPackagePartProvider(environment),
|
||||
null
|
||||
configuration
|
||||
).getFactory();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
@@ -204,11 +226,12 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
@NotNull Printer printer,
|
||||
@NotNull File[] files,
|
||||
@NotNull FilesWriter holderFull,
|
||||
@NotNull FilesWriter holderMock)
|
||||
throws IOException
|
||||
{
|
||||
@NotNull FilesWriter holderMock,
|
||||
@NotNull FilesWriter holderInheritMFP
|
||||
) throws IOException {
|
||||
holderFull.writeFilesOnDiskIfNeeded();
|
||||
holderMock.writeFilesOnDiskIfNeeded();
|
||||
holderInheritMFP.writeFilesOnDiskIfNeeded();
|
||||
|
||||
for (File file : files) {
|
||||
if (SpecialFiles.getExcludedFiles().contains(file.getName())) {
|
||||
@@ -217,60 +240,44 @@ public class CodegenTestsOnAndroidGenerator extends UsefulTestCase {
|
||||
if (file.isDirectory()) {
|
||||
File[] listFiles = file.listFiles();
|
||||
if (listFiles != null) {
|
||||
processFiles(printer, listFiles, holderFull, holderMock);
|
||||
processFiles(printer, listFiles, holderFull, holderMock, holderInheritMFP);
|
||||
}
|
||||
}
|
||||
else if (!FileUtilRt.getExtension(file.getName()).equals(KotlinFileType.INSTANCE.getDefaultExtension())) {
|
||||
// skip non kotlin files
|
||||
}
|
||||
else {
|
||||
String text = FileUtil.loadFile(file, true);
|
||||
//TODO: support multifile tests
|
||||
if (text.contains("FILE:")) continue;
|
||||
//TODO: support JvmFileName annotation & WITH_REFLECT directive
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(text, "WITH_REFLECT") || text.contains("JvmFileName")) continue;
|
||||
String fullFileText = FileUtil.loadFile(file, true);
|
||||
|
||||
//TODO: support multifile facades
|
||||
//TODO: support multifile facades hierarchies
|
||||
if (hasBoxMethod(fullFileText)) {
|
||||
FilesWriter filesHolder = InTextDirectivesUtils.isDirectiveDefined(fullFileText, "FULL_JDK") ||
|
||||
InTextDirectivesUtils.isDirectiveDefined(fullFileText, "WITH_RUNTIME") ||
|
||||
InTextDirectivesUtils.isDirectiveDefined(fullFileText, "WITH_REFLECT") ? holderFull : holderMock;
|
||||
filesHolder = fullFileText.contains("+JVM.INHERIT_MULTIFILE_PARTS") ? holderInheritMFP : filesHolder;
|
||||
|
||||
FqName classWithBoxMethod = AndroidTestGeneratorKt.genFiles(file, fullFileText, filesHolder);
|
||||
if (classWithBoxMethod == null)
|
||||
continue;
|
||||
|
||||
if (hasBoxMethod(text)) {
|
||||
String generatedTestName = generateTestName(file.getName());
|
||||
String packageName = file.getPath().replaceAll("\\\\|-|\\.|/", "_");
|
||||
text = changePackage(packageName, text);
|
||||
|
||||
FilesWriter filesHolder = InTextDirectivesUtils.isDirectiveDefined(text, "FULL_JDK") ||
|
||||
InTextDirectivesUtils.isDirectiveDefined(text, "WITH_RUNTIME") ? holderFull : holderMock;
|
||||
CodegenTestFiles codegenFile = CodegenTestFiles.create(file.getName(), text, filesHolder.environment.getProject());
|
||||
filesHolder.files.add(codegenFile.getPsiFile());
|
||||
|
||||
generateTestMethod(printer, generatedTestName, StringUtil.escapeStringCharacters(file.getPath()));
|
||||
generateTestMethod(printer, generatedTestName, classWithBoxMethod.asString(), StringUtil.escapeStringCharacters(file.getPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static boolean hasBoxMethod(String text) {
|
||||
return text.contains("fun box()");
|
||||
}
|
||||
|
||||
private String changePackage(String testName, String text) {
|
||||
if (text.contains("package ")) {
|
||||
Matcher matcher = packagePattern.matcher(text);
|
||||
return matcher.replaceAll("package " + testName);
|
||||
}
|
||||
else {
|
||||
String packageDirective = "package " + testName + ";\n";
|
||||
if (text.contains("@file:")) {
|
||||
int index = text.lastIndexOf("@file:");
|
||||
int packageDirectiveIndex = text.indexOf("\n", index);
|
||||
return text.substring(0, packageDirectiveIndex + 1) + packageDirective + text.substring(packageDirectiveIndex + 1);
|
||||
} else {
|
||||
return packageDirective + text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateTestMethod(Printer p, String testName, String packageName) {
|
||||
private static void generateTestMethod(Printer p, String testName, String className, String filePath) {
|
||||
p.println("public void test" + testName + "() throws Exception {");
|
||||
p.pushIndent();
|
||||
p.println("invokeBoxMethod(\"" + packageName + "\", \"OK\");");
|
||||
p.println("invokeBoxMethod(" + className + ".class, \"" + filePath + "\", \"OK\");");
|
||||
p.popIndent();
|
||||
p.println("}");
|
||||
p.println();
|
||||
|
||||
@@ -36,45 +36,63 @@ public class SpecialFiles {
|
||||
private static void fillExcludedFiles() {
|
||||
excludedFiles.add("native"); // Reflection is used to check full class name
|
||||
|
||||
excludedFiles.add("reflection");
|
||||
excludedFiles.add("enclosing"); //reflection tests
|
||||
excludedFiles.add("noReflectAtRuntime"); //reflection tests
|
||||
excludedFiles.add("methodsFromAny"); //reflection tests
|
||||
|
||||
excludedFiles.add("kt3238.kt"); // Reflection
|
||||
excludedFiles.add("kt1482_2279.kt"); // Reflection
|
||||
excludedFiles.add("extensionMethod.kt"); // Reflection loadClass
|
||||
|
||||
excludedFiles.add("nestedInPackage.kt"); // Cannot change package name
|
||||
excludedFiles.add("importNestedClass.kt"); // Cannot change package name
|
||||
excludedFiles.add("packageQualifiedMethod.kt"); // Cannot change package name
|
||||
excludedFiles.add("classObjectToString.kt"); // Cannot change package name
|
||||
excludedFiles.add("invokeOnClassObjectOfNestedClass2.kt"); // Cannot change package name
|
||||
excludedFiles.add("invokeOnImportedEnum1.kt"); // Cannot change package name
|
||||
excludedFiles.add("invokeOnImportedEnum2.kt"); // Cannot change package name
|
||||
excludedFiles.add("sortEnumEntries.kt"); // Cannot change package name
|
||||
excludedFiles.add("assertionStackTrace.kt"); // Cannot change package name
|
||||
excludedFiles.add("anonymousObjectReifiedSupertype.kt"); // Cannot change package name
|
||||
excludedFiles.add("innerAnonymousObject.kt"); // Cannot change package name
|
||||
excludedFiles.add("nestedReifiedSignature.kt"); // Cannot change package name
|
||||
excludedFiles.add("recursiveInnerAnonymousObject.kt"); // Cannot change package name
|
||||
excludedFiles.add("approximateCapturedTypes.kt"); // Cannot change package name
|
||||
excludedFiles.add("classForEnumEntry.kt"); // Cannot change package name
|
||||
excludedFiles.add("kt10143.kt"); // Cannot change package name
|
||||
excludedFiles.add("internalTopLevelOtherPackage.kt"); // Cannot change package name
|
||||
excludedFiles.add("noPrivateDelegation.kt"); // Cannot change package name
|
||||
excludedFiles.add("platformTypeAssertionStackTrace.kt"); // Cannot change package name
|
||||
excludedFiles.add("packages.kt"); // Cannot change package name
|
||||
excludedFiles.add("kt10259.kt"); // Cannot change package name
|
||||
excludedFiles.add("kt11081.kt"); // Cannot change package name
|
||||
excludedFiles.add("kt6990.kt"); // Cannot change package name
|
||||
excludedFiles.add("mainInFiles.kt"); // Cannot change package name
|
||||
excludedFiles.add("noClassForSimpleEnum.kt"); // Cannot change package name
|
||||
excludedFiles.add("simpleClassLiteral.kt"); // Cannot change package name
|
||||
excludedFiles.add("jvmName.kt"); // Cannot change package name
|
||||
excludedFiles.add("qualifiedName.kt"); // Cannot change package name
|
||||
excludedFiles.add("topLevelProperty.kt"); // Cannot change package name
|
||||
excludedFiles.add("typeParameters.kt"); // Cannot change package name
|
||||
|
||||
excludedFiles.add("kt684.kt"); // StackOverflow with StringBuilder (escape())
|
||||
|
||||
excludedFiles.add("kt529.kt"); // Bug
|
||||
excludedFiles.add("kt344.kt"); // Bug
|
||||
|
||||
excludedFiles.add("comparisonWithNullCallsFun.kt"); // java.lang.NoClassDefFoundError: kotlin.Nothing
|
||||
excludedFiles.add("kt3574.kt"); // java.lang.NoClassDefFoundError: kotlin.Nothing
|
||||
|
||||
excludedFiles.add("genericBackingFieldSignature.kt"); // Wrong signature after package renaming
|
||||
excludedFiles.add("genericMethodSignature.kt"); // Wrong signature after package renaming
|
||||
excludedFiles.add("kt11121.kt"); // Wrong signature after package renaming
|
||||
excludedFiles.add("kt5112.kt"); // Wrong signature after package renaming
|
||||
|
||||
excludedFiles.add("classpath.kt"); // Some classes are not visible on android
|
||||
|
||||
excludedFiles.add("manyNumbers.kt"); // Out of memory
|
||||
|
||||
excludedFiles.add("smap"); // Line numbers
|
||||
excludedFiles.add("external"); //native methods
|
||||
|
||||
// TODO: fix import processing
|
||||
excludedFiles.add("useImportedMemberFromCompanion.kt");
|
||||
excludedFiles.add("useImportedMember.kt");
|
||||
excludedFiles.add("importStaticMemberFromObject.kt");
|
||||
excludedFiles.add("enclosingInfo"); // Wrong enclosing info after package renaming
|
||||
excludedFiles.add("signature"); // Wrong signature after package renaming
|
||||
|
||||
excludedFiles.add("functionNtoStringNoReflect.kt"); // disabled cause test executed with reflection
|
||||
|
||||
excludedFiles.add("nestedClasses.kt"); // additional nested class in 'Thread' class on Android
|
||||
excludedFiles.add("kt12200Const.kt"); // no 'modifiers' field in 'java.lang.reflect.Field' class
|
||||
|
||||
excludedFiles.add("closureOfInnerLocalClass.kt"); // KT-8120
|
||||
excludedFiles.add("closureWithSelfInstantiation.kt"); // KT-8120
|
||||
}
|
||||
|
||||
private SpecialFiles() {
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class CodegenUtil {
|
||||
|
||||
private CodegenUtil() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FunctionDescriptor getDeclaredFunctionByRawSignature(
|
||||
@NotNull ClassDescriptor owner,
|
||||
@NotNull Name name,
|
||||
@NotNull ClassifierDescriptor returnedClassifier,
|
||||
@NotNull ClassifierDescriptor... valueParameterClassifiers
|
||||
) {
|
||||
Collection<SimpleFunctionDescriptor> functions = owner.getDefaultType().getMemberScope().getContributedFunctions(name, NoLookupLocation.FROM_BACKEND);
|
||||
for (FunctionDescriptor function : functions) {
|
||||
if (!CallResolverUtilKt.isOrOverridesSynthesized(function)
|
||||
&& function.getTypeParameters().isEmpty()
|
||||
&& valueParameterClassesMatch(function.getValueParameters(), Arrays.asList(valueParameterClassifiers))
|
||||
&& rawTypeMatches(function.getReturnType(), returnedClassifier)) {
|
||||
return function;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PropertyDescriptor getDelegatePropertyIfAny(KtExpression expression, ClassDescriptor classDescriptor, BindingContext bindingContext) {
|
||||
PropertyDescriptor propertyDescriptor = null;
|
||||
if (expression instanceof KtSimpleNameExpression) {
|
||||
ResolvedCall<?> call = CallUtilKt.getResolvedCall(expression, bindingContext);
|
||||
if (call != null) {
|
||||
CallableDescriptor callResultingDescriptor = call.getResultingDescriptor();
|
||||
if (callResultingDescriptor instanceof ValueParameterDescriptor) {
|
||||
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) callResultingDescriptor;
|
||||
// constructor parameter
|
||||
if (valueParameterDescriptor.getContainingDeclaration() instanceof ConstructorDescriptor) {
|
||||
// constructor of my class
|
||||
if (valueParameterDescriptor.getContainingDeclaration().getContainingDeclaration() == classDescriptor) {
|
||||
propertyDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameterDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo: when and if frontend will allow properties defined not as constructor parameters to be used in delegation specifier
|
||||
}
|
||||
}
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
public static boolean isFinalPropertyWithBackingField(PropertyDescriptor propertyDescriptor, BindingContext bindingContext) {
|
||||
return propertyDescriptor != null &&
|
||||
!propertyDescriptor.isVar() &&
|
||||
Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
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 || Visibilities.isPrivate(traitMember.getVisibility())) continue;
|
||||
|
||||
assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember;
|
||||
|
||||
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
|
||||
// with traitMember's modality
|
||||
result.putAll(copyFunctions(inheritedMember, traitMember, inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC,
|
||||
CallableMemberDescriptor.Kind.DECLARATION, true));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<FunctionDescriptor, FunctionDescriptor> copyFunctions(
|
||||
@NotNull CallableMemberDescriptor inheritedMember,
|
||||
@NotNull CallableMemberDescriptor traitMember,
|
||||
DeclarationDescriptor newOwner,
|
||||
Modality modality,
|
||||
Visibility visibility,
|
||||
CallableMemberDescriptor.Kind kind,
|
||||
boolean copyOverrides
|
||||
) {
|
||||
CallableMemberDescriptor copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides);
|
||||
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>(0);
|
||||
if (traitMember instanceof SimpleFunctionDescriptor) {
|
||||
result.put((FunctionDescriptor) traitMember, (FunctionDescriptor) copy);
|
||||
}
|
||||
else if (traitMember instanceof PropertyDescriptor) {
|
||||
for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) {
|
||||
for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) {
|
||||
if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind
|
||||
result.put(traitAccessor, inheritedAccessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
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();
|
||||
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
assert superClassDescriptor != null : "superClassDescriptor should not be null: " + specifier.getText();
|
||||
return superClassDescriptor;
|
||||
}
|
||||
|
||||
private static boolean valueParameterClassesMatch(
|
||||
@NotNull List<ValueParameterDescriptor> parameters,
|
||||
@NotNull List<ClassifierDescriptor> classifiers
|
||||
) {
|
||||
if (parameters.size() != classifiers.size()) return false;
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
ValueParameterDescriptor parameterDescriptor = parameters.get(i);
|
||||
ClassifierDescriptor classDescriptor = classifiers.get(i);
|
||||
if (!rawTypeMatches(parameterDescriptor.getType(), classDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean rawTypeMatches(KotlinType type, ClassifierDescriptor classifier) {
|
||||
return type.getConstructor().equals(classifier.getTypeConstructor());
|
||||
}
|
||||
|
||||
public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
||||
KotlinType nullableString = TypeUtils.makeNullable(DescriptorUtilsKt.getBuiltIns(functionDescriptor).getStringType());
|
||||
return DescriptorUtils.ENUM_VALUE_OF.equals(functionDescriptor.getName())
|
||||
&& methodTypeParameters.size() == 1
|
||||
&& KotlinTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Integer getLineNumberForElement(@NotNull PsiElement statement, boolean markEndOffset) {
|
||||
PsiFile file = statement.getContainingFile();
|
||||
if (file instanceof KtFile) {
|
||||
if (KtPsiFactoryKt.getDoNotAnalyze((KtFile) file) != null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (statement instanceof KtConstructorDelegationReferenceExpression && statement.getTextLength() == 0) {
|
||||
// PsiElement for constructor delegation reference is always generated, so we shouldn't mark it's line number if it's empty
|
||||
return null;
|
||||
}
|
||||
|
||||
Document document = file.getViewProvider().getDocument();
|
||||
return document != null ? document.getLineNumber(markEndOffset ? statement.getTextRange().getEndOffset() : statement.getTextOffset()) + 1 : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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.backend.common
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.bridges.findTraitImplementation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
|
||||
object CodegenUtil {
|
||||
// class Foo : Bar by baz
|
||||
// descriptor = Foo
|
||||
// toInterface = Bar
|
||||
// delegateExpressionType = typeof(baz)
|
||||
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||
@JvmStatic
|
||||
fun getDelegates(
|
||||
descriptor: ClassDescriptor,
|
||||
toInterface: ClassDescriptor,
|
||||
delegateExpressionType: KotlinType? = null
|
||||
): Map<CallableMemberDescriptor, CallableDescriptor> {
|
||||
if (delegateExpressionType?.isDynamic() ?: false) return emptyMap()
|
||||
|
||||
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.asIterable()
|
||||
.sortedWith(MemberComparator.INSTANCE)
|
||||
.keysToMapExceptNulls { delegatingMember ->
|
||||
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
|
||||
.mapNotNull { overriddenDescriptor ->
|
||||
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))
|
||||
.firstOrNull {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it))
|
||||
.map(CallableMemberDescriptor::getOriginal)
|
||||
.contains(overriddenDescriptor.original)
|
||||
}
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
|
||||
actualDelegates.firstOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDeclaredFunctionByRawSignature(
|
||||
owner: ClassDescriptor,
|
||||
name: Name,
|
||||
returnedClassifier: ClassifierDescriptor,
|
||||
vararg valueParameterClassifiers: ClassifierDescriptor
|
||||
): FunctionDescriptor? {
|
||||
return owner.defaultType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).firstOrNull { function ->
|
||||
!isOrOverridesSynthesized(function) &&
|
||||
function.typeParameters.isEmpty() &&
|
||||
valueParameterClassesMatch(function.valueParameters, valueParameterClassifiers.toList()) &&
|
||||
rawTypeMatches(function.returnType!!, returnedClassifier)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDelegatePropertyIfAny(
|
||||
expression: KtExpression, classDescriptor: ClassDescriptor, bindingContext: BindingContext
|
||||
): PropertyDescriptor? {
|
||||
val call = (expression as? KtSimpleNameExpression)?.getResolvedCall(bindingContext) ?: return null
|
||||
val callResultingDescriptor = call.resultingDescriptor as? ValueParameterDescriptor ?: return null
|
||||
// constructor parameter
|
||||
if (callResultingDescriptor.containingDeclaration is ConstructorDescriptor) {
|
||||
// constructor of my class
|
||||
if (callResultingDescriptor.containingDeclaration.containingDeclaration === classDescriptor) {
|
||||
return bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, callResultingDescriptor)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isFinalPropertyWithBackingField(propertyDescriptor: PropertyDescriptor?, bindingContext: BindingContext): Boolean {
|
||||
return propertyDescriptor != null &&
|
||||
!propertyDescriptor.isVar &&
|
||||
(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor) ?: false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getNonPrivateTraitMethods(descriptor: ClassDescriptor): Map<FunctionDescriptor, FunctionDescriptor> {
|
||||
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||
for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) {
|
||||
if (declaration !is CallableMemberDescriptor) continue
|
||||
|
||||
val traitMember = findTraitImplementation(declaration)
|
||||
if (traitMember == null || Visibilities.isPrivate(traitMember.visibility)) continue
|
||||
|
||||
assert(traitMember.modality !== Modality.ABSTRACT) { "Cannot delegate to abstract trait method: $declaration" }
|
||||
|
||||
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
|
||||
// with traitMember's modality
|
||||
result.putAll(copyFunctions(declaration, traitMember, declaration.containingDeclaration, traitMember.modality,
|
||||
Visibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, true))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun copyFunctions(
|
||||
inheritedMember: CallableMemberDescriptor,
|
||||
traitMember: CallableMemberDescriptor,
|
||||
newOwner: DeclarationDescriptor,
|
||||
modality: Modality,
|
||||
visibility: Visibility,
|
||||
kind: CallableMemberDescriptor.Kind,
|
||||
copyOverrides: Boolean
|
||||
): Map<FunctionDescriptor, FunctionDescriptor> {
|
||||
val copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides)
|
||||
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||
if (traitMember is SimpleFunctionDescriptor) {
|
||||
result[traitMember] = copy as FunctionDescriptor
|
||||
}
|
||||
else if (traitMember is PropertyDescriptor) {
|
||||
for (traitAccessor in traitMember.accessors) {
|
||||
for (inheritedAccessor in (copy as PropertyDescriptor).accessors) {
|
||||
if (inheritedAccessor.javaClass == traitAccessor.javaClass) { // same accessor kind
|
||||
result.put(traitAccessor, inheritedAccessor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSuperClassBySuperTypeListEntry(specifier: KtSuperTypeListEntry, bindingContext: BindingContext): ClassDescriptor {
|
||||
val superType = bindingContext.get(BindingContext.TYPE, specifier.typeReference!!)
|
||||
?: error("superType should not be null: ${specifier.text}")
|
||||
|
||||
return superType.constructor.declarationDescriptor as? ClassDescriptor
|
||||
?: error("ClassDescriptor of superType should not be null: ${specifier.text}")
|
||||
}
|
||||
|
||||
private fun valueParameterClassesMatch(
|
||||
parameters: List<ValueParameterDescriptor>,
|
||||
classifiers: List<ClassifierDescriptor>
|
||||
): Boolean {
|
||||
if (parameters.size != classifiers.size) return false
|
||||
for ((parameterDescriptor, classDescriptor) in parameters.zip(classifiers)) {
|
||||
if (!rawTypeMatches(parameterDescriptor.type, classDescriptor)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun rawTypeMatches(type: KotlinType, classifier: ClassifierDescriptor): Boolean =
|
||||
type.constructor == classifier.typeConstructor
|
||||
|
||||
@JvmStatic
|
||||
fun isEnumValueOfMethod(functionDescriptor: FunctionDescriptor): Boolean {
|
||||
val methodTypeParameters = functionDescriptor.valueParameters
|
||||
val nullableString = TypeUtils.makeNullable(functionDescriptor.builtIns.stringType)
|
||||
return DescriptorUtils.ENUM_VALUE_OF == functionDescriptor.name
|
||||
&& methodTypeParameters.size == 1
|
||||
&& KotlinTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters[0].type, nullableString)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLineNumberForElement(statement: PsiElement, markEndOffset: Boolean): Int? {
|
||||
val file = statement.containingFile
|
||||
if (file is KtFile && file.doNotAnalyze != null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (statement is KtConstructorDelegationReferenceExpression && statement.textLength == 0) {
|
||||
// PsiElement for constructor delegation reference is always generated, so we shouldn't mark it's line number if it's empty
|
||||
return null
|
||||
}
|
||||
|
||||
val document = file.viewProvider.document
|
||||
return document?.getLineNumber(if (markEndOffset) statement.textRange.endOffset else statement.textOffset)?.plus(1)
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
import java.util.Comparator
|
||||
|
||||
object CodegenUtilKt {
|
||||
|
||||
// class Foo : Bar by baz
|
||||
// descriptor = Foo
|
||||
// toInterface = Bar
|
||||
// delegateExpressionType = typeof(baz)
|
||||
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||
@JvmStatic fun getDelegates(
|
||||
descriptor: ClassDescriptor,
|
||||
toInterface: ClassDescriptor,
|
||||
delegateExpressionType: KotlinType? = null
|
||||
): Map<CallableMemberDescriptor, CallableDescriptor> {
|
||||
if (delegateExpressionType?.isDynamic() ?: false) return mapOf();
|
||||
|
||||
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
|
||||
.filterIsInstance<CallableMemberDescriptor>()
|
||||
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
|
||||
.asIterable()
|
||||
.sortedWith(MemberComparator.INSTANCE)
|
||||
.keysToMapExceptNulls {
|
||||
delegatingMember ->
|
||||
|
||||
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
|
||||
.mapNotNull {
|
||||
overriddenDescriptor ->
|
||||
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))
|
||||
.firstOrNull {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it))
|
||||
.map { it.original }
|
||||
.contains(overriddenDescriptor.original)
|
||||
}
|
||||
}
|
||||
else null
|
||||
}
|
||||
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
|
||||
actualDelegates.firstOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.KtClass;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A platform-independent logic for generating data class synthetic methods.
|
||||
* TODO: data class with zero components gets no toString/equals/hashCode methods. This is inconsistent and should be
|
||||
* changed here with the platform backends adopted.
|
||||
*/
|
||||
public abstract class DataClassMethodGenerator {
|
||||
private final KtClassOrObject declaration;
|
||||
private final BindingContext bindingContext;
|
||||
private final ClassDescriptor classDescriptor;
|
||||
private final KotlinBuiltIns builtIns;
|
||||
|
||||
public DataClassMethodGenerator(KtClassOrObject declaration, BindingContext bindingContext) {
|
||||
this.declaration = declaration;
|
||||
this.bindingContext = bindingContext;
|
||||
this.classDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration);
|
||||
this.builtIns = DescriptorUtilsKt.getBuiltIns(classDescriptor);
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
generateComponentFunctionsForDataClasses();
|
||||
|
||||
generateCopyFunctionForDataClasses(getPrimaryConstructorParameters());
|
||||
|
||||
List<PropertyDescriptor> properties = getDataProperties();
|
||||
if (!properties.isEmpty()) {
|
||||
generateDataClassToStringIfNeeded(properties);
|
||||
generateDataClassHashCodeIfNeeded(properties);
|
||||
generateDataClassEqualsIfNeeded(properties);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter);
|
||||
|
||||
protected abstract void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<KtParameter> constructorParameters);
|
||||
|
||||
protected abstract void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
||||
|
||||
protected abstract void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
||||
|
||||
protected abstract void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
||||
|
||||
@NotNull
|
||||
protected ClassDescriptor getClassDescriptor() {
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
private void generateComponentFunctionsForDataClasses() {
|
||||
ConstructorDescriptor constructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
||||
// primary constructor should exist for data classes
|
||||
// but when generating light-classes still need to check we have one
|
||||
if (constructor == null) return;
|
||||
|
||||
for (ValueParameterDescriptor parameter : constructor.getValueParameters()) {
|
||||
FunctionDescriptor function = bindingContext.get(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter);
|
||||
if (function != null) {
|
||||
generateComponentFunction(function, parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateCopyFunctionForDataClasses(List<KtParameter> constructorParameters) {
|
||||
FunctionDescriptor copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor);
|
||||
if (copyFunction != null) {
|
||||
generateCopyFunction(copyFunction, constructorParameters);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDataClassToStringIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor function = getDeclaredMember("toString", builtIns.getString());
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateToStringMethod(function, properties);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDataClassHashCodeIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor function = getDeclaredMember("hashCode", builtIns.getInt());
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateHashCodeMethod(function, properties);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDataClassEqualsIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor function = getDeclaredMember("equals", builtIns.getBoolean(), builtIns.getAny());
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateEqualsMethod(function, properties);
|
||||
}
|
||||
}
|
||||
|
||||
private List<PropertyDescriptor> getDataProperties() {
|
||||
List<PropertyDescriptor> result = Lists.newArrayList();
|
||||
for (KtParameter parameter : getPrimaryConstructorParameters()) {
|
||||
if (parameter.hasValOrVar()) {
|
||||
result.add(bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<KtParameter> getPrimaryConstructorParameters() {
|
||||
if (declaration instanceof KtClass) {
|
||||
return declaration.getPrimaryConstructorParameters();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FunctionDescriptor getDeclaredMember(
|
||||
@NotNull String name,
|
||||
@NotNull ClassDescriptor returnedClassifier,
|
||||
@NotNull ClassDescriptor... valueParameterClassifiers
|
||||
) {
|
||||
return CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||
classDescriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the member is an inherited implementation of a method from Any
|
||||
*/
|
||||
private boolean isTrivial(@NotNull FunctionDescriptor function) {
|
||||
if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (CallableDescriptor overridden : OverrideResolver.getOverriddenDeclarations(function)) {
|
||||
if (overridden instanceof CallableMemberDescriptor
|
||||
&& ((CallableMemberDescriptor) overridden).getKind() == CallableMemberDescriptor.Kind.DECLARATION
|
||||
&& !overridden.getContainingDeclaration().equals(builtIns.getAny())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
|
||||
/**
|
||||
* A platform-independent logic for generating data class synthetic methods.
|
||||
* TODO: data class with zero components gets no toString/equals/hashCode methods. This is inconsistent and should be
|
||||
* changed here with the platform backends adopted.
|
||||
*/
|
||||
abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject, private val bindingContext: BindingContext) {
|
||||
protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration)
|
||||
|
||||
private val builtIns = classDescriptor.builtIns
|
||||
|
||||
fun generate() {
|
||||
generateComponentFunctionsForDataClasses()
|
||||
|
||||
generateCopyFunctionForDataClasses(primaryConstructorParameters)
|
||||
|
||||
val properties = dataProperties
|
||||
if (properties.isNotEmpty()) {
|
||||
generateDataClassToStringIfNeeded(properties)
|
||||
generateDataClassHashCodeIfNeeded(properties)
|
||||
generateDataClassEqualsIfNeeded(properties)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor)
|
||||
|
||||
protected abstract fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>)
|
||||
|
||||
protected abstract fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
protected abstract fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
protected abstract fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||
|
||||
private fun generateComponentFunctionsForDataClasses() {
|
||||
// primary constructor should exist for data classes
|
||||
// but when generating light-classes still need to check we have one
|
||||
val constructor = classDescriptor.unsubstitutedPrimaryConstructor ?: return
|
||||
|
||||
for (parameter in constructor.valueParameters) {
|
||||
val function = bindingContext.get(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter)
|
||||
if (function != null) {
|
||||
generateComponentFunction(function, parameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateCopyFunctionForDataClasses(constructorParameters: List<KtParameter>) {
|
||||
val copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor) ?: return
|
||||
generateCopyFunction(copyFunction, constructorParameters)
|
||||
}
|
||||
|
||||
private fun generateDataClassToStringIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getDeclaredMember("toString", builtIns.string)
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateToStringMethod(function, properties)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDataClassHashCodeIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getDeclaredMember("hashCode", builtIns.int)
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateHashCodeMethod(function, properties)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDataClassEqualsIfNeeded(properties: List<PropertyDescriptor>) {
|
||||
val function = getDeclaredMember("equals", builtIns.boolean, builtIns.any)
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateEqualsMethod(function, properties)
|
||||
}
|
||||
}
|
||||
|
||||
private val dataProperties: List<PropertyDescriptor>
|
||||
get() = primaryConstructorParameters
|
||||
.filter { it.hasValOrVar() }
|
||||
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
|
||||
|
||||
private val primaryConstructorParameters: List<KtParameter>
|
||||
get() = (declaration as? KtClass)?.getPrimaryConstructorParameters().orEmpty()
|
||||
|
||||
private fun getDeclaredMember(
|
||||
name: String,
|
||||
returnedClassifier: ClassDescriptor,
|
||||
vararg valueParameterClassifiers: ClassDescriptor
|
||||
): FunctionDescriptor? = CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||
classDescriptor, Name.identifier(name), returnedClassifier, *valueParameterClassifiers
|
||||
)
|
||||
|
||||
/**
|
||||
* @return true if the member is an inherited implementation of a method from Any
|
||||
*/
|
||||
private fun isTrivial(function: FunctionDescriptor): Boolean {
|
||||
return function.kind != CallableMemberDescriptor.Kind.DECLARATION &&
|
||||
OverrideResolver.getOverriddenDeclarations(function).none { overridden ->
|
||||
overridden is CallableMemberDescriptor &&
|
||||
overridden.kind == CallableMemberDescriptor.Kind.DECLARATION &&
|
||||
overridden.containingDeclaration != builtIns.any
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ interface FunctionHandle {
|
||||
fun getOverridden(): Iterable<FunctionHandle>
|
||||
}
|
||||
|
||||
data class Bridge<Signature>(
|
||||
data class Bridge<out Signature>(
|
||||
val from: Signature,
|
||||
val to: Signature
|
||||
) {
|
||||
|
||||
@@ -279,7 +279,7 @@ public abstract class AnnotationCodegen {
|
||||
ClassifierDescriptor classifierDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
|
||||
assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
|
||||
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor);
|
||||
if (rp == RetentionPolicy.SOURCE && typeMapper.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
|
||||
if (rp == RetentionPolicy.SOURCE && typeMapper.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -404,6 +404,7 @@ public abstract class AnnotationCodegen {
|
||||
case FULL:
|
||||
throw new IllegalStateException("Don't know how to compile annotation value " + value);
|
||||
case LIGHT_CLASSES:
|
||||
case KAPT:
|
||||
return null;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown builder mode: " + mode);
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.protobuf.MessageLite;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import kotlin.Unit;
|
||||
@@ -39,6 +38,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite;
|
||||
import org.jetbrains.kotlin.resolve.DeprecationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
@@ -562,11 +562,6 @@ public class AsmUtil {
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
|
||||
}
|
||||
|
||||
public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) {
|
||||
numConst(myDelta, expectedType, v);
|
||||
v.add(expectedType);
|
||||
}
|
||||
|
||||
public static void numConst(int value, Type type, InstructionAdapter v) {
|
||||
if (type == Type.FLOAT_TYPE) {
|
||||
v.fconst(value);
|
||||
@@ -585,9 +580,11 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void genIncrement(Type expectedType, Type baseType, int myDelta, InstructionAdapter v) {
|
||||
genIncrement(baseType, myDelta, v);
|
||||
StackValue.coerce(baseType, expectedType, v);
|
||||
public static void genIncrement(Type baseType, int myDelta, InstructionAdapter v) {
|
||||
Type operationType = numberFunctionOperandType(baseType);
|
||||
numConst(myDelta, operationType, v);
|
||||
v.add(operationType);
|
||||
StackValue.coerce(operationType, baseType, v);
|
||||
}
|
||||
|
||||
public static void swap(InstructionAdapter v, Type stackTop, Type afterTop) {
|
||||
|
||||
@@ -32,8 +32,6 @@ open class BranchedValue(
|
||||
val opcode: Int
|
||||
) : StackValue(Type.BOOLEAN_TYPE) {
|
||||
|
||||
constructor(or: BranchedValue, opcode: Int) : this(or.arg1, or.arg2, or.operandType, opcode)
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
val branchJumpLabel = Label()
|
||||
condJump(branchJumpLabel, v, true)
|
||||
@@ -63,7 +61,7 @@ open class BranchedValue(
|
||||
companion object {
|
||||
val negatedOperations = hashMapOf<Int, Int>()
|
||||
|
||||
val TRUE: BranchedValue = object : BranchedValue(StackValue.Constant(true, Type.BOOLEAN_TYPE), null, Type.BOOLEAN_TYPE, IFEQ) {
|
||||
val TRUE: BranchedValue = object : BranchedValue(StackValue.none()/*not used*/, null, Type.BOOLEAN_TYPE, IFEQ) {
|
||||
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||
if (!jumpIfFalse) {
|
||||
v.goTo(jumpLabel)
|
||||
@@ -85,7 +83,7 @@ open class BranchedValue(
|
||||
}
|
||||
}
|
||||
|
||||
val FALSE: BranchedValue = object : BranchedValue(StackValue.Constant(false, Type.BOOLEAN_TYPE), null, Type.BOOLEAN_TYPE, IFEQ) {
|
||||
val FALSE: BranchedValue = object : BranchedValue(StackValue.none()/*not used*/, null, Type.BOOLEAN_TYPE, IFEQ) {
|
||||
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||
if (jumpIfFalse) {
|
||||
v.goTo(jumpLabel)
|
||||
@@ -249,7 +247,7 @@ class NumberCompare(
|
||||
}
|
||||
|
||||
class ObjectCompare(
|
||||
val opToken: IElementType,
|
||||
opToken: IElementType,
|
||||
operandType: Type,
|
||||
left: StackValue,
|
||||
right: StackValue
|
||||
|
||||
@@ -25,4 +25,8 @@ public enum ClassBuilderMode {
|
||||
* Generating light classes: Only function signatures
|
||||
*/
|
||||
LIGHT_CLASSES,
|
||||
/**
|
||||
* Function signatures + metadata (to support incremental compilation with kapt)
|
||||
*/
|
||||
KAPT;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ import static org.jetbrains.kotlin.codegen.ExpressionCodegen.generateClassLitera
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
@@ -219,10 +220,15 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
|
||||
@Override
|
||||
protected void generateKotlinMetadataAnnotation() {
|
||||
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(funDescriptor);
|
||||
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, funDescriptor);
|
||||
assert method != null : "No method for " + funDescriptor;
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
|
||||
|
||||
final DescriptorSerializer serializer =
|
||||
DescriptorSerializer.createForLambda(new JvmSerializerExtension(v.getSerializationBindings(), state));
|
||||
|
||||
final ProtoBuf.Function functionProto = serializer.functionProto(funDescriptor).build();
|
||||
final ProtoBuf.Function functionProto = serializer.functionProto(freeLambdaDescriptor).build();
|
||||
|
||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, KotlinClassHeader.Kind.SYNTHETIC_CLASS, new Function1<AnnotationVisitor, Unit>() {
|
||||
@Override
|
||||
@@ -233,6 +239,30 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
|
||||
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
||||
*/
|
||||
@NotNull
|
||||
private static FunctionDescriptor createFreeLambdaDescriptor(@NotNull FunctionDescriptor descriptor) {
|
||||
FunctionDescriptor.CopyBuilder<? extends FunctionDescriptor> builder = descriptor.newCopyBuilder();
|
||||
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0);
|
||||
builder.setTypeParameters(typeParameters);
|
||||
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
while (container != null) {
|
||||
if (container instanceof ClassDescriptor) {
|
||||
typeParameters.addAll(((ClassDescriptor) container).getDeclaredTypeParameters());
|
||||
}
|
||||
else if (container instanceof CallableDescriptor && !(container instanceof ConstructorDescriptor)) {
|
||||
typeParameters.addAll(((CallableDescriptor) container).getTypeParameters());
|
||||
}
|
||||
container = container.getContainingDeclaration();
|
||||
}
|
||||
|
||||
return typeParameters.isEmpty() ? descriptor : builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
writeOuterClassAndEnclosingMethod();
|
||||
|
||||
@@ -134,7 +134,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
annotationCodegen.genAnnotations(it.value, signature.valueParameters[it.index].asmType)
|
||||
}
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) {
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) {
|
||||
FunctionCodegen.generateLocalVariablesForParameters(mv, signature, null, Label(), Label(), remainingParameters, isStatic)
|
||||
mv.visitEnd()
|
||||
return
|
||||
|
||||
@@ -38,13 +38,10 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicCallable;
|
||||
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.*;
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
|
||||
@@ -66,6 +63,7 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
@@ -568,6 +566,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
ResolvedCall<? extends CallableDescriptor> loopRangeCall = RangeCodegenUtil.getLoopRangeResolvedCall(forExpression, bindingContext);
|
||||
if (loopRangeCall != null) {
|
||||
CallableDescriptor loopRangeCallee = loopRangeCall.getResultingDescriptor();
|
||||
if (RangeCodegenUtil.isArrayOrPrimitiveArrayIndices(loopRangeCallee)) {
|
||||
generateForLoop(createForInArrayIndicesRangeLoopGenerator(forExpression, loopRangeCall));
|
||||
return StackValue.none();
|
||||
}
|
||||
else if (RangeCodegenUtil.isCollectionIndices(loopRangeCallee)) {
|
||||
generateForLoop(createForInCollectionIndicesRangeLoopGenerator(forExpression, loopRangeCall));
|
||||
return StackValue.none();
|
||||
}
|
||||
}
|
||||
|
||||
KtExpression loopRange = forExpression.getLoopRange();
|
||||
assert loopRange != null;
|
||||
KotlinType loopRangeType = bindingContext.getType(loopRange);
|
||||
@@ -592,6 +603,24 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return StackValue.none();
|
||||
}
|
||||
|
||||
private AbstractForLoopGenerator createForInCollectionIndicesRangeLoopGenerator(
|
||||
@NotNull KtForExpression forExpression,
|
||||
@NotNull ResolvedCall<? extends CallableDescriptor> loopRangeCall
|
||||
) {
|
||||
ReceiverValue extensionReceiver = loopRangeCall.getExtensionReceiver();
|
||||
assert extensionReceiver != null : "Extension receiver should be non-null for optimizable 'indices' call";
|
||||
return new ForInCollectionIndicesRangeLoopGenerator(forExpression, extensionReceiver);
|
||||
}
|
||||
|
||||
private AbstractForLoopGenerator createForInArrayIndicesRangeLoopGenerator(
|
||||
@NotNull KtForExpression forExpression,
|
||||
@NotNull ResolvedCall<? extends CallableDescriptor> loopRangeCall
|
||||
) {
|
||||
ReceiverValue extensionReceiver = loopRangeCall.getExtensionReceiver();
|
||||
assert extensionReceiver != null : "Extension receiver should be non-null for optimizable 'indices' call";
|
||||
return new ForInArrayIndicesRangeLoopGenerator(forExpression, extensionReceiver);
|
||||
}
|
||||
|
||||
private OwnerKind contextKind() {
|
||||
return context.getContextKind();
|
||||
}
|
||||
@@ -765,9 +794,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
// This method consumes range/progression from stack
|
||||
// The result is stored to local variable
|
||||
protected void generateRangeOrProgressionProperty(Type loopRangeType, String getterName, Type elementType, int varToStore) {
|
||||
v.invokevirtual(loopRangeType.getInternalName(), getterName, "()" + elementType.getDescriptor(), false);
|
||||
v.store(varToStore, elementType);
|
||||
protected void generateRangeOrProgressionProperty(
|
||||
@NotNull Type loopRangeType,
|
||||
@NotNull String getterName,
|
||||
@NotNull Type getterReturnType,
|
||||
@NotNull Type varType,
|
||||
int varToStore
|
||||
) {
|
||||
v.invokevirtual(loopRangeType.getInternalName(), getterName, "()" + getterReturnType.getDescriptor(), false);
|
||||
StackValue.local(varToStore, varType).store(StackValue.onStack(getterReturnType), v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -922,6 +957,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
private abstract class AbstractForInProgressionOrRangeLoopGenerator extends AbstractForLoopGenerator {
|
||||
protected int endVar;
|
||||
|
||||
private StackValue loopParameter;
|
||||
|
||||
private AbstractForInProgressionOrRangeLoopGenerator(@NotNull KtForExpression forExpression) {
|
||||
super(forExpression);
|
||||
|
||||
@@ -948,8 +985,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
protected void checkPostCondition(@NotNull Label loopExit) {
|
||||
assert endVar != -1 :
|
||||
"endVar must be allocated, endVar = " + endVar;
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
loopParameter().put(asmElementType, v);
|
||||
v.load(endVar, asmElementType);
|
||||
if (asmElementType.getSort() == Type.LONG) {
|
||||
v.lcmp();
|
||||
@@ -963,6 +999,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@Override
|
||||
public void checkPreCondition(@NotNull Label loopExit) {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected StackValue loopParameter() {
|
||||
if (loopParameter == null) {
|
||||
loopParameter = StackValue.local(loopParameterVar, loopParameterType);
|
||||
}
|
||||
return loopParameter;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class AbstractForInRangeLoopGenerator extends AbstractForInProgressionOrRangeLoopGenerator {
|
||||
@@ -981,8 +1025,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public void checkEmptyLoop(@NotNull Label loopExit) {
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
loopParameter().put(asmElementType, v);
|
||||
v.load(endVar, asmElementType);
|
||||
if (asmElementType.getSort() == Type.LONG) {
|
||||
v.lcmp();
|
||||
@@ -1001,13 +1044,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
protected void increment(@NotNull Label loopExit) {
|
||||
checkPostCondition(loopExit);
|
||||
|
||||
if (asmElementType == Type.INT_TYPE) {
|
||||
if (loopParameterType == Type.INT_TYPE) {
|
||||
v.iinc(loopParameterVar, 1);
|
||||
}
|
||||
else {
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
StackValue loopParameter = loopParameter();
|
||||
loopParameter.put(asmElementType, v);
|
||||
genIncrement(asmElementType, 1, v);
|
||||
v.store(loopParameterVar, asmElementType);
|
||||
loopParameter.store(StackValue.onStack(asmElementType), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1025,8 +1069,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
protected void storeRangeStartAndEnd() {
|
||||
gen(rangeCall.left, asmElementType);
|
||||
v.store(loopParameterVar, asmElementType);
|
||||
gen(rangeCall.left, loopParameterType);
|
||||
v.store(loopParameterVar, loopParameterType);
|
||||
|
||||
gen(rangeCall.right, asmElementType);
|
||||
v.store(endVar, asmElementType);
|
||||
@@ -1047,8 +1091,56 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.dup();
|
||||
|
||||
// ranges inherit first and last from corresponding progressions
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, endVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, asmElementType, endVar);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class ForInOptimizedIndicesLoopGenerator extends AbstractForInRangeLoopGenerator {
|
||||
protected final ReceiverValue receiverValue;
|
||||
|
||||
private ForInOptimizedIndicesLoopGenerator(@NotNull KtForExpression forExpression, @NotNull ReceiverValue receiverValue) {
|
||||
super(forExpression);
|
||||
this.receiverValue = receiverValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void storeRangeStartAndEnd() {
|
||||
StackValue.local(loopParameterVar, loopParameterType).store(StackValue.constant(0, asmElementType), v);
|
||||
|
||||
StackValue receiver = generateReceiverValue(receiverValue, false);
|
||||
receiver.put(receiver.type, v);
|
||||
getReceiverSizeAsInt();
|
||||
v.iconst(1);
|
||||
v.sub(Type.INT_TYPE);
|
||||
StackValue.local(endVar, asmElementType).store(StackValue.onStack(Type.INT_TYPE), v);
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>(receiver -> size:I)</code>
|
||||
*/
|
||||
protected abstract void getReceiverSizeAsInt();
|
||||
}
|
||||
|
||||
private class ForInCollectionIndicesRangeLoopGenerator extends ForInOptimizedIndicesLoopGenerator {
|
||||
private ForInCollectionIndicesRangeLoopGenerator(@NotNull KtForExpression forExpression, @NotNull ReceiverValue receiverValue) {
|
||||
super(forExpression, receiverValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getReceiverSizeAsInt() {
|
||||
v.invokeinterface("java/util/Collection", "size", "()I");
|
||||
}
|
||||
}
|
||||
|
||||
private class ForInArrayIndicesRangeLoopGenerator extends ForInOptimizedIndicesLoopGenerator {
|
||||
private ForInArrayIndicesRangeLoopGenerator(@NotNull KtForExpression forExpression, @NotNull ReceiverValue receiverValue) {
|
||||
super(forExpression, receiverValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getReceiverSizeAsInt() {
|
||||
v.arraylength();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1079,15 +1171,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.dup();
|
||||
v.dup();
|
||||
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, endVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getStep", incrementType, incrementVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getFirst", asmElementType, loopParameterType, loopParameterVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getLast", asmElementType, asmElementType, endVar);
|
||||
generateRangeOrProgressionProperty(asmLoopRangeType, "getStep", incrementType, incrementType, incrementVar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkEmptyLoop(@NotNull Label loopExit) {
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
loopParameter().put(asmElementType, v);
|
||||
v.load(endVar, asmElementType);
|
||||
v.load(incrementVar, incrementType);
|
||||
|
||||
@@ -1132,7 +1223,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
protected void increment(@NotNull Label loopExit) {
|
||||
checkPostCondition(loopExit);
|
||||
|
||||
v.load(loopParameterVar, asmElementType);
|
||||
StackValue loopParameter = loopParameter();
|
||||
loopParameter.put(asmElementType, v);
|
||||
v.load(incrementVar, asmElementType);
|
||||
v.add(asmElementType);
|
||||
|
||||
@@ -1140,7 +1232,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StackValue.coerce(Type.INT_TYPE, asmElementType, v);
|
||||
}
|
||||
|
||||
v.store(loopParameterVar, asmElementType);
|
||||
loopParameter.store(StackValue.onStack(asmElementType), v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1983,8 +2075,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
VariableAsFunctionResolvedCall call = (VariableAsFunctionResolvedCall) resolvedCall;
|
||||
resolvedCall = call.getVariableCall();
|
||||
}
|
||||
receiver = StackValue.receiver(resolvedCall, receiver, this, null);
|
||||
|
||||
descriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
//Check early if KCallableNameProperty is applicable to prevent closure generation
|
||||
StackValue intrinsicResult = applyIntrinsic(descriptor, KCallableNameProperty.class, resolvedCall, receiver);
|
||||
if (intrinsicResult != null) return intrinsicResult;
|
||||
|
||||
receiver = StackValue.receiver(resolvedCall, receiver, this, null);
|
||||
if (descriptor instanceof FakeCallableDescriptorForObject) {
|
||||
descriptor = ((FakeCallableDescriptorForObject) descriptor).getReferencedDescriptor();
|
||||
}
|
||||
@@ -1997,17 +2095,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (isSyntheticField) {
|
||||
descriptor = ((SyntheticFieldDescriptor) descriptor).getPropertyDescriptor();
|
||||
}
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor memberDescriptor = DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor);
|
||||
|
||||
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor);
|
||||
if (intrinsic instanceof IntrinsicPropertyGetter) {
|
||||
//TODO: intrinsic properties (see intermediateValueForProperty)
|
||||
Type returnType = typeMapper.mapType(memberDescriptor);
|
||||
StackValue intrinsicResult = ((IntrinsicPropertyGetter) intrinsic).generate(resolvedCall, this, returnType, receiver);
|
||||
if (intrinsicResult != null) return intrinsicResult;
|
||||
}
|
||||
}
|
||||
StackValue intrinsicResult = applyIntrinsic(descriptor, IntrinsicPropertyGetter.class, resolvedCall, receiver);
|
||||
if (intrinsicResult != null) return intrinsicResult;
|
||||
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
@@ -2056,6 +2146,25 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private StackValue applyIntrinsic(
|
||||
DeclarationDescriptor descriptor,
|
||||
Class<? extends IntrinsicPropertyGetter> intrinsicType,
|
||||
ResolvedCall<?> resolvedCall,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor memberDescriptor = DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor);
|
||||
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor);
|
||||
if (intrinsicType.isInstance(intrinsic)) {
|
||||
//TODO: intrinsic properties (see intermediateValueForProperty)
|
||||
Type returnType = typeMapper.mapType(memberDescriptor);
|
||||
return ((IntrinsicPropertyGetter) intrinsic).generate(resolvedCall, this, returnType, receiver);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassDescriptor getSuperCallTarget(@NotNull Call call) {
|
||||
KtSuperExpression superExpression = CallResolverUtilKt.getSuperCallExpression(call);
|
||||
@@ -2718,7 +2827,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
if (hasSpread) {
|
||||
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
|
||||
if (size == 1) {
|
||||
// Arrays.copyOf(array, newLength)
|
||||
// Arrays.copyOf(receiverValue, newLength)
|
||||
ValueArgument argument = arguments.get(0);
|
||||
Type arrayType = arrayOfReferences ? Type.getType("[Ljava/lang/Object;")
|
||||
: Type.getType("[" + elementType.getDescriptor());
|
||||
@@ -2836,7 +2945,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
|
||||
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
|
||||
element, classBuilder, resolvedCall
|
||||
element, classBuilder, variableDescriptor, resolvedCall
|
||||
);
|
||||
codegen.generate();
|
||||
|
||||
@@ -3334,7 +3443,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
Type storeType;
|
||||
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
|
||||
genIncrement(asmResultType, asmBaseType, increment, v);
|
||||
genIncrement(asmBaseType, increment, v);
|
||||
storeType = asmBaseType;
|
||||
}
|
||||
else {
|
||||
@@ -3958,7 +4067,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
|
||||
private boolean isExhaustive(@NotNull KtWhenExpression whenExpression, boolean isStatement) {
|
||||
if (isStatement) {
|
||||
if (isStatement && !BindingContextUtilsKt.isUsedAsExpression(whenExpression, bindingContext)) {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue;
|
||||
@@ -198,7 +197,7 @@ public class FunctionCodegen {
|
||||
parentBodyCodegen.addAdditionalTask(new JvmStaticGenerator(functionDescriptor, origin, state, parentBodyCodegen));
|
||||
}
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES || isAbstractMethod(functionDescriptor, contextKind)) {
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL || isAbstractMethod(functionDescriptor, contextKind)) {
|
||||
generateLocalVariableTable(
|
||||
mv,
|
||||
jvmSignature,
|
||||
@@ -564,9 +563,6 @@ public class FunctionCodegen {
|
||||
// equals(Any?), hashCode(), toString() never need bridges
|
||||
if (isMethodOfAny(descriptor)) return;
|
||||
|
||||
// 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.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
|
||||
|
||||
Set<Bridge<Method>> bridgesToGenerate;
|
||||
|
||||
@@ -27,7 +27,6 @@ import kotlin.jvm.functions.Function2;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtilKt;
|
||||
import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
@@ -158,7 +157,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
if (!ktClass.hasModifier(KtTokens.OPEN_KEYWORD) && !isAbstract) {
|
||||
// Light-class mode: Do not make enum classes final since PsiClass corresponding to enum is expected to be inheritable from
|
||||
isFinal = !(ktClass.isEnum() && state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES);
|
||||
isFinal = !(ktClass.isEnum() && state.getClassBuilderMode() != ClassBuilderMode.FULL);
|
||||
}
|
||||
isStatic = !ktClass.isInner();
|
||||
}
|
||||
@@ -169,7 +168,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
int access = 0;
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES && !DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL && !DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||
// ClassBuilderMode.LIGHT_CLASSES means we are generating light classes & looking at a nested or inner class
|
||||
// Light class generation is implemented so that Cls-classes only read bare code of classes,
|
||||
// without knowing whether these classes are inner or not (see ClassStubBuilder.EMPTY_STRATEGY)
|
||||
@@ -265,7 +264,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void writeEnclosingMethod() {
|
||||
// Do not emit enclosing method in "light-classes mode" since currently we generate local light classes as if they're top level
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) {
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -496,7 +495,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
||||
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties) {
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
@@ -553,7 +552,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
||||
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties) {
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "hashCode", "()I", null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
@@ -602,7 +601,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
||||
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties) {
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
@@ -654,7 +653,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getType());
|
||||
String fieldName = ((FieldOwnerContext) context.getParentContext()).getFieldName(propertyDescriptor, false);
|
||||
iv.getfield(classAsmType.getInternalName(), fieldName, type.getDescriptor());
|
||||
return type.getReturnType();
|
||||
return type;
|
||||
}
|
||||
else {
|
||||
//noinspection ConstantConditions
|
||||
@@ -692,7 +691,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateCopyFunction(@NotNull final FunctionDescriptor function, @NotNull List<KtParameter> constructorParameters) {
|
||||
public void generateCopyFunction(
|
||||
@NotNull final FunctionDescriptor function,
|
||||
@NotNull List<? extends KtParameter> constructorParameters
|
||||
) {
|
||||
final Type thisDescriptorType = typeMapper.mapType(descriptor);
|
||||
|
||||
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, function), function, new FunctionGenerationStrategy() {
|
||||
@@ -1640,8 +1642,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
fieldInfo.name, fieldInfo.type.getDescriptor(), /*TODO*/null, null);
|
||||
}
|
||||
|
||||
protected void generateDelegates(ClassDescriptor toTrait, KotlinType delegateExpressionType, DelegationFieldsInfo.Field field) {
|
||||
for (Map.Entry<CallableMemberDescriptor, CallableDescriptor> entry : CodegenUtilKt.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) {
|
||||
private void generateDelegates(ClassDescriptor toTrait, KotlinType delegateExpressionType, DelegationFieldsInfo.Field field) {
|
||||
for (Map.Entry<CallableMemberDescriptor, CallableDescriptor> entry :
|
||||
CodegenUtil.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) {
|
||||
CallableMemberDescriptor callableMemberDescriptor = entry.getKey();
|
||||
CallableDescriptor delegateTo = entry.getValue();
|
||||
if (callableMemberDescriptor instanceof PropertyDescriptor) {
|
||||
|
||||
@@ -146,8 +146,27 @@ public class JvmCodegenUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only properties of the same class can be directly accessed, except when we are evaluating expressions in the debugger
|
||||
if (!isCallInsideSameClassAsDeclared(property, context) && !isDebuggerContext(context)) return false;
|
||||
if (!isCallInsideSameClassAsDeclared(property, context)) {
|
||||
if (!isDebuggerContext(context)) {
|
||||
// Unless we are evaluating expression in debugger context, only properties of the same class can be directly accessed
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// In debugger we want to access through accessors if they are generated
|
||||
|
||||
// Non default accessors must always be generated
|
||||
for (PropertyAccessorDescriptor accessorDescriptor : property.getAccessors()) {
|
||||
if (!accessorDescriptor.isDefault()) {
|
||||
if (forGetter == accessorDescriptor instanceof PropertyGetterDescriptor) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If property overrides something, accessors must be generated too
|
||||
if (!property.getOverriddenDescriptors().isEmpty()) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Delegated and extension properties have no backing fields
|
||||
if (isDelegated || property.getExtensionReceiverParameter() != null) return false;
|
||||
|
||||
@@ -109,9 +109,9 @@ public class JvmRuntimeTypes {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinType getSupertypeForPropertyReference(@NotNull PropertyDescriptor descriptor) {
|
||||
public KotlinType getSupertypeForPropertyReference(@NotNull PropertyDescriptor descriptor, boolean isMutable) {
|
||||
int arity = (descriptor.getExtensionReceiverParameter() != null ? 1 : 0) +
|
||||
(descriptor.getDispatchReceiverParameter() != null ? 1 : 0);
|
||||
return (descriptor.isVar() ? mutablePropertyReferences : propertyReferences).get(arity).getDefaultType();
|
||||
return (isMutable ? mutablePropertyReferences : propertyReferences).get(arity).getDefaultType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,12 +82,13 @@ class JvmStaticGenerator(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
@JvmStatic
|
||||
fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor
|
||||
val copies = CodegenUtil.copyFunctions(
|
||||
memberDescriptor,
|
||||
memberDescriptor,
|
||||
descriptor.containingDeclaration.containingDeclaration,
|
||||
descriptor.containingDeclaration.containingDeclaration!!,
|
||||
descriptor.modality,
|
||||
descriptor.visibility,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
|
||||
@@ -59,6 +59,7 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlags;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.codegen.ClassBuilderModeUtilKt.shouldGenerateMetadata;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
@@ -119,7 +120,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
|
||||
generateSyntheticParts();
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
if (shouldGenerateMetadata(state.getClassBuilderMode())) {
|
||||
generateKotlinMetadataAnnotation();
|
||||
}
|
||||
|
||||
@@ -233,7 +234,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
}
|
||||
|
||||
private static void badDescriptor(ClassDescriptor descriptor, ClassBuilderMode mode) {
|
||||
if (mode != ClassBuilderMode.LIGHT_CLASSES) {
|
||||
if (mode == ClassBuilderMode.FULL) {
|
||||
throw new IllegalStateException("Generating bad descriptor in ClassBuilderMode = " + mode + ": " + descriptor);
|
||||
}
|
||||
}
|
||||
@@ -408,10 +409,11 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
|
||||
KtExpression initializer = property.getInitializer();
|
||||
|
||||
ConstantValue<?> initializerValue = computeInitializerValue(property, propertyDescriptor, initializer);
|
||||
ConstantValue<?> initializerValue =
|
||||
initializer != null ? ExpressionCodegen.getCompileTimeConstant(initializer, bindingContext) : null;
|
||||
// we must write constant values for fields in light classes,
|
||||
// because Java's completion for annotation arguments uses this information
|
||||
if (initializerValue == null) return state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES;
|
||||
if (initializerValue == null) return state.getClassBuilderMode() == ClassBuilderMode.FULL;
|
||||
|
||||
//TODO: OPTIMIZATION: don't initialize static final fields
|
||||
KotlinType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
|
||||
@@ -419,19 +421,6 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
return !skipDefaultValue(propertyDescriptor, initializerValue.getValue(), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ConstantValue<?> computeInitializerValue(
|
||||
@NotNull KtProperty property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@Nullable KtExpression initializer
|
||||
) {
|
||||
if (property.isVar() && initializer != null) {
|
||||
BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer");
|
||||
return constantExpressionEvaluator.evaluateToConstantValue(initializer, tempTrace, propertyDescriptor.getType());
|
||||
}
|
||||
return propertyDescriptor.getCompileTimeInitializer();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private KotlinType getPropertyOrDelegateType(@NotNull KtProperty property, @NotNull PropertyDescriptor descriptor) {
|
||||
KtExpression delegateExpression = property.getDelegateExpression();
|
||||
@@ -495,7 +484,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
v.newField(NO_ORIGIN, ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME,
|
||||
"[" + K_PROPERTY_TYPE, null, null);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
|
||||
InstructionAdapter iv = createOrGetClInitCodegen().v;
|
||||
iv.iconst(delegatedProperties.size());
|
||||
|
||||
@@ -32,7 +32,8 @@ 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.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.*
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.DELEGATING
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.INHERITING
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
@@ -262,7 +263,7 @@ class MultifileClassCodegen(
|
||||
if (Visibilities.isPrivate(descriptor.visibility)) return false
|
||||
if (AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE) return false
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) return true
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) return true
|
||||
|
||||
if (shouldGeneratePartHierarchy) {
|
||||
if (descriptor !is PropertyDescriptor || !descriptor.isConst) return false
|
||||
@@ -322,7 +323,7 @@ class MultifileClassCodegen(
|
||||
}
|
||||
|
||||
private fun writeKotlinMultifileFacadeAnnotationIfNeeded() {
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) return
|
||||
if (!state.classBuilderMode.shouldGenerateMetadata()) return
|
||||
if (files.any { it.isScript }) return
|
||||
|
||||
writeKotlinMetadata(classBuilder, KotlinClassHeader.Kind.MULTIFILE_CLASS) { av ->
|
||||
|
||||
@@ -24,7 +24,8 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.*
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.DELEGATING
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader.MultifileClassKind.INHERITING
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
@@ -45,7 +46,7 @@ class MultifileClassPartCodegen(
|
||||
private val packageFragment: PackageFragmentDescriptor,
|
||||
private val superClassInternalName: String,
|
||||
private val shouldGeneratePartHierarchy: Boolean,
|
||||
private val partContext: MultifileClassPartContext,
|
||||
partContext: MultifileClassPartContext,
|
||||
state: GenerationState
|
||||
) : MemberCodegen<KtFile>(state, null, partContext, file, v) {
|
||||
private val partType = partContext.filePartType
|
||||
@@ -76,7 +77,7 @@ class MultifileClassPartCodegen(
|
||||
}
|
||||
|
||||
override fun generate() {
|
||||
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) return
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) return
|
||||
|
||||
super.generate()
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ public class PropertyCodegen {
|
||||
|
||||
FieldVisitor fv = builder.newField(
|
||||
JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||
typeMapper.mapFieldSignature(kotlinType, propertyDescriptor), defaultValue
|
||||
isDelegate ? null : typeMapper.mapFieldSignature(kotlinType, propertyDescriptor), defaultValue
|
||||
);
|
||||
|
||||
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.method
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -44,6 +45,7 @@ class PropertyReferenceCodegen(
|
||||
context: ClassContext,
|
||||
expression: KtElement,
|
||||
classBuilder: ClassBuilder,
|
||||
private val localVariableDescriptorForReference: VariableDescriptor,
|
||||
resolvedCall: ResolvedCall<*>
|
||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||
private val classDescriptor = context.contextDescriptor
|
||||
@@ -136,7 +138,7 @@ class PropertyReferenceCodegen(
|
||||
value.put(OBJECT_TYPE, this)
|
||||
}
|
||||
|
||||
if (!target.isVar) return
|
||||
if (!ReflectionTypes.isKMutablePropertyType(localVariableDescriptorForReference.type)) return
|
||||
|
||||
val setterParameters = (getterParameters + arrayOf(OBJECT_TYPE))
|
||||
generateAccessor(method("set", Type.VOID_TYPE, *setterParameters)) { value ->
|
||||
|
||||
@@ -19,14 +19,17 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
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.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -97,6 +100,24 @@ public class RangeCodegenUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ResolvedCall<? extends CallableDescriptor> getLoopRangeResolvedCall(@NotNull KtForExpression forExpression, @NotNull BindingContext bindingContext) {
|
||||
KtExpression loopRange = KtPsiUtil.deparenthesize(forExpression.getLoopRange());
|
||||
|
||||
if (loopRange instanceof KtQualifiedExpression) {
|
||||
KtQualifiedExpression qualifiedExpression = (KtQualifiedExpression) loopRange;
|
||||
KtExpression selector = qualifiedExpression.getSelectorExpression();
|
||||
if (selector instanceof KtCallExpression || selector instanceof KtSimpleNameExpression) {
|
||||
return CallUtilKt.getResolvedCall(selector, bindingContext);
|
||||
}
|
||||
}
|
||||
else if (loopRange instanceof KtSimpleNameExpression) {
|
||||
return CallUtilKt.getResolvedCall(loopRange, bindingContext);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PrimitiveType getPrimitiveRangeElementType(KotlinType rangeType) {
|
||||
return getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE);
|
||||
@@ -138,6 +159,39 @@ public class RangeCodegenUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isArrayOrPrimitiveArrayIndices(@NotNull CallableDescriptor descriptor) {
|
||||
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false;
|
||||
|
||||
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
|
||||
if (extensionReceiver == null) return false;
|
||||
KotlinType extensionReceiverType = extensionReceiver.getType();
|
||||
if (!KotlinBuiltIns.isArray(extensionReceiverType) && !KotlinBuiltIns.isPrimitiveArray(extensionReceiverType)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isCollectionIndices(@NotNull CallableDescriptor descriptor) {
|
||||
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false;
|
||||
|
||||
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
|
||||
if (extensionReceiver == null) return false;
|
||||
KotlinType extensionReceiverType = extensionReceiver.getType();
|
||||
if (!KotlinBuiltIns.isCollectionOrNullableCollection(extensionReceiverType)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isTopLevelInPackage(@NotNull CallableDescriptor descriptor, @NotNull String name, @NotNull String packageName) {
|
||||
if (!name.equals(descriptor.getName().asString())) return false;
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (!(containingDeclaration instanceof PackageFragmentDescriptor)) return false;
|
||||
String packageFqName = ((PackageFragmentDescriptor) containingDeclaration).getFqName().asString();
|
||||
if (!packageName.equals(packageFqName)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class BinaryCall {
|
||||
public final KtExpression left;
|
||||
public final KtExpression op;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,18 +19,16 @@ package org.jetbrains.kotlin.codegen;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
|
||||
public class SamCodegenUtil {
|
||||
@Nullable
|
||||
public static FunctionDescriptor getOriginalIfSamAdapter(@NotNull FunctionDescriptor fun) {
|
||||
if (fun instanceof SamAdapterDescriptor<?>) {
|
||||
return ((SamAdapterDescriptor<?>) fun).getOriginForSam();
|
||||
}
|
||||
|
||||
if (fun instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
return ((SamAdapterExtensionFunctionDescriptor) fun).getSourceFunction();
|
||||
if (fun instanceof SamAdapterDescriptor<?> || fun instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
//noinspection unchecked
|
||||
return ((SyntheticMemberDescriptor<FunctionDescriptor>) fun).getBaseDescriptorForSynthetic();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -394,9 +394,10 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
else if (fromType.getSort() == Type.OBJECT) {
|
||||
if (fromType.equals(getType(Boolean.class)) || fromType.equals(getType(Character.class))) {
|
||||
unbox(unboxType(fromType), v);
|
||||
coerce(unboxType(fromType), toType, v);
|
||||
Type unboxedType = unboxPrimitiveTypeOrNull(fromType);
|
||||
if (unboxedType != null) {
|
||||
unbox(unboxedType, v);
|
||||
coerce(unboxedType, toType, v);
|
||||
}
|
||||
else {
|
||||
if (toType.getSort() == Type.BOOLEAN || toType.getSort() == Type.CHAR) {
|
||||
@@ -709,12 +710,13 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Constant extends StackValue {
|
||||
private static class Constant extends StackValue {
|
||||
@Nullable
|
||||
private final Object value;
|
||||
|
||||
public Constant(@Nullable Object value, Type type) {
|
||||
super(type, false);
|
||||
assert !Type.BOOLEAN_TYPE.equals(type) : "Boolean constants should be created via 'StackValue.constant'";
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -723,6 +725,9 @@ public abstract class StackValue {
|
||||
if (value instanceof Integer || value instanceof Byte || value instanceof Short) {
|
||||
v.iconst(((Number) value).intValue());
|
||||
}
|
||||
else if (value instanceof Character) {
|
||||
v.iconst(((Character) value).charValue());
|
||||
}
|
||||
else if (value instanceof Long) {
|
||||
v.lconst((Long) value);
|
||||
}
|
||||
@@ -1146,7 +1151,7 @@ public abstract class StackValue {
|
||||
value = ((Double) value).floatValue();
|
||||
}
|
||||
|
||||
new Constant(value, this.type).putSelector(type, v);
|
||||
StackValue.constant(value, this.type).putSelector(type, v);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class StackValueWithLeaveTask(
|
||||
}
|
||||
}
|
||||
|
||||
open class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter) -> Unit) : StackValue(resultType) {
|
||||
open class OperationStackValue(resultType: Type, val lambda: (v: InstructionAdapter) -> Unit) : StackValue(resultType) {
|
||||
|
||||
override fun putSelector(type: Type, v: InstructionAdapter) {
|
||||
lambda(v)
|
||||
|
||||
@@ -30,7 +30,7 @@ class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, pr
|
||||
override fun getAnnotations() = actual
|
||||
}
|
||||
|
||||
class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
|
||||
class AnnotatedWithOnlyTargetedAnnotations(original: Annotated) : Annotated {
|
||||
private val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
|
||||
|
||||
override fun getAnnotations() = annotations
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.util.containers.Stack;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes;
|
||||
import org.jetbrains.kotlin.cfg.WhenChecker;
|
||||
import org.jetbrains.kotlin.codegen.*;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -46,7 +47,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.NullValue;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -295,7 +295,11 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
callableDescriptor = bindingContext.get(VARIABLE, expression);
|
||||
if (callableDescriptor == null) return;
|
||||
|
||||
supertypes = Collections.singleton(runtimeTypes.getSupertypeForPropertyReference((PropertyDescriptor) target));
|
||||
//noinspection ConstantConditions
|
||||
supertypes = Collections.singleton(runtimeTypes.getSupertypeForPropertyReference(
|
||||
(PropertyDescriptor) target,
|
||||
ReflectionTypes.Companion.isKMutablePropertyType(callableDescriptor.getReturnType())
|
||||
));
|
||||
}
|
||||
else {
|
||||
return;
|
||||
@@ -335,7 +339,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
if (delegate != null && descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
String name = inventAnonymousClassName();
|
||||
KotlinType supertype = runtimeTypes.getSupertypeForPropertyReference(propertyDescriptor);
|
||||
KotlinType supertype = runtimeTypes.getSupertypeForPropertyReference(propertyDescriptor, propertyDescriptor.isVar());
|
||||
ClassDescriptor classDescriptor = recordClassForCallable(delegate, propertyDescriptor, Collections.singleton(supertype), name);
|
||||
recordClosure(classDescriptor, name);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
import java.util.*
|
||||
|
||||
class BridgeForBuiltinSpecial<Signature : Any>(
|
||||
class BridgeForBuiltinSpecial<out Signature : Any>(
|
||||
val from: Signature, val to: Signature,
|
||||
val isSpecial: Boolean = false,
|
||||
val isDelegateToSuper: Boolean = false
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
fun ClassBuilderMode.shouldGenerateMetadata() =
|
||||
this == ClassBuilderMode.FULL || this == ClassBuilderMode.KAPT
|
||||
@@ -23,8 +23,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder;
|
||||
import org.jetbrains.kotlin.codegen.FieldInfo;
|
||||
import org.jetbrains.kotlin.codegen.StackValue;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -36,27 +34,16 @@ import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.isThis0;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
|
||||
public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjectTransformationInfo> {
|
||||
|
||||
protected final GenerationState state;
|
||||
|
||||
protected final KotlinTypeMapper typeMapper;
|
||||
private final InliningContext inliningContext;
|
||||
private final Type oldObjectType;
|
||||
private final boolean isSameModule;
|
||||
private final Map<String, List<String>> fieldNames = new HashMap<String, List<String>>();
|
||||
|
||||
private MethodNode constructor;
|
||||
|
||||
private String sourceInfo;
|
||||
|
||||
private String debugInfo;
|
||||
|
||||
private SourceMapper sourceMapper;
|
||||
|
||||
private final InliningContext inliningContext;
|
||||
|
||||
private final Type oldObjectType;
|
||||
|
||||
private final boolean isSameModule;
|
||||
|
||||
private final Map<String, List<String>> fieldNames = new HashMap<String, List<String>>();
|
||||
|
||||
public AnonymousObjectTransformer(
|
||||
@NotNull AnonymousObjectTransformationInfo transformationInfo,
|
||||
@NotNull InliningContext inliningContext,
|
||||
@@ -64,8 +51,6 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
) {
|
||||
super(transformationInfo, inliningContext.state);
|
||||
this.isSameModule = isSameModule;
|
||||
this.state = inliningContext.state;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.inliningContext = inliningContext;
|
||||
this.oldObjectType = Type.getObjectType(transformationInfo.getOldClassName());
|
||||
}
|
||||
@@ -94,25 +79,25 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions
|
||||
) {
|
||||
MethodNode node = new MethodNode(access, name, desc, signature, exceptions);
|
||||
if (name.equals("<init>")){
|
||||
if (constructor != null)
|
||||
if (name.equals("<init>")) {
|
||||
if (constructor != null) {
|
||||
throw new RuntimeException("Lambda, SAM or anonymous object should have only one constructor");
|
||||
|
||||
}
|
||||
constructor = node;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
methodsToTransform.add(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(
|
||||
int access, @NotNull String name, @NotNull String desc, String signature, Object value
|
||||
) {
|
||||
public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) {
|
||||
addUniqueField(name);
|
||||
if (InlineCodegenUtil.isCapturedFieldName(name)) {
|
||||
return null;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value);
|
||||
}
|
||||
}
|
||||
@@ -125,7 +110,6 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
|
||||
}
|
||||
}, ClassReader.SKIP_FRAMES);
|
||||
|
||||
@@ -218,29 +202,30 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
@NotNull ParametersBuilder capturedBuilder,
|
||||
boolean isConstructor
|
||||
) {
|
||||
ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode);
|
||||
Parameters parameters = isConstructor ? capturedBuilder.buildParameters() : getMethodParametersWithCaptured(capturedBuilder, sourceNode);
|
||||
ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifiedTypeInliner.reifyInstructions(sourceNode);
|
||||
Parameters parameters =
|
||||
isConstructor ? capturedBuilder.buildParameters() : getMethodParametersWithCaptured(capturedBuilder, sourceNode);
|
||||
|
||||
RegeneratedLambdaFieldRemapper remapper =
|
||||
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), transformationInfo.getNewClassName(),
|
||||
parameters, transformationInfo.getCapturedLambdasToInline(),
|
||||
parentRemapper, isConstructor);
|
||||
RegeneratedLambdaFieldRemapper remapper = new RegeneratedLambdaFieldRemapper(
|
||||
oldObjectType.getInternalName(), transformationInfo.getNewClassName(), parameters,
|
||||
transformationInfo.getCapturedLambdasToInline(), parentRemapper, isConstructor
|
||||
);
|
||||
|
||||
MethodInliner inliner =
|
||||
new MethodInliner(
|
||||
sourceNode,
|
||||
parameters,
|
||||
inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper,
|
||||
isSameModule,
|
||||
"Transformer for " + transformationInfo.getOldClassName(),
|
||||
sourceMapper,
|
||||
new InlineCallSiteInfo(
|
||||
transformationInfo.getOldClassName(),
|
||||
sourceNode.name,
|
||||
isConstructor ? transformationInfo.getNewConstructorDescriptor() : sourceNode.desc),
|
||||
null
|
||||
);
|
||||
MethodInliner inliner = new MethodInliner(
|
||||
sourceNode,
|
||||
parameters,
|
||||
inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper,
|
||||
isSameModule,
|
||||
"Transformer for " + transformationInfo.getOldClassName(),
|
||||
sourceMapper,
|
||||
new InlineCallSiteInfo(
|
||||
transformationInfo.getOldClassName(),
|
||||
sourceNode.name,
|
||||
isConstructor ? transformationInfo.getNewConstructorDescriptor() : sourceNode.desc
|
||||
),
|
||||
null
|
||||
);
|
||||
|
||||
InlineResult result = inliner.doInline(deferringVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE);
|
||||
result.getReifiedTypeParametersUsages().mergeAll(typeParametersToReify);
|
||||
@@ -258,13 +243,13 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
List<Type> descTypes = new ArrayList<Type>();
|
||||
|
||||
Parameters constructorParams = constructorInlineBuilder.buildParameters();
|
||||
int [] capturedIndexes = new int [constructorParams.getReal().size() + constructorParams.getCaptured().size()];
|
||||
int[] capturedIndexes = new int[constructorParams.getReal().size() + constructorParams.getCaptured().size()];
|
||||
int index = 0;
|
||||
int size = 0;
|
||||
|
||||
//complex processing cause it could have super constructor call params
|
||||
for (ParameterInfo info : constructorParams) {
|
||||
if (!info.isSkipped()) { //not inlined
|
||||
if (!info.isSkipped) { //not inlined
|
||||
if (info.isCaptured() || info instanceof CapturedParamInfo) {
|
||||
capturedIndexes[index] = size;
|
||||
index++;
|
||||
@@ -280,17 +265,16 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
|
||||
//TODO for inline method make public class
|
||||
transformationInfo.setNewConstructorDescriptor(constructorDescriptor);
|
||||
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN,
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
"<init>", constructorDescriptor,
|
||||
null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
MethodVisitor constructorVisitor = classBuilder.newMethod(
|
||||
NO_ORIGIN, AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY
|
||||
);
|
||||
|
||||
final Label newBodyStartLabel = new Label();
|
||||
constructorVisitor.visitLabel(newBodyStartLabel);
|
||||
//initialize captured fields
|
||||
List<NewJavaField> newFieldsWithSkipped = TransformationUtilsKt.getNewFieldsToGenerate(allCapturedBuilder.listCaptured());
|
||||
List<FieldInfo> fieldInfoWithSkipped = TransformationUtilsKt.transformToFieldInfo(
|
||||
Type.getObjectType(transformationInfo.getNewClassName()), newFieldsWithSkipped);
|
||||
List<FieldInfo> fieldInfoWithSkipped =
|
||||
TransformationUtilsKt.transformToFieldInfo(Type.getObjectType(transformationInfo.getNewClassName()), newFieldsWithSkipped);
|
||||
|
||||
int paramIndex = 0;
|
||||
InstructionAdapter capturedFieldInitializer = new InstructionAdapter(constructorVisitor);
|
||||
@@ -311,23 +295,28 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
|
||||
if (fake.getLambda() != null) {
|
||||
//set remap value to skip this fake (captured with lambda already skipped)
|
||||
StackValue composed = StackValue.field(fake.getType(),
|
||||
oldObjectType,
|
||||
fake.getNewFieldName(),
|
||||
false,
|
||||
StackValue.LOCAL_0);
|
||||
StackValue composed = StackValue.field(
|
||||
fake.getType(),
|
||||
oldObjectType,
|
||||
fake.getNewFieldName(),
|
||||
false,
|
||||
StackValue.LOCAL_0
|
||||
);
|
||||
fake.setRemapValue(composed);
|
||||
}
|
||||
}
|
||||
|
||||
MethodNode intermediateMethodNode = new MethodNode(AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
MethodNode intermediateMethodNode =
|
||||
new MethodNode(AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
|
||||
|
||||
AbstractInsnNode first = intermediateMethodNode.instructions.getFirst();
|
||||
final Label oldStartLabel = first instanceof LabelNode ? ((LabelNode) first).getLabel() : null;
|
||||
intermediateMethodNode.accept(new MethodBodyVisitor(capturedFieldInitializer) {
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
|
||||
public void visitLocalVariable(
|
||||
@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index
|
||||
) {
|
||||
if (oldStartLabel == start) {
|
||||
start = newBodyStartLabel;//patch for jack&jill
|
||||
}
|
||||
@@ -335,14 +324,13 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
}
|
||||
});
|
||||
constructorVisitor.visitEnd();
|
||||
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
|
||||
AsmUtil.genClosureFields(
|
||||
TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Parameters getMethodParametersWithCaptured(
|
||||
@NotNull ParametersBuilder capturedBuilder,
|
||||
@NotNull MethodNode sourceNode
|
||||
) {
|
||||
private Parameters getMethodParametersWithCaptured(@NotNull ParametersBuilder capturedBuilder, @NotNull MethodNode sourceNode) {
|
||||
ParametersBuilder builder = ParametersBuilder.initializeBuilderFrom(oldObjectType, sourceNode.desc);
|
||||
for (CapturedParamInfo param : capturedBuilder.listCaptured()) {
|
||||
builder.addCapturedParamCopy(param);
|
||||
@@ -353,26 +341,23 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
@NotNull
|
||||
private static DeferredMethodVisitor newMethod(@NotNull final ClassBuilder builder, @NotNull final MethodNode original) {
|
||||
return new DeferredMethodVisitor(
|
||||
new MethodNode(original.access,
|
||||
original.name,
|
||||
original.desc,
|
||||
original.signature,
|
||||
ArrayUtil.toStringArray(original.exceptions)),
|
||||
|
||||
new MethodNode(
|
||||
original.access, original.name, original.desc, original.signature,
|
||||
ArrayUtil.toStringArray(original.exceptions)
|
||||
),
|
||||
new Function0<MethodVisitor>() {
|
||||
@Override
|
||||
public MethodVisitor invoke() {
|
||||
return builder.newMethod(
|
||||
NO_ORIGIN,
|
||||
original.access,
|
||||
original.name,
|
||||
original.desc,
|
||||
original.signature,
|
||||
ArrayUtil.toStringArray(original.exceptions));
|
||||
NO_ORIGIN, original.access, original.name, original.desc, original.signature,
|
||||
ArrayUtil.toStringArray(original.exceptions)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<CapturedParamInfo> extractParametersMappingAndPatchConstructor(
|
||||
@NotNull MethodNode constructor,
|
||||
@NotNull ParametersBuilder capturedParamBuilder,
|
||||
@@ -380,14 +365,6 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
@NotNull final AnonymousObjectTransformationInfo transformationInfo,
|
||||
@NotNull FieldRemapper parentFieldRemapper
|
||||
) {
|
||||
|
||||
CapturedParamOwner owner = new CapturedParamOwner() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.getObjectType(transformationInfo.getOldClassName());
|
||||
}
|
||||
};
|
||||
|
||||
Set<LambdaInfo> capturedLambdas = new LinkedHashSet<LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamInfo> constructorAdditionalFakeParams = new ArrayList<CapturedParamInfo>();
|
||||
Map<Integer, LambdaInfo> indexToLambda = transformationInfo.getLambdasToInline();
|
||||
@@ -400,7 +377,6 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
FieldInsnNode fieldNode = (FieldInsnNode) cur;
|
||||
String fieldName = fieldNode.name;
|
||||
if (fieldNode.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(fieldName)) {
|
||||
|
||||
boolean isPrevVarNode = fieldNode.getPrevious() instanceof VarInsnNode;
|
||||
boolean isPrevPrevVarNode = isPrevVarNode && fieldNode.getPrevious().getPrevious() instanceof VarInsnNode;
|
||||
|
||||
@@ -410,8 +386,14 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
VarInsnNode previous = (VarInsnNode) fieldNode.getPrevious();
|
||||
int varIndex = previous.var;
|
||||
LambdaInfo lambdaInfo = indexToLambda.get(varIndex);
|
||||
String newFieldName = isThis0(fieldName) && shouldRenameThis0(parentFieldRemapper, indexToLambda.values()) ? getNewFieldName(fieldName, true) : fieldName;
|
||||
CapturedParamInfo info = capturedParamBuilder.addCapturedParam(owner, fieldName, newFieldName, Type.getType(fieldNode.desc), lambdaInfo != null, null);
|
||||
String newFieldName =
|
||||
isThis0(fieldName) && shouldRenameThis0(parentFieldRemapper, indexToLambda.values())
|
||||
? getNewFieldName(fieldName, true)
|
||||
: fieldName;
|
||||
CapturedParamInfo info = capturedParamBuilder.addCapturedParam(
|
||||
Type.getObjectType(transformationInfo.getOldClassName()), fieldName, newFieldName,
|
||||
Type.getType(fieldNode.desc), lambdaInfo != null, null
|
||||
);
|
||||
if (lambdaInfo != null) {
|
||||
info.setLambda(lambdaInfo);
|
||||
capturedLambdas.add(lambdaInfo);
|
||||
@@ -440,14 +422,15 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
constructorDesc = Type.getMethodDescriptor(Type.VOID_TYPE);
|
||||
}
|
||||
|
||||
Type [] types = Type.getArgumentTypes(constructorDesc);
|
||||
Type[] types = Type.getArgumentTypes(constructorDesc);
|
||||
for (Type type : types) {
|
||||
LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextValueParameterIndex());
|
||||
ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null, null);
|
||||
ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null);
|
||||
parameterInfo.setLambda(info);
|
||||
if (capturedParams.contains(parameterInfo.getIndex())) {
|
||||
parameterInfo.setCaptured(true);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//otherwise it's super constructor parameter
|
||||
}
|
||||
}
|
||||
@@ -456,7 +439,9 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
//TODO: some of such parameters could be skipped - we should perform additional analysis
|
||||
Map<String, LambdaInfo> capturedLambdasToInline = new HashMap<String, LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamDesc> allRecapturedParameters = new ArrayList<CapturedParamDesc>();
|
||||
boolean addCapturedNotAddOuter = parentFieldRemapper.isRoot() || (parentFieldRemapper instanceof InlinedLambdaRemapper && parentFieldRemapper.getParent().isRoot());
|
||||
boolean addCapturedNotAddOuter =
|
||||
parentFieldRemapper.isRoot() ||
|
||||
(parentFieldRemapper instanceof InlinedLambdaRemapper && parentFieldRemapper.getParent().isRoot());
|
||||
Map<String, CapturedParamInfo> alreadyAdded = new HashMap<String, CapturedParamInfo>();
|
||||
for (LambdaInfo info : capturedLambdas) {
|
||||
if (addCapturedNotAddOuter) {
|
||||
@@ -466,19 +451,21 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
|
||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(
|
||||
desc,
|
||||
alreadyAddedParam != null ? alreadyAddedParam.getNewFieldName() : getNewFieldName(desc.getFieldName(), false));
|
||||
StackValue composed = StackValue.field(desc.getType(),
|
||||
oldObjectType, /*TODO owner type*/
|
||||
recapturedParamInfo.getNewFieldName(),
|
||||
false,
|
||||
StackValue.LOCAL_0);
|
||||
alreadyAddedParam != null ? alreadyAddedParam.getNewFieldName() : getNewFieldName(desc.getFieldName(), false),
|
||||
alreadyAddedParam != null
|
||||
);
|
||||
StackValue composed = StackValue.field(
|
||||
desc.getType(),
|
||||
oldObjectType, /*TODO owner type*/
|
||||
recapturedParamInfo.getNewFieldName(),
|
||||
false,
|
||||
StackValue.LOCAL_0
|
||||
);
|
||||
recapturedParamInfo.setRemapValue(composed);
|
||||
allRecapturedParameters.add(desc);
|
||||
|
||||
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName()).setRemapValue(composed);
|
||||
if (alreadyAddedParam != null) {
|
||||
recapturedParamInfo.setSkipInConstructor(true);
|
||||
}
|
||||
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName())
|
||||
.setRemapValue(composed);
|
||||
|
||||
if (isThis0(desc.getFieldName())) {
|
||||
alreadyAdded.put(key, recapturedParamInfo);
|
||||
@@ -492,15 +479,10 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
//lambda with non InlinedLambdaRemapper already have outer
|
||||
FieldRemapper parent = parentFieldRemapper.getParent();
|
||||
assert parent instanceof RegeneratedLambdaFieldRemapper;
|
||||
final Type ownerType = Type.getObjectType(parent.getLambdaInternalName());
|
||||
|
||||
CapturedParamDesc desc = new CapturedParamDesc(new CapturedParamOwner() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return ownerType;
|
||||
}
|
||||
}, InlineCodegenUtil.THIS, ownerType);
|
||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.THIS$0/*outer lambda/object*/);
|
||||
Type ownerType = Type.getObjectType(parent.getLambdaInternalName());
|
||||
CapturedParamDesc desc = new CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType);
|
||||
CapturedParamInfo recapturedParamInfo =
|
||||
capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.THIS$0/*outer lambda/object*/, false);
|
||||
StackValue composed = StackValue.LOCAL_0;
|
||||
recapturedParamInfo.setRemapValue(composed);
|
||||
allRecapturedParameters.add(desc);
|
||||
@@ -514,7 +496,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
return constructorAdditionalFakeParams;
|
||||
}
|
||||
|
||||
private static boolean shouldRenameThis0(@NotNull FieldRemapper parentFieldRemapper, Collection<LambdaInfo> values) {
|
||||
private static boolean shouldRenameThis0(@NotNull FieldRemapper parentFieldRemapper, @NotNull Collection<LambdaInfo> values) {
|
||||
if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
||||
for (LambdaInfo value : values) {
|
||||
for (CapturedParamDesc desc : value.getCapturedVars()) {
|
||||
@@ -528,11 +510,12 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getNewFieldName(@NotNull String oldName, boolean originalField) {
|
||||
private String getNewFieldName(@NotNull String oldName, boolean originalField) {
|
||||
if (InlineCodegenUtil.THIS$0.equals(oldName)) {
|
||||
if (!originalField) {
|
||||
return oldName;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
||||
return addUniqueField(oldName + InlineCodegenUtil.INLINE_FUN_THIS_0_SUFFIX);
|
||||
}
|
||||
@@ -553,7 +536,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
return newName;
|
||||
}
|
||||
|
||||
private static boolean isFirstDeclSiteLambdaFieldRemapper(FieldRemapper parentRemapper) {
|
||||
private static boolean isFirstDeclSiteLambdaFieldRemapper(@NotNull FieldRemapper parentRemapper) {
|
||||
return !(parentRemapper instanceof RegeneratedLambdaFieldRemapper) && !(parentRemapper instanceof InlinedLambdaRemapper);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.jetbrains.org.objectweb.asm.signature.SignatureReader
|
||||
import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor
|
||||
|
||||
class AsmTypeRemapper(val typeRemapper: TypeRemapper, val isDefaultGeneration: Boolean, val result: InlineResult) : Remapper() {
|
||||
|
||||
override fun map(type: String): String {
|
||||
return typeRemapper.map(type)
|
||||
}
|
||||
@@ -33,7 +32,6 @@ class AsmTypeRemapper(val typeRemapper: TypeRemapper, val isDefaultGeneration: B
|
||||
}
|
||||
|
||||
return object : RemappingSignatureAdapter(v, this) {
|
||||
|
||||
override fun visitTypeVariable(name: String) {
|
||||
/*TODO try to erase absent type variable*/
|
||||
val mapping = typeRemapper.mapTypeParameter(name) ?: return super.visitTypeVariable(name)
|
||||
@@ -54,4 +52,4 @@ class AsmTypeRemapper(val typeRemapper: TypeRemapper, val isDefaultGeneration: B
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,19 +20,19 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class CapturedParamDesc {
|
||||
private final CapturedParamOwner containingLambda;
|
||||
private final Type containingLambdaType;
|
||||
private final String fieldName;
|
||||
private final Type type;
|
||||
|
||||
public CapturedParamDesc(@NotNull CapturedParamOwner containingLambda, @NotNull String fieldName, @NotNull Type type) {
|
||||
this.containingLambda = containingLambda;
|
||||
public CapturedParamDesc(@NotNull Type containingLambdaType, @NotNull String fieldName, @NotNull Type type) {
|
||||
this.containingLambdaType = containingLambdaType;
|
||||
this.fieldName = fieldName;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getContainingLambdaName() {
|
||||
return containingLambda.getType().getInternalName();
|
||||
return containingLambdaType.getInternalName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -44,9 +44,4 @@ public class CapturedParamDesc {
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CapturedParamDesc createDesc(@NotNull CapturedParamOwner containingLambdaInfo, @NotNull String fieldName, @NotNull Type type) {
|
||||
return new CapturedParamDesc(containingLambdaInfo, fieldName, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,38 +17,33 @@
|
||||
package org.jetbrains.kotlin.codegen.inline;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.StackValue;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class CapturedParamInfo extends ParameterInfo {
|
||||
|
||||
public static final CapturedParamInfo STUB = new CapturedParamInfo(CapturedParamDesc.createDesc(new CapturedParamOwner() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.getObjectType("STUB");
|
||||
}
|
||||
}, "STUB", Type.getObjectType("STUB")), true, -1, -1);
|
||||
|
||||
public final CapturedParamDesc desc;
|
||||
|
||||
private final String newFieldName;
|
||||
|
||||
private boolean skipInConstructor;
|
||||
|
||||
public CapturedParamInfo(@NotNull CapturedParamDesc desc, boolean skipped, int index, int remapIndex) {
|
||||
this(desc, desc.getFieldName(), skipped, index, remapIndex);
|
||||
}
|
||||
private final boolean skipInConstructor;
|
||||
|
||||
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, int remapIndex) {
|
||||
super(desc.getType(), skipped, index, remapIndex, index);
|
||||
this.desc = desc;
|
||||
this.newFieldName = newFieldName;
|
||||
this.skipInConstructor = false;
|
||||
}
|
||||
|
||||
public CapturedParamInfo(@NotNull CapturedParamDesc desc, @NotNull String newFieldName, boolean skipped, int index, StackValue remapIndex) {
|
||||
public CapturedParamInfo(
|
||||
@NotNull CapturedParamDesc desc,
|
||||
@NotNull String newFieldName,
|
||||
boolean skipped,
|
||||
int index,
|
||||
@Nullable StackValue remapIndex,
|
||||
boolean skipInConstructor
|
||||
) {
|
||||
super(desc.getType(), skipped, index, remapIndex, index);
|
||||
this.desc = desc;
|
||||
this.newFieldName = newFieldName;
|
||||
this.skipInConstructor = skipInConstructor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -67,11 +62,10 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CapturedParamInfo clone(int newIndex, StackValue newRamapIndex) {
|
||||
CapturedParamInfo capturedParamInfo = new CapturedParamInfo(desc, newFieldName, isSkipped, newIndex, newRamapIndex);
|
||||
capturedParamInfo.setLambda(lambda);
|
||||
capturedParamInfo.setSkipInConstructor(skipInConstructor);
|
||||
return capturedParamInfo;
|
||||
private CapturedParamInfo clone(int newIndex, @Nullable StackValue newRemapIndex) {
|
||||
CapturedParamInfo result = new CapturedParamInfo(desc, newFieldName, isSkipped, newIndex, newRemapIndex, skipInConstructor);
|
||||
result.setLambda(getLambda());
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -82,8 +76,4 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
public boolean isSkipInConstructor() {
|
||||
return skipInConstructor;
|
||||
}
|
||||
|
||||
public void setSkipInConstructor(boolean skipInConstructor) {
|
||||
this.skipInConstructor = skipInConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,18 +17,12 @@
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.google.common.collect.LinkedListMultimap
|
||||
import java.util.ArrayList
|
||||
import com.intellij.util.containers.Stack
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import java.util.Comparator
|
||||
import java.util.Collections
|
||||
import java.util.*
|
||||
|
||||
abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
|
||||
|
||||
val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo()
|
||||
|
||||
val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo()
|
||||
|
||||
var nextFreeLocalIndex: Int = parameterSize
|
||||
@@ -70,11 +64,11 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
|
||||
result
|
||||
}
|
||||
|
||||
Collections.sort<TryCatchBlockNodeInfo>(intervals, comp)
|
||||
return intervals;
|
||||
Collections.sort(intervals, comp)
|
||||
return intervals
|
||||
}
|
||||
|
||||
protected fun substituteTryBlockNodes(node: MethodNode) {
|
||||
fun substituteTryBlockNodes(node: MethodNode) {
|
||||
node.tryCatchBlocks.clear()
|
||||
sortTryCatchBlocks(tryBlocksMetaInfo.allIntervals)
|
||||
for (info in tryBlocksMetaInfo.getMeaningfulIntervals()) {
|
||||
@@ -82,7 +76,6 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun substituteLocalVarTable(node: MethodNode) {
|
||||
node.localVariables.clear()
|
||||
for (info in localVarsMetaInfo.getMeaningfulIntervals()) {
|
||||
@@ -92,13 +85,9 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
|
||||
}
|
||||
|
||||
class IntervalMetaInfo<T : SplittableInterval<T>> {
|
||||
|
||||
val intervalStarts = LinkedListMultimap.create<LabelNode, T>()
|
||||
|
||||
val intervalEnds = LinkedListMultimap.create<LabelNode, T>()
|
||||
|
||||
val allIntervals: ArrayList<T> = arrayListOf()
|
||||
|
||||
val currentIntervals: MutableSet<T> = linkedSetOf()
|
||||
|
||||
fun addNewInterval(newInfo: T) {
|
||||
@@ -117,17 +106,10 @@ class IntervalMetaInfo<T : SplittableInterval<T>> {
|
||||
intervalEnds.put(remapped.endLabel, remapped)
|
||||
}
|
||||
|
||||
fun splitCurrentIntervals(by : Interval, keepStart: Boolean): List<SplitPair<T>> {
|
||||
fun splitCurrentIntervals(by: Interval, keepStart: Boolean): List<SplitPair<T>> {
|
||||
return currentIntervals.map { split(it, by, keepStart) }
|
||||
}
|
||||
|
||||
fun splitAndRemoveIntervalsFromCurrents(by : Interval) {
|
||||
val copies = ArrayList(currentIntervals)
|
||||
copies.forEach {
|
||||
splitAndRemoveInterval(it, by, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun processCurrent(curIns: LabelNode, directOrder: Boolean) {
|
||||
getInterval(curIns, directOrder).forEach {
|
||||
val added = currentIntervals.add(it)
|
||||
@@ -140,25 +122,27 @@ class IntervalMetaInfo<T : SplittableInterval<T>> {
|
||||
}
|
||||
}
|
||||
|
||||
fun split(interval: T, by : Interval, keepStart: Boolean): SplitPair<T> {
|
||||
fun split(interval: T, by: Interval, keepStart: Boolean): SplitPair<T> {
|
||||
val split = interval.split(by, keepStart)
|
||||
if (!keepStart) {
|
||||
remapStartLabel(split.newPart.startLabel, split.patchedPart)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
remapEndLabel(split.newPart.endLabel, split.patchedPart)
|
||||
}
|
||||
addNewInterval(split.newPart)
|
||||
return split
|
||||
}
|
||||
|
||||
fun splitAndRemoveInterval(interval: T, by : Interval, keepStart: Boolean): SplitPair<T> {
|
||||
fun splitAndRemoveInterval(interval: T, by: Interval, keepStart: Boolean): SplitPair<T> {
|
||||
val splitPair = split(interval, by, keepStart)
|
||||
val removed = currentIntervals.remove(splitPair.patchedPart)
|
||||
assert(removed, {"Wrong interval structure: $splitPair"})
|
||||
assert(removed) { "Wrong interval structure: $splitPair" }
|
||||
return splitPair
|
||||
}
|
||||
|
||||
fun getInterval(curIns: LabelNode, isOpen: Boolean) = if (isOpen) intervalStarts.get(curIns) else intervalEnds.get(curIns)
|
||||
fun getInterval(curIns: LabelNode, isOpen: Boolean) =
|
||||
if (isOpen) intervalStarts.get(curIns) else intervalEnds.get(curIns)
|
||||
}
|
||||
|
||||
private fun Interval.isMeaningless(): Boolean {
|
||||
@@ -175,23 +159,16 @@ fun <T : SplittableInterval<T>> IntervalMetaInfo<T>.getMeaningfulIntervals(): Li
|
||||
}
|
||||
|
||||
class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) {
|
||||
|
||||
init {
|
||||
node.tryCatchBlocks.forEach { addTryNode(it) }
|
||||
node.localVariables.forEach { addLocalVarNode(it) }
|
||||
node.tryCatchBlocks.forEach {
|
||||
tryBlocksMetaInfo.addNewInterval(TryCatchBlockNodeInfo(it, false))
|
||||
}
|
||||
node.localVariables.forEach {
|
||||
localVarsMetaInfo.addNewInterval(LocalVarNodeWrapper(it))
|
||||
}
|
||||
}
|
||||
|
||||
fun addLocalVarNode(it: LocalVariableNode) {
|
||||
localVarsMetaInfo.addNewInterval(LocalVarNodeWrapper(it))
|
||||
}
|
||||
|
||||
fun addTryNode(node: TryCatchBlockNode) {
|
||||
tryBlocksMetaInfo.addNewInterval(TryCatchBlockNodeInfo(node, false))
|
||||
}
|
||||
|
||||
override fun instructionIndex(inst: AbstractInsnNode): Int {
|
||||
return node.instructions.indexOf(inst)
|
||||
}
|
||||
override fun instructionIndex(inst: AbstractInsnNode): Int = node.instructions.indexOf(inst)
|
||||
}
|
||||
|
||||
class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInterval<LocalVarNodeWrapper> {
|
||||
@@ -216,5 +193,4 @@ class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInt
|
||||
LocalVariableNode(node.name, node.desc, node.signature, newPartInterval.first, newPartInterval.second, node.index)
|
||||
))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.StackValue;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
|
||||
@@ -29,30 +28,24 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class FieldRemapper {
|
||||
|
||||
private final String lambdaInternalName;
|
||||
|
||||
protected FieldRemapper parent;
|
||||
|
||||
private final String lambdaInternalName;
|
||||
private final Parameters params;
|
||||
|
||||
public FieldRemapper(@Nullable String lambdaInternalName, @Nullable FieldRemapper parent, @NotNull Parameters methodParams) {
|
||||
this.lambdaInternalName = lambdaInternalName;
|
||||
this.parent = parent;
|
||||
params = methodParams;
|
||||
this.params = methodParams;
|
||||
}
|
||||
|
||||
protected boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) {
|
||||
protected boolean canProcess(@NotNull String fieldOwner, @NotNull String fieldName, boolean isFolding) {
|
||||
return fieldOwner.equals(getLambdaInternalName()) &&
|
||||
//don't process general field of anonymous objects
|
||||
InlineCodegenUtil.isCapturedFieldName(fieldName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AbstractInsnNode foldFieldAccessChainIfNeeded(
|
||||
@NotNull List<AbstractInsnNode> capturedFieldAccess,
|
||||
@NotNull MethodNode node
|
||||
) {
|
||||
public AbstractInsnNode foldFieldAccessChainIfNeeded(@NotNull List<AbstractInsnNode> capturedFieldAccess, @NotNull MethodNode node) {
|
||||
if (capturedFieldAccess.size() == 1) {
|
||||
//just aload
|
||||
return null;
|
||||
@@ -72,33 +65,33 @@ public class FieldRemapper {
|
||||
int currentInstruction,
|
||||
@NotNull MethodNode node
|
||||
) {
|
||||
AbstractInsnNode transformed = null;
|
||||
boolean checkParent = !isRoot() && currentInstruction < capturedFieldAccess.size() - 1;
|
||||
if (checkParent) {
|
||||
transformed = parent.foldFieldAccessChainIfNeeded(capturedFieldAccess, currentInstruction + 1, node);
|
||||
}
|
||||
|
||||
if (transformed == null) {
|
||||
//if parent couldn't transform
|
||||
FieldInsnNode insnNode = (FieldInsnNode) capturedFieldAccess.get(currentInstruction);
|
||||
if (canProcess(insnNode.owner, insnNode.name, true)) {
|
||||
insnNode.name = "$$$" + insnNode.name;
|
||||
insnNode.setOpcode(Opcodes.GETSTATIC);
|
||||
|
||||
AbstractInsnNode next = capturedFieldAccess.get(0);
|
||||
while (next != insnNode) {
|
||||
AbstractInsnNode toDelete = next;
|
||||
next = next.getNext();
|
||||
node.instructions.remove(toDelete);
|
||||
}
|
||||
|
||||
transformed = capturedFieldAccess.get(capturedFieldAccess.size() - 1);
|
||||
AbstractInsnNode transformed = parent.foldFieldAccessChainIfNeeded(capturedFieldAccess, currentInstruction + 1, node);
|
||||
if (transformed != null) {
|
||||
return transformed;
|
||||
}
|
||||
}
|
||||
|
||||
return transformed;
|
||||
FieldInsnNode insnNode = (FieldInsnNode) capturedFieldAccess.get(currentInstruction);
|
||||
if (canProcess(insnNode.owner, insnNode.name, true)) {
|
||||
insnNode.name = "$$$" + insnNode.name;
|
||||
insnNode.setOpcode(Opcodes.GETSTATIC);
|
||||
|
||||
AbstractInsnNode next = capturedFieldAccess.get(0);
|
||||
while (next != insnNode) {
|
||||
AbstractInsnNode toDelete = next;
|
||||
next = next.getNext();
|
||||
node.instructions.remove(toDelete);
|
||||
}
|
||||
|
||||
return capturedFieldAccess.get(capturedFieldAccess.size() - 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode) {
|
||||
return findField(fieldInsnNode, params.getCaptured());
|
||||
}
|
||||
@@ -106,13 +99,15 @@ public class FieldRemapper {
|
||||
@Nullable
|
||||
protected CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection<CapturedParamInfo> captured) {
|
||||
for (CapturedParamInfo valueDescriptor : captured) {
|
||||
if (valueDescriptor.getOriginalFieldName().equals(fieldInsnNode.name) && fieldInsnNode.owner.equals(valueDescriptor.getContainingLambdaName())) {
|
||||
if (valueDescriptor.getOriginalFieldName().equals(fieldInsnNode.name) &&
|
||||
valueDescriptor.getContainingLambdaName().equals(fieldInsnNode.owner)) {
|
||||
return valueDescriptor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldRemapper getParent() {
|
||||
return parent;
|
||||
}
|
||||
@@ -131,8 +126,7 @@ public class FieldRemapper {
|
||||
|
||||
@Nullable
|
||||
public StackValue getFieldForInline(@NotNull FieldInsnNode node, @Nullable StackValue prefix) {
|
||||
CapturedParamInfo field = MethodInliner.findCapturedField(node, this);
|
||||
return field.getRemapValue();
|
||||
return MethodInliner.findCapturedField(node, this).getRemapValue();
|
||||
}
|
||||
|
||||
public boolean isInsideInliningLambda() {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.inline;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -27,19 +28,16 @@ import java.util.List;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getLoadStoreArgSize;
|
||||
|
||||
public class InlineAdapter extends InstructionAdapter {
|
||||
|
||||
private int nextLocalIndex = 0;
|
||||
private final SourceMapper sourceMapper;
|
||||
|
||||
private boolean isLambdaInlining = false;
|
||||
|
||||
private final List<CatchBlock> blocks = new ArrayList<CatchBlock>();
|
||||
|
||||
private boolean isLambdaInlining = false;
|
||||
private int nextLocalIndex = 0;
|
||||
private int nextLocalIndexBeforeInline = -1;
|
||||
|
||||
public InlineAdapter(MethodVisitor mv, int localsSize, @NotNull SourceMapper sourceMapper) {
|
||||
public InlineAdapter(@NotNull MethodVisitor mv, int localsSize, @NotNull SourceMapper sourceMapper) {
|
||||
super(InlineCodegenUtil.API, mv);
|
||||
nextLocalIndex = localsSize;
|
||||
this.nextLocalIndex = localsSize;
|
||||
this.sourceMapper = sourceMapper;
|
||||
}
|
||||
|
||||
@@ -70,15 +68,15 @@ public class InlineAdapter extends InstructionAdapter {
|
||||
this.isLambdaInlining = isInlining;
|
||||
if (isInlining) {
|
||||
nextLocalIndexBeforeInline = nextLocalIndex;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
nextLocalIndex = nextLocalIndexBeforeInline;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTryCatchBlock(Label start,
|
||||
Label end, Label handler, String type) {
|
||||
if(!isLambdaInlining) {
|
||||
public void visitTryCatchBlock(@NotNull Label start, @NotNull Label end, @NotNull Label handler, @Nullable String type) {
|
||||
if (!isLambdaInlining) {
|
||||
blocks.add(new CatchBlock(start, end, handler, type));
|
||||
}
|
||||
else {
|
||||
@@ -87,7 +85,7 @@ public class InlineAdapter extends InstructionAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLineNumber(int line, Label start) {
|
||||
public void visitLineNumber(int line, @NotNull Label start) {
|
||||
if (InlineCodegenUtil.GENERATE_SMAP) {
|
||||
line = sourceMapper.mapLineNumber(line);
|
||||
}
|
||||
@@ -111,7 +109,7 @@ public class InlineAdapter extends InstructionAdapter {
|
||||
private final Label handler;
|
||||
private final String type;
|
||||
|
||||
public CatchBlock(Label start, Label end, Label handler, String type) {
|
||||
public CatchBlock(@NotNull Label start, @NotNull Label end, @NotNull Label handler, @Nullable String type) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.handler = handler;
|
||||
|
||||
@@ -34,7 +34,8 @@ inline fun <K, V> SLRUMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
|
||||
val answer = defaultValue()
|
||||
put(key, answer)
|
||||
answer
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,7 @@ import org.jetbrains.kotlin.modules.TargetId;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
@@ -87,7 +84,9 @@ public class InlineCodegen extends CallGenerator {
|
||||
private final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
|
||||
|
||||
private final ReifiedTypeInliner reifiedTypeInliner;
|
||||
@Nullable private final TypeParameterMappings typeParameterMappings;
|
||||
|
||||
@Nullable
|
||||
private final TypeParameterMappings typeParameterMappings;
|
||||
|
||||
private LambdaInfo activeLambda;
|
||||
|
||||
@@ -133,35 +132,53 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void genCallInner(@NotNull Callable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
|
||||
SMAPAndMethodNode nodeAndSmap = null;
|
||||
public void genCallInner(
|
||||
@NotNull Callable callableMethod,
|
||||
@Nullable ResolvedCall<?> resolvedCall,
|
||||
boolean callDefault,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
if (!state.getInlineCycleReporter().enterIntoInlining(resolvedCall)) {
|
||||
generateStub(resolvedCall, codegen);
|
||||
return;
|
||||
}
|
||||
|
||||
SMAPAndMethodNode nodeAndSmap = null;
|
||||
try {
|
||||
nodeAndSmap = createMethodNode(callDefault);
|
||||
nodeAndSmap = createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault);
|
||||
endCall(inlineCall(nodeAndSmap));
|
||||
}
|
||||
catch (CompilationException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (InlineException e) {
|
||||
throw throwCompilationException(nodeAndSmap, e, false);
|
||||
}
|
||||
catch (Exception e) {
|
||||
boolean generateNodeText = !(e instanceof InlineException);
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(this.codegen.getContext().getContextDescriptor());
|
||||
throw new CompilationException("Couldn't inline method call '" +
|
||||
functionDescriptor.getName() +
|
||||
"' into \n" + (element != null ? element.getText() : "null psi element " + this.codegen.getContext().getContextDescriptor()) +
|
||||
(generateNodeText ? ("\ncause: " + InlineCodegenUtil.getNodeText(nodeAndSmap != null ? nodeAndSmap.getNode(): null)) : ""),
|
||||
e, callElement);
|
||||
throw throwCompilationException(nodeAndSmap, e, true);
|
||||
}
|
||||
finally {
|
||||
state.getInlineCycleReporter().exitFromInliningOf(resolvedCall);
|
||||
}
|
||||
}
|
||||
|
||||
protected void generateStub(@Nullable ResolvedCall<?> resolvedCall, @NotNull ExpressionCodegen codegen) {
|
||||
@NotNull
|
||||
private CompilationException throwCompilationException(
|
||||
@Nullable SMAPAndMethodNode nodeAndSmap, @NotNull Exception e, boolean generateNodeText
|
||||
) {
|
||||
CallableMemberDescriptor contextDescriptor = codegen.getContext().getContextDescriptor();
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor);
|
||||
MethodNode node = nodeAndSmap != null ? nodeAndSmap.getNode() : null;
|
||||
throw new CompilationException(
|
||||
"Couldn't inline method call '" + functionDescriptor.getName() + "' into\n" +
|
||||
contextDescriptor + "\n" +
|
||||
(element != null ? element.getText() : "<no source>") +
|
||||
(generateNodeText ? ("\nCause: " + InlineCodegenUtil.getNodeText(node)) : ""),
|
||||
e, callElement
|
||||
);
|
||||
}
|
||||
|
||||
private void generateStub(@Nullable ResolvedCall<?> resolvedCall, @NotNull ExpressionCodegen codegen) {
|
||||
leaveTemps();
|
||||
assert resolvedCall != null;
|
||||
String message = "Call is part of inline cycle: " + resolvedCall.getCall().getCallElement().getText();
|
||||
@@ -178,56 +195,62 @@ public class InlineCodegen extends CallGenerator {
|
||||
codegen.markLineNumberAfterInlineIfNeeded();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SMAPAndMethodNode createMethodNode(boolean callDefault) throws IOException {
|
||||
return createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, state);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static SMAPAndMethodNode createMethodNode(
|
||||
@NotNull final FunctionDescriptor functionDescriptor,
|
||||
@NotNull JvmMethodSignature jvmSignature,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull CodegenContext context,
|
||||
boolean callDefault,
|
||||
@NotNull final GenerationState state
|
||||
boolean callDefault
|
||||
) {
|
||||
|
||||
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||
final Method asmMethod = callDefault
|
||||
? typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind())
|
||||
: jvmSignature.getAsmMethod();
|
||||
final GenerationState state = codegen.getState();
|
||||
final Method asmMethod =
|
||||
callDefault
|
||||
? state.getTypeMapper().mapDefaultMethod(functionDescriptor, context.getContextKind())
|
||||
: jvmSignature.getAsmMethod();
|
||||
|
||||
MethodId methodId = new MethodId(DescriptorUtils.getFqNameSafe(functionDescriptor.getContainingDeclaration()), asmMethod);
|
||||
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !(functionDescriptor instanceof DeserializedSimpleFunctionDescriptor)) {
|
||||
return doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, codegen, context, callDefault, state, asmMethod);
|
||||
final FunctionDescriptor directMember = getCallableFromObject(functionDescriptor);
|
||||
if (!isBuiltInArrayIntrinsic(directMember) && !(directMember instanceof DeserializedSimpleFunctionDescriptor)) {
|
||||
return doCreateMethodNodeFromSource(directMember, jvmSignature, codegen, context, callDefault, state, asmMethod);
|
||||
}
|
||||
|
||||
SMAPAndMethodNode resultInCache =
|
||||
InlineCacheKt
|
||||
.getOrPut(state.getInlineCache().getMethodNodeById(), methodId, new Function0<SMAPAndMethodNode>() {
|
||||
@Override
|
||||
public SMAPAndMethodNode invoke() {
|
||||
return doCreateMethodNodeFromCompiled(functionDescriptor,
|
||||
state, asmMethod);
|
||||
}
|
||||
});
|
||||
SMAPAndMethodNode resultInCache = InlineCacheKt.getOrPut(
|
||||
state.getInlineCache().getMethodNodeById(), methodId, new Function0<SMAPAndMethodNode>() {
|
||||
@Override
|
||||
public SMAPAndMethodNode invoke() {
|
||||
SMAPAndMethodNode result = doCreateMethodNodeFromCompiled(directMember, state, asmMethod);
|
||||
if (result == null) {
|
||||
throw new IllegalStateException("Couldn't obtain compiled function body for " + functionDescriptor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return resultInCache.copyWithNewNode(cloneMethodNode(resultInCache.getNode()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static FunctionDescriptor getCallableFromObject(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
if (functionDescriptor instanceof FunctionImportedFromObject) {
|
||||
return ((FunctionImportedFromObject) functionDescriptor).getCallableFromObject();
|
||||
}
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MethodNode cloneMethodNode(@NotNull MethodNode methodNode) {
|
||||
methodNode.instructions.resetLabels();
|
||||
MethodNode result = new MethodNode(
|
||||
API, methodNode.access, methodNode.name, methodNode.desc, methodNode.signature,
|
||||
methodNode.exceptions.toArray(ArrayUtil.EMPTY_STRING_ARRAY));
|
||||
ArrayUtil.toStringArray(methodNode.exceptions)
|
||||
);
|
||||
methodNode.accept(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
private static SMAPAndMethodNode doCreateMethodNodeFromCompiled(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull final GenerationState state,
|
||||
@@ -235,7 +258,6 @@ public class InlineCodegen extends CallGenerator {
|
||||
) {
|
||||
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||
|
||||
SMAPAndMethodNode nodeAndSMAP;
|
||||
if (isBuiltInArrayIntrinsic(functionDescriptor)) {
|
||||
ClassId classId = IntrinsicArrayConstructorsKt.getClassId();
|
||||
byte[] bytes = InlineCacheKt.getOrPut(state.getInlineCache().getClassBytes(), classId, new Function0<byte[]>() {
|
||||
@@ -245,24 +267,13 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
});
|
||||
|
||||
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
|
||||
bytes,
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
classId
|
||||
);
|
||||
|
||||
if (nodeAndSMAP == null) {
|
||||
throw new IllegalStateException("Couldn't obtain array constructor body for " + descriptorName(functionDescriptor));
|
||||
}
|
||||
|
||||
return nodeAndSMAP;
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId);
|
||||
}
|
||||
|
||||
assert functionDescriptor instanceof DeserializedSimpleFunctionDescriptor;
|
||||
assert functionDescriptor instanceof DeserializedSimpleFunctionDescriptor : "Not a deserialized function: " + functionDescriptor;
|
||||
|
||||
KotlinTypeMapper.ContainingClassesInfo containingClasses = typeMapper.getContainingClassesForDeserializedCallable(
|
||||
(DeserializedSimpleFunctionDescriptor) functionDescriptor);
|
||||
KotlinTypeMapper.ContainingClassesInfo containingClasses =
|
||||
typeMapper.getContainingClassesForDeserializedCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor);
|
||||
|
||||
final ClassId containerId = containingClasses.getImplClassId();
|
||||
|
||||
@@ -282,15 +293,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
});
|
||||
|
||||
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
|
||||
bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId
|
||||
);
|
||||
|
||||
if (nodeAndSMAP == null) {
|
||||
throw new IllegalStateException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
|
||||
}
|
||||
|
||||
return nodeAndSMAP;
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -306,27 +309,31 @@ public class InlineCodegen extends CallGenerator {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
|
||||
|
||||
if (!(element instanceof KtNamedFunction)) {
|
||||
throw new IllegalStateException("Couldn't find declaration for function " + descriptorName(functionDescriptor));
|
||||
throw new IllegalStateException("Couldn't find declaration for function " + functionDescriptor);
|
||||
}
|
||||
KtNamedFunction inliningFunction = (KtNamedFunction) element;
|
||||
|
||||
MethodNode node = new MethodNode(InlineCodegenUtil.API,
|
||||
getMethodAsmFlags(functionDescriptor, context.getContextKind()) | (callDefault ? Opcodes.ACC_STATIC : 0),
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
null,
|
||||
null);
|
||||
MethodNode node = new MethodNode(
|
||||
InlineCodegenUtil.API,
|
||||
getMethodAsmFlags(functionDescriptor, context.getContextKind()) | (callDefault ? Opcodes.ACC_STATIC : 0),
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
null, null
|
||||
);
|
||||
|
||||
//for maxLocals calculation
|
||||
MethodVisitor maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node);
|
||||
MethodContext methodContext = context.getParentContext().intoFunction(functionDescriptor);
|
||||
CodegenContext parentContext = context.getParentContext();
|
||||
assert parentContext != null : "Context has no parent: " + context;
|
||||
MethodContext methodContext = parentContext.intoFunction(functionDescriptor);
|
||||
|
||||
SMAP smap;
|
||||
if (callDefault) {
|
||||
Type implementationOwner = state.getTypeMapper().mapImplementationOwner(functionDescriptor);
|
||||
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(codegen.getParentCodegen(), inliningFunction,
|
||||
(FieldOwnerContext) methodContext.getParentContext(),
|
||||
implementationOwner.getInternalName());
|
||||
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(
|
||||
codegen.getParentCodegen(), inliningFunction, (FieldOwnerContext) methodContext.getParentContext(),
|
||||
implementationOwner.getInternalName()
|
||||
);
|
||||
FunctionCodegen.generateDefaultImplBody(
|
||||
methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
inliningFunction, parentCodegen, asmMethod
|
||||
@@ -334,7 +341,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.getOrCreateSourceMapper().getResultMappings());
|
||||
}
|
||||
else {
|
||||
smap = generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction, jvmSignature, false, codegen, state);
|
||||
smap = generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction, jvmSignature, false, codegen);
|
||||
}
|
||||
maxCalcAdapter.visitMaxs(-1, -1);
|
||||
maxCalcAdapter.visitEnd();
|
||||
@@ -349,7 +356,8 @@ public class InlineCodegen extends CallGenerator {
|
||||
functionDescriptor.getContainingDeclaration() instanceof BuiltInsPackageFragment;
|
||||
}
|
||||
|
||||
private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
|
||||
@NotNull
|
||||
private InlineResult inlineCall(@NotNull SMAPAndMethodNode nodeAndSmap) {
|
||||
DefaultSourceMapper defaultSourceMapper = codegen.getParentCodegen().getOrCreateSourceMapper();
|
||||
defaultSourceMapper.setCallSiteMarker(new CallSiteMarker(codegen.getLastLineNumber()));
|
||||
MethodNode node = nodeAndSmap.getNode();
|
||||
@@ -365,7 +373,8 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
InliningContext info = new RootInliningContext(
|
||||
expressionMap, state, codegen.getInlineNameGenerator().subGenerator(jvmSignature.getAsmMethod().getName()),
|
||||
codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings);
|
||||
callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings
|
||||
);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(
|
||||
node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
|
||||
@@ -376,7 +385,6 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);
|
||||
|
||||
|
||||
MethodNode adapter = InlineCodegenUtil.createEmptyMethodNode();
|
||||
//hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
|
||||
adapter.visitInsn(Opcodes.NOP);
|
||||
@@ -394,7 +402,9 @@ public class InlineCodegen extends CallGenerator {
|
||||
};
|
||||
|
||||
List<MethodInliner.PointForExternalFinallyBlocks> infos = MethodInliner.processReturns(adapter, labelOwner, true, null);
|
||||
generateAndInsertFinallyBlocks(adapter, infos, ((StackValue.Local)remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index);
|
||||
generateAndInsertFinallyBlocks(
|
||||
adapter, infos, ((StackValue.Local) remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index
|
||||
);
|
||||
removeStaticInitializationTrigger(adapter);
|
||||
removeFinallyMarkers(adapter);
|
||||
|
||||
@@ -407,7 +417,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void removeStaticInitializationTrigger(MethodNode methodNode) {
|
||||
private static void removeStaticInitializationTrigger(@NotNull MethodNode methodNode) {
|
||||
InsnList insnList = methodNode.instructions;
|
||||
AbstractInsnNode insn = insnList.getFirst();
|
||||
while (insn != null) {
|
||||
@@ -422,6 +432,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private InlineCallSiteInfo getInlineCallSiteInfo() {
|
||||
MethodContext context = codegen.getContext();
|
||||
MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
|
||||
@@ -435,7 +446,9 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
JvmMethodSignature signature = typeMapper.mapSignatureSkipGeneric(context.getFunctionDescriptor(), context.getContextKind());
|
||||
return new InlineCallSiteInfo(parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor());
|
||||
return new InlineCallSiteInfo(
|
||||
parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor()
|
||||
);
|
||||
}
|
||||
|
||||
private void generateClosuresBodies() {
|
||||
@@ -444,25 +457,29 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private SMAPAndMethodNode generateLambdaBody(LambdaInfo info) {
|
||||
@NotNull
|
||||
private SMAPAndMethodNode generateLambdaBody(@NotNull LambdaInfo info) {
|
||||
KtExpression declaration = info.getFunctionWithBodyOrCallableReference();
|
||||
FunctionDescriptor descriptor = info.getFunctionDescriptor();
|
||||
|
||||
MethodContext parentContext = codegen.getContext();
|
||||
|
||||
MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor, info.isCrossInline);
|
||||
MethodContext context =
|
||||
codegen.getContext().intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor, info.isCrossInline);
|
||||
|
||||
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(descriptor);
|
||||
Method asmMethod = jvmMethodSignature.getAsmMethod();
|
||||
MethodNode methodNode = new MethodNode(InlineCodegenUtil.API, getMethodAsmFlags(descriptor, context.getContextKind()), asmMethod.getName(), asmMethod.getDescriptor(), null, null);
|
||||
MethodNode methodNode = new MethodNode(
|
||||
InlineCodegenUtil.API, getMethodAsmFlags(descriptor, context.getContextKind()),
|
||||
asmMethod.getName(), asmMethod.getDescriptor(), null, null
|
||||
);
|
||||
|
||||
MethodVisitor adapter = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
|
||||
|
||||
SMAP smap = generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature, true, codegen, state);
|
||||
SMAP smap = generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature, true, codegen);
|
||||
adapter.visitMaxs(-1, -1);
|
||||
return new SMAPAndMethodNode(methodNode, smap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SMAP generateMethodBody(
|
||||
@NotNull MethodVisitor adapter,
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@@ -470,32 +487,29 @@ public class InlineCodegen extends CallGenerator {
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull JvmMethodSignature jvmMethodSignature,
|
||||
boolean isLambda,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull GenerationState state
|
||||
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
FakeMemberCodegen parentCodegen =
|
||||
new FakeMemberCodegen(codegen.getParentCodegen(), expression,
|
||||
(FieldOwnerContext) context.getParentContext(),
|
||||
isLambda ? codegen.getParentCodegen().getClassName()
|
||||
: state.getTypeMapper().mapImplementationOwner(descriptor).getInternalName());
|
||||
GenerationState state = codegen.getState();
|
||||
|
||||
// Wrapping for preventing marking actual parent codegen as containing reified markers
|
||||
FakeMemberCodegen parentCodegen = new FakeMemberCodegen(
|
||||
codegen.getParentCodegen(), expression, (FieldOwnerContext) context.getParentContext(),
|
||||
isLambda ? codegen.getParentCodegen().getClassName()
|
||||
: state.getTypeMapper().mapImplementationOwner(descriptor).getInternalName()
|
||||
);
|
||||
|
||||
FunctionGenerationStrategy strategy =
|
||||
expression instanceof KtCallableReferenceExpression ?
|
||||
new FunctionReferenceGenerationStrategy(
|
||||
state,
|
||||
descriptor,
|
||||
CallUtilKt.getResolvedCallWithAssert(((KtCallableReferenceExpression) expression).getCallableReference(),
|
||||
codegen.getBindingContext()
|
||||
)) :
|
||||
CallUtilKt.getResolvedCallWithAssert(
|
||||
((KtCallableReferenceExpression) expression).getCallableReference(), codegen.getBindingContext()
|
||||
)
|
||||
) :
|
||||
new FunctionGenerationStrategy.FunctionDefault(state, descriptor, (KtDeclarationWithBody) expression);
|
||||
|
||||
FunctionCodegen.generateMethodBody(
|
||||
adapter, descriptor, context, jvmMethodSignature,
|
||||
strategy,
|
||||
// Wrapping for preventing marking actual parent codegen as containing reifier markers
|
||||
parentCodegen
|
||||
);
|
||||
FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen);
|
||||
|
||||
if (isLambda) {
|
||||
codegen.propagateChildReifiedTypeParametersUsages(parentCodegen.getReifiedTypeParametersUsages());
|
||||
@@ -516,13 +530,18 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
private static class FakeMemberCodegen extends MemberCodegen {
|
||||
private final MemberCodegen delegate;
|
||||
private final String className;
|
||||
|
||||
@NotNull final MemberCodegen delegate;
|
||||
@NotNull private final String className;
|
||||
|
||||
public FakeMemberCodegen(@NotNull MemberCodegen wrapped, @NotNull KtElement declaration, @NotNull FieldOwnerContext codegenContext, @NotNull String className) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public FakeMemberCodegen(
|
||||
@NotNull MemberCodegen wrapped,
|
||||
@NotNull KtElement declaration,
|
||||
@NotNull FieldOwnerContext codegenContext,
|
||||
@NotNull String className
|
||||
) {
|
||||
super(wrapped, declaration, codegenContext);
|
||||
delegate = wrapped;
|
||||
this.delegate = wrapped;
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
@@ -556,11 +575,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterParameterPut(
|
||||
@NotNull Type type,
|
||||
@Nullable StackValue stackValue,
|
||||
int parameterIndex
|
||||
) {
|
||||
public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, int parameterIndex) {
|
||||
putArgumentOrCapturedToLocalVal(type, stackValue, -1, parameterIndex);
|
||||
}
|
||||
|
||||
@@ -578,7 +593,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
ParameterInfo info;
|
||||
if (capturedParamIndex >= 0) {
|
||||
CapturedParamDesc capturedParamInfoInLambda = activeLambda.getCapturedVars().get(capturedParamIndex);
|
||||
info = invocationParamBuilder.addCapturedParam(capturedParamInfoInLambda, capturedParamInfoInLambda.getFieldName());
|
||||
info = invocationParamBuilder.addCapturedParam(capturedParamInfoInLambda, capturedParamInfoInLambda.getFieldName(), false);
|
||||
info.setRemapValue(remappedIndex);
|
||||
}
|
||||
else {
|
||||
@@ -590,11 +605,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
/*descriptor is null for captured vars*/
|
||||
public static boolean shouldPutValue(
|
||||
@NotNull Type type,
|
||||
@Nullable StackValue stackValue
|
||||
) {
|
||||
|
||||
private static boolean shouldPutValue(@NotNull Type type, @Nullable StackValue stackValue) {
|
||||
if (stackValue == null) {
|
||||
//default or vararg
|
||||
return true;
|
||||
@@ -628,7 +639,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void recordParameterValueInLocalVal(ParameterInfo... infos) {
|
||||
private void recordParameterValueInLocalVal(@NotNull ParameterInfo... infos) {
|
||||
int[] index = new int[infos.length];
|
||||
for (int i = 0; i < infos.length; i++) {
|
||||
ParameterInfo info = infos[i];
|
||||
@@ -652,34 +663,33 @@ public class InlineCodegen extends CallGenerator {
|
||||
@Override
|
||||
public void putHiddenParams() {
|
||||
if ((getMethodAsmFlags(functionDescriptor, context.getContextKind()) & Opcodes.ACC_STATIC) == 0) {
|
||||
invocationParamBuilder.addNextParameter(AsmTypes.OBJECT_TYPE, false, null);
|
||||
invocationParamBuilder.addNextParameter(AsmTypes.OBJECT_TYPE, false);
|
||||
}
|
||||
|
||||
for (JvmMethodParameterSignature param : jvmSignature.getValueParameters()) {
|
||||
if (param.getKind() == JvmMethodParameterKind.VALUE) {
|
||||
break;
|
||||
}
|
||||
invocationParamBuilder.addNextParameter(param.getAsmType(), false, null);
|
||||
invocationParamBuilder.addNextParameter(param.getAsmType(), false);
|
||||
}
|
||||
|
||||
invocationParamBuilder.markValueParametesStart();
|
||||
invocationParamBuilder.markValueParametersStart();
|
||||
List<ParameterInfo> hiddenParameters = invocationParamBuilder.buildParameters().getReal();
|
||||
recordParameterValueInLocalVal(hiddenParameters.toArray(new ParameterInfo[hiddenParameters.size()]));
|
||||
}
|
||||
|
||||
public void leaveTemps() {
|
||||
FrameMap frameMap = codegen.getFrameMap();
|
||||
private void leaveTemps() {
|
||||
List<ParameterInfo> infos = invocationParamBuilder.listAllParams();
|
||||
for (ListIterator<? extends ParameterInfo> iterator = infos.listIterator(infos.size()); iterator.hasPrevious(); ) {
|
||||
ParameterInfo param = iterator.previous();
|
||||
if (!param.isSkippedOrRemapped()) {
|
||||
frameMap.leaveTemp(param.type);
|
||||
codegen.getFrameMap().leaveTemp(param.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*lambda or callable reference*/
|
||||
public boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
|
||||
private boolean isInliningParameter(@NotNull KtExpression expression, @NotNull ValueParameterDescriptor valueParameterDescriptor) {
|
||||
//TODO deparenthisise typed
|
||||
KtExpression deparenthesized = KtPsiUtil.deparenthesize(expression);
|
||||
|
||||
@@ -693,17 +703,16 @@ public class InlineCodegen extends CallGenerator {
|
||||
isInlinableParameterExpression(deparenthesized);
|
||||
}
|
||||
|
||||
protected static boolean isInlinableParameterExpression(KtExpression deparenthesized) {
|
||||
private static boolean isInlinableParameterExpression(@Nullable KtExpression deparenthesized) {
|
||||
return deparenthesized instanceof KtLambdaExpression ||
|
||||
deparenthesized instanceof KtNamedFunction ||
|
||||
deparenthesized instanceof KtCallableReferenceExpression;
|
||||
}
|
||||
|
||||
public void rememberClosure(KtExpression expression, Type type, ValueParameterDescriptor parameter) {
|
||||
private void rememberClosure(@NotNull KtExpression expression, @NotNull Type type, @NotNull ValueParameterDescriptor parameter) {
|
||||
KtExpression lambda = KtPsiUtil.deparenthesize(expression);
|
||||
assert isInlinableParameterExpression(lambda) : "Couldn't find inline expression in " + expression.getText();
|
||||
|
||||
|
||||
LambdaInfo info = new LambdaInfo(lambda, typeMapper, parameter.isCrossinline());
|
||||
|
||||
ParameterInfo closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.getIndex());
|
||||
@@ -712,7 +721,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static Set<String> getDeclarationLabels(@Nullable PsiElement lambdaOrFun, @NotNull DeclarationDescriptor descriptor) {
|
||||
public static Set<String> getDeclarationLabels(@Nullable PsiElement lambdaOrFun, @NotNull DeclarationDescriptor descriptor) {
|
||||
Set<String> result = new HashSet<String>();
|
||||
|
||||
if (lambdaOrFun != null) {
|
||||
@@ -739,18 +748,25 @@ public class InlineCodegen extends CallGenerator {
|
||||
activeLambda = null;
|
||||
}
|
||||
|
||||
public static CodegenContext getContext(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state, @Nullable KtFile sourceFile) {
|
||||
@NotNull
|
||||
public static CodegenContext getContext(
|
||||
@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state, @Nullable KtFile sourceFile
|
||||
) {
|
||||
if (descriptor instanceof PackageFragmentDescriptor) {
|
||||
return new PackageContext((PackageFragmentDescriptor) descriptor, state.getRootContext(), null, sourceFile);
|
||||
}
|
||||
|
||||
CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state, sourceFile);
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
assert container != null : "No container for descriptor: " + descriptor;
|
||||
CodegenContext parent = getContext(container, state, sourceFile);
|
||||
|
||||
if (descriptor instanceof ScriptDescriptor) {
|
||||
List<ScriptDescriptor> earlierScripts = state.getReplSpecific().getEarlierScriptsForReplInterpreter();
|
||||
return parent.intoScript((ScriptDescriptor) descriptor,
|
||||
earlierScripts == null ? Collections.emptyList() : earlierScripts,
|
||||
(ClassDescriptor) descriptor, state.getTypeMapper());
|
||||
return parent.intoScript(
|
||||
(ScriptDescriptor) descriptor,
|
||||
earlierScripts == null ? Collections.emptyList() : earlierScripts,
|
||||
(ClassDescriptor) descriptor, state.getTypeMapper()
|
||||
);
|
||||
}
|
||||
else if (descriptor instanceof ClassDescriptor) {
|
||||
OwnerKind kind = DescriptorUtils.isInterface(descriptor) ? OwnerKind.DEFAULT_IMPLS : OwnerKind.IMPLEMENTATION;
|
||||
@@ -760,11 +776,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
return parent.intoFunction((FunctionDescriptor) descriptor);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Couldn't build context for " + descriptorName(descriptor));
|
||||
}
|
||||
|
||||
private static String descriptorName(DeclarationDescriptor descriptor) {
|
||||
return DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor);
|
||||
throw new IllegalStateException("Couldn't build context for " + descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -784,18 +796,11 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putValueIfNeeded(
|
||||
@NotNull Type parameterType,
|
||||
@NotNull StackValue value
|
||||
) {
|
||||
public void putValueIfNeeded(@NotNull Type parameterType, @NotNull StackValue value) {
|
||||
putValueIfNeeded(parameterType, value, -1);
|
||||
}
|
||||
|
||||
private void putValueIfNeeded(
|
||||
@NotNull Type parameterType,
|
||||
@NotNull StackValue value,
|
||||
int index
|
||||
) {
|
||||
private void putValueIfNeeded(@NotNull Type parameterType, @NotNull StackValue value, int index) {
|
||||
if (shouldPutValue(parameterType, value)) {
|
||||
value.put(parameterType, codegen.v);
|
||||
}
|
||||
@@ -803,17 +808,14 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putCapturedValueOnStack(
|
||||
@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex
|
||||
) {
|
||||
public void putCapturedValueOnStack(@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex) {
|
||||
if (shouldPutValue(stackValue.type, stackValue)) {
|
||||
stackValue.put(stackValue.type, codegen.v);
|
||||
}
|
||||
putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex, paramIndex);
|
||||
}
|
||||
|
||||
|
||||
public void generateAndInsertFinallyBlocks(
|
||||
private void generateAndInsertFinallyBlocks(
|
||||
@NotNull MethodNode intoNode,
|
||||
@NotNull List<MethodInliner.PointForExternalFinallyBlocks> insertPoints,
|
||||
int offsetForFinallyLocalVar
|
||||
@@ -881,7 +883,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
//processor.substituteLocalVarTable(intoNode);
|
||||
}
|
||||
|
||||
public void removeFinallyMarkers(@NotNull MethodNode intoNode) {
|
||||
private void removeFinallyMarkers(@NotNull MethodNode intoNode) {
|
||||
if (InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) return;
|
||||
|
||||
InsnList instructions = intoNode.instructions;
|
||||
@@ -900,6 +902,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SourceMapper createNestedSourceMapper(@NotNull SMAPAndMethodNode nodeAndSmap, @NotNull SourceMapper parent) {
|
||||
return new NestedSourceMapper(parent, nodeAndSmap.getSortedRanges(), nodeAndSmap.getClassSMAP().getSourceInfo());
|
||||
}
|
||||
@@ -918,7 +921,8 @@ public class InlineCodegen extends CallGenerator {
|
||||
IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId);
|
||||
String classFilePath = InlineCodegenUtilsKt.getClassFilePath(sourceDescriptor, state.getTypeMapper(), incrementalCache);
|
||||
String sourceFilePath = InlineCodegenUtilsKt.getSourceFilePath(targetDescriptor);
|
||||
incrementalCache.registerInline(classFilePath, jvmSignature.toString(), sourceFilePath);
|
||||
Method method = jvmSignature.getAsmMethod();
|
||||
incrementalCache.registerInline(classFilePath, method.getName() + method.getDescriptor(), sourceFilePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -65,7 +65,7 @@ class InlineCodegenForDefaultBody(
|
||||
}
|
||||
|
||||
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||
val nodeAndSmap = InlineCodegen.createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, state)
|
||||
val nodeAndSmap = InlineCodegen.createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault)
|
||||
val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper)
|
||||
|
||||
val node = nodeAndSmap.node
|
||||
@@ -111,4 +111,4 @@ class InlineCodegenForDefaultBody(
|
||||
override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List<ArgumentAndDeclIndex>, valueParameterTypes: List<Type>) {
|
||||
throw UnsupportedOperationException("Shouldn't be called")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,10 @@
|
||||
package org.jetbrains.kotlin.codegen.inline;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import kotlin.text.StringsKt;
|
||||
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.codegen.MemberCodegen;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
@@ -31,7 +29,6 @@ import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
|
||||
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt;
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
@@ -63,19 +60,19 @@ public class InlineCodegenUtil {
|
||||
public static final boolean GENERATE_SMAP = true;
|
||||
public static final int API = Opcodes.ASM5;
|
||||
|
||||
public static final String CAPTURED_FIELD_PREFIX = "$";
|
||||
public static final String NON_CAPTURED_FIELD_PREFIX = "$$";
|
||||
private static final String CAPTURED_FIELD_PREFIX = "$";
|
||||
private static final String NON_CAPTURED_FIELD_PREFIX = "$$";
|
||||
public static final String THIS$0 = "this$0";
|
||||
public static final String THIS = "this";
|
||||
public static final String RECEIVER$0 = "receiver$0";
|
||||
public static final String NON_LOCAL_RETURN = "$$$$$NON_LOCAL_RETURN$$$$$";
|
||||
private static final String RECEIVER$0 = "receiver$0";
|
||||
private static final String NON_LOCAL_RETURN = "$$$$$NON_LOCAL_RETURN$$$$$";
|
||||
public static final String FIRST_FUN_LABEL = "$$$$$ROOT$$$$$";
|
||||
public static final String NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function";
|
||||
public static final String INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker";
|
||||
public static final String INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall";
|
||||
public static final String INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall";
|
||||
public static final String INLINE_MARKER_FINALLY_START = "finallyStart";
|
||||
public static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
|
||||
private static final String INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker";
|
||||
private static final String INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall";
|
||||
private static final String INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall";
|
||||
private static final String INLINE_MARKER_FINALLY_START = "finallyStart";
|
||||
private static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
|
||||
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
|
||||
public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun";
|
||||
public static final String INLINE_FUN_VAR_SUFFIX = "$iv";
|
||||
@@ -93,6 +90,7 @@ public class InlineCodegenUtil {
|
||||
final int[] lines = new int[2];
|
||||
lines[0] = Integer.MAX_VALUE;
|
||||
lines[1] = Integer.MIN_VALUE;
|
||||
//noinspection PointlessBitwiseExpression
|
||||
cr.accept(new ClassVisitor(API) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
@@ -174,7 +172,7 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) {
|
||||
private static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) {
|
||||
FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName();
|
||||
String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName);
|
||||
//TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file
|
||||
@@ -182,6 +180,7 @@ public class InlineCodegenUtil {
|
||||
return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getInlineName(
|
||||
@NotNull CodegenContext codegenContext,
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
@@ -190,6 +189,7 @@ public class InlineCodegenUtil {
|
||||
return getInlineName(codegenContext, codegenContext.getContextDescriptor(), typeMapper, fileClassesManager);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getInlineName(
|
||||
@NotNull CodegenContext codegenContext,
|
||||
@NotNull DeclarationDescriptor currentDescriptor,
|
||||
@@ -197,21 +197,24 @@ public class InlineCodegenUtil {
|
||||
@NotNull JvmFileClassesProvider fileClassesProvider
|
||||
) {
|
||||
if (currentDescriptor instanceof PackageFragmentDescriptor) {
|
||||
PsiFile file = getContainingFile(codegenContext);
|
||||
PsiFile file = DescriptorToSourceUtils.getContainingFile(codegenContext.getContextDescriptor());
|
||||
|
||||
Type implementationOwnerType;
|
||||
if (file == null) {
|
||||
implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(codegenContext);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
implementationOwnerType = FileClasses.getFileClassType(fileClassesProvider, (KtFile) file);
|
||||
}
|
||||
|
||||
if (implementationOwnerType == null) {
|
||||
DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
|
||||
//noinspection ConstantConditions
|
||||
throw new RuntimeException("Couldn't find declaration for " +
|
||||
contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() +
|
||||
"; context: " + codegenContext);
|
||||
throw new RuntimeException(
|
||||
"Couldn't find declaration for " +
|
||||
contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() +
|
||||
"; context: " + codegenContext
|
||||
);
|
||||
}
|
||||
|
||||
return implementationOwnerType.getInternalName();
|
||||
@@ -219,12 +222,12 @@ public class InlineCodegenUtil {
|
||||
else if (currentDescriptor instanceof ClassifierDescriptor) {
|
||||
Type type = typeMapper.mapType((ClassifierDescriptor) currentDescriptor);
|
||||
return type.getInternalName();
|
||||
} else if (currentDescriptor instanceof FunctionDescriptor) {
|
||||
}
|
||||
else if (currentDescriptor instanceof FunctionDescriptor) {
|
||||
ClassDescriptor descriptor =
|
||||
typeMapper.getBindingContext().get(CodegenBinding.CLASS_FOR_CALLABLE, (FunctionDescriptor) currentDescriptor);
|
||||
if (descriptor != null) {
|
||||
Type type = typeMapper.mapType(descriptor);
|
||||
return type.getInternalName();
|
||||
return typeMapper.mapType(descriptor).getInternalName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,14 +249,15 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
|
||||
public static boolean isWhenMappingAccess(@NotNull String internalName, @NotNull String fieldName) {
|
||||
return fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) && internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX);
|
||||
return fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) &&
|
||||
internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX);
|
||||
}
|
||||
|
||||
public static boolean isAnonymousSingletonLoad(@NotNull String internalName, @NotNull String fieldName) {
|
||||
return JvmAbi.INSTANCE_FIELD.equals(fieldName) && isAnonymousClass(internalName);
|
||||
}
|
||||
|
||||
public static boolean isAnonymousClass(String internalName) {
|
||||
public static boolean isAnonymousClass(@NotNull String internalName) {
|
||||
String shortName = getLastNamePart(internalName);
|
||||
int index = shortName.lastIndexOf("$");
|
||||
|
||||
@@ -271,16 +275,6 @@ public class InlineCodegenUtil {
|
||||
return index < 0 ? internalName : internalName.substring(index + 1);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiFile getContainingFile(CodegenContext codegenContext) {
|
||||
DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
|
||||
PsiElement psiElement = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor);
|
||||
if (psiElement != null) {
|
||||
return psiElement.getContainingFile();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static MethodVisitor wrapWithMaxLocalCalc(@NotNull MethodNode methodNode) {
|
||||
return new MaxStackFrameSizeAndLocalsCalculator(API, methodNode.access, methodNode.desc, methodNode);
|
||||
@@ -317,7 +311,8 @@ public class InlineCodegenUtil {
|
||||
return getMarkedReturnLabelOrNull(returnIns) != null;
|
||||
}
|
||||
|
||||
public static @Nullable String getMarkedReturnLabelOrNull(@NotNull AbstractInsnNode returnInsn) {
|
||||
@Nullable
|
||||
public static String getMarkedReturnLabelOrNull(@NotNull AbstractInsnNode returnInsn) {
|
||||
if (!isReturnOpcode(returnInsn.getOpcode())) {
|
||||
return null;
|
||||
}
|
||||
@@ -335,30 +330,33 @@ public class InlineCodegenUtil {
|
||||
iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type getReturnType(int opcode) {
|
||||
switch (opcode) {
|
||||
case Opcodes.RETURN: return Type.VOID_TYPE;
|
||||
case Opcodes.IRETURN: return Type.INT_TYPE;
|
||||
case Opcodes.DRETURN: return Type.DOUBLE_TYPE;
|
||||
case Opcodes.FRETURN: return Type.FLOAT_TYPE;
|
||||
case Opcodes.LRETURN: return Type.LONG_TYPE;
|
||||
default: return AsmTypes.OBJECT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull InsnList instructions, @NotNull AbstractInsnNode beforeNode) {
|
||||
ListIterator<AbstractInsnNode> iterator = from.instructions.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
AbstractInsnNode next = iterator.next();
|
||||
instructions.insertBefore(beforeNode, next);
|
||||
case Opcodes.RETURN:
|
||||
return Type.VOID_TYPE;
|
||||
case Opcodes.IRETURN:
|
||||
return Type.INT_TYPE;
|
||||
case Opcodes.DRETURN:
|
||||
return Type.DOUBLE_TYPE;
|
||||
case Opcodes.FRETURN:
|
||||
return Type.FLOAT_TYPE;
|
||||
case Opcodes.LRETURN:
|
||||
return Type.LONG_TYPE;
|
||||
default:
|
||||
return AsmTypes.OBJECT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) {
|
||||
insertNodeBefore(from, to.instructions, beforeNode);
|
||||
ListIterator<AbstractInsnNode> iterator = from.instructions.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
AbstractInsnNode next = iterator.next();
|
||||
to.instructions.insertBefore(beforeNode, next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static MethodNode createEmptyMethodNode() {
|
||||
return new MethodNode(API, 0, "fake", "()V", null, null);
|
||||
}
|
||||
@@ -374,11 +372,7 @@ public class InlineCodegenUtil {
|
||||
|
||||
@NotNull
|
||||
public static String getNodeText(@Nullable MethodNode node) {
|
||||
return getNodeText(node, new Textifier());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getNodeText(@Nullable MethodNode node, @NotNull Textifier textifier) {
|
||||
Textifier textifier = new Textifier();
|
||||
if (node == null) {
|
||||
return "Not generated";
|
||||
}
|
||||
@@ -386,7 +380,7 @@ public class InlineCodegenUtil {
|
||||
StringWriter sw = new StringWriter();
|
||||
textifier.print(new PrintWriter(sw));
|
||||
sw.flush();
|
||||
return node.name + " " + node.desc + ": \n " + sw.getBuffer().toString();
|
||||
return node.name + " " + node.desc + ":\n" + sw.getBuffer().toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -397,13 +391,11 @@ public class InlineCodegenUtil {
|
||||
if (outputFile != null) {
|
||||
return new ClassReader(outputFile.asByteArray());
|
||||
}
|
||||
else {
|
||||
VirtualFile file = findVirtualFileImprecise(state, internalName);
|
||||
if (file == null) {
|
||||
throw new RuntimeException("Couldn't find virtual file for " + internalName);
|
||||
}
|
||||
VirtualFile file = findVirtualFileImprecise(state, internalName);
|
||||
if (file != null) {
|
||||
return new ClassReader(file.contentsToByteArray());
|
||||
}
|
||||
throw new RuntimeException("Couldn't find virtual file for " + internalName);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -424,10 +416,10 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
|
||||
public static boolean isFinallyMarker(@Nullable AbstractInsnNode node) {
|
||||
return isFinallyMarker(node, INLINE_MARKER_FINALLY_END) || isFinallyMarker(node, INLINE_MARKER_FINALLY_START);
|
||||
return node != null && (isFinallyStart(node) || isFinallyEnd(node));
|
||||
}
|
||||
|
||||
public static boolean isFinallyMarker(@Nullable AbstractInsnNode node, String name) {
|
||||
private static boolean isFinallyMarker(@NotNull AbstractInsnNode node, String name) {
|
||||
if (!(node instanceof MethodInsnNode)) return false;
|
||||
MethodInsnNode method = (MethodInsnNode) node;
|
||||
return INLINE_MARKER_CLASS_NAME.equals(method.owner) && name.equals(method.name);
|
||||
@@ -437,69 +429,51 @@ public class InlineCodegenUtil {
|
||||
return context.isInlineMethodContext() || context instanceof InlineLambdaContext;
|
||||
}
|
||||
|
||||
public static int getConstant(AbstractInsnNode ins) {
|
||||
public static int getConstant(@NotNull AbstractInsnNode ins) {
|
||||
int opcode = ins.getOpcode();
|
||||
Integer value;
|
||||
if (opcode >= Opcodes.ICONST_0 && opcode <= Opcodes.ICONST_5) {
|
||||
value = opcode - Opcodes.ICONST_0;
|
||||
return opcode - Opcodes.ICONST_0;
|
||||
}
|
||||
else if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) {
|
||||
IntInsnNode index = (IntInsnNode) ins;
|
||||
value = index.operand;
|
||||
return ((IntInsnNode) ins).operand;
|
||||
}
|
||||
else {
|
||||
LdcInsnNode index = (LdcInsnNode) ins;
|
||||
value = (Integer) index.cst;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static class LabelTextifier extends Textifier {
|
||||
|
||||
public LabelTextifier() {
|
||||
super(API);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@TestOnly
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public String getLabelNameIfExists(@NotNull Label l) {
|
||||
return labelNames == null ? null : labelNames.get(l);
|
||||
return (Integer) index.cst;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addInlineMarker(
|
||||
@NotNull InstructionAdapter v,
|
||||
boolean isStartNotEnd
|
||||
) {
|
||||
v.visitMethodInsn(Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME,
|
||||
(isStartNotEnd ? INLINE_MARKER_BEFORE_METHOD_NAME : INLINE_MARKER_AFTER_METHOD_NAME),
|
||||
"()V", false);
|
||||
public static void addInlineMarker(@NotNull InstructionAdapter v, boolean isStartNotEnd) {
|
||||
v.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME,
|
||||
isStartNotEnd ? INLINE_MARKER_BEFORE_METHOD_NAME : INLINE_MARKER_AFTER_METHOD_NAME,
|
||||
"()V", false
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean isInlineMarker(AbstractInsnNode insn) {
|
||||
public static boolean isInlineMarker(@NotNull AbstractInsnNode insn) {
|
||||
return isInlineMarker(insn, null);
|
||||
}
|
||||
|
||||
public static boolean isInlineMarker(AbstractInsnNode insn, String name) {
|
||||
if (insn instanceof MethodInsnNode) {
|
||||
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
|
||||
return insn.getOpcode() == Opcodes.INVOKESTATIC &&
|
||||
methodInsnNode.owner.equals(INLINE_MARKER_CLASS_NAME) &&
|
||||
(name != null ? methodInsnNode.name.equals(name)
|
||||
: methodInsnNode.name.equals(INLINE_MARKER_BEFORE_METHOD_NAME) ||
|
||||
methodInsnNode.name.equals(INLINE_MARKER_AFTER_METHOD_NAME));
|
||||
}
|
||||
else {
|
||||
private static boolean isInlineMarker(@NotNull AbstractInsnNode insn, @Nullable String name) {
|
||||
if (!(insn instanceof MethodInsnNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
|
||||
return insn.getOpcode() == Opcodes.INVOKESTATIC &&
|
||||
methodInsnNode.owner.equals(INLINE_MARKER_CLASS_NAME) &&
|
||||
(name != null ? methodInsnNode.name.equals(name)
|
||||
: methodInsnNode.name.equals(INLINE_MARKER_BEFORE_METHOD_NAME) ||
|
||||
methodInsnNode.name.equals(INLINE_MARKER_AFTER_METHOD_NAME));
|
||||
}
|
||||
|
||||
public static boolean isBeforeInlineMarker(AbstractInsnNode insn) {
|
||||
public static boolean isBeforeInlineMarker(@NotNull AbstractInsnNode insn) {
|
||||
return isInlineMarker(insn, INLINE_MARKER_BEFORE_METHOD_NAME);
|
||||
}
|
||||
|
||||
public static boolean isAfterInlineMarker(AbstractInsnNode insn) {
|
||||
public static boolean isAfterInlineMarker(@NotNull AbstractInsnNode insn) {
|
||||
return isInlineMarker(insn, INLINE_MARKER_AFTER_METHOD_NAME);
|
||||
}
|
||||
|
||||
@@ -511,44 +485,27 @@ public class InlineCodegenUtil {
|
||||
return opcode >= Opcodes.ISTORE && opcode <= Opcodes.ASTORE;
|
||||
}
|
||||
|
||||
public static int calcMarkerShift(Parameters parameters, MethodNode node) {
|
||||
public static int calcMarkerShift(@NotNull Parameters parameters, @NotNull MethodNode node) {
|
||||
int markerShiftTemp = getIndexAfterLastMarker(node);
|
||||
return markerShiftTemp - parameters.getRealArgsSizeOnStack() + parameters.getArgsSizeOnStack();
|
||||
}
|
||||
|
||||
protected static int getIndexAfterLastMarker(MethodNode node) {
|
||||
int markerShiftTemp = -1;
|
||||
private static int getIndexAfterLastMarker(@NotNull MethodNode node) {
|
||||
int result = -1;
|
||||
for (LocalVariableNode variable : node.localVariables) {
|
||||
if (isFakeLocalVariableForInline(variable.name)) {
|
||||
markerShiftTemp = Math.max(markerShiftTemp, variable.index + 1);
|
||||
result = Math.max(result, variable.index + 1);
|
||||
}
|
||||
}
|
||||
return markerShiftTemp;
|
||||
}
|
||||
|
||||
public static boolean isFakeLocalVariableForInline(@NotNull String name) {
|
||||
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT);
|
||||
}
|
||||
|
||||
public static boolean isThis0(String name) {
|
||||
return THIS$0.equals(name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AbstractInsnNode getPrevMeaningful(@NotNull AbstractInsnNode node) {
|
||||
AbstractInsnNode result = node.getPrevious();
|
||||
while (result != null && !UtilKt.isMeaningful(result)) {
|
||||
result = result.getPrevious();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void removeInterval(@NotNull MethodNode node, @NotNull AbstractInsnNode startInc, @NotNull AbstractInsnNode endInc) {
|
||||
while (startInc != endInc) {
|
||||
AbstractInsnNode next = startInc.getNext();
|
||||
node.instructions.remove(startInc);
|
||||
startInc = next;
|
||||
}
|
||||
node.instructions.remove(startInc);
|
||||
public static boolean isFakeLocalVariableForInline(@NotNull String name) {
|
||||
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) ||
|
||||
name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT);
|
||||
}
|
||||
|
||||
public static boolean isThis0(@NotNull String name) {
|
||||
return THIS$0.equals(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
|
||||
import java.util.Collection;
|
||||
|
||||
public class InlinedLambdaRemapper extends FieldRemapper {
|
||||
|
||||
public InlinedLambdaRemapper(
|
||||
@NotNull String lambdaInternalName,
|
||||
@NotNull FieldRemapper parent,
|
||||
@@ -34,16 +33,13 @@ public class InlinedLambdaRemapper extends FieldRemapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) {
|
||||
return isFolding && super.canProcess(fieldOwner, fieldName, isFolding);
|
||||
public boolean canProcess(@NotNull String fieldOwner, @NotNull String fieldName, boolean isFolding) {
|
||||
return isFolding && super.canProcess(fieldOwner, fieldName, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public CapturedParamInfo findField(
|
||||
@NotNull FieldInsnNode fieldInsnNode,
|
||||
@NotNull Collection<CapturedParamInfo> captured
|
||||
) {
|
||||
public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection<CapturedParamInfo> captured) {
|
||||
return parent.findField(fieldInsnNode, captured);
|
||||
}
|
||||
|
||||
@@ -52,14 +48,12 @@ public class InlinedLambdaRemapper extends FieldRemapper {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StackValue getFieldForInline(@NotNull FieldInsnNode node, @Nullable StackValue prefix) {
|
||||
if (parent.isRoot()) {
|
||||
return super.getFieldForInline(node, prefix);
|
||||
} else {
|
||||
return parent.getFieldForInline(node, prefix);
|
||||
}
|
||||
return parent.getFieldForInline(node, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,87 +25,76 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class InliningContext {
|
||||
|
||||
@Nullable
|
||||
private final InliningContext parent;
|
||||
|
||||
public final Map<Integer, LambdaInfo> expressionMap;
|
||||
|
||||
private final Map<Integer, LambdaInfo> expressionMap;
|
||||
public final GenerationState state;
|
||||
|
||||
public final NameGenerator nameGenerator;
|
||||
|
||||
public final TypeRemapper typeRemapper;
|
||||
|
||||
public final ReifiedTypeInliner reifedTypeInliner;
|
||||
|
||||
public final ReifiedTypeInliner reifiedTypeInliner;
|
||||
public final boolean isInliningLambda;
|
||||
|
||||
public final boolean classRegeneration;
|
||||
|
||||
protected InliningContext(
|
||||
public InliningContext(
|
||||
@Nullable InliningContext parent,
|
||||
@NotNull Map<Integer, LambdaInfo> map,
|
||||
@NotNull Map<Integer, LambdaInfo> expressionMap,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull TypeRemapper typeRemapper,
|
||||
@NotNull ReifiedTypeInliner reifedTypeInliner,
|
||||
@NotNull ReifiedTypeInliner reifiedTypeInliner,
|
||||
boolean isInliningLambda,
|
||||
boolean classRegeneration
|
||||
) {
|
||||
this.parent = parent;
|
||||
expressionMap = map;
|
||||
this.expressionMap = expressionMap;
|
||||
this.state = state;
|
||||
this.nameGenerator = nameGenerator;
|
||||
this.typeRemapper = typeRemapper;
|
||||
this.reifedTypeInliner = reifedTypeInliner;
|
||||
this.reifiedTypeInliner = reifiedTypeInliner;
|
||||
this.isInliningLambda = isInliningLambda;
|
||||
this.classRegeneration = classRegeneration;
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator) {
|
||||
return subInline(generator, Collections.<String, String>emptyMap());
|
||||
@NotNull
|
||||
public InliningContext subInline(@NotNull NameGenerator generator) {
|
||||
return subInline(generator, Collections.<String, String>emptyMap(), isInliningLambda);
|
||||
}
|
||||
|
||||
public InliningContext subInlineLambda(LambdaInfo lambdaInfo) {
|
||||
@NotNull
|
||||
public InliningContext subInlineLambda(@NotNull LambdaInfo lambdaInfo) {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put(lambdaInfo.getLambdaClassType().getInternalName(), null); //mark lambda inlined
|
||||
return subInline(nameGenerator.subGenerator("lambda"), map, true);
|
||||
}
|
||||
|
||||
private InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
|
||||
return subInline(generator, additionalTypeMappings, isInliningLambda);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InliningContext subInlineWithClassRegeneration(
|
||||
@NotNull NameGenerator generator,
|
||||
@NotNull Map<String, String> newTypeMappings,
|
||||
@NotNull InlineCallSiteInfo callSiteInfo
|
||||
) {
|
||||
return new RegeneratedClassContext(this, expressionMap, state, generator,
|
||||
TypeRemapper.createFrom(typeRemapper, newTypeMappings),
|
||||
reifedTypeInliner, isInliningLambda, callSiteInfo);
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
|
||||
return subInline(generator, additionalTypeMappings, isInliningLambda, classRegeneration);
|
||||
return new RegeneratedClassContext(
|
||||
this, expressionMap, state, generator, TypeRemapper.createFrom(typeRemapper, newTypeMappings),
|
||||
reifiedTypeInliner, isInliningLambda, callSiteInfo
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private InliningContext subInline(
|
||||
NameGenerator generator,
|
||||
Map<String, String> additionalTypeMappings,
|
||||
boolean isInliningLambda,
|
||||
boolean isRegeneration
|
||||
@NotNull NameGenerator generator, @NotNull Map<String, String> additionalTypeMappings, boolean isInliningLambda
|
||||
) {
|
||||
//isInliningLambda && !this.isInliningLambda for root inline lambda
|
||||
return new InliningContext(this, expressionMap, state, generator,
|
||||
TypeRemapper.createFrom(
|
||||
typeRemapper,
|
||||
additionalTypeMappings,
|
||||
//root inline lambda
|
||||
isInliningLambda && !this.isInliningLambda
|
||||
),
|
||||
reifedTypeInliner, isInliningLambda, isRegeneration);
|
||||
return new InliningContext(
|
||||
this, expressionMap, state, generator,
|
||||
TypeRemapper.createFrom(
|
||||
typeRemapper,
|
||||
additionalTypeMappings,
|
||||
//root inline lambda
|
||||
isInliningLambda && !this.isInliningLambda
|
||||
),
|
||||
reifiedTypeInliner, isInliningLambda, classRegeneration
|
||||
);
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
@@ -114,12 +103,8 @@ public class InliningContext {
|
||||
|
||||
@NotNull
|
||||
public RootInliningContext getRoot() {
|
||||
if (isRoot()) {
|
||||
return (RootInliningContext) this;
|
||||
}
|
||||
else {
|
||||
return parent.getRoot();
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
return isRoot() ? (RootInliningContext) this : parent.getRoot();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -127,11 +112,7 @@ public class InliningContext {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public boolean isInliningLambdaRootContext() {
|
||||
//noinspection ConstantConditions
|
||||
return isInliningLambda && !getParent().isInliningLambda;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InlineCallSiteInfo getCallSiteInfo() {
|
||||
assert parent != null : "At least root context should return proper value";
|
||||
return parent.getCallSiteInfo();
|
||||
|
||||
@@ -39,37 +39,27 @@ import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||
|
||||
public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
|
||||
public class LambdaInfo implements LabelOwner {
|
||||
public final KtExpression expression;
|
||||
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
|
||||
@NotNull
|
||||
public final Set<String> labels;
|
||||
|
||||
private final CalculatedClosure closure;
|
||||
|
||||
public final boolean isCrossInline;
|
||||
|
||||
private SMAPAndMethodNode node;
|
||||
|
||||
private List<CapturedParamDesc> capturedVars;
|
||||
|
||||
private final FunctionDescriptor functionDescriptor;
|
||||
|
||||
private final ClassDescriptor classDescriptor;
|
||||
|
||||
private final Type closureClassType;
|
||||
|
||||
LambdaInfo(@NotNull KtExpression expr, @NotNull KotlinTypeMapper typeMapper, boolean isCrossInline) {
|
||||
private SMAPAndMethodNode node;
|
||||
private List<CapturedParamDesc> capturedVars;
|
||||
|
||||
public LambdaInfo(@NotNull KtExpression expression, @NotNull KotlinTypeMapper typeMapper, boolean isCrossInline) {
|
||||
this.isCrossInline = isCrossInline;
|
||||
this.expression = expr instanceof KtLambdaExpression ?
|
||||
((KtLambdaExpression) expr).getFunctionLiteral() : expr;
|
||||
this.expression = expression instanceof KtLambdaExpression ?
|
||||
((KtLambdaExpression) expression).getFunctionLiteral() : expression;
|
||||
|
||||
this.typeMapper = typeMapper;
|
||||
BindingContext bindingContext = typeMapper.getBindingContext();
|
||||
functionDescriptor = bindingContext.get(BindingContext.FUNCTION, expression);
|
||||
functionDescriptor = bindingContext.get(BindingContext.FUNCTION, this.expression);
|
||||
assert functionDescriptor != null : "Function is not resolved to descriptor: " + expression.getText();
|
||||
|
||||
classDescriptor = anonymousClassForCallable(bindingContext, functionDescriptor);
|
||||
@@ -78,34 +68,39 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
closure = bindingContext.get(CLOSURE, classDescriptor);
|
||||
assert closure != null : "Closure for lambda should be not null " + expression.getText();
|
||||
|
||||
|
||||
labels = InlineCodegen.getDeclarationLabels(expr, functionDescriptor);
|
||||
labels = InlineCodegen.getDeclarationLabels(expression, functionDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SMAPAndMethodNode getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(SMAPAndMethodNode node) {
|
||||
public void setNode(@NotNull SMAPAndMethodNode node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionDescriptor getFunctionDescriptor() {
|
||||
return functionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KtExpression getFunctionWithBodyOrCallableReference() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getClassDescriptor() {
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getLambdaClassType() {
|
||||
return closureClassType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<CapturedParamDesc> getCapturedVars() {
|
||||
//lazy initialization cause it would be calculated after object creation
|
||||
if (capturedVars == null) {
|
||||
@@ -114,11 +109,12 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
if (closure.getCaptureThis() != null) {
|
||||
Type type = typeMapper.mapType(closure.getCaptureThis());
|
||||
EnclosedValueDescriptor descriptor =
|
||||
new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD,
|
||||
null,
|
||||
StackValue.field(type, closureClassType, AsmUtil.CAPTURED_THIS_FIELD, false,
|
||||
StackValue.LOCAL_0),
|
||||
type);
|
||||
new EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_THIS_FIELD,
|
||||
/* descriptor = */ null,
|
||||
StackValue.field(type, closureClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
||||
type
|
||||
);
|
||||
capturedVars.add(getCapturedParamInfo(descriptor));
|
||||
}
|
||||
|
||||
@@ -127,10 +123,10 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
EnclosedValueDescriptor descriptor =
|
||||
new EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_RECEIVER_FIELD,
|
||||
null,
|
||||
StackValue.field(type, closureClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false,
|
||||
StackValue.LOCAL_0),
|
||||
type);
|
||||
/* descriptor = */ null,
|
||||
StackValue.field(type, closureClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0),
|
||||
type
|
||||
);
|
||||
capturedVars.add(getCapturedParamInfo(descriptor));
|
||||
}
|
||||
|
||||
@@ -143,38 +139,30 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
|
||||
@NotNull
|
||||
private CapturedParamDesc getCapturedParamInfo(@NotNull EnclosedValueDescriptor descriptor) {
|
||||
return CapturedParamDesc.createDesc(this, descriptor.getFieldName(), descriptor.getType());
|
||||
return new CapturedParamDesc(closureClassType, descriptor.getFieldName(), descriptor.getType());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Type> getInvokeParamsWithoutCaptured() {
|
||||
Type[] types = typeMapper.mapAsmMethod(functionDescriptor).getArgumentTypes();
|
||||
return Arrays.asList(types);
|
||||
return Arrays.asList(typeMapper.mapAsmMethod(functionDescriptor).getArgumentTypes());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Parameters addAllParameters(FieldRemapper remapper) {
|
||||
public Parameters addAllParameters(@NotNull FieldRemapper remapper) {
|
||||
Method asmMethod = typeMapper.mapAsmMethod(getFunctionDescriptor());
|
||||
ParametersBuilder builder =
|
||||
ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, asmMethod.getDescriptor(), this);
|
||||
ParametersBuilder builder = ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, asmMethod.getDescriptor(), this);
|
||||
|
||||
for (CapturedParamDesc info : getCapturedVars()) {
|
||||
CapturedParamInfo field = remapper.findField(new FieldInsnNode(0, info.getContainingLambdaName(), info.getFieldName(), ""));
|
||||
assert field != null : "Captured field not found: " + info.getContainingLambdaName() + "." + info.getFieldName();
|
||||
builder.addCapturedParam(field, info.getFieldName());
|
||||
}
|
||||
|
||||
return builder.buildParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
return closureClassType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMyLabel(@NotNull String name) {
|
||||
return labels.contains(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,16 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import static org.jetbrains.kotlin.codegen.inline.LocalVarRemapper.RemapStatus.*;
|
||||
|
||||
public class LocalVarRemapper {
|
||||
|
||||
private final Parameters params;
|
||||
private final int actualParamsSize;
|
||||
|
||||
private final StackValue[] remapValues;
|
||||
private final int additionalShift;
|
||||
|
||||
public LocalVarRemapper(Parameters params, int additionalShift) {
|
||||
public LocalVarRemapper(@NotNull Parameters params, int additionalShift) {
|
||||
this.additionalShift = additionalShift;
|
||||
this.params = params;
|
||||
|
||||
remapValues = new StackValue [params.getArgsSizeOnStack()];
|
||||
remapValues = new StackValue[params.getArgsSizeOnStack()];
|
||||
|
||||
int realSize = 0;
|
||||
for (ParameterInfo info : params) {
|
||||
@@ -56,7 +54,8 @@ public class LocalVarRemapper {
|
||||
actualParamsSize = realSize;
|
||||
}
|
||||
|
||||
public RemapInfo doRemap(int index) {
|
||||
@NotNull
|
||||
private RemapInfo doRemap(int index) {
|
||||
int remappedIndex;
|
||||
|
||||
if (index < params.getArgsSizeOnStack()) {
|
||||
@@ -67,16 +66,20 @@ public class LocalVarRemapper {
|
||||
}
|
||||
if (info.isRemapped()) {
|
||||
return new RemapInfo(remapped, info, REMAPPED);
|
||||
} else {
|
||||
remappedIndex = ((StackValue.Local)remapped).index;
|
||||
}
|
||||
} else {
|
||||
remappedIndex = actualParamsSize - params.getArgsSizeOnStack() + index; //captured params not used directly in this inlined method, they used in closure
|
||||
else {
|
||||
remappedIndex = ((StackValue.Local) remapped).index;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//captured params are not used directly in this inlined method, they are used in closure
|
||||
remappedIndex = actualParamsSize - params.getArgsSizeOnStack() + index;
|
||||
}
|
||||
|
||||
return new RemapInfo(StackValue.local(remappedIndex + additionalShift, AsmTypes.OBJECT_TYPE), null, SHIFT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RemapInfo remap(int index) {
|
||||
RemapInfo info = doRemap(index);
|
||||
if (FAIL == info.status) {
|
||||
@@ -86,23 +89,29 @@ public class LocalVarRemapper {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void visitIincInsn(int var, int increment, MethodVisitor mv) {
|
||||
public void visitIincInsn(int var, int increment, @NotNull MethodVisitor mv) {
|
||||
RemapInfo remap = remap(var);
|
||||
assert remap.value instanceof StackValue.Local;
|
||||
assert remap.value instanceof StackValue.Local : "Remapped value should be a local: " + remap.value;
|
||||
mv.visitIincInsn(((StackValue.Local) remap.value).index, increment);
|
||||
}
|
||||
|
||||
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index, MethodVisitor mv) {
|
||||
public void visitLocalVariable(
|
||||
@NotNull String name,
|
||||
@NotNull String desc,
|
||||
@Nullable String signature,
|
||||
@NotNull Label start,
|
||||
@NotNull Label end,
|
||||
int index,
|
||||
MethodVisitor mv
|
||||
) {
|
||||
RemapInfo info = doRemap(index);
|
||||
//add entries only for shifted vars
|
||||
if (SHIFT == info.status) {
|
||||
int newIndex = ((StackValue.Local) info.value).index;
|
||||
mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
|
||||
mv.visitLocalVariable(name, desc, signature, start, end, ((StackValue.Local) info.value).index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void visitVarInsn(int opcode, int var, InstructionAdapter mv) {
|
||||
public void visitVarInsn(int opcode, int var, @NotNull InstructionAdapter mv) {
|
||||
RemapInfo remapInfo = remap(var);
|
||||
StackValue value = remapInfo.value;
|
||||
if (value instanceof StackValue.Local) {
|
||||
@@ -117,7 +126,8 @@ public class LocalVarRemapper {
|
||||
if (remapInfo.parameterInfo != null) {
|
||||
StackValue.coerce(value.type, remapInfo.parameterInfo.type, mv);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
assert remapInfo.parameterInfo != null : "Non local value should have parameter info";
|
||||
value.put(remapInfo.parameterInfo.type, mv);
|
||||
}
|
||||
@@ -134,15 +144,15 @@ public class LocalVarRemapper {
|
||||
public final ParameterInfo parameterInfo;
|
||||
public final RemapStatus status;
|
||||
|
||||
public RemapInfo(@NotNull StackValue value, @Nullable ParameterInfo info, RemapStatus remapStatus) {
|
||||
public RemapInfo(@NotNull StackValue value, @Nullable ParameterInfo parameterInfo, @NotNull RemapStatus remapStatus) {
|
||||
this.value = value;
|
||||
parameterInfo = info;
|
||||
this.parameterInfo = parameterInfo;
|
||||
this.status = remapStatus;
|
||||
}
|
||||
|
||||
public RemapInfo(@NotNull ParameterInfo info) {
|
||||
public RemapInfo(@NotNull ParameterInfo parameterInfo) {
|
||||
this.value = null;
|
||||
parameterInfo = info;
|
||||
this.parameterInfo = parameterInfo;
|
||||
this.status = FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class MethodBodyVisitor extends InstructionAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAttribute(Attribute attr) {
|
||||
public void visitAttribute(@NotNull Attribute attr) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -43,45 +43,24 @@ import java.util.*;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*;
|
||||
|
||||
public class MethodInliner {
|
||||
|
||||
private final MethodNode node;
|
||||
|
||||
private final Parameters parameters;
|
||||
|
||||
private final InliningContext inliningContext;
|
||||
|
||||
private final FieldRemapper nodeRemapper;
|
||||
|
||||
private final boolean isSameModule;
|
||||
|
||||
private final String errorPrefix;
|
||||
|
||||
private final SourceMapper sourceMapper;
|
||||
|
||||
private final InlineCallSiteInfo inlineCallSiteInfo;
|
||||
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
|
||||
private final List<InvokeCall> invokeCalls = new ArrayList<InvokeCall>();
|
||||
|
||||
//keeps order
|
||||
private final List<TransformationInfo> transformations = new ArrayList<TransformationInfo>();
|
||||
//current state
|
||||
private final Map<String, String> currentTypeMapping = new HashMap<String, String>();
|
||||
|
||||
private final InlineResult result;
|
||||
|
||||
private int lambdasFinallyBlocks;
|
||||
|
||||
private final InlineOnlySmapSkipper inlineOnlySmapSkipper;
|
||||
|
||||
/*
|
||||
*
|
||||
* @param node
|
||||
* @param parameters
|
||||
* @param inliningContext
|
||||
* @param lambdaType - in case on lambda 'invoke' inlining
|
||||
*/
|
||||
public MethodInliner(
|
||||
@NotNull MethodNode node,
|
||||
@NotNull Parameters parameters,
|
||||
@@ -106,6 +85,7 @@ public class MethodInliner {
|
||||
this.inlineOnlySmapSkipper = smapSkipper;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InlineResult doInline(
|
||||
@NotNull MethodVisitor adapter,
|
||||
@NotNull LocalVarRemapper remapper,
|
||||
@@ -115,6 +95,7 @@ public class MethodInliner {
|
||||
return doInline(adapter, remapper, remapReturn, labelOwner, 0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private InlineResult doInline(
|
||||
@NotNull MethodVisitor adapter,
|
||||
@NotNull LocalVarRemapper remapper,
|
||||
@@ -129,11 +110,12 @@ public class MethodInliner {
|
||||
Label end = new Label();
|
||||
transformedNode = doInline(transformedNode);
|
||||
removeClosureAssertions(transformedNode);
|
||||
InsnList instructions = transformedNode.instructions;
|
||||
instructions.resetLabels();
|
||||
transformedNode.instructions.resetLabels();
|
||||
|
||||
MethodNode resultNode = new MethodNode(InlineCodegenUtil.API, transformedNode.access, transformedNode.name, transformedNode.desc,
|
||||
transformedNode.signature, ArrayUtil.toStringArray(transformedNode.exceptions));
|
||||
MethodNode resultNode = new MethodNode(
|
||||
InlineCodegenUtil.API, transformedNode.access, transformedNode.name, transformedNode.desc,
|
||||
transformedNode.signature, ArrayUtil.toStringArray(transformedNode.exceptions)
|
||||
);
|
||||
RemapVisitor visitor = new RemapVisitor(resultNode, remapper, nodeRemapper);
|
||||
try {
|
||||
transformedNode.accept(visitor);
|
||||
@@ -145,7 +127,10 @@ public class MethodInliner {
|
||||
resultNode.visitLabel(end);
|
||||
|
||||
if (inliningContext.isRoot()) {
|
||||
InternalFinallyBlockInliner.processInlineFunFinallyBlocks(resultNode, lambdasFinallyBlocks, ((StackValue.Local)remapper.remap(parameters.getArgsSizeOnStack() + 1).value).index);
|
||||
StackValue remapValue = remapper.remap(parameters.getArgsSizeOnStack() + 1).value;
|
||||
InternalFinallyBlockInliner.processInlineFunFinallyBlocks(
|
||||
resultNode, lambdasFinallyBlocks, ((StackValue.Local) remapValue).index
|
||||
);
|
||||
}
|
||||
|
||||
processReturns(resultNode, labelOwner, remapReturn, end);
|
||||
@@ -156,8 +141,8 @@ public class MethodInliner {
|
||||
return result;
|
||||
}
|
||||
|
||||
private MethodNode doInline(final MethodNode node) {
|
||||
|
||||
@NotNull
|
||||
private MethodNode doInline(@NotNull MethodNode node) {
|
||||
final Deque<InvokeCall> currentInvokes = new LinkedList<InvokeCall>(invokeCalls);
|
||||
|
||||
final MethodNode resultNode = new MethodNode(node.access, node.name, node.desc, node.signature, null);
|
||||
@@ -174,8 +159,8 @@ public class MethodInliner {
|
||||
|
||||
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
|
||||
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
|
||||
|
||||
private TransformationInfo transformationInfo;
|
||||
|
||||
private void handleAnonymousObjectRegeneration() {
|
||||
transformationInfo = iterator.next();
|
||||
|
||||
@@ -190,10 +175,7 @@ public class MethodInliner {
|
||||
currentTypeMapping,
|
||||
inlineCallSiteInfo
|
||||
);
|
||||
ObjectTransformer transformer = transformationInfo.createTransformer(
|
||||
childInliningContext,
|
||||
isSameModule
|
||||
);
|
||||
ObjectTransformer transformer = transformationInfo.createTransformer(childInliningContext, isSameModule);
|
||||
|
||||
InlineResult transformResult = transformer.doTransform(nodeRemapper);
|
||||
result.addAllClassesToRemove(transformResult);
|
||||
@@ -213,7 +195,7 @@ public class MethodInliner {
|
||||
|
||||
@Override
|
||||
public void anew(@NotNull Type type) {
|
||||
if (isAnonymousConstructorCall(type.getInternalName(), "<init>")) {
|
||||
if (isAnonymousClass(type.getInternalName())) {
|
||||
handleAnonymousObjectRegeneration();
|
||||
}
|
||||
|
||||
@@ -245,23 +227,25 @@ public class MethodInliner {
|
||||
|
||||
setLambdaInlining(true);
|
||||
SMAP lambdaSMAP = info.getNode().getClassSMAP();
|
||||
//noinspection ConstantConditions
|
||||
SourceMapper mapper =
|
||||
inliningContext.classRegeneration && !inliningContext.isInliningLambda ?
|
||||
new NestedSourceMapper(sourceMapper, lambdaSMAP.getIntervals(), lambdaSMAP.getSourceInfo())
|
||||
inliningContext.classRegeneration && !inliningContext.isInliningLambda
|
||||
? new NestedSourceMapper(sourceMapper, lambdaSMAP.getIntervals(), lambdaSMAP.getSourceInfo())
|
||||
: new InlineLambdaSourceMapper(sourceMapper.getParent(), info.getNode());
|
||||
MethodInliner inliner = new MethodInliner(info.getNode().getNode(), lambdaParameters,
|
||||
inliningContext.subInlineLambda(info),
|
||||
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
|
||||
"Lambda inlining " + info.getLambdaClassType().getInternalName(),
|
||||
mapper, inlineCallSiteInfo, null);
|
||||
MethodInliner inliner = new MethodInliner(
|
||||
info.getNode().getNode(), lambdaParameters, inliningContext.subInlineLambda(info),
|
||||
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
|
||||
"Lambda inlining " + info.getLambdaClassType().getInternalName(),
|
||||
mapper, inlineCallSiteInfo, null
|
||||
);
|
||||
|
||||
LocalVarRemapper remapper = new LocalVarRemapper(lambdaParameters, valueParamShift);
|
||||
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);//TODO add skipped this and receiver
|
||||
//TODO add skipped this and receiver
|
||||
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);
|
||||
result.addAllClassesToRemove(lambdaResult);
|
||||
|
||||
//return value boxing/unboxing
|
||||
Method bridge =
|
||||
typeMapper.mapAsmMethod(ClosureCodegen.getErasedInvokeFunction(info.getFunctionDescriptor()));
|
||||
Method bridge = typeMapper.mapAsmMethod(ClosureCodegen.getErasedInvokeFunction(info.getFunctionDescriptor()));
|
||||
Method delegate = typeMapper.mapAsmMethod(info.getFunctionDescriptor());
|
||||
StackValue.onStack(delegate.getReturnType()).put(bridge.getReturnType(), this);
|
||||
setLambdaInlining(false);
|
||||
@@ -274,31 +258,38 @@ public class MethodInliner {
|
||||
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
|
||||
//TODO add proper message
|
||||
assert transformationInfo instanceof AnonymousObjectTransformationInfo :
|
||||
"<init> call doesn't correspond to object transformation info: " + owner + "." + name + ", info " + transformationInfo;
|
||||
"<init> call doesn't correspond to object transformation info: " +
|
||||
owner + "." + name + ", info " + transformationInfo;
|
||||
if (transformationInfo.shouldRegenerate(isSameModule)) {
|
||||
//put additional captured parameters on stack
|
||||
for (CapturedParamDesc capturedParamDesc : ((AnonymousObjectTransformationInfo) transformationInfo).getAllRecapturedParameters()) {
|
||||
visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
|
||||
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor());
|
||||
AnonymousObjectTransformationInfo info = (AnonymousObjectTransformationInfo) transformationInfo;
|
||||
for (CapturedParamDesc capturedParamDesc : info.getAllRecapturedParameters()) {
|
||||
visitFieldInsn(
|
||||
Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
|
||||
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor()
|
||||
);
|
||||
}
|
||||
super.visitMethodInsn(opcode, transformationInfo.getNewClassName(), name,
|
||||
((AnonymousObjectTransformationInfo) transformationInfo).getNewConstructorDescriptor(), itf);
|
||||
super.visitMethodInsn(opcode, transformationInfo.getNewClassName(), name, info.getNewConstructorDescriptor(), itf);
|
||||
|
||||
//TODO: add new inner class also for other contexts
|
||||
if (inliningContext.getParent() instanceof RegeneratedClassContext) {
|
||||
inliningContext.getParent().typeRemapper.addAdditionalMappings(transformationInfo.getOldClassName(), transformationInfo.getNewClassName());
|
||||
inliningContext.getParent().typeRemapper.addAdditionalMappings(
|
||||
transformationInfo.getOldClassName(), transformationInfo.getNewClassName()
|
||||
);
|
||||
}
|
||||
|
||||
transformationInfo = null;
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf);
|
||||
}
|
||||
else {
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
}
|
||||
else if (!inliningContext.isInliningLambda && ReifiedTypeInliner.isNeedClassReificationMarker(new MethodInsnNode(opcode, owner, name, desc, false))) {
|
||||
else if (!inliningContext.isInliningLambda &&
|
||||
ReifiedTypeInliner.isNeedClassReificationMarker(new MethodInsnNode(opcode, owner, name, desc, false))) {
|
||||
//we shouldn't process here content of inlining lambda it should be reified at external level
|
||||
}
|
||||
else {
|
||||
super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf);
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +306,6 @@ public class MethodInliner {
|
||||
lambdasFinallyBlocks = resultNode.tryCatchBlocks.size();
|
||||
super.visitMaxs(stack, locals);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
node.accept(lambdaInliner);
|
||||
@@ -324,18 +314,20 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CapturedParamInfo findCapturedField(FieldInsnNode node, FieldRemapper fieldRemapper) {
|
||||
public static CapturedParamInfo findCapturedField(@NotNull FieldInsnNode node, @NotNull FieldRemapper fieldRemapper) {
|
||||
assert node.name.startsWith("$$$") : "Captured field template should start with $$$ prefix";
|
||||
FieldInsnNode fin = new FieldInsnNode(node.getOpcode(), node.owner, node.name.substring(3), node.desc);
|
||||
CapturedParamInfo field = fieldRemapper.findField(fin);
|
||||
if (field == null) {
|
||||
throw new IllegalStateException("Couldn't find captured field " + node.owner + "." + node.name + " in " + fieldRemapper.getLambdaInternalName());
|
||||
throw new IllegalStateException(
|
||||
"Couldn't find captured field " + node.owner + "." + node.name + " in " + fieldRemapper.getLambdaInternalName()
|
||||
);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) {
|
||||
private MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) {
|
||||
final int capturedParamsSize = parameters.getCapturedArgsSizeOnStack();
|
||||
final int realParametersSize = parameters.getRealArgsSizeOnStack();
|
||||
Type[] types = Type.getArgumentTypes(node.desc);
|
||||
@@ -345,8 +337,10 @@ public class MethodInliner {
|
||||
Type[] allTypes = ArrayUtil.mergeArrays(types, capturedTypes.toArray(new Type[capturedTypes.size()]));
|
||||
|
||||
node.instructions.resetLabels();
|
||||
MethodNode transformedNode = new MethodNode(InlineCodegenUtil.API, node.access, node.name, Type.getMethodDescriptor(returnType, allTypes), node.signature, null) {
|
||||
|
||||
MethodNode transformedNode = new MethodNode(
|
||||
InlineCodegenUtil.API, node.access, node.name, Type.getMethodDescriptor(returnType, allTypes), node.signature, null
|
||||
) {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private final boolean GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && inlineOnlySmapSkipper == null;
|
||||
|
||||
private final boolean isInliningLambda = nodeRemapper.isInsideInliningLambda();
|
||||
@@ -372,7 +366,7 @@ public class MethodInliner {
|
||||
|
||||
@Override
|
||||
public void visitLineNumber(int line, @NotNull Label start) {
|
||||
if(isInliningLambda || GENERATE_DEBUG_INFO) {
|
||||
if (isInliningLambda || GENERATE_DEBUG_INFO) {
|
||||
super.visitLineNumber(line, start);
|
||||
}
|
||||
}
|
||||
@@ -382,9 +376,8 @@ public class MethodInliner {
|
||||
@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index
|
||||
) {
|
||||
if (isInliningLambda || GENERATE_DEBUG_INFO) {
|
||||
String varSuffix = inliningContext.isRoot() &&
|
||||
!InlineCodegenUtil.isFakeLocalVariableForInline(name) ?
|
||||
INLINE_FUN_VAR_SUFFIX : "";
|
||||
String varSuffix =
|
||||
inliningContext.isRoot() && !InlineCodegenUtil.isFakeLocalVariableForInline(name) ? INLINE_FUN_VAR_SUFFIX : "";
|
||||
String varName = !varSuffix.isEmpty() && name.equals("this") ? name + "_" : name;
|
||||
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index));
|
||||
}
|
||||
@@ -400,7 +393,9 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected MethodNode markPlacesForInlineAndRemoveInlinable(@NotNull MethodNode node, @NotNull LabelOwner labelOwner, int finallyDeepShift) {
|
||||
private MethodNode markPlacesForInlineAndRemoveInlinable(
|
||||
@NotNull MethodNode node, @NotNull LabelOwner labelOwner, int finallyDeepShift
|
||||
) {
|
||||
node = prepareNode(node, finallyDeepShift);
|
||||
|
||||
Frame<SourceValue>[] sources = analyzeMethodNodeBeforeInline(node);
|
||||
@@ -460,9 +455,7 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
transformations.add(
|
||||
buildConstructorInvocation(
|
||||
owner, desc, lambdaMapping, awaitClassReification
|
||||
)
|
||||
buildConstructorInvocation(owner, desc, lambdaMapping, awaitClassReification)
|
||||
);
|
||||
awaitClassReification = false;
|
||||
}
|
||||
@@ -482,7 +475,8 @@ public class MethodInliner {
|
||||
else if (isWhenMappingAccess(className, fieldInsnNode.name)) {
|
||||
transformations.add(
|
||||
new WhenMappingTransformationInfo(
|
||||
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode)
|
||||
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -498,7 +492,8 @@ public class MethodInliner {
|
||||
//NB: Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
|
||||
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
|
||||
//but as result all this labels will be merged into one (see KT-5863)
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
toDelete.add(prevNode);
|
||||
}
|
||||
}
|
||||
@@ -522,6 +517,7 @@ public class MethodInliner {
|
||||
return node;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Frame<SourceValue>[] analyzeMethodNodeBeforeInline(@NotNull MethodNode node) {
|
||||
try {
|
||||
new MandatoryMethodTransformer().transform("fake", node);
|
||||
@@ -545,14 +541,12 @@ public class MethodInliner {
|
||||
}
|
||||
};
|
||||
|
||||
Frame<SourceValue>[] sources;
|
||||
try {
|
||||
sources = analyzer.analyze("fake", node);
|
||||
return analyzer.analyze("fake", node);
|
||||
}
|
||||
catch (AnalyzerException e) {
|
||||
throw wrapException(e, node, "couldn't inline method call");
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
private static boolean isEmptyTryInterval(@NotNull TryCatchBlockNode tryCatchBlockNode) {
|
||||
@@ -595,7 +589,8 @@ public class MethodInliner {
|
||||
int varIndex = ((VarInsnNode) insnNode).var;
|
||||
return getLambdaIfExists(varIndex);
|
||||
}
|
||||
else if (insnNode instanceof FieldInsnNode) {
|
||||
|
||||
if (insnNode instanceof FieldInsnNode) {
|
||||
FieldInsnNode fieldInsnNode = (FieldInsnNode) insnNode;
|
||||
if (fieldInsnNode.name.startsWith("$$$")) {
|
||||
return findCapturedField(fieldInsnNode, nodeRemapper).getLambda();
|
||||
@@ -605,6 +600,7 @@ public class MethodInliner {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private LambdaInfo getLambdaIfExists(int varIndex) {
|
||||
if (varIndex < parameters.getArgsSizeOnStack()) {
|
||||
return parameters.getParameterByDeclarationSlot(varIndex).getLambda();
|
||||
@@ -612,13 +608,14 @@ public class MethodInliner {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void removeClosureAssertions(MethodNode node) {
|
||||
private static void removeClosureAssertions(@NotNull MethodNode node) {
|
||||
AbstractInsnNode cur = node.instructions.getFirst();
|
||||
while (cur != null && cur.getNext() != null) {
|
||||
AbstractInsnNode next = cur.getNext();
|
||||
if (next.getType() == AbstractInsnNode.METHOD_INSN) {
|
||||
MethodInsnNode methodInsnNode = (MethodInsnNode) next;
|
||||
if (methodInsnNode.name.equals("checkParameterIsNotNull") && methodInsnNode.owner.equals(IntrinsicMethods.INTRINSICS_CLASS_NAME)) {
|
||||
if (methodInsnNode.name.equals("checkParameterIsNotNull") &&
|
||||
methodInsnNode.owner.equals(IntrinsicMethods.INTRINSICS_CLASS_NAME)) {
|
||||
AbstractInsnNode prev = cur.getPrevious();
|
||||
|
||||
assert cur.getOpcode() == Opcodes.LDC : "checkParameterIsNotNull should go after LDC but " + cur;
|
||||
@@ -676,7 +673,7 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<AbstractInsnNode> getCapturedFieldAccessChain(@NotNull VarInsnNode aload0) {
|
||||
private static List<AbstractInsnNode> getCapturedFieldAccessChain(@NotNull VarInsnNode aload0) {
|
||||
List<AbstractInsnNode> fieldAccessChain = new ArrayList<AbstractInsnNode>();
|
||||
fieldAccessChain.add(aload0);
|
||||
AbstractInsnNode next = aload0.getNext();
|
||||
@@ -697,7 +694,9 @@ public class MethodInliner {
|
||||
return fieldAccessChain;
|
||||
}
|
||||
|
||||
public static void putStackValuesIntoLocals(List<Type> directOrder, int shift, InstructionAdapter iv, String descriptor) {
|
||||
private static void putStackValuesIntoLocals(
|
||||
@NotNull List<Type> directOrder, int shift, @NotNull InstructionAdapter iv, @NotNull String descriptor
|
||||
) {
|
||||
Type[] actualParams = Type.getArgumentTypes(descriptor);
|
||||
assert actualParams.length == directOrder.size() : "Number of expected and actual params should be equals!";
|
||||
|
||||
@@ -719,42 +718,21 @@ public class MethodInliner {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: check it's external module
|
||||
//TODO?: assert method exists in facade?
|
||||
public String changeOwnerForExternalPackage(String type, int opcode) {
|
||||
//if (isSameModule || (opcode & Opcodes.INVOKESTATIC) == 0) {
|
||||
// return type;
|
||||
//}
|
||||
|
||||
//JvmClassName name = JvmClassName.byInternalName(type);
|
||||
//String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(name.getPackageFqName());
|
||||
//if (type.startsWith(packageClassInternalName + '$')) {
|
||||
// VirtualFile virtualFile = InlineCodegenUtil.findVirtualFile(inliningContext.state.getProject(), type);
|
||||
// if (virtualFile != null) {
|
||||
// KotlinJvmBinaryClass klass = KotlinBinaryClassCache.getKotlinBinaryClass(virtualFile);
|
||||
// if (klass != null && klass.getClassHeader().getSyntheticClassKind() == KotlinSyntheticClass.Kind.PACKAGE_PART) {
|
||||
// return packageClassInternalName;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RuntimeException wrapException(@NotNull Throwable originalException, @NotNull MethodNode node, @NotNull String errorSuffix) {
|
||||
private RuntimeException wrapException(@NotNull Throwable originalException, @NotNull MethodNode node, @NotNull String errorSuffix) {
|
||||
if (originalException instanceof InlineException) {
|
||||
return new InlineException(errorPrefix + ": " + errorSuffix, originalException);
|
||||
}
|
||||
else {
|
||||
return new InlineException(errorPrefix + ": " + errorSuffix + "\ncause: " +
|
||||
getNodeText(node), originalException);
|
||||
return new InlineException(errorPrefix + ": " + errorSuffix + "\nCause: " + getNodeText(node), originalException);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
//process local and global returns (local substituted with goto end-label global kept unchanged)
|
||||
public static List<PointForExternalFinallyBlocks> processReturns(@NotNull MethodNode node, @NotNull LabelOwner labelOwner, boolean remapReturn, Label endLabel) {
|
||||
public static List<PointForExternalFinallyBlocks> processReturns(
|
||||
@NotNull MethodNode node, @NotNull LabelOwner labelOwner, boolean remapReturn, @Nullable Label endLabel
|
||||
) {
|
||||
if (!remapReturn) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -785,9 +763,9 @@ public class MethodInliner {
|
||||
//generate finally block before nonLocalReturn flag/return/goto
|
||||
LabelNode label = new LabelNode();
|
||||
instructions.insert(insnNode, label);
|
||||
result.add(new PointForExternalFinallyBlocks(getInstructionToInsertFinallyBefore(insnNode, isLocalReturn),
|
||||
getReturnType(insnNode.getOpcode()),
|
||||
label));
|
||||
result.add(new PointForExternalFinallyBlocks(
|
||||
getInstructionToInsertFinallyBefore(insnNode, isLocalReturn), getReturnType(insnNode.getOpcode()), label
|
||||
));
|
||||
}
|
||||
insnNode = insnNode.getNext();
|
||||
}
|
||||
@@ -860,7 +838,7 @@ public class MethodInliner {
|
||||
}
|
||||
}
|
||||
|
||||
public void transform(MethodNode methodNode) {
|
||||
public void transform(@NotNull MethodNode methodNode) {
|
||||
int returnVariableIndex = -1;
|
||||
if (needsReturnVariable) {
|
||||
returnVariableIndex = methodNode.maxLocals;
|
||||
@@ -872,6 +850,7 @@ public class MethodInliner {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LocalReturnsNormalizer createFor(
|
||||
@NotNull MethodNode methodNode,
|
||||
@NotNull LabelOwner owner,
|
||||
@@ -905,21 +884,16 @@ public class MethodInliner {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
private static AbstractInsnNode getInstructionToInsertFinallyBefore(@NotNull AbstractInsnNode nonLocalReturnOrJump, boolean isLocal) {
|
||||
private static AbstractInsnNode getInstructionToInsertFinallyBefore(@NotNull AbstractInsnNode nonLocalReturnOrJump, boolean isLocal) {
|
||||
return isLocal ? nonLocalReturnOrJump : nonLocalReturnOrJump.getPrevious();
|
||||
}
|
||||
|
||||
//Place to insert finally blocks from try blocks that wraps inline fun call
|
||||
public static class PointForExternalFinallyBlocks {
|
||||
|
||||
final AbstractInsnNode beforeIns;
|
||||
|
||||
final Type returnType;
|
||||
|
||||
final LabelNode finallyIntervalEnd;
|
||||
public final AbstractInsnNode beforeIns;
|
||||
public final Type returnType;
|
||||
public final LabelNode finallyIntervalEnd;
|
||||
|
||||
public PointForExternalFinallyBlocks(
|
||||
@NotNull AbstractInsnNode beforeIns,
|
||||
@@ -930,6 +904,5 @@ public class MethodInliner {
|
||||
this.returnType = returnType;
|
||||
this.finallyIntervalEnd = finallyIntervalEnd;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
@@ -25,7 +24,6 @@ import org.jetbrains.org.objectweb.asm.tree.VarInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
|
||||
|
||||
|
||||
fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
|
||||
insnNode: AbstractInsnNode?,
|
||||
processSwap: Boolean,
|
||||
@@ -59,7 +57,7 @@ fun MethodInliner.getLambdaIfExistsAndMarkInstructions(
|
||||
else if (processSwap && insnNode.opcode == Opcodes.SWAP) {
|
||||
val swapFrame = frames[insnList.indexOf(insnNode)] ?: return null
|
||||
val dispatchReceiver = swapFrame.top()!!.singleOrNullInsn()
|
||||
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete).let {
|
||||
getLambdaIfExistsAndMarkInstructions(dispatchReceiver, false, insnList, frames, toDelete)?.let {
|
||||
//remove swap instruction (dispatch receiver would be deleted on recursion call): see 'complexStack/simpleExtension.1.kt' test
|
||||
toDelete.add(insnNode)
|
||||
return it
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
abstract class ObjectTransformer<T : TransformationInfo>(@JvmField val transformationInfo: T, val state: GenerationState) {
|
||||
abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val transformationInfo: T, val state: GenerationState) {
|
||||
|
||||
abstract fun doTransform(parentRemapper: FieldRemapper): InlineResult
|
||||
|
||||
@@ -42,14 +42,13 @@ abstract class ObjectTransformer<T : TransformationInfo>(@JvmField val transform
|
||||
|
||||
return RemappingClassBuilder(
|
||||
classBuilder,
|
||||
AsmTypeRemapper(inliningContext.typeRemapper, inliningContext.root.typeParameterMappings == null, transformationResult))
|
||||
AsmTypeRemapper(inliningContext.typeRemapper, inliningContext.root.typeParameterMappings == null, transformationResult)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun createClassReader(): ClassReader {
|
||||
return InlineCodegenUtil.buildClassReaderByInternalName(state, transformationInfo.oldClassName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WhenMappingTransformer(
|
||||
@@ -72,7 +71,7 @@ class WhenMappingTransformer(
|
||||
}
|
||||
|
||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
||||
return if (name.equals(fieldNode.name)) {
|
||||
return if (name == fieldNode.name) {
|
||||
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
|
||||
}
|
||||
else {
|
||||
@@ -80,18 +79,22 @@ class WhenMappingTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||
val methodNode = MethodNode(access, name, desc, signature, exceptions)
|
||||
methodNodes.add(methodNode)
|
||||
return methodNode
|
||||
override fun visitMethod(
|
||||
access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?
|
||||
): MethodVisitor? {
|
||||
return MethodNode(access, name, desc, signature, exceptions).apply {
|
||||
methodNodes.add(this)
|
||||
}
|
||||
}
|
||||
}, ClassReader.SKIP_FRAMES)
|
||||
|
||||
assert(methodNodes.size == 1, { "When mapping ${fieldNode.owner} class should contain only one method but: " + methodNodes.joinToString { it.name } })
|
||||
assert(methodNodes.size == 1) {
|
||||
"When mapping ${fieldNode.owner} class should contain only one method but: " + methodNodes.joinToString { it.name }
|
||||
}
|
||||
val clinit = methodNodes.first()
|
||||
assert(clinit.name == "<clinit>", { "When mapping should contains only <clinit> method, but contains '${clinit.name}'" })
|
||||
|
||||
var transformedClinit = cutOtherMappings(clinit)
|
||||
val transformedClinit = cutOtherMappings(clinit)
|
||||
val result = classBuilder.newMethod(
|
||||
JvmDeclarationOrigin.NO_ORIGIN, transformedClinit.access, transformedClinit.name, transformedClinit.desc,
|
||||
transformedClinit.signature, transformedClinit.exceptions.toTypedArray()
|
||||
@@ -102,7 +105,6 @@ class WhenMappingTransformer(
|
||||
return transformationResult
|
||||
}
|
||||
|
||||
|
||||
private fun cutOtherMappings(node: MethodNode): MethodNode {
|
||||
val myArrayAccess = InsnSequence(node.instructions).first {
|
||||
it is FieldInsnNode && it.name.equals(transformationInfo.fieldNode.name)
|
||||
@@ -123,9 +125,9 @@ class WhenMappingTransformer(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun isValues(node: AbstractInsnNode) = node is MethodInsnNode &&
|
||||
node.opcode == Opcodes.INVOKESTATIC &&
|
||||
node.name == "values" &&
|
||||
node.desc == "()[" + Type.getObjectType(node.owner).descriptor
|
||||
private fun isValues(node: AbstractInsnNode) =
|
||||
node is MethodInsnNode &&
|
||||
node.opcode == Opcodes.INVOKESTATIC &&
|
||||
node.name == "values" &&
|
||||
node.desc == "()[" + Type.getObjectType(node.owner).descriptor
|
||||
}
|
||||
|
||||
|
||||
@@ -22,28 +22,22 @@ import org.jetbrains.kotlin.codegen.StackValue;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
class ParameterInfo {
|
||||
|
||||
protected final int index;
|
||||
|
||||
protected final int declarationIndex;
|
||||
private final int index;
|
||||
public final int declarationIndex;
|
||||
public final Type type;
|
||||
//for skipped parameter: e.g. inlined lambda
|
||||
public final boolean isSkipped;
|
||||
|
||||
private boolean isCaptured;
|
||||
|
||||
public final Type type;
|
||||
|
||||
//for skipped parameter: e.g. inlined lambda
|
||||
public boolean isSkipped;
|
||||
|
||||
private LambdaInfo lambda;
|
||||
//in case when parameter could be extracted from outer context (e.g. from local var)
|
||||
private StackValue remapValue;
|
||||
|
||||
public LambdaInfo lambda;
|
||||
|
||||
ParameterInfo(Type type, boolean skipped, int index, int remapValue, int declarationIndex) {
|
||||
public ParameterInfo(@NotNull Type type, boolean skipped, int index, int remapValue, int declarationIndex) {
|
||||
this(type, skipped, index, remapValue == -1 ? null : StackValue.local(remapValue, type), declarationIndex);
|
||||
}
|
||||
|
||||
ParameterInfo(@NotNull Type type, boolean skipped, int index, @Nullable StackValue remapValue, int declarationIndex) {
|
||||
public ParameterInfo(@NotNull Type type, boolean skipped, int index, @Nullable StackValue remapValue, int declarationIndex) {
|
||||
this.type = type;
|
||||
this.isSkipped = skipped;
|
||||
this.remapValue = remapValue;
|
||||
@@ -52,7 +46,7 @@ class ParameterInfo {
|
||||
}
|
||||
|
||||
public boolean isSkippedOrRemapped() {
|
||||
return isSkipped || remapValue != null;
|
||||
return isSkipped || isRemapped();
|
||||
}
|
||||
|
||||
public boolean isRemapped() {
|
||||
@@ -68,10 +62,6 @@ class ParameterInfo {
|
||||
return index;
|
||||
}
|
||||
|
||||
public boolean isSkipped() {
|
||||
return isSkipped;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getType() {
|
||||
return type;
|
||||
@@ -82,12 +72,14 @@ class ParameterInfo {
|
||||
return lambda;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ParameterInfo setLambda(@Nullable LambdaInfo lambda) {
|
||||
this.lambda = lambda;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParameterInfo setRemapValue(StackValue remapValue) {
|
||||
@NotNull
|
||||
public ParameterInfo setRemapValue(@Nullable StackValue remapValue) {
|
||||
this.remapValue = remapValue;
|
||||
return this;
|
||||
}
|
||||
@@ -96,13 +88,7 @@ class ParameterInfo {
|
||||
return isCaptured;
|
||||
}
|
||||
|
||||
public ParameterInfo setSkipped(boolean skipped) {
|
||||
isSkipped = skipped;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setCaptured(boolean isCaptured) {
|
||||
this.isCaptured = isCaptured;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
|
||||
}
|
||||
}
|
||||
|
||||
fun getDeclarationSlot(info : ParameterInfo): Int {
|
||||
fun getDeclarationSlot(info: ParameterInfo): Int {
|
||||
return paramToDeclByteCodeIndex[info]!!
|
||||
}
|
||||
|
||||
@@ -54,10 +54,7 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
|
||||
}
|
||||
|
||||
private fun get(index: Int): ParameterInfo {
|
||||
if (index < real.size) {
|
||||
return real.get(index)
|
||||
}
|
||||
return captured.get(index - real.size)
|
||||
return real.getOrNull(index) ?: captured[index - real.size]
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<ParameterInfo> {
|
||||
@@ -71,7 +68,7 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
|
||||
|
||||
companion object {
|
||||
fun shift(capturedParams: List<CapturedParamInfo>, realSize: Int): List<CapturedParamInfo> {
|
||||
return capturedParams.withIndex().map { it.value.newIndex(it.index+ realSize) }
|
||||
return capturedParams.withIndex().map { it.value.newIndex(it.index + realSize) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,9 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.lang.Deprecated
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
|
||||
internal class ParametersBuilder private constructor(){
|
||||
import java.util.*
|
||||
|
||||
internal class ParametersBuilder private constructor() {
|
||||
private val valueAndHiddenParams = arrayListOf<ParameterInfo>()
|
||||
private val capturedParams = arrayListOf<CapturedParamInfo>()
|
||||
private var valueParamStart = 0
|
||||
@@ -40,51 +36,46 @@ internal class ParametersBuilder private constructor(){
|
||||
return info
|
||||
}
|
||||
|
||||
fun addNextParameter(type: Type, skipped: Boolean, remapValue: StackValue?): ParameterInfo {
|
||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size))
|
||||
fun addNextParameter(type: Type, skipped: Boolean): ParameterInfo {
|
||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, null, valueAndHiddenParams.size))
|
||||
}
|
||||
|
||||
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
|
||||
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue,
|
||||
if (parameterIndex == -1) valueAndHiddenParams.size else { parameterIndex + valueParamStart }))
|
||||
return addParameter(ParameterInfo(
|
||||
type, skipped, nextValueParameterIndex, remapValue,
|
||||
if (parameterIndex == -1) valueAndHiddenParams.size else parameterIndex + valueParamStart
|
||||
))
|
||||
}
|
||||
|
||||
fun addCapturedParam(
|
||||
original: CapturedParamInfo,
|
||||
newFieldName: String): CapturedParamInfo {
|
||||
val info = CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCapturedIndex(), original.getIndex())
|
||||
info.setLambda(original.getLambda())
|
||||
fun addCapturedParam(original: CapturedParamInfo, newFieldName: String): CapturedParamInfo {
|
||||
val info = CapturedParamInfo(original.desc, newFieldName, original.isSkipped, nextCapturedIndex(), original.index)
|
||||
info.lambda = original.lambda
|
||||
return addCapturedParameter(info)
|
||||
}
|
||||
|
||||
private fun nextCapturedIndex(): Int {
|
||||
return nextCaptured
|
||||
private fun nextCapturedIndex(): Int = nextCaptured
|
||||
|
||||
fun addCapturedParam(desc: CapturedParamDesc, newFieldName: String, skipInConstructor: Boolean): CapturedParamInfo {
|
||||
return addCapturedParameter(CapturedParamInfo(desc, newFieldName, false, nextCapturedIndex(), null, skipInConstructor))
|
||||
}
|
||||
|
||||
fun addCapturedParamCopy(copyFrom: CapturedParamInfo): CapturedParamInfo {
|
||||
return addCapturedParameter(copyFrom.newIndex(nextCapturedIndex()))
|
||||
}
|
||||
|
||||
fun addCapturedParam(
|
||||
desc: CapturedParamDesc,
|
||||
newFieldName: String): CapturedParamInfo {
|
||||
val info = CapturedParamInfo(desc, newFieldName, false, nextCapturedIndex(), null)
|
||||
return addCapturedParameter(info)
|
||||
}
|
||||
|
||||
fun addCapturedParamCopy(
|
||||
copyFrom: CapturedParamInfo): CapturedParamInfo {
|
||||
val info = copyFrom.newIndex(nextCapturedIndex())
|
||||
return addCapturedParameter(info)
|
||||
}
|
||||
|
||||
fun addCapturedParam(
|
||||
containingLambda: CapturedParamOwner,
|
||||
containingLambdaType: Type,
|
||||
fieldName: String,
|
||||
newFieldName: String,
|
||||
type: Type,
|
||||
skipped: Boolean,
|
||||
original: ParameterInfo?): CapturedParamInfo {
|
||||
val info = CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), newFieldName, skipped, nextCapturedIndex(),
|
||||
if (original != null) original.getIndex() else -1)
|
||||
original: ParameterInfo?
|
||||
): CapturedParamInfo {
|
||||
val info = CapturedParamInfo(
|
||||
CapturedParamDesc(containingLambdaType, fieldName, type), newFieldName, skipped, nextCapturedIndex(), original?.index ?: -1
|
||||
)
|
||||
if (original != null) {
|
||||
info.setLambda(original.getLambda())
|
||||
info.lambda = original.lambda
|
||||
}
|
||||
return addCapturedParameter(info)
|
||||
}
|
||||
@@ -101,7 +92,7 @@ internal class ParametersBuilder private constructor(){
|
||||
return info
|
||||
}
|
||||
|
||||
fun markValueParametesStart(){
|
||||
fun markValueParametersStart() {
|
||||
this.valueParamStart = valueAndHiddenParams.size
|
||||
}
|
||||
|
||||
@@ -119,23 +110,24 @@ internal class ParametersBuilder private constructor(){
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun newBuilder(): ParametersBuilder {
|
||||
return ParametersBuilder()
|
||||
}
|
||||
|
||||
@JvmOverloads @JvmStatic
|
||||
fun initializeBuilderFrom(objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null, addThis: Boolean = true): ParametersBuilder {
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
fun initializeBuilderFrom(
|
||||
objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null, addThis: Boolean = true
|
||||
): ParametersBuilder {
|
||||
val builder = newBuilder()
|
||||
if (addThis) {
|
||||
//skipped this for inlined lambda cause it will be removed
|
||||
builder.addThis(objectType, inlineLambda != null).setLambda(inlineLambda)
|
||||
builder.addThis(objectType, inlineLambda != null).lambda = inlineLambda
|
||||
}
|
||||
|
||||
val types = Type.getArgumentTypes(descriptor)
|
||||
for (type in types) {
|
||||
builder.addNextParameter(type, false, null)
|
||||
for (type in Type.getArgumentTypes(descriptor)) {
|
||||
builder.addNextParameter(type, false)
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import java.util.Map;
|
||||
|
||||
public class RegeneratedClassContext extends InliningContext {
|
||||
private InlineCallSiteInfo callSiteInfo;
|
||||
private final InlineCallSiteInfo callSiteInfo;
|
||||
|
||||
public RegeneratedClassContext(
|
||||
@Nullable InliningContext parent,
|
||||
@@ -39,6 +39,8 @@ public class RegeneratedClassContext extends InliningContext {
|
||||
this.callSiteInfo = callSiteInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InlineCallSiteInfo getCallSiteInfo() {
|
||||
return callSiteInfo;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
private final boolean isConstructor;
|
||||
|
||||
public RegeneratedLambdaFieldRemapper(
|
||||
String oldOwnerType,
|
||||
String newOwnerType,
|
||||
Parameters parameters,
|
||||
Map<String, LambdaInfo> recapturedLambdas,
|
||||
FieldRemapper remapper,
|
||||
@NotNull String oldOwnerType,
|
||||
@NotNull String newOwnerType,
|
||||
@NotNull Parameters parameters,
|
||||
@NotNull Map<String, LambdaInfo> recapturedLambdas,
|
||||
@NotNull FieldRemapper remapper,
|
||||
boolean isConstructor
|
||||
) {
|
||||
super(oldOwnerType, remapper, parameters);
|
||||
@@ -50,12 +50,12 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) {
|
||||
public boolean canProcess(@NotNull String fieldOwner, @NotNull String fieldName, boolean isFolding) {
|
||||
return super.canProcess(fieldOwner, fieldName, isFolding) || isRecapturedLambdaType(fieldOwner, isFolding);
|
||||
}
|
||||
|
||||
private boolean isRecapturedLambdaType(String owner, boolean isFolding) {
|
||||
return recapturedLambdas.containsKey(owner) && (isFolding || false == parent instanceof InlinedLambdaRemapper);
|
||||
private boolean isRecapturedLambdaType(@NotNull String owner, boolean isFolding) {
|
||||
return recapturedLambdas.containsKey(owner) && (isFolding || !(parent instanceof InlinedLambdaRemapper));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -64,9 +64,8 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
boolean searchInParent = !canProcess(fieldInsnNode.owner, fieldInsnNode.name, false);
|
||||
if (searchInParent) {
|
||||
return parent.findField(fieldInsnNode);
|
||||
} else {
|
||||
return findFieldInMyCaptured(fieldInsnNode);
|
||||
}
|
||||
return findFieldInMyCaptured(fieldInsnNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,10 +74,11 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CapturedParamInfo findFieldInMyCaptured(@NotNull FieldInsnNode fieldInsnNode) {
|
||||
private CapturedParamInfo findFieldInMyCaptured(@NotNull FieldInsnNode fieldInsnNode) {
|
||||
return super.findField(fieldInsnNode, parameters.getCaptured());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getNewLambdaInternalName() {
|
||||
return newOwnerType;
|
||||
@@ -98,18 +98,23 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
|
||||
boolean searchInParent = false;
|
||||
if (field == null) {
|
||||
field = findFieldInMyCaptured(new FieldInsnNode(Opcodes.GETSTATIC, oldOwnerType, "this$0", Type.getObjectType(parent.getLambdaInternalName()).getDescriptor()));
|
||||
field = findFieldInMyCaptured(new FieldInsnNode(
|
||||
Opcodes.GETSTATIC, oldOwnerType, InlineCodegenUtil.THIS$0,
|
||||
Type.getObjectType(parent.getLambdaInternalName()).getDescriptor()
|
||||
));
|
||||
searchInParent = true;
|
||||
if (field == null) {
|
||||
throw new IllegalStateException("Couldn't find captured this " + getLambdaInternalName() + " for " + node.name);
|
||||
}
|
||||
}
|
||||
|
||||
StackValue result = StackValue.field(field.isSkipped ?
|
||||
Type.getObjectType(parent.parent.getNewLambdaInternalName()) : field.getType(),
|
||||
Type.getObjectType(getNewLambdaInternalName()), /*TODO owner type*/
|
||||
field.getNewFieldName(), false,
|
||||
prefix == null ? StackValue.LOCAL_0 : prefix);
|
||||
StackValue result = StackValue.field(
|
||||
field.isSkipped ?
|
||||
Type.getObjectType(parent.parent.getNewLambdaInternalName()) : field.getType(),
|
||||
Type.getObjectType(getNewLambdaInternalName()), /*TODO owner type*/
|
||||
field.getNewFieldName(), false,
|
||||
prefix == null ? StackValue.LOCAL_0 : prefix
|
||||
);
|
||||
|
||||
return searchInParent ? parent.getFieldForInline(node, result) : result;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ class ReificationArgument(
|
||||
ReificationArgument(
|
||||
replacement.parameterName,
|
||||
this.nullable || (replacement.nullable && this.arrayDepth == 0),
|
||||
this.arrayDepth + replacement.arrayDepth)
|
||||
this.arrayDepth + replacement.arrayDepth
|
||||
)
|
||||
|
||||
fun reify(replacementAsmType: Type, kotlinType: KotlinType) =
|
||||
Pair(Type.getType("[".repeat(arrayDepth) + replacementAsmType), kotlinType.arrayOf(arrayDepth).makeNullableIfNeeded(nullable))
|
||||
@@ -57,7 +58,6 @@ class ReificationArgument(
|
||||
}
|
||||
|
||||
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) {
|
||||
|
||||
enum class OperationKind {
|
||||
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
|
||||
|
||||
@@ -65,8 +65,8 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||
@JvmField val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||
|
||||
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
|
||||
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
|
||||
@@ -76,10 +76,12 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
return insn.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && namePredicate(insn.name)
|
||||
}
|
||||
|
||||
@JvmStatic fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
|
||||
@JvmStatic
|
||||
fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
|
||||
isReifiedMarker(insn) { s -> s == NEED_CLASS_REIFICATION_MARKER_METHOD_NAME }
|
||||
|
||||
@JvmStatic fun putNeedClassReificationMarker(v: MethodVisitor) {
|
||||
@JvmStatic
|
||||
fun putNeedClassReificationMarker(v: MethodVisitor) {
|
||||
v.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, NEED_CLASS_REIFICATION_MARKER_METHOD_NAME,
|
||||
@@ -102,7 +104,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
|
||||
val instructions = node.instructions
|
||||
maxStackSize = 0
|
||||
var result = ReifiedTypeParametersUsages()
|
||||
val result = ReifiedTypeParametersUsages()
|
||||
for (insn in instructions.toArray()) {
|
||||
if (isOperationReifiedMarker(insn)) {
|
||||
val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions)
|
||||
@@ -144,7 +146,8 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
}
|
||||
|
||||
return null
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
val newReificationArgument = reificationArgument.combine(mapping.reificationArgument!!)
|
||||
instructions.set(insn.previous!!, LdcInsnNode(newReificationArgument.asString()))
|
||||
return mapping.reificationArgument.parameterName
|
||||
@@ -154,43 +157,45 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
||||
|
||||
private fun processAs(insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
safe: Boolean) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
|
||||
if (stubCheckcast !is TypeInsnNode) return false
|
||||
private fun processAs(
|
||||
insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
safe: Boolean
|
||||
) = rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
|
||||
if (stubCheckcast !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
|
||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubCheckcast)
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubCheckcast)
|
||||
|
||||
// TODO: refine max stack calculation (it's not always as big as +4)
|
||||
maxStackSize = Math.max(maxStackSize, 4)
|
||||
// TODO: refine max stack calculation (it's not always as big as +4)
|
||||
maxStackSize = Math.max(maxStackSize, 4)
|
||||
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun processIs(insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type) =
|
||||
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
|
||||
if (stubInstanceOf !is TypeInsnNode) return false
|
||||
private fun processIs(
|
||||
insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type
|
||||
) = rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
|
||||
if (stubInstanceOf !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
||||
val newMethodNode = MethodNode(InlineCodegenUtil.API)
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubInstanceOf)
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubInstanceOf)
|
||||
|
||||
// TODO: refine max stack calculation (it's not always as big as +2)
|
||||
maxStackSize = Math.max(maxStackSize, 2)
|
||||
return true
|
||||
}
|
||||
// TODO: refine max stack calculation (it's not always as big as +2)
|
||||
maxStackSize = Math.max(maxStackSize, 2)
|
||||
return true
|
||||
}
|
||||
|
||||
inline private fun rewriteNextTypeInsn(
|
||||
marker: MethodInsnNode,
|
||||
@@ -214,7 +219,6 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
next.cst = parameter
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val MethodInsnNode.reificationArgument: ReificationArgument?
|
||||
@@ -242,16 +246,18 @@ class TypeParameterMappings() {
|
||||
private val mappingsByName = hashMapOf<String, TypeParameterMapping>()
|
||||
|
||||
fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String, isReified: Boolean) {
|
||||
mappingsByName[name] = TypeParameterMapping(name, type, asmType, reificationArgument = null, signature = signature, isReified = isReified)
|
||||
mappingsByName[name] = TypeParameterMapping(
|
||||
name, type, asmType, reificationArgument = null, signature = signature, isReified = isReified
|
||||
)
|
||||
}
|
||||
|
||||
fun addParameterMappingForFurtherReification(name: String, type: KotlinType, reificationArgument: ReificationArgument, isReified: Boolean) {
|
||||
mappingsByName[name] = TypeParameterMapping(name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified)
|
||||
mappingsByName[name] = TypeParameterMapping(
|
||||
name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified
|
||||
)
|
||||
}
|
||||
|
||||
operator fun get(name: String): TypeParameterMapping? {
|
||||
return mappingsByName[name]
|
||||
}
|
||||
operator fun get(name: String): TypeParameterMapping? = mappingsByName[name]
|
||||
|
||||
fun hasReifiedParameters() = mappingsByName.values.any { it.isReified }
|
||||
|
||||
@@ -261,7 +267,8 @@ class TypeParameterMappings() {
|
||||
}
|
||||
|
||||
class TypeParameterMapping(
|
||||
val name: String, val type: KotlinType,
|
||||
val name: String,
|
||||
val type: KotlinType,
|
||||
val asmType: Type?,
|
||||
val reificationArgument: ReificationArgument?,
|
||||
val signature: String?,
|
||||
|
||||
@@ -28,14 +28,14 @@ public class RemapVisitor extends MethodBodyVisitor {
|
||||
private final FieldRemapper nodeRemapper;
|
||||
private final InstructionAdapter instructionAdapter;
|
||||
|
||||
protected RemapVisitor(
|
||||
MethodVisitor mv,
|
||||
LocalVarRemapper localVarRemapper,
|
||||
FieldRemapper nodeRemapper
|
||||
public RemapVisitor(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull LocalVarRemapper remapper,
|
||||
@NotNull FieldRemapper nodeRemapper
|
||||
) {
|
||||
super(mv);
|
||||
this.instructionAdapter = new InstructionAdapter(mv);
|
||||
this.remapper = localVarRemapper;
|
||||
this.remapper = remapper;
|
||||
this.nodeRemapper = nodeRemapper;
|
||||
}
|
||||
|
||||
@@ -58,19 +58,13 @@ public class RemapVisitor extends MethodBodyVisitor {
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, @NotNull String owner, @NotNull String name, @NotNull String desc) {
|
||||
if (name.startsWith("$$$")) {
|
||||
if (nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot()) {
|
||||
FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
|
||||
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
|
||||
assert inline != null : "Captured field should have not null stackValue " + fin;
|
||||
inline.put(inline.type, this);
|
||||
}
|
||||
else {
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
if (name.startsWith("$$$") && (nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot())) {
|
||||
FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
|
||||
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
|
||||
assert inline != null : "Captured field should have not null stackValue " + fin;
|
||||
inline.put(inline.type, this);
|
||||
return;
|
||||
}
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.psi.KtElement;
|
||||
import java.util.Map;
|
||||
|
||||
public class RootInliningContext extends InliningContext {
|
||||
public final CodegenContext startContext;
|
||||
private final InlineCallSiteInfo inlineCallSiteInfo;
|
||||
public final TypeParameterMappings typeParameterMappings;
|
||||
public final KtElement callElement;
|
||||
@@ -34,7 +33,6 @@ public class RootInliningContext extends InliningContext {
|
||||
@NotNull Map<Integer, LambdaInfo> map,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull CodegenContext startContext,
|
||||
@NotNull KtElement callElement,
|
||||
@NotNull InlineCallSiteInfo classNameToInline,
|
||||
@NotNull ReifiedTypeInliner inliner,
|
||||
@@ -42,11 +40,11 @@ public class RootInliningContext extends InliningContext {
|
||||
) {
|
||||
super(null, map, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), inliner, false, false);
|
||||
this.callElement = callElement;
|
||||
this.startContext = startContext;
|
||||
this.inlineCallSiteInfo = classNameToInline;
|
||||
this.typeParameterMappings = typeParameterMappings;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public InlineCallSiteInfo getCallSiteInfo() {
|
||||
return inlineCallSiteInfo;
|
||||
|
||||
@@ -55,7 +55,9 @@ class SMAPBuilder(
|
||||
val combinedMapping = FileMapping(source, path)
|
||||
realMappings.forEach { fileMapping ->
|
||||
fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { rangeMapping ->
|
||||
combinedMapping.addRangeMapping(RangeMapping(rangeMapping.callSiteMarker!!.lineNumber, rangeMapping.dest, rangeMapping.range))
|
||||
combinedMapping.addRangeMapping(RangeMapping(
|
||||
rangeMapping.callSiteMarker!!.lineNumber, rangeMapping.dest, rangeMapping.range
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +97,11 @@ open class NestedSourceMapper(
|
||||
|
||||
if (mappedLineNumber > 0) {
|
||||
return mappedLineNumber
|
||||
} else {
|
||||
val rangeForMapping = (if (lastVisitedRange?.contains(lineNumber) ?: false) lastVisitedRange!! else findMappingIfExists(lineNumber))
|
||||
?: error("Can't find range to map line $lineNumber in ${sourceInfo.source}:${sourceInfo.pathOrCleanFQN}")
|
||||
}
|
||||
else {
|
||||
val rangeForMapping =
|
||||
(if (lastVisitedRange?.contains(lineNumber) ?: false) lastVisitedRange!! else findMappingIfExists(lineNumber))
|
||||
?: error("Can't find range to map line $lineNumber in ${sourceInfo.source}: ${sourceInfo.pathOrCleanFQN}")
|
||||
val sourceLineNumber = rangeForMapping.mapDestToSource(lineNumber)
|
||||
val newLineNumber = parent.mapLineNumber(sourceLineNumber, rangeForMapping.parent!!.name, rangeForMapping.parent!!.path)
|
||||
if (newLineNumber > 0) {
|
||||
@@ -132,9 +136,7 @@ open class InlineLambdaSourceMapper(
|
||||
//don't remap origin lambda line numbers
|
||||
return lineNumber
|
||||
}
|
||||
else {
|
||||
return super.mapLineNumber(lineNumber)
|
||||
}
|
||||
return super.mapLineNumber(lineNumber)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +154,6 @@ interface SourceMapper {
|
||||
}
|
||||
|
||||
fun endMapping() {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -179,11 +180,8 @@ object IdenticalSourceMapper : SourceMapper {
|
||||
class CallSiteMarker(val lineNumber: Int)
|
||||
|
||||
open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
||||
|
||||
private var maxUsedValue: Int = sourceInfo.linesInFile
|
||||
|
||||
private var lastMappedWithChanges: RawFileMapping? = null
|
||||
|
||||
private var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
|
||||
|
||||
protected val origin: RawFileMapping
|
||||
@@ -197,7 +195,6 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
||||
override val resultMappings: List<FileMapping>
|
||||
get() = fileMappings.values.map { it.toFileMapping() }
|
||||
|
||||
|
||||
init {
|
||||
val name = sourceInfo.source
|
||||
val path = sourceInfo.pathOrCleanFQN
|
||||
@@ -206,8 +203,8 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
||||
fileMappings.put(createKey(name, path), origin)
|
||||
}
|
||||
|
||||
constructor(sourceInfo: SourceInfo, fileMappings: List<FileMapping>): this(sourceInfo) {
|
||||
fileMappings.asSequence().drop(1)
|
||||
constructor(sourceInfo: SourceInfo, fileMappings: List<FileMapping>) : this(sourceInfo) {
|
||||
fileMappings.asSequence().drop(1)
|
||||
//default one mapped through sourceInfo
|
||||
.forEach { fileMapping ->
|
||||
val newFileMapping = getOrRegisterNewSource(fileMapping.name, fileMapping.path)
|
||||
@@ -227,7 +224,7 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
||||
override fun mapLineNumber(lineNumber: Int): Int {
|
||||
if (lineNumber < 0) {
|
||||
//no source information, so just skip this linenumber
|
||||
return - 1
|
||||
return -1
|
||||
}
|
||||
//TODO maybe add assertion that linenumber contained in fileMappings
|
||||
return lineNumber
|
||||
@@ -238,8 +235,7 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
||||
//no source information, so just skip this linenumber
|
||||
return -1
|
||||
}
|
||||
val mappedLineIndex = createMapping(getOrRegisterNewSource(sourceName, sourcePath), source)
|
||||
return mappedLineIndex
|
||||
return createMapping(getOrRegisterNewSource(sourceName, sourcePath), source)
|
||||
}
|
||||
|
||||
private fun createMapping(fileMapping: RawFileMapping, lineNumber: Int): Int {
|
||||
@@ -263,6 +259,7 @@ class SMAP(val fileMappings: List<FileMapping>) {
|
||||
val intervals = fileMappings.flatMap { it.lineMappings }.sortedWith(RangeMapping.Comparator)
|
||||
|
||||
val sourceInfo: SourceInfo
|
||||
|
||||
init {
|
||||
val defaultMapping = default.lineMappings.first()
|
||||
sourceInfo = SourceInfo(default.name, default.path, defaultMapping.source + defaultMapping.range - 1)
|
||||
@@ -349,7 +346,7 @@ data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1, var
|
||||
get() = dest + range - 1
|
||||
|
||||
operator fun contains(destLine: Int): Boolean {
|
||||
return if (skip) true else dest <= destLine && destLine < dest + range
|
||||
return skip || (dest <= destLine && destLine < dest + range)
|
||||
}
|
||||
|
||||
fun mapDestToSource(destLine: Int): Int {
|
||||
@@ -365,12 +362,7 @@ data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1, var
|
||||
if (o1 == o2) return 0
|
||||
|
||||
val res = o1.dest - o2.dest
|
||||
if (res == 0) {
|
||||
return o1.range - o2.range
|
||||
}
|
||||
else {
|
||||
return res
|
||||
}
|
||||
return if (res == 0) o1.range - o2.range else res
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ object SMAPParser {
|
||||
/*only simple mapping now*/
|
||||
val targetSplit = lineMapping.indexOf(':')
|
||||
val originalPart = lineMapping.substring(0, targetSplit)
|
||||
var rangeSeparator = originalPart.indexOf(',').let { if (it < 0) targetSplit else it }
|
||||
val rangeSeparator = originalPart.indexOf(',').let { if (it < 0) targetSplit else it }
|
||||
|
||||
val fileSeparator = lineMapping.indexOf('#')
|
||||
val originalIndex = originalPart.substring(0, fileSeparator).toInt()
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
import java.util.*
|
||||
|
||||
interface TransformationInfo {
|
||||
|
||||
val oldClassName: String
|
||||
|
||||
val newClassName: String
|
||||
@@ -29,10 +27,7 @@ interface TransformationInfo {
|
||||
|
||||
fun canRemoveAfterTransformation(): Boolean
|
||||
|
||||
fun createTransformer(
|
||||
inliningContext: InliningContext,
|
||||
sameModule: Boolean
|
||||
): ObjectTransformer<*>
|
||||
fun createTransformer(inliningContext: InliningContext, sameModule: Boolean): ObjectTransformer<*>
|
||||
}
|
||||
|
||||
class WhenMappingTransformationInfo(
|
||||
@@ -41,22 +36,17 @@ class WhenMappingTransformationInfo(
|
||||
val alreadyRegenerated: Boolean,
|
||||
val fieldNode: FieldInsnNode
|
||||
) : TransformationInfo {
|
||||
|
||||
override val newClassName by lazy {
|
||||
nameGenerator.genWhenClassNamePrefix() + TRANSFORMED_WHEN_MAPPING_MARKER + oldClassName.substringAfterLast("/").substringAfterLast(TRANSFORMED_WHEN_MAPPING_MARKER)
|
||||
nameGenerator.genWhenClassNamePrefix() + TRANSFORMED_WHEN_MAPPING_MARKER +
|
||||
oldClassName.substringAfterLast("/").substringAfterLast(TRANSFORMED_WHEN_MAPPING_MARKER)
|
||||
}
|
||||
|
||||
override fun shouldRegenerate(sameModule: Boolean): Boolean {
|
||||
return !alreadyRegenerated && !sameModule
|
||||
}
|
||||
override fun shouldRegenerate(sameModule: Boolean): Boolean = !alreadyRegenerated && !sameModule
|
||||
|
||||
override fun canRemoveAfterTransformation(): Boolean {
|
||||
return true
|
||||
}
|
||||
override fun canRemoveAfterTransformation(): Boolean = true
|
||||
|
||||
override fun createTransformer(inliningContext: InliningContext, sameModule: Boolean): ObjectTransformer<*> {
|
||||
return WhenMappingTransformer(this, inliningContext)
|
||||
}
|
||||
override fun createTransformer(inliningContext: InliningContext, sameModule: Boolean): ObjectTransformer<*> =
|
||||
WhenMappingTransformer(this, inliningContext)
|
||||
|
||||
companion object {
|
||||
const val TRANSFORMED_WHEN_MAPPING_MARKER = "\$wm$"
|
||||
@@ -71,8 +61,8 @@ class AnonymousObjectTransformationInfo internal constructor(
|
||||
private val alreadyRegenerated: Boolean,
|
||||
val constructorDesc: String?,
|
||||
private val isStaticOrigin: Boolean,
|
||||
nameGenerator: NameGenerator) : TransformationInfo {
|
||||
|
||||
nameGenerator: NameGenerator
|
||||
) : TransformationInfo {
|
||||
override val newClassName: String by lazy {
|
||||
nameGenerator.genLambdaClassName()
|
||||
}
|
||||
@@ -89,14 +79,10 @@ class AnonymousObjectTransformationInfo internal constructor(
|
||||
alreadyRegenerated: Boolean,
|
||||
isStaticOrigin: Boolean,
|
||||
nameGenerator: NameGenerator
|
||||
) : this(
|
||||
ownerInternalName, needReification,
|
||||
HashMap<Int, LambdaInfo>(), false, alreadyRegenerated, null, isStaticOrigin, nameGenerator) {
|
||||
}
|
||||
) : this(ownerInternalName, needReification, hashMapOf(), false, alreadyRegenerated, null, isStaticOrigin, nameGenerator)
|
||||
|
||||
override fun shouldRegenerate(sameModule: Boolean): Boolean {
|
||||
return !alreadyRegenerated && (!lambdasToInline.isEmpty() || !sameModule || capturedOuterRegenerated || needReification)
|
||||
}
|
||||
override fun shouldRegenerate(sameModule: Boolean): Boolean =
|
||||
!alreadyRegenerated && (!lambdasToInline.isEmpty() || !sameModule || capturedOuterRegenerated || needReification)
|
||||
|
||||
override fun canRemoveAfterTransformation(): Boolean {
|
||||
// Note: It is unsafe to remove anonymous class that is referenced by GETSTATIC within lambda
|
||||
@@ -104,7 +90,6 @@ class AnonymousObjectTransformationInfo internal constructor(
|
||||
return !isStaticOrigin
|
||||
}
|
||||
|
||||
override fun createTransformer(inliningContext: InliningContext, sameModule: Boolean): ObjectTransformer<*> {
|
||||
return AnonymousObjectTransformer(this, inliningContext, sameModule);
|
||||
}
|
||||
override fun createTransformer(inliningContext: InliningContext, sameModule: Boolean): ObjectTransformer<*> =
|
||||
AnonymousObjectTransformer(this, inliningContext, sameModule)
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.firstLabelInChain
|
||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode
|
||||
|
||||
enum class TryCatchPosition {
|
||||
START,
|
||||
@@ -26,9 +26,9 @@ enum class TryCatchPosition {
|
||||
INNER
|
||||
}
|
||||
|
||||
class SplitPair<T: Interval>(val patchedPart: T, val newPart: T)
|
||||
class SplitPair<out T : Interval>(val patchedPart: T, val newPart: T)
|
||||
|
||||
class SimpleInterval(override val startLabel: LabelNode, override val endLabel: LabelNode ) : Interval
|
||||
class SimpleInterval(override val startLabel: LabelNode, override val endLabel: LabelNode) : Interval
|
||||
|
||||
interface Interval {
|
||||
val startLabel: LabelNode
|
||||
@@ -36,20 +36,21 @@ interface Interval {
|
||||
|
||||
/*note that some intervals are mutable */
|
||||
fun isEmpty(): Boolean = startLabel == endLabel
|
||||
|
||||
}
|
||||
|
||||
interface SplittableInterval<T: Interval> : Interval {
|
||||
interface SplittableInterval<out T : Interval> : Interval {
|
||||
fun split(splitBy: Interval, keepStart: Boolean): SplitPair<T>
|
||||
}
|
||||
|
||||
|
||||
interface IntervalWithHandler : Interval {
|
||||
val handler: LabelNode
|
||||
val type: String?
|
||||
}
|
||||
|
||||
class TryCatchBlockNodeInfo(val node: TryCatchBlockNode, val onlyCopyNotProcess: Boolean) : IntervalWithHandler, SplittableInterval<TryCatchBlockNodeInfo> {
|
||||
class TryCatchBlockNodeInfo(
|
||||
val node: TryCatchBlockNode,
|
||||
val onlyCopyNotProcess: Boolean
|
||||
) : IntervalWithHandler, SplittableInterval<TryCatchBlockNodeInfo> {
|
||||
override val startLabel: LabelNode
|
||||
get() = node.start
|
||||
override val endLabel: LabelNode
|
||||
@@ -77,16 +78,16 @@ class TryCatchBlockNodeInfo(val node: TryCatchBlockNode, val onlyCopyNotProcess:
|
||||
}
|
||||
}
|
||||
|
||||
class TryCatchBlockNodePosition(val nodeInfo: TryCatchBlockNodeInfo, var position: TryCatchPosition) : IntervalWithHandler by nodeInfo {
|
||||
|
||||
}
|
||||
class TryCatchBlockNodePosition(
|
||||
val nodeInfo: TryCatchBlockNodeInfo,
|
||||
var position: TryCatchPosition
|
||||
) : IntervalWithHandler by nodeInfo
|
||||
|
||||
class TryBlockCluster<T : IntervalWithHandler>(val blocks: MutableList<T>) {
|
||||
val defaultHandler: T?
|
||||
get() = blocks.firstOrNull() { it.type == null }
|
||||
}
|
||||
|
||||
|
||||
fun <T : IntervalWithHandler> doClustering(blocks: List<T>): List<TryBlockCluster<T>> {
|
||||
data class TryBlockInterval(val startLabel: LabelNode, val endLabel: LabelNode)
|
||||
|
||||
|
||||
@@ -16,16 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
|
||||
class TypeParameter(val oldName: String, val newName: String?, val isReified: Boolean, val signature: String?)
|
||||
class TypeParameter(val oldName: String, val newName: String?, val isReified: Boolean, val signature: String?)
|
||||
|
||||
//typeMapping data could be changed outside through method processing
|
||||
class TypeRemapper private constructor(private val typeMapping: MutableMap<String, String>, val parent: TypeRemapper?, val isInlineLambda: Boolean = false) {
|
||||
|
||||
class TypeRemapper private constructor(
|
||||
private val typeMapping: MutableMap<String, String>,
|
||||
val parent: TypeRemapper?,
|
||||
val isInlineLambda: Boolean = false
|
||||
) {
|
||||
private var additionalMappings: MutableMap<String, String> = hashMapOf()
|
||||
|
||||
|
||||
private val typeParametersMapping: MutableMap<String, TypeParameter> = hashMapOf()
|
||||
|
||||
fun addMapping(type: String, newType: String) {
|
||||
@@ -37,11 +38,11 @@ class TypeRemapper private constructor(private val typeMapping: MutableMap<Strin
|
||||
}
|
||||
|
||||
fun map(type: String): String {
|
||||
return typeMapping[type] ?: additionalMappings?.get(type) ?: type
|
||||
return typeMapping[type] ?: additionalMappings[type] ?: type
|
||||
}
|
||||
|
||||
fun addAdditionalMappings(oldName: String, newName: String) {
|
||||
additionalMappings!!.put(oldName, newName)
|
||||
additionalMappings[oldName] = newName
|
||||
}
|
||||
|
||||
fun registerTypeParameter(name: String) {
|
||||
@@ -52,7 +53,9 @@ class TypeRemapper private constructor(private val typeMapping: MutableMap<Strin
|
||||
}
|
||||
|
||||
fun registerTypeParameter(mapping: TypeParameterMapping) {
|
||||
typeParametersMapping[mapping.name] = TypeParameter(mapping.name, mapping.reificationArgument?.parameterName, mapping.isReified, mapping.signature)
|
||||
typeParametersMapping[mapping.name] = TypeParameter(
|
||||
mapping.name, mapping.reificationArgument?.parameterName, mapping.isReified, mapping.signature
|
||||
)
|
||||
}
|
||||
|
||||
fun mapTypeParameter(name: String): TypeParameter? {
|
||||
@@ -60,14 +63,13 @@ class TypeRemapper private constructor(private val typeMapping: MutableMap<Strin
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun createRoot(formalTypeParameters: TypeParameterMappings?): TypeRemapper {
|
||||
val typeRemapper = TypeRemapper(HashMap<String, String>(), null)
|
||||
formalTypeParameters?.forEach {
|
||||
typeRemapper.registerTypeParameter(it)
|
||||
return TypeRemapper(HashMap<String, String>(), null).apply {
|
||||
formalTypeParameters?.forEach {
|
||||
registerTypeParameter(it)
|
||||
}
|
||||
}
|
||||
return typeRemapper
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@@ -82,9 +84,9 @@ class TypeRemapper private constructor(private val typeMapping: MutableMap<Strin
|
||||
}
|
||||
|
||||
private fun createNewAndMerge(remapper: TypeRemapper, additionalTypeMappings: Map<String, String>): MutableMap<String, String> {
|
||||
val map = HashMap(remapper.typeMapping)
|
||||
map += additionalTypeMappings
|
||||
return map
|
||||
return HashMap(remapper.typeMapping).apply {
|
||||
this += additionalTypeMappings
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ public class IntrinsicMethods {
|
||||
public IntrinsicMethods() {
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, new JavaClassProperty());
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.kClass, "java", -1, new KClassJavaProperty());
|
||||
intrinsicsMap.registerIntrinsic(KotlinBuiltIns.FQ_NAMES.kCallable.toSafe(), null, "name", -1, new KCallableNameProperty());
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorEnter", 1, MonitorInstruction.MONITOR_ENTER);
|
||||
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorExit", 1, MonitorInstruction.MONITOR_EXIT);
|
||||
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.array, "isArrayOf", 0, new IsArrayOf());
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class KCallableNameProperty : IntrinsicPropertyGetter() {
|
||||
override fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? {
|
||||
val expressionReceiver = resolvedCall!!.dispatchReceiver as? ExpressionReceiver ?: return null
|
||||
val expression = expressionReceiver.expression as? KtCallableReferenceExpression ?: return null
|
||||
val callableReference = expression.callableReference
|
||||
val descriptor = callableReference.getResolvedCall(codegen.bindingContext)?.resultingDescriptor ?: return null
|
||||
val name = descriptor.name.asString()
|
||||
|
||||
return StackValue.operation(returnType) { iv ->
|
||||
iv.aconst(name)
|
||||
StackValue.coerce(AsmTypes.JAVA_STRING_TYPE, returnType, iv)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user