mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-13 00:21:28 +00:00
Compare commits
1018 Commits
build-1.4.
...
igotti/com
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31e9b6d904 | ||
|
|
f45ba79a16 | ||
|
|
75a3808230 | ||
|
|
4b9c7a1ae1 | ||
|
|
d6ccdb3caa | ||
|
|
6e40117116 | ||
|
|
ad988dbf43 | ||
|
|
23ed6c4a1f | ||
|
|
ec01893237 | ||
|
|
d4f57fb835 | ||
|
|
9eeee6aad7 | ||
|
|
54e7c79257 | ||
|
|
c7f5a2cba2 | ||
|
|
a332a5f26d | ||
|
|
7ee125e1ad | ||
|
|
c12fb1e069 | ||
|
|
6d4eb9ae52 | ||
|
|
9b68e4fe56 | ||
|
|
390d062721 | ||
|
|
b360fb5119 | ||
|
|
29566723b8 | ||
|
|
9016a573ca | ||
|
|
208c7274dd | ||
|
|
c0cd010b7d | ||
|
|
01c4e66edb | ||
|
|
51749b9747 | ||
|
|
ed83e3ccef | ||
|
|
7e6d080123 | ||
|
|
ecb7478794 | ||
|
|
08dc03a704 | ||
|
|
096ff0e8a9 | ||
|
|
d1a8f57740 | ||
|
|
e6885323da | ||
|
|
22de20e7e5 | ||
|
|
42420cb6fc | ||
|
|
536e0e23a0 | ||
|
|
91ee63432a | ||
|
|
60d592716d | ||
|
|
35055d1895 | ||
|
|
dc8f24b8bc | ||
|
|
61f8d3e558 | ||
|
|
1bad380381 | ||
|
|
70ee51d88c | ||
|
|
e3f1f18ca3 | ||
|
|
985311d9f0 | ||
|
|
1003b81c93 | ||
|
|
dfa6dfa960 | ||
|
|
296ee2da4a | ||
|
|
4454a0681b | ||
|
|
cda8177502 | ||
|
|
e8b0ce00e1 | ||
|
|
807d41028e | ||
|
|
266149b88c | ||
|
|
a6139f3635 | ||
|
|
a9c96a7cde | ||
|
|
a03510e3c0 | ||
|
|
d639816393 | ||
|
|
e38448c6f2 | ||
|
|
b1ca06b21d | ||
|
|
05b5894ef1 | ||
|
|
0db69cadb6 | ||
|
|
8e0f403f02 | ||
|
|
6e2fb72bb6 | ||
|
|
0ebc11270b | ||
|
|
54d8afea40 | ||
|
|
5195cc8c12 | ||
|
|
b64c7cce84 | ||
|
|
35c4cc6d45 | ||
|
|
07949aaf4f | ||
|
|
6c8c126ebc | ||
|
|
7359bb8a00 | ||
|
|
03913ff029 | ||
|
|
2010d8d2b9 | ||
|
|
f764d3a021 | ||
|
|
b8602fa31a | ||
|
|
197e096017 | ||
|
|
bc0e466981 | ||
|
|
4ac45eb38b | ||
|
|
846e50a0c0 | ||
|
|
d47fc7280b | ||
|
|
50c92f2a05 | ||
|
|
b173284d1d | ||
|
|
0fe8fec1d1 | ||
|
|
465e9f2d68 | ||
|
|
8c9ebc1bf9 | ||
|
|
c2eab08cc9 | ||
|
|
d5fbd93fe6 | ||
|
|
9e69ffad36 | ||
|
|
883dd95e3c | ||
|
|
2308e5bb7c | ||
|
|
096dc25701 | ||
|
|
db7401d8eb | ||
|
|
e066afc67f | ||
|
|
5b3b35cd78 | ||
|
|
3a3d6e740c | ||
|
|
50abb07245 | ||
|
|
f53b059410 | ||
|
|
0b9106b0f8 | ||
|
|
963258189a | ||
|
|
456139fc5e | ||
|
|
97e320b57f | ||
|
|
7a4d414c59 | ||
|
|
6a9dfd4935 | ||
|
|
774db02b23 | ||
|
|
06adac1abf | ||
|
|
543168c61d | ||
|
|
8501ea78c8 | ||
|
|
79e663828a | ||
|
|
f5a97ea56e | ||
|
|
dad7fd383c | ||
|
|
f0a4f838f2 | ||
|
|
f4cd25ce72 | ||
|
|
67dee52b8a | ||
|
|
958b8a0b10 | ||
|
|
0fcd011abb | ||
|
|
1a01ba0ae5 | ||
|
|
da2683d180 | ||
|
|
dd21736471 | ||
|
|
c9fd79c311 | ||
|
|
1c0a9d2981 | ||
|
|
26df2a5c68 | ||
|
|
31ba40cc99 | ||
|
|
c22272bbca | ||
|
|
66e2f95dba | ||
|
|
3c3b1bb5e4 | ||
|
|
f042b04320 | ||
|
|
14f7529c1b | ||
|
|
aab8555d65 | ||
|
|
ec431460b3 | ||
|
|
2a27ca828c | ||
|
|
acc4118903 | ||
|
|
3ec2095c9f | ||
|
|
3881220386 | ||
|
|
86f9cb6eef | ||
|
|
b53cb5cb4c | ||
|
|
1f47c6d54f | ||
|
|
035cc57cf4 | ||
|
|
ad0070ed8a | ||
|
|
f9483b1f4f | ||
|
|
f405b3f827 | ||
|
|
7c4f59dfcb | ||
|
|
ec936b7286 | ||
|
|
fbf4abf0cf | ||
|
|
53454a783c | ||
|
|
8fca343ef0 | ||
|
|
434444cd69 | ||
|
|
c3aed433ae | ||
|
|
80b7fbd07a | ||
|
|
3ecee5c7cd | ||
|
|
dff7d7b7b9 | ||
|
|
1e02fa3db9 | ||
|
|
8877bac873 | ||
|
|
b359bf1859 | ||
|
|
cd80eced32 | ||
|
|
5c6f452c10 | ||
|
|
e7816b4ec2 | ||
|
|
f6a23ea441 | ||
|
|
9cee2962db | ||
|
|
04424a1ec3 | ||
|
|
a9e03937a3 | ||
|
|
8a8536f8ae | ||
|
|
ea7b5827ab | ||
|
|
5827be4182 | ||
|
|
ca3c72c143 | ||
|
|
f5e6001d82 | ||
|
|
e19c0c9768 | ||
|
|
12bf8a44e7 | ||
|
|
b9a9000569 | ||
|
|
a01b840eab | ||
|
|
ec23c25286 | ||
|
|
23e218396e | ||
|
|
2742e643c1 | ||
|
|
f20ed39b92 | ||
|
|
a01e66a618 | ||
|
|
c1d350f8f3 | ||
|
|
fe50bb4b93 | ||
|
|
5ed28b38be | ||
|
|
a47c818a3c | ||
|
|
af5a381c2b | ||
|
|
bb43a66716 | ||
|
|
25a91a217e | ||
|
|
b744ee0aa4 | ||
|
|
7152156659 | ||
|
|
71cc288a14 | ||
|
|
221d24c597 | ||
|
|
6eec8c28ad | ||
|
|
74348d5ffb | ||
|
|
453008e488 | ||
|
|
84baa0b4c2 | ||
|
|
ee9be61c20 | ||
|
|
7719dfca4a | ||
|
|
870b7d234f | ||
|
|
ad39d0520a | ||
|
|
3967522c08 | ||
|
|
7e22572324 | ||
|
|
3eca687611 | ||
|
|
4c62f64396 | ||
|
|
8259bf749d | ||
|
|
7a3d730aec | ||
|
|
1c49b230f4 | ||
|
|
05022109fc | ||
|
|
9e47d0b33c | ||
|
|
9c5ff6c131 | ||
|
|
6228fa4d3e | ||
|
|
7448b8beb0 | ||
|
|
2600ebb961 | ||
|
|
299b0f0102 | ||
|
|
72f92d7a3b | ||
|
|
1431649c4d | ||
|
|
e1b99580eb | ||
|
|
a5a72a89fc | ||
|
|
bb455ec8f6 | ||
|
|
087de68b3a | ||
|
|
54c9582ac4 | ||
|
|
fa4d790f5a | ||
|
|
fabb0584da | ||
|
|
0123dbce21 | ||
|
|
152def62cb | ||
|
|
50c2c38624 | ||
|
|
ca598b6465 | ||
|
|
1f721796b8 | ||
|
|
5aae3b5d27 | ||
|
|
fc2161c2a6 | ||
|
|
428dcd847f | ||
|
|
d82dc86c71 | ||
|
|
5e16373af6 | ||
|
|
5393074d61 | ||
|
|
66ef49cecc | ||
|
|
b21a9476c0 | ||
|
|
b7711678c2 | ||
|
|
af5a70dcf5 | ||
|
|
a64526acfb | ||
|
|
9af30f4ac7 | ||
|
|
7f50dcb3a8 | ||
|
|
af6d5b76f5 | ||
|
|
2b6a0d6c58 | ||
|
|
3eed0609b2 | ||
|
|
36ebbc49f4 | ||
|
|
72c8b38864 | ||
|
|
bca9242492 | ||
|
|
56064f2a92 | ||
|
|
feaa53c4f2 | ||
|
|
522eeae062 | ||
|
|
d1fac6dce1 | ||
|
|
8c155578f7 | ||
|
|
4f6fe1d0ca | ||
|
|
c9658eb6e4 | ||
|
|
afd71d3d19 | ||
|
|
b047d78580 | ||
|
|
0b9fc1541d | ||
|
|
fe71d5256c | ||
|
|
a3d85e108f | ||
|
|
d982203d56 | ||
|
|
e406669190 | ||
|
|
62e335ac88 | ||
|
|
fe009ac695 | ||
|
|
d54a35ef56 | ||
|
|
13afb2e45e | ||
|
|
699ea0aa2b | ||
|
|
f487118be5 | ||
|
|
223ed1ad60 | ||
|
|
90cfa80683 | ||
|
|
423aeb9a08 | ||
|
|
e56abcbb85 | ||
|
|
d8ab046136 | ||
|
|
d5e71ebef1 | ||
|
|
79c15e49b6 | ||
|
|
820b8c3c54 | ||
|
|
5f1cc3b152 | ||
|
|
d76dc6f57e | ||
|
|
f2f95496e3 | ||
|
|
3398683093 | ||
|
|
81f1f441fc | ||
|
|
39bd97147f | ||
|
|
b1e9dbf994 | ||
|
|
f173af9238 | ||
|
|
9e3f17c52a | ||
|
|
a3252b9480 | ||
|
|
ef1e54eda9 | ||
|
|
c87bc2123c | ||
|
|
a46c6ce5df | ||
|
|
f995192f21 | ||
|
|
6c83e9fb85 | ||
|
|
19bc39d3ab | ||
|
|
af3b057ba2 | ||
|
|
c0dac9bf32 | ||
|
|
3a5f42cc5e | ||
|
|
018215f47d | ||
|
|
94be4d77ff | ||
|
|
19093e2e02 | ||
|
|
98ce49ba73 | ||
|
|
7053f1d00c | ||
|
|
5a6cf19c68 | ||
|
|
e9a7be4a46 | ||
|
|
1624327ba4 | ||
|
|
c5ffbfd33c | ||
|
|
6b98ea2378 | ||
|
|
39ebc8cfa5 | ||
|
|
52e7cd5725 | ||
|
|
325ad14ac9 | ||
|
|
8c4eef9844 | ||
|
|
5b62c9e54d | ||
|
|
55aafb3430 | ||
|
|
068d547375 | ||
|
|
9acd98071e | ||
|
|
cc97138e9c | ||
|
|
fa335b5360 | ||
|
|
8dc75def19 | ||
|
|
664775a43f | ||
|
|
e631146fa7 | ||
|
|
3ae6b27556 | ||
|
|
6670a2fff8 | ||
|
|
569decce43 | ||
|
|
d114945b76 | ||
|
|
e0be8f271f | ||
|
|
40fb6c67d2 | ||
|
|
aefaa6dc7f | ||
|
|
92291c03e8 | ||
|
|
203ca018e5 | ||
|
|
488538889b | ||
|
|
956b57a55d | ||
|
|
881de0a538 | ||
|
|
9112da2ad7 | ||
|
|
06be32550b | ||
|
|
a5602165ec | ||
|
|
e1f7296426 | ||
|
|
37b3b3ec56 | ||
|
|
3d30598774 | ||
|
|
36631a5954 | ||
|
|
86e13c25b3 | ||
|
|
ae89507736 | ||
|
|
16eb23c6b1 | ||
|
|
13594c80aa | ||
|
|
f3f818edc3 | ||
|
|
d9c08945a3 | ||
|
|
ecb89ad259 | ||
|
|
4189bc88c2 | ||
|
|
b967e11511 | ||
|
|
22e826770d | ||
|
|
1346883837 | ||
|
|
185f7419d5 | ||
|
|
397ff26e20 | ||
|
|
ae391f3776 | ||
|
|
1bebcd398e | ||
|
|
82d31adb24 | ||
|
|
4af389ba92 | ||
|
|
285f613ef7 | ||
|
|
6f61ea7f67 | ||
|
|
07ca355af8 | ||
|
|
afceec71a4 | ||
|
|
2566fbea87 | ||
|
|
f9ee1dc22d | ||
|
|
fb49a586ef | ||
|
|
984a11995a | ||
|
|
a3f676317f | ||
|
|
899d471646 | ||
|
|
8c21f04bf4 | ||
|
|
334cab7357 | ||
|
|
b4d026f5bf | ||
|
|
a6d11b0207 | ||
|
|
01053c938a | ||
|
|
d921dd0eed | ||
|
|
4693d595b7 | ||
|
|
f47e602118 | ||
|
|
ace5d0357c | ||
|
|
018cfc7df6 | ||
|
|
1dbb3d7c0f | ||
|
|
4042214bb2 | ||
|
|
22a5bc4144 | ||
|
|
82c960d40d | ||
|
|
d4d4697202 | ||
|
|
3edbf7f541 | ||
|
|
102d5c7d5a | ||
|
|
7e832e50ac | ||
|
|
bc7c8e4819 | ||
|
|
7581e0bd8e | ||
|
|
9dd8eda1c9 | ||
|
|
81b30b7399 | ||
|
|
071149e0fb | ||
|
|
7efb32628e | ||
|
|
8d4dac398d | ||
|
|
eff02b6e72 | ||
|
|
3cf71c1d2b | ||
|
|
0ed719f792 | ||
|
|
d169435300 | ||
|
|
83824d0ba6 | ||
|
|
162a2d5851 | ||
|
|
0e970407a4 | ||
|
|
3921613956 | ||
|
|
5d7999a808 | ||
|
|
17b473fcb6 | ||
|
|
f1a418373c | ||
|
|
e66d6a8954 | ||
|
|
bbf448b39d | ||
|
|
14fd1d3c9f | ||
|
|
ace259314b | ||
|
|
3d51af2935 | ||
|
|
c289612e57 | ||
|
|
a4c4b2650c | ||
|
|
82c8b5f368 | ||
|
|
9017654b9d | ||
|
|
04e6c63cc9 | ||
|
|
1376dbf9cf | ||
|
|
e051251b27 | ||
|
|
cbbbf40b90 | ||
|
|
8ca2aa47f8 | ||
|
|
c29c140a9c | ||
|
|
723ebb4f57 | ||
|
|
9b861739cd | ||
|
|
4eb04af01e | ||
|
|
a6cf16ddfc | ||
|
|
46ae6136cb | ||
|
|
9b5110b9f3 | ||
|
|
3122760c49 | ||
|
|
e8524137c3 | ||
|
|
f10696da5e | ||
|
|
6793b27330 | ||
|
|
c8269baa92 | ||
|
|
2ad8488e6a | ||
|
|
748a326104 | ||
|
|
36f4b6daf3 | ||
|
|
3080b4c435 | ||
|
|
ba90e87756 | ||
|
|
272f6abe69 | ||
|
|
e6efb81014 | ||
|
|
5d603a8be4 | ||
|
|
285aa123b7 | ||
|
|
17a0e3a078 | ||
|
|
810966e408 | ||
|
|
ee0ec421ce | ||
|
|
6c1e2cc196 | ||
|
|
85be0450ba | ||
|
|
6b913da698 | ||
|
|
7c586ce736 | ||
|
|
6982db7d02 | ||
|
|
0b9b1b6945 | ||
|
|
aac72871e7 | ||
|
|
842e2dc02f | ||
|
|
d06e35b061 | ||
|
|
a50911156d | ||
|
|
6ed1cc5cd8 | ||
|
|
f9f715c31e | ||
|
|
752ff9de5d | ||
|
|
f2b940ffd4 | ||
|
|
5663dfb772 | ||
|
|
e54640ddad | ||
|
|
39125a75e7 | ||
|
|
c88ea2f2e6 | ||
|
|
84bc151cb3 | ||
|
|
d0e9dc05b5 | ||
|
|
47d091702b | ||
|
|
adc5a55d65 | ||
|
|
667e96f971 | ||
|
|
9a8a1113db | ||
|
|
11e0f427ac | ||
|
|
a0b0f72edf | ||
|
|
635ff59d10 | ||
|
|
faa95bfc33 | ||
|
|
582ce1199f | ||
|
|
eef86d47a0 | ||
|
|
4462ecb280 | ||
|
|
d9f9c93dc8 | ||
|
|
082c358f9d | ||
|
|
bdb8811f95 | ||
|
|
aaf939a650 | ||
|
|
9788525ec7 | ||
|
|
663c8e5a46 | ||
|
|
ad314e93eb | ||
|
|
a6e488e2b4 | ||
|
|
45a0aa04a1 | ||
|
|
17059682e9 | ||
|
|
f47e5cb2d0 | ||
|
|
6941cd6d28 | ||
|
|
2aeb1ea234 | ||
|
|
cd3fc5b8ec | ||
|
|
41d2f41141 | ||
|
|
89e377763a | ||
|
|
c83244c8b5 | ||
|
|
bf11f1892d | ||
|
|
6430209074 | ||
|
|
6d1da6e6d5 | ||
|
|
2340a86d8d | ||
|
|
6c968859ad | ||
|
|
272ccf64ae | ||
|
|
c748b6f3ee | ||
|
|
4b954c347a | ||
|
|
32e1ec8e98 | ||
|
|
64590cc56b | ||
|
|
2ead2fba08 | ||
|
|
fdf4f477a6 | ||
|
|
9f0ef77531 | ||
|
|
ce8e511b79 | ||
|
|
5a4ce2aa4c | ||
|
|
94d20d9176 | ||
|
|
64141b8b38 | ||
|
|
56c819f06e | ||
|
|
2bfce4f127 | ||
|
|
83e68be2dc | ||
|
|
4a4fb5a590 | ||
|
|
4abbcd1267 | ||
|
|
91814364de | ||
|
|
baa2c56e2d | ||
|
|
cc2884b8ae | ||
|
|
1ea3db90e1 | ||
|
|
51edf2b351 | ||
|
|
e3184e407d | ||
|
|
c9ed27e674 | ||
|
|
811ed1ade4 | ||
|
|
e302e06c73 | ||
|
|
47d5bbc224 | ||
|
|
e67c8a55bf | ||
|
|
d10e56c358 | ||
|
|
031952268a | ||
|
|
ee2e40ce6b | ||
|
|
70d416cafd | ||
|
|
dfe23e770c | ||
|
|
297d296b62 | ||
|
|
9bc7a43991 | ||
|
|
4a7b4d655c | ||
|
|
208c06516b | ||
|
|
bcf6ee0c0b | ||
|
|
ed6f13cf56 | ||
|
|
e40dc37be8 | ||
|
|
55b836a0ac | ||
|
|
fda8d7de8b | ||
|
|
85d7a0f6b1 | ||
|
|
05b00a1302 | ||
|
|
bd3b23b933 | ||
|
|
f9129332b7 | ||
|
|
724bb1b134 | ||
|
|
155b716e7e | ||
|
|
18b218bfa8 | ||
|
|
3cf77d29b5 | ||
|
|
4542f3b720 | ||
|
|
220bf6d62f | ||
|
|
3461effd47 | ||
|
|
7f2cf571b0 | ||
|
|
50c477bee1 | ||
|
|
de33b83bb3 | ||
|
|
577250d73f | ||
|
|
4dc6583f31 | ||
|
|
4f36e2ccfc | ||
|
|
1e7f8ea037 | ||
|
|
5760c0be9c | ||
|
|
2b2ae8a5f1 | ||
|
|
bc2b96f634 | ||
|
|
2677fa7472 | ||
|
|
52bf630f6c | ||
|
|
ba5a335e95 | ||
|
|
3407904e68 | ||
|
|
e57d34dd9e | ||
|
|
46491c12ee | ||
|
|
a411549e38 | ||
|
|
5004bb3636 | ||
|
|
6a37955a36 | ||
|
|
31d73c5d79 | ||
|
|
df7b7cf61a | ||
|
|
e81a7f10c1 | ||
|
|
7688197841 | ||
|
|
cef9ed1dae | ||
|
|
bb04eae93e | ||
|
|
45f036548b | ||
|
|
d51b14fe3c | ||
|
|
0254734bb5 | ||
|
|
ba25b0faaf | ||
|
|
b161839092 | ||
|
|
1a2d28d25b | ||
|
|
3790f31d80 | ||
|
|
e696d1d06a | ||
|
|
2e597a3a32 | ||
|
|
2a55560f3b | ||
|
|
abfe566255 | ||
|
|
a8a696c7e1 | ||
|
|
79060e7f40 | ||
|
|
c71e87068a | ||
|
|
829e5908d0 | ||
|
|
3fcdf6c78c | ||
|
|
64f13ab3ae | ||
|
|
9b462b76d4 | ||
|
|
fbabbfab44 | ||
|
|
dc77df1083 | ||
|
|
2d15914d20 | ||
|
|
bdf1441c80 | ||
|
|
59cdf3c52e | ||
|
|
db91b520a5 | ||
|
|
6356807997 | ||
|
|
238bfe3771 | ||
|
|
1c945430bc | ||
|
|
2f34bc88dc | ||
|
|
ea7ffa70b3 | ||
|
|
6690f946d6 | ||
|
|
6f425ee951 | ||
|
|
dd33640238 | ||
|
|
7490c229ac | ||
|
|
a7071344f5 | ||
|
|
9c889aab17 | ||
|
|
f6b62f2299 | ||
|
|
3027fab238 | ||
|
|
d539a870ed | ||
|
|
fabbfdc7f8 | ||
|
|
dc71ab5bb3 | ||
|
|
b1414fa477 | ||
|
|
be99f44c4f | ||
|
|
eb3685d6ac | ||
|
|
615d24bbd2 | ||
|
|
f4337eede1 | ||
|
|
f129ab55c5 | ||
|
|
cc2fe6b0c6 | ||
|
|
f115bde682 | ||
|
|
8b17718086 | ||
|
|
9cba72d5dd | ||
|
|
01a6e7abf3 | ||
|
|
8f29f8bc9d | ||
|
|
b7449c2d6e | ||
|
|
dd4a8d01c9 | ||
|
|
dd743f05c1 | ||
|
|
f912602ddc | ||
|
|
2df646e273 | ||
|
|
1a3553cdb7 | ||
|
|
c6262b5ff2 | ||
|
|
fc09534464 | ||
|
|
d53c554c8c | ||
|
|
6d606e5291 | ||
|
|
26371ea023 | ||
|
|
c196ce5f09 | ||
|
|
a2be789d37 | ||
|
|
6f1b3e0f17 | ||
|
|
73813aef23 | ||
|
|
3acf7a4679 | ||
|
|
389dcff125 | ||
|
|
50ac8eb95b | ||
|
|
4fbed9b363 | ||
|
|
1da036ac98 | ||
|
|
1dd7417746 | ||
|
|
6b378cab29 | ||
|
|
28c95b1108 | ||
|
|
a4b53b4a20 | ||
|
|
643a4b9c3b | ||
|
|
b71e4ebb3f | ||
|
|
f495c4e215 | ||
|
|
90021f3ece | ||
|
|
89fa3572ec | ||
|
|
0c9720f20c | ||
|
|
b782e8f0f0 | ||
|
|
06b6477d04 | ||
|
|
0c984c5e62 | ||
|
|
5a49ccac76 | ||
|
|
f782ea075b | ||
|
|
a67d97bdf8 | ||
|
|
5d6d287faa | ||
|
|
15d744c3da | ||
|
|
4997c9535c | ||
|
|
e40ba73950 | ||
|
|
4fa87d2caa | ||
|
|
76f8109ff6 | ||
|
|
3278451b07 | ||
|
|
df046683cc | ||
|
|
bf9d4f065b | ||
|
|
e4b7c39110 | ||
|
|
ee48580e06 | ||
|
|
531a63bd19 | ||
|
|
b045adf83a | ||
|
|
9d51180202 | ||
|
|
74becc7e96 | ||
|
|
918895b88f | ||
|
|
aa0c2486c3 | ||
|
|
b96109f23f | ||
|
|
77eacae958 | ||
|
|
49d092cae8 | ||
|
|
0761a17e2f | ||
|
|
514282fb0a | ||
|
|
489c4ec5ec | ||
|
|
3d28945ecb | ||
|
|
7526162f6f | ||
|
|
3702d31cbc | ||
|
|
866f188120 | ||
|
|
c1db9b6d40 | ||
|
|
1ba0870ae3 | ||
|
|
abc5eb4740 | ||
|
|
c2fc633ad6 | ||
|
|
319a38bd5c | ||
|
|
cd0012c527 | ||
|
|
ca57d6cd16 | ||
|
|
a0071885bf | ||
|
|
687c96060f | ||
|
|
17df92e999 | ||
|
|
599ff4711e | ||
|
|
c64577b735 | ||
|
|
cdf5323f8c | ||
|
|
2a4caf6dc8 | ||
|
|
8da05ed597 | ||
|
|
7c65bb2e3f | ||
|
|
b98bdca849 | ||
|
|
f8a21340d0 | ||
|
|
09e6ffdb0a | ||
|
|
cfc2c0fb20 | ||
|
|
4f5d121478 | ||
|
|
e7c72637a1 | ||
|
|
ae578e0a5d | ||
|
|
ee6d6adf70 | ||
|
|
c33a4c5c5b | ||
|
|
3ccb8fa3a8 | ||
|
|
e71bd4e4a4 | ||
|
|
f43626f57f | ||
|
|
826c5dd92e | ||
|
|
3897f51f8e | ||
|
|
f60d24c621 | ||
|
|
1b5b0d2839 | ||
|
|
af32cad1ae | ||
|
|
fd7331bbc0 | ||
|
|
8008185b77 | ||
|
|
8f7648c60a | ||
|
|
ff39880677 | ||
|
|
b1cd56ba91 | ||
|
|
612fd6d1bf | ||
|
|
ff516cac73 | ||
|
|
e76eaa4b5b | ||
|
|
b406d85ca3 | ||
|
|
cfa1d91aa4 | ||
|
|
c34286a327 | ||
|
|
ed7b8e9b85 | ||
|
|
0d7e641736 | ||
|
|
89cf32eccc | ||
|
|
ba606147c9 | ||
|
|
18a3d7ee08 | ||
|
|
60f17c3adf | ||
|
|
572dee6835 | ||
|
|
52ae63f191 | ||
|
|
d5987fd7f3 | ||
|
|
9c9e13d93e | ||
|
|
0df455cb52 | ||
|
|
c28d8c6575 | ||
|
|
9e05c702ab | ||
|
|
ddcc3b39f7 | ||
|
|
c592201a43 | ||
|
|
95a8060946 | ||
|
|
fd0c644b6f | ||
|
|
cd8af5d3ec | ||
|
|
a1497682ed | ||
|
|
db86076864 | ||
|
|
752d676523 | ||
|
|
589cea557b | ||
|
|
fc872d5a53 | ||
|
|
e53fd1b582 | ||
|
|
bbb98f9168 | ||
|
|
a33affc325 | ||
|
|
016dd91e37 | ||
|
|
24d229e5a0 | ||
|
|
5aed541d9e | ||
|
|
333bb4da50 | ||
|
|
196907b2ef | ||
|
|
0129b71cfe | ||
|
|
347f52ae10 | ||
|
|
c8be2876bc | ||
|
|
bdf76f9264 | ||
|
|
29a55fc47e | ||
|
|
300fd9bd07 | ||
|
|
cedfb71a1e | ||
|
|
05b48bbf85 | ||
|
|
d44aef3f3d | ||
|
|
bcd2707fe6 | ||
|
|
b30328a766 | ||
|
|
54e068dee2 | ||
|
|
d86384225e | ||
|
|
8de4966e53 | ||
|
|
f342508a6e | ||
|
|
6793fb285e | ||
|
|
85919ed0fc | ||
|
|
433053e479 | ||
|
|
a4ed71075d | ||
|
|
43903e5d19 | ||
|
|
c6935a57a4 | ||
|
|
d69266de50 | ||
|
|
5ff07baf53 | ||
|
|
40f5663a57 | ||
|
|
6698dc7597 | ||
|
|
57d2939cf9 | ||
|
|
d50f520639 | ||
|
|
8646f6a098 | ||
|
|
e7b981c467 | ||
|
|
99d0fa0d29 | ||
|
|
d2261f5491 | ||
|
|
26c27f55b3 | ||
|
|
fff5d9a684 | ||
|
|
c208f038ad | ||
|
|
24451f62ac | ||
|
|
cd5ed54cd6 | ||
|
|
df5b86c289 | ||
|
|
da9080055c | ||
|
|
247da4984e | ||
|
|
ded996aedf | ||
|
|
62aa6d01e9 | ||
|
|
406c249d99 | ||
|
|
0b06f0a05b | ||
|
|
5904591676 | ||
|
|
d33521052f | ||
|
|
831757018c | ||
|
|
9f3601412b | ||
|
|
8322d7b007 | ||
|
|
7a3b6e2d71 | ||
|
|
2680ea6bdd | ||
|
|
a2930b45f6 | ||
|
|
35c681685b | ||
|
|
31f8fe0461 | ||
|
|
15a33a8503 | ||
|
|
8f8eaa28d5 | ||
|
|
9833e2202e | ||
|
|
a1e6f566f6 | ||
|
|
246fb31786 | ||
|
|
18fa5266b7 | ||
|
|
21a1e2e89f | ||
|
|
00572395da | ||
|
|
808a776efb | ||
|
|
27b9c6ff29 | ||
|
|
619b922215 | ||
|
|
4d323d3567 | ||
|
|
b3067d655e | ||
|
|
3731d4b89a | ||
|
|
f15d1ef23e | ||
|
|
3467230242 | ||
|
|
f169c8ea24 | ||
|
|
b37c2a05fd | ||
|
|
43ab4ad8e8 | ||
|
|
04c0b8c07d | ||
|
|
fd93654c4f | ||
|
|
e6be134f2a | ||
|
|
29c2d62e43 | ||
|
|
0c7284de01 | ||
|
|
dd577e1008 | ||
|
|
bf415704b6 | ||
|
|
599215e74a | ||
|
|
4bd744f163 | ||
|
|
14387332d5 | ||
|
|
9c89859c67 | ||
|
|
d827f9b040 | ||
|
|
4861b47f9c | ||
|
|
2e22b8eb9a | ||
|
|
60da60757d | ||
|
|
c043fc2272 | ||
|
|
3ee7e9272b | ||
|
|
222c663fac | ||
|
|
abf2a9e073 | ||
|
|
ad321e45dc | ||
|
|
5bdf9f6e39 | ||
|
|
544a6bf15e | ||
|
|
2f4f4dbbd8 | ||
|
|
d0e2a653f7 | ||
|
|
64def2e173 | ||
|
|
8b641bf613 | ||
|
|
a20e9ae0ed | ||
|
|
f936a0fc9b | ||
|
|
2de7051165 | ||
|
|
64c2b4b076 | ||
|
|
e7c6653182 | ||
|
|
6be8a83ff9 | ||
|
|
0ff84eaa63 | ||
|
|
3ac2bae4ce | ||
|
|
ba770f7b61 | ||
|
|
3ebad2acec | ||
|
|
f3f88cae7a | ||
|
|
6c93217539 | ||
|
|
8baba38099 | ||
|
|
61d02d9ecb | ||
|
|
9c1577092b | ||
|
|
51db272e0e | ||
|
|
95b4fa4b31 | ||
|
|
42e8017bde | ||
|
|
bc34bc3f96 | ||
|
|
5a2cdfcab4 | ||
|
|
003aea2e68 | ||
|
|
2bb6e4fd97 | ||
|
|
eca562a006 | ||
|
|
95b2a583ae | ||
|
|
c02dd720dc | ||
|
|
6af8f320f7 | ||
|
|
9408bb84e9 | ||
|
|
a7de4a8b4b | ||
|
|
759127df9a | ||
|
|
c58e819a6a | ||
|
|
0d310c0fa4 | ||
|
|
e14e58c121 | ||
|
|
1acce46133 | ||
|
|
7f6c03c926 | ||
|
|
7df92cd00b | ||
|
|
a736551c2a | ||
|
|
45bbdaf73f | ||
|
|
6735cc8937 | ||
|
|
40f907ec2f | ||
|
|
67668d798b | ||
|
|
12c001f491 | ||
|
|
76f78d3fde | ||
|
|
37abdb1732 | ||
|
|
8e35545e10 | ||
|
|
df07b77271 | ||
|
|
fe5dd4dba1 | ||
|
|
b75d0eb1a1 | ||
|
|
a983b0bf74 | ||
|
|
c9d97ae555 | ||
|
|
034243b5e7 | ||
|
|
1cb56ee946 | ||
|
|
9f6f8088e3 | ||
|
|
e23f3b54c6 | ||
|
|
51244d7b1d | ||
|
|
cfd92f252a | ||
|
|
314474c33b | ||
|
|
7a89bd9c90 | ||
|
|
8cb4a8f5c6 | ||
|
|
890109beb8 | ||
|
|
98c6efaed9 | ||
|
|
2cc4d878a8 | ||
|
|
41ca51cb9e | ||
|
|
ae1cfff5d2 | ||
|
|
3eb4d46c3d | ||
|
|
10ce3c58e1 | ||
|
|
75f05d8329 | ||
|
|
b17a28381b | ||
|
|
54b1c512c5 | ||
|
|
56d960c65b | ||
|
|
641fa1f17c | ||
|
|
10aef79434 | ||
|
|
066d77f396 | ||
|
|
4afd7c553b | ||
|
|
b425bf9a1b | ||
|
|
9261f69dc8 | ||
|
|
7ea52ebb45 | ||
|
|
4bc10f4c4f | ||
|
|
2c72f53937 | ||
|
|
78385d5f63 | ||
|
|
5e58a66c58 | ||
|
|
6bd91ec5b0 | ||
|
|
27467e4db7 | ||
|
|
9f6f6838b8 | ||
|
|
579dd8f8fe | ||
|
|
b92a228fb3 | ||
|
|
b795b38794 | ||
|
|
866c33fbde | ||
|
|
5440a5e228 | ||
|
|
beb70526a2 | ||
|
|
cf78058cc2 | ||
|
|
4668518b2f | ||
|
|
9d3d59fccb | ||
|
|
1ecd1a293d | ||
|
|
2a71fe97cf | ||
|
|
354d7306dd | ||
|
|
162c2f3dc9 | ||
|
|
c26e1e9c1a | ||
|
|
0f4fadf104 | ||
|
|
4a1451ab63 | ||
|
|
d775852781 | ||
|
|
695558465d | ||
|
|
6d23e50142 | ||
|
|
9db82bfcc8 | ||
|
|
6584df3e01 | ||
|
|
d9883067e6 | ||
|
|
a0ed2c8640 | ||
|
|
bf9e7ad09a | ||
|
|
058b229544 | ||
|
|
48db96b66d | ||
|
|
cb1c0344b8 | ||
|
|
ff76ba52d8 | ||
|
|
04e8cba857 | ||
|
|
e3721ed406 | ||
|
|
28332933ce | ||
|
|
dc7621a112 | ||
|
|
4b5f3b7a94 | ||
|
|
0fe5694cb7 | ||
|
|
4df8744b34 | ||
|
|
349d07ad43 | ||
|
|
a5e9e09755 | ||
|
|
51af1c13b1 | ||
|
|
f46fc19fdf | ||
|
|
bcfd089473 | ||
|
|
b9911d0e0c | ||
|
|
f98a4e6715 | ||
|
|
63b03d29dc | ||
|
|
7cf4395ccd | ||
|
|
d7e82bf899 | ||
|
|
4ccff3f1b1 | ||
|
|
91fce721b3 | ||
|
|
4027079b41 | ||
|
|
b711c6d398 | ||
|
|
07863b61d8 | ||
|
|
dc7b1fbff9 | ||
|
|
b8aacf0786 | ||
|
|
dc2a9cdc81 | ||
|
|
2c918d2787 | ||
|
|
232efa6303 | ||
|
|
d19d52292e | ||
|
|
9a80850700 | ||
|
|
cc0e39ebca | ||
|
|
a9ba94cf0e | ||
|
|
a569e29091 | ||
|
|
a7f9e3ab09 | ||
|
|
69809fef94 | ||
|
|
17e1f081c7 | ||
|
|
15ff74209c | ||
|
|
d9cbc459d0 | ||
|
|
44cf0a9f72 | ||
|
|
2249c223fe | ||
|
|
6ed4229359 | ||
|
|
36a6eedd9c | ||
|
|
052710db16 | ||
|
|
becc9c21f0 | ||
|
|
b3f9fa22b4 | ||
|
|
733e596eed | ||
|
|
8d48d899d0 | ||
|
|
266a7a67f0 | ||
|
|
181dd432ca | ||
|
|
f1bad0c9ae | ||
|
|
e9dc1e07b9 | ||
|
|
311860699e | ||
|
|
2441ee80e4 | ||
|
|
2f3e3b9c9e | ||
|
|
cbcc76c3ff | ||
|
|
8c455d9e08 | ||
|
|
ae39d748e4 | ||
|
|
b5dd16784a | ||
|
|
b9357b5486 |
8
.idea/artifacts/dist_root.xml
generated
8
.idea/artifacts/dist_root.xml
generated
@@ -1,8 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact build-on-make="true" name="dist_root">
|
||||
<output-path>$PROJECT_DIR$/dist</output-path>
|
||||
<root id="root">
|
||||
<element id="artifact" artifact-name="dist" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
1
.idea/dictionaries/yan.xml
generated
1
.idea/dictionaries/yan.xml
generated
@@ -6,6 +6,7 @@
|
||||
<w>destructured</w>
|
||||
<w>hacky</w>
|
||||
<w>impls</w>
|
||||
<w>inlined</w>
|
||||
<w>kapt</w>
|
||||
<w>kotlinc</w>
|
||||
<w>mutators</w>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.benchmarks
|
||||
|
||||
import org.openjdk.jmh.annotations.*
|
||||
import org.openjdk.jmh.infra.Blackhole
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Benchmark)
|
||||
open class ManyImplicitReceiversBenchmark : AbstractSimpleFileBenchmark() {
|
||||
@Param("1", "10", "50")
|
||||
private var size: Int = 0
|
||||
|
||||
@Benchmark
|
||||
fun benchmark(bh: Blackhole) {
|
||||
analyzeGreenFile(bh)
|
||||
}
|
||||
|
||||
override fun buildText(): String {
|
||||
return buildString {
|
||||
appendln("inline fun <T, R> with(receiver: T, block: T.() -> R): R = block()")
|
||||
|
||||
for (i in 1..size) {
|
||||
appendln("interface A$i {")
|
||||
appendln(" fun foo$i()")
|
||||
appendln("}")
|
||||
appendln()
|
||||
}
|
||||
appendln()
|
||||
append("fun test(")
|
||||
append((1..size).joinToString(", ") { "a$it: A$it" })
|
||||
appendln(" {")
|
||||
for (i in 1..size) {
|
||||
appendln("with(a$i) {")
|
||||
}
|
||||
for (i in 1..size) {
|
||||
appendln("foo$i()")
|
||||
}
|
||||
for (i in 1..size) {
|
||||
appendln("}")
|
||||
}
|
||||
appendln("}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,9 @@ dependencies {
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(protobufFull())
|
||||
testCompile(kotlinStdlib())
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi") }
|
||||
|
||||
Platform[193].orLower {
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
|
||||
}
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
}
|
||||
|
||||
|
||||
@@ -128,8 +128,8 @@ open class IncrementalJsCache(
|
||||
}
|
||||
|
||||
for ((srcFile, irData) in incrementalResults.irFileData) {
|
||||
val (fileData, symbols, types, strings, declarations, bodies, fqn) = irData
|
||||
irTranslationResults.put(srcFile, fileData, symbols, types, strings, declarations, bodies, fqn)
|
||||
val (fileData, types, signatures, strings, declarations, bodies, fqn) = irData
|
||||
irTranslationResults.put(srcFile, fileData, types, signatures, strings, declarations, bodies, fqn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,8 +240,8 @@ private class TranslationResultMap(
|
||||
private object IrTranslationResultValueExternalizer : DataExternalizer<IrTranslationResultValue> {
|
||||
override fun save(output: DataOutput, value: IrTranslationResultValue) {
|
||||
output.writeArray(value.fileData)
|
||||
output.writeArray(value.symbols)
|
||||
output.writeArray(value.types)
|
||||
output.writeArray(value.signatures)
|
||||
output.writeArray(value.strings)
|
||||
output.writeArray(value.declarations)
|
||||
output.writeArray(value.bodies)
|
||||
@@ -262,14 +262,14 @@ private object IrTranslationResultValueExternalizer : DataExternalizer<IrTransla
|
||||
|
||||
override fun read(input: DataInput): IrTranslationResultValue {
|
||||
val fileData = input.readArray()
|
||||
val symbols = input.readArray()
|
||||
val types = input.readArray()
|
||||
val signatures = input.readArray()
|
||||
val strings = input.readArray()
|
||||
val declarations = input.readArray()
|
||||
val bodies = input.readArray()
|
||||
val fqn = input.readArray()
|
||||
|
||||
return IrTranslationResultValue(fileData, symbols, types, strings, declarations, bodies, fqn)
|
||||
return IrTranslationResultValue(fileData, types, signatures, strings, declarations, bodies, fqn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,8 +280,8 @@ private class IrTranslationResultMap(
|
||||
BasicStringMap<IrTranslationResultValue>(storageFile, IrTranslationResultValueExternalizer) {
|
||||
override fun dumpValue(value: IrTranslationResultValue): String =
|
||||
"Filedata: ${value.fileData.md5()}, " +
|
||||
"Symbols: ${value.symbols.md5()}, " +
|
||||
"Types: ${value.types.md5()}, " +
|
||||
"Signatures: ${value.signatures.md5()}, " +
|
||||
"Strings: ${value.strings.md5()}, " +
|
||||
"Declarations: ${value.declarations.md5()}, " +
|
||||
"Bodies: ${value.bodies.md5()}"
|
||||
@@ -289,15 +289,15 @@ private class IrTranslationResultMap(
|
||||
fun put(
|
||||
sourceFile: File,
|
||||
newFiledata: ByteArray,
|
||||
newSymbols: ByteArray,
|
||||
newTypes: ByteArray,
|
||||
newSignatures: ByteArray,
|
||||
newStrings: ByteArray,
|
||||
newDeclarations: ByteArray,
|
||||
newBodies: ByteArray,
|
||||
fqn: ByteArray
|
||||
) {
|
||||
storage[pathConverter.toPath(sourceFile)] =
|
||||
IrTranslationResultValue(newFiledata, newSymbols, newTypes, newStrings, newDeclarations, newBodies, fqn)
|
||||
IrTranslationResultValue(newFiledata, newTypes, newSignatures, newStrings, newDeclarations, newBodies, fqn)
|
||||
}
|
||||
|
||||
operator fun get(sourceFile: File): IrTranslationResultValue? =
|
||||
|
||||
@@ -28,9 +28,8 @@ import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.synthetic.SAM_LOOKUP_NAME
|
||||
import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
class NonCachingLazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
storage = createMap()
|
||||
return storage
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
} else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
@@ -8,7 +8,7 @@ buildscript {
|
||||
extra["defaultSnapshotVersion"] = "1.4-SNAPSHOT"
|
||||
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
|
||||
|
||||
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap("1.4.0-dev-1075", cacheRedirectorEnabled))
|
||||
kotlinBootstrapFrom(BootstrapOption.BintrayBootstrap("1.4.0-dev-1818", cacheRedirectorEnabled))
|
||||
|
||||
repositories {
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
@@ -28,6 +28,7 @@ buildscript {
|
||||
dependencies {
|
||||
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
|
||||
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
|
||||
classpath("com.gradle.publish:plugin-publish-plugin:0.9.7")
|
||||
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
|
||||
classpath("net.sf.proguard:proguard-gradle:6.1.0")
|
||||
@@ -172,14 +173,14 @@ extra["versions.org.springframework"] = "4.2.0.RELEASE"
|
||||
extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.completion-ranking-kotlin"] = "0.0.2"
|
||||
extra["versions.completion-ranking-kotlin"] = "0.1.2"
|
||||
extra["versions.r8"] = "1.5.70"
|
||||
|
||||
// NOTE: please, also change KTOR_NAME in pathUtil.kt and all versions in corresponding jar names in daemon tests.
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.4-dev-14287"
|
||||
extra["versions.kotlin-native"] = "1.4-dev-14579"
|
||||
}
|
||||
|
||||
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
|
||||
@@ -197,11 +198,11 @@ extra["IntellijCoreDependencies"] =
|
||||
"jdom",
|
||||
"jna",
|
||||
"log4j",
|
||||
"picocontainer",
|
||||
if (Platform[201].orHigher()) null else "picocontainer",
|
||||
"snappy-in-java",
|
||||
"streamex",
|
||||
"trove4j"
|
||||
)
|
||||
).filterNotNull()
|
||||
|
||||
|
||||
extra["compilerModules"] = arrayOf(
|
||||
@@ -385,6 +386,11 @@ allprojects {
|
||||
isReproducibleFileOrder = true
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
outputs.cacheIf { false }
|
||||
// https://youtrack.jetbrains.com/issue/KT-37089
|
||||
}
|
||||
|
||||
tasks {
|
||||
register("listArchives") { listConfigurationContents("archives") }
|
||||
|
||||
@@ -536,7 +542,8 @@ tasks {
|
||||
}
|
||||
|
||||
register("wasmCompilerTest") {
|
||||
dependsOn(":js:js.tests:wasmTest")
|
||||
// TODO: fix once
|
||||
// dependsOn(":js:js.tests:wasmTest")
|
||||
}
|
||||
|
||||
register("firCompilerTest") {
|
||||
@@ -545,7 +552,17 @@ tasks {
|
||||
dependsOn(":compiler:fir:fir2ir:test")
|
||||
dependsOn(":compiler:fir:lightTree:test")
|
||||
}
|
||||
|
||||
|
||||
register("firAllTest") {
|
||||
dependsOn(
|
||||
":compiler:fir:psi2fir:test",
|
||||
":compiler:fir:lightTree:test",
|
||||
":compiler:fir:resolve:test",
|
||||
":compiler:fir:fir2ir:test",
|
||||
":idea:firTest"
|
||||
)
|
||||
}
|
||||
|
||||
register("compilerFrontendVisualizerTest") {
|
||||
dependsOn("compiler:visualizer:test")
|
||||
}
|
||||
@@ -615,7 +632,7 @@ tasks {
|
||||
register("konan-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":native:kotlin-native-commonizer:test"
|
||||
":native:kotlin-klib-commonizer:test"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -657,6 +674,13 @@ tasks {
|
||||
)
|
||||
}
|
||||
|
||||
register("idea-plugin-performance-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
":idea:performanceTests:performanceTest"
|
||||
)
|
||||
}
|
||||
|
||||
register("android-ide-tests") {
|
||||
dependsOn("dist")
|
||||
dependsOn(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
extra["versions.shadow"] = "5.2.0"
|
||||
extra["versions.native-platform"] = "0.14"
|
||||
|
||||
buildscript {
|
||||
@@ -22,7 +21,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.8")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$buildSrcKotlinVersion")
|
||||
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:$buildSrcKotlinVersion")
|
||||
}
|
||||
@@ -46,10 +45,6 @@ plugins {
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
register("pill-configurable") {
|
||||
id = "pill-configurable"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
|
||||
}
|
||||
register("jps-compatible") {
|
||||
id = "jps-compatible"
|
||||
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatiblePlugin"
|
||||
@@ -72,10 +67,11 @@ val intellijUltimateEnabled by extra(kotlinBuildProperties.intellijUltimateEnabl
|
||||
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
|
||||
val verifyDependencyOutput by extra( getBooleanProperty("kotlin.build.dependency.output.verification") ?: isTeamcityBuild)
|
||||
|
||||
extra["intellijReleaseType"] = if (extra["versions.intellijSdk"]?.toString()?.endsWith("SNAPSHOT") == true)
|
||||
"snapshots"
|
||||
else
|
||||
"releases"
|
||||
extra["intellijReleaseType"] = when {
|
||||
extra["versions.intellijSdk"]?.toString()?.contains("-EAP-") == true -> "snapshots"
|
||||
extra["versions.intellijSdk"]?.toString()?.endsWith("SNAPSHOT") == true -> "nightly"
|
||||
else -> "releases"
|
||||
}
|
||||
|
||||
extra["versions.androidDxSources"] = "5.0.0_r2"
|
||||
|
||||
@@ -94,14 +90,14 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib", embeddedKotlinVersion))
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.8")
|
||||
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
|
||||
|
||||
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
|
||||
implementation("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
|
||||
implementation("net.rubygrapefruit:native-platform-windows-i386:${property("versions.native-platform")}")
|
||||
implementation("com.jakewharton.dex:dex-method-list:3.0.0")
|
||||
|
||||
implementation("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
|
||||
implementation("com.github.jengelman.gradle.plugins:shadow:${rootProject.extra["versions.shadow"]}")
|
||||
implementation("org.jetbrains.intellij.deps:asm-all:7.0.1")
|
||||
|
||||
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
|
||||
|
||||
@@ -373,10 +373,7 @@ fun writeIvyXml(
|
||||
|
||||
sourcesJar.forEach { jarFile ->
|
||||
emptyElement("artifact") {
|
||||
val sourcesArtifactName = jarFile.name
|
||||
.substringBeforeLast("-")
|
||||
.substringBeforeLast("-")
|
||||
|
||||
val sourcesArtifactName = jarFile.name.substringBefore("-$version")
|
||||
attributes(
|
||||
"name" to sourcesArtifactName,
|
||||
"type" to "jar",
|
||||
|
||||
@@ -20,7 +20,7 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.8")
|
||||
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.12")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ fun CompatibilityPredicate.or(other: CompatibilityPredicate): CompatibilityPredi
|
||||
}
|
||||
|
||||
enum class Platform : CompatibilityPredicate {
|
||||
P183, P191, P192, P193;
|
||||
P183, P191, P192, P193, P201;
|
||||
|
||||
val version: Int = name.drop(1).toInt()
|
||||
|
||||
@@ -44,6 +44,7 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
|
||||
IJ191(Platform.P191),
|
||||
IJ192(Platform.P192),
|
||||
IJ193(Platform.P193),
|
||||
IJ201(Platform.P201),
|
||||
|
||||
AS35(Platform.P183),
|
||||
AS36(Platform.P192),
|
||||
|
||||
@@ -14,9 +14,15 @@ import org.gradle.kotlin.dsl.extra
|
||||
import org.gradle.kotlin.dsl.project
|
||||
import java.io.File
|
||||
|
||||
val Project.isSnapshotIntellij get() = rootProject.extra["versions.intellijSdk"].toString().endsWith("SNAPSHOT")
|
||||
private val Project.isEAPIntellij get() = rootProject.extra["versions.intellijSdk"].toString().contains("-EAP-")
|
||||
private val Project.isNightlyIntellij get() = rootProject.extra["versions.intellijSdk"].toString().endsWith("SNAPSHOT") && !isEAPIntellij
|
||||
|
||||
val Project.intellijRepo get() = "https://www.jetbrains.com/intellij-repository/" + if (isSnapshotIntellij) "snapshots" else "releases"
|
||||
val Project.intellijRepo get() =
|
||||
when {
|
||||
isEAPIntellij -> "https://www.jetbrains.com/intellij-repository/snapshots"
|
||||
isNightlyIntellij -> "https://www.jetbrains.com/intellij-repository/nightly"
|
||||
else -> "https://www.jetbrains.com/intellij-repository/releases"
|
||||
}
|
||||
|
||||
fun Project.commonDep(coord: String): String {
|
||||
val parts = coord.split(':')
|
||||
|
||||
36
buildSrc/src/main/kotlin/pill/JpsCompatiblePlugin.kt
Normal file
36
buildSrc/src/main/kotlin/pill/JpsCompatiblePlugin.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
@Suppress("unused")
|
||||
class JpsCompatiblePlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.configurations.maybeCreate(EmbeddedComponents.CONFIGURATION_NAME)
|
||||
project.extensions.create("pill", PillExtension::class.java)
|
||||
|
||||
// 'jpsTest' does not require the 'tests-jar' artifact
|
||||
project.configurations.create("jpsTest")
|
||||
|
||||
if (project == project.rootProject) {
|
||||
project.tasks.create("pill") {
|
||||
dependsOn(":pill:pill-importer:pill")
|
||||
|
||||
if (System.getProperty("pill.android.tests", "false") == "true") {
|
||||
TaskUtils.useAndroidSdk(this)
|
||||
TaskUtils.useAndroidJar(this)
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.create("unpill") {
|
||||
dependsOn(":pill:pill-importer:unpill")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
@@ -7,33 +12,40 @@ import org.gradle.api.Project
|
||||
open class PillExtension {
|
||||
enum class Variant {
|
||||
// Default variant (./gradlew pill)
|
||||
BASE() { override val includes = setOf(BASE) },
|
||||
BASE() {
|
||||
override val includes = setOf(BASE)
|
||||
},
|
||||
|
||||
// Full variant (./gradlew pill -Dpill.variant=full)
|
||||
FULL() { override val includes = setOf(BASE, FULL) },
|
||||
FULL() {
|
||||
override val includes = setOf(BASE, FULL)
|
||||
},
|
||||
|
||||
// Do not import the project to JPS model, but set some options for it
|
||||
NONE() { override val includes = emptySet<Variant>() },
|
||||
NONE() {
|
||||
override val includes = emptySet<Variant>()
|
||||
},
|
||||
|
||||
// 'BASE' if the "jps-compatible" plugin is applied, 'NONE' otherwise
|
||||
DEFAULT() { override val includes = emptySet<Variant>() };
|
||||
DEFAULT() {
|
||||
override val includes = emptySet<Variant>()
|
||||
};
|
||||
|
||||
abstract val includes: Set<Variant>
|
||||
}
|
||||
|
||||
open var variant: Variant = Variant.DEFAULT
|
||||
|
||||
open var importAsLibrary: Boolean = false
|
||||
|
||||
open var excludedDirs: List<File> = emptyList()
|
||||
|
||||
@Suppress("unused")
|
||||
fun Project.excludedDirs(vararg dirs: String) {
|
||||
excludedDirs = excludedDirs + dirs.map { File(projectDir, it) }
|
||||
}
|
||||
|
||||
open var libraryPath: File? = null
|
||||
set(v) {
|
||||
importAsLibrary = true
|
||||
field = v
|
||||
}
|
||||
@Suppress("unused")
|
||||
fun serialize() = mapOf<String, Any?>(
|
||||
"variant" to variant.name,
|
||||
"excludedDirs" to excludedDirs
|
||||
)
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import org.gradle.api.artifacts.*
|
||||
import org.gradle.api.artifacts.component.*
|
||||
|
||||
class DependencyMapper(val predicate: (ResolvedArtifact) -> Boolean, val mapping: (ResolvedArtifact) -> MappedDependency?) {
|
||||
companion object {
|
||||
fun forProject(path: String, mapping: (ResolvedArtifact) -> MappedDependency?): DependencyMapper {
|
||||
return DependencyMapper(
|
||||
predicate = { artifact ->
|
||||
val identifier = artifact.id.componentIdentifier as? ProjectComponentIdentifier
|
||||
identifier?.projectPath == path
|
||||
},
|
||||
mapping = mapping
|
||||
)
|
||||
}
|
||||
|
||||
fun forModule(group: String, module: String, version: String?, mapping: (ResolvedArtifact) -> MappedDependency?): DependencyMapper {
|
||||
return DependencyMapper(
|
||||
predicate = { artifact ->
|
||||
val identifier = artifact.id.componentIdentifier as? ModuleComponentIdentifier
|
||||
identifier?.group == group && identifier?.module == module && (version == null || identifier?.version == version)
|
||||
},
|
||||
mapping = mapping
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MappedDependency(val main: PDependency?, val deferred: List<PDependency> = emptyList())
|
||||
|
||||
class ParserContext(val dependencyMappers: List<DependencyMapper>, val variant: PillExtension.Variant)
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import java.io.File
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.artifacts.*
|
||||
import org.gradle.api.artifacts.component.*
|
||||
|
||||
data class PDependencies(val main: List<PDependency>, val deferred: List<PDependency>) {
|
||||
fun join(): List<PDependency> {
|
||||
return main + deferred
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.resolveDependencies(
|
||||
configuration: Configuration,
|
||||
forTests: Boolean,
|
||||
dependencyMappers: List<DependencyMapper>,
|
||||
withEmbedded: Boolean = false
|
||||
): PDependencies {
|
||||
val dependencies = mutableListOf<PDependency>()
|
||||
val deferred = mutableListOf<PDependency>()
|
||||
|
||||
nextArtifact@ for (artifact in configuration.resolvedConfiguration.resolvedArtifacts) {
|
||||
val identifier = artifact.id.componentIdentifier
|
||||
|
||||
for (mapper in dependencyMappers) {
|
||||
if (mapper.predicate(artifact)) {
|
||||
val mapped = mapper.mapping(artifact)
|
||||
|
||||
if (mapped != null) {
|
||||
mapped.main?.let { dependencies += it }
|
||||
deferred += mapped.deferred
|
||||
}
|
||||
|
||||
continue@nextArtifact
|
||||
}
|
||||
}
|
||||
|
||||
fun addProjectDependency(projectPath: String) {
|
||||
val project = rootProject.findProject(projectPath) ?: error("Cannot find project $projectPath")
|
||||
|
||||
fun addSourceSet(name: String, suffix: String): Boolean {
|
||||
val sourceSet = project.sourceSets?.findByName(name)?.takeIf { !it.allSource.isEmpty() } ?: return false
|
||||
dependencies += PDependency.Module(project.pillModuleName + '.' + suffix)
|
||||
return true
|
||||
}
|
||||
|
||||
if (forTests && artifact.classifier == "tests") {
|
||||
addSourceSet(SourceSet.TEST_SOURCE_SET_NAME, "test") || addSourceSet(SourceSet.MAIN_SOURCE_SET_NAME, "src")
|
||||
} else {
|
||||
addSourceSet(SourceSet.MAIN_SOURCE_SET_NAME, "src")
|
||||
}
|
||||
|
||||
if (withEmbedded) {
|
||||
val embeddedConfiguration = project.configurations.findByName(EmbeddedComponents.CONFIGURATION_NAME)
|
||||
if (embeddedConfiguration != null) {
|
||||
dependencies += resolveDependencies(embeddedConfiguration, forTests, dependencyMappers, withEmbedded).join()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when (identifier) {
|
||||
is ProjectComponentIdentifier -> addProjectDependency(identifier.projectPath)
|
||||
is LibraryBinaryIdentifier -> addProjectDependency(identifier.projectPath)
|
||||
is ModuleComponentIdentifier -> {
|
||||
val file = artifact.file
|
||||
val library = PLibrary(file.name, classes = listOf(file))
|
||||
dependencies += PDependency.ModuleLibrary(library)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val existingFiles = mutableSetOf<File>()
|
||||
|
||||
for (dependency in configuration.dependencies) {
|
||||
if (dependency !is SelfResolvingDependency) {
|
||||
continue
|
||||
}
|
||||
|
||||
val files = dependency.resolve().filter { it !in existingFiles }.takeIf { it.isNotEmpty() } ?: continue
|
||||
existingFiles.addAll(files)
|
||||
val library = PLibrary(dependency.name, classes = files.toList())
|
||||
deferred += PDependency.ModuleLibrary(library)
|
||||
}
|
||||
|
||||
return PDependencies(dependencies, deferred)
|
||||
}
|
||||
@@ -1,420 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.*
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.plugins.JavaPlugin
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.plugins.ide.idea.IdeaPlugin
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.internal.HasConvention
|
||||
import org.gradle.api.internal.file.copy.CopySpecInternal
|
||||
import org.gradle.api.internal.file.copy.SingleParentCopySpec
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
import org.jetbrains.kotlin.pill.POrderRoot.*
|
||||
import org.jetbrains.kotlin.pill.PSourceRoot.*
|
||||
import org.jetbrains.kotlin.pill.PillExtension.*
|
||||
import java.io.File
|
||||
import java.util.LinkedList
|
||||
|
||||
data class PProject(
|
||||
val name: String,
|
||||
val rootDirectory: File,
|
||||
val modules: List<PModule>,
|
||||
val libraries: List<PLibrary>
|
||||
)
|
||||
|
||||
data class PModule(
|
||||
val name: String,
|
||||
val rootDirectory: File,
|
||||
val moduleFile: File,
|
||||
val contentRoots: List<PContentRoot>,
|
||||
val orderRoots: List<POrderRoot>,
|
||||
val moduleForProductionSources: PModule? = null
|
||||
)
|
||||
|
||||
data class PContentRoot(
|
||||
val path: File,
|
||||
val forTests: Boolean,
|
||||
val sourceRoots: List<PSourceRoot>,
|
||||
val excludedDirectories: List<File>
|
||||
)
|
||||
|
||||
data class PSourceRoot(
|
||||
val path: File,
|
||||
val kind: Kind,
|
||||
val kotlinOptions: PSourceRootKotlinOptions?
|
||||
) {
|
||||
enum class Kind { PRODUCTION, TEST, RESOURCES, TEST_RESOURCES }
|
||||
}
|
||||
|
||||
data class PSourceRootKotlinOptions(
|
||||
val noStdlib: Boolean?,
|
||||
val noReflect: Boolean?,
|
||||
val moduleName: String?,
|
||||
val apiVersion: String?,
|
||||
val languageVersion: String?,
|
||||
val jvmTarget: String?,
|
||||
val extraArguments: List<String>
|
||||
) {
|
||||
fun intersect(other: PSourceRootKotlinOptions) = PSourceRootKotlinOptions(
|
||||
if (noStdlib == other.noStdlib) noStdlib else null,
|
||||
if (noReflect == other.noReflect) noReflect else null,
|
||||
if (moduleName == other.moduleName) moduleName else null,
|
||||
if (apiVersion == other.apiVersion) apiVersion else null,
|
||||
if (languageVersion == other.languageVersion) languageVersion else null,
|
||||
if (jvmTarget == other.jvmTarget) jvmTarget else null,
|
||||
extraArguments.intersect(other.extraArguments).toList()
|
||||
)
|
||||
}
|
||||
|
||||
data class POrderRoot(
|
||||
val dependency: PDependency,
|
||||
val scope: Scope,
|
||||
val isExported: Boolean = false,
|
||||
val isProductionOnTestDependency: Boolean = false
|
||||
) {
|
||||
enum class Scope { COMPILE, TEST, RUNTIME, PROVIDED }
|
||||
}
|
||||
|
||||
sealed class PDependency {
|
||||
data class Module(val name: String) : PDependency()
|
||||
data class Library(val name: String) : PDependency()
|
||||
data class ModuleLibrary(val library: PLibrary) : PDependency()
|
||||
}
|
||||
|
||||
data class PLibrary(
|
||||
val name: String,
|
||||
val classes: List<File>,
|
||||
val javadoc: List<File> = emptyList(),
|
||||
val sources: List<File> = emptyList(),
|
||||
val annotations: List<File> = emptyList(),
|
||||
val dependencies: List<PLibrary> = emptyList(),
|
||||
val originalName: String = name
|
||||
) {
|
||||
fun attachSource(file: File): PLibrary {
|
||||
return this.copy(sources = this.sources + listOf(file))
|
||||
}
|
||||
}
|
||||
|
||||
fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext): PProject = with (context) {
|
||||
if (project != project.rootProject) {
|
||||
error("$project is not a root project")
|
||||
}
|
||||
|
||||
fun Project.matchesSelectedVariant(): Boolean {
|
||||
val extension = this.extensions.findByType(PillExtension::class.java) ?: return true
|
||||
val projectVariant = extension.variant.takeUnless { it == Variant.DEFAULT } ?: Variant.BASE
|
||||
return projectVariant in context.variant.includes
|
||||
}
|
||||
|
||||
val (includedProjects, excludedProjects) = project.allprojects
|
||||
.partition { it.plugins.hasPlugin(JpsCompatiblePlugin::class.java) && it.matchesSelectedVariant() }
|
||||
|
||||
val modules = includedProjects.flatMap { parseModules(it, excludedProjects) }
|
||||
|
||||
return PProject("Kotlin", project.projectDir, modules, libraries)
|
||||
}
|
||||
|
||||
/*
|
||||
Ordering here and below is significant.
|
||||
Placing 'runtime' configuration dependencies on the top make 'idea' tests to run normally.
|
||||
('idea' module has 'intellij-core' as transitive dependency, and we really need to get rid of it.)
|
||||
*/
|
||||
private val CONFIGURATION_MAPPING = mapOf(
|
||||
listOf("runtimeClasspath") to Scope.RUNTIME,
|
||||
listOf("compileClasspath", "compileOnly") to Scope.PROVIDED,
|
||||
listOf("embedded") to Scope.COMPILE
|
||||
)
|
||||
|
||||
private val TEST_CONFIGURATION_MAPPING = mapOf(
|
||||
listOf("runtimeClasspath", "testRuntimeClasspath") to Scope.RUNTIME,
|
||||
listOf("compileClasspath", "testCompileClasspath", "compileOnly", "testCompileOnly") to Scope.PROVIDED,
|
||||
listOf("jpsTest") to Scope.TEST
|
||||
)
|
||||
|
||||
private fun ParserContext.parseModules(project: Project, excludedProjects: List<Project>): List<PModule> {
|
||||
val (productionContentRoots, testContentRoots) = parseContentRoots(project).partition { !it.forTests }
|
||||
|
||||
val modules = mutableListOf<PModule>()
|
||||
|
||||
fun getJavaExcludedDirs() = project.plugins.findPlugin(IdeaPlugin::class.java)
|
||||
?.model?.module?.excludeDirs?.toList() ?: emptyList()
|
||||
|
||||
fun getPillExcludedDirs() = project.extensions.getByType(PillExtension::class.java).excludedDirs
|
||||
|
||||
val allExcludedDirs = getPillExcludedDirs() + getJavaExcludedDirs() + project.buildDir +
|
||||
(if (project == project.rootProject) excludedProjects.map { it.buildDir } else emptyList())
|
||||
|
||||
var productionSourcesModule: PModule? = null
|
||||
|
||||
fun getModuleFile(suffix: String = ""): File {
|
||||
val relativePath = File(project.projectDir, project.pillModuleName + suffix + ".iml")
|
||||
.toRelativeString(project.rootProject.projectDir)
|
||||
|
||||
return File(project.rootProject.projectDir, ".idea/modules/$relativePath")
|
||||
}
|
||||
|
||||
for ((nameSuffix, roots) in mapOf(".src" to productionContentRoots, ".test" to testContentRoots)) {
|
||||
if (roots.isEmpty()) {
|
||||
continue
|
||||
}
|
||||
|
||||
val mainRoot = roots.first()
|
||||
|
||||
var dependencies = parseDependencies(project, mainRoot.forTests)
|
||||
if (productionContentRoots.isNotEmpty() && mainRoot.forTests) {
|
||||
val productionModuleDependency = PDependency.Module(project.pillModuleName + ".src")
|
||||
dependencies += POrderRoot(productionModuleDependency, Scope.COMPILE, true)
|
||||
}
|
||||
|
||||
val module = PModule(
|
||||
project.pillModuleName + nameSuffix,
|
||||
mainRoot.path,
|
||||
getModuleFile(nameSuffix),
|
||||
roots,
|
||||
dependencies,
|
||||
productionSourcesModule
|
||||
)
|
||||
|
||||
modules += module
|
||||
|
||||
if (!mainRoot.forTests) {
|
||||
productionSourcesModule = module
|
||||
}
|
||||
}
|
||||
|
||||
val mainModuleFileRelativePath = when (project) {
|
||||
project.rootProject -> File(project.rootProject.projectDir, project.rootProject.name + ".iml")
|
||||
else -> getModuleFile()
|
||||
}
|
||||
|
||||
modules += PModule(
|
||||
project.pillModuleName,
|
||||
project.projectDir,
|
||||
mainModuleFileRelativePath,
|
||||
listOf(PContentRoot(project.projectDir, false, emptyList(), allExcludedDirs)),
|
||||
if (modules.isEmpty()) parseDependencies(project, false) else emptyList()
|
||||
)
|
||||
|
||||
return modules
|
||||
}
|
||||
|
||||
private fun parseContentRoots(project: Project): List<PContentRoot> {
|
||||
val sourceRoots = parseSourceRoots(project).groupBy { it.kind }
|
||||
fun getRoots(kind: PSourceRoot.Kind) = sourceRoots[kind] ?: emptyList()
|
||||
|
||||
val productionSourceRoots = getRoots(Kind.PRODUCTION) + getRoots(Kind.RESOURCES)
|
||||
val testSourceRoots = getRoots(Kind.TEST) + getRoots(Kind.TEST_RESOURCES)
|
||||
|
||||
fun createContentRoots(sourceRoots: List<PSourceRoot>, forTests: Boolean): List<PContentRoot> {
|
||||
return sourceRoots.map { PContentRoot(it.path, forTests, listOf(it), emptyList()) }
|
||||
}
|
||||
|
||||
return createContentRoots(productionSourceRoots, forTests = false) +
|
||||
createContentRoots(testSourceRoots, forTests = true)
|
||||
}
|
||||
|
||||
private fun parseSourceRoots(project: Project): List<PSourceRoot> {
|
||||
if (!project.plugins.hasPlugin(JavaPlugin::class.java)) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val kotlinTasksBySourceSet = project.tasks.names
|
||||
.filter { it.startsWith("compile") && it.endsWith("Kotlin") }
|
||||
.map { project.tasks.getByName(it) }
|
||||
.associateBy { it.invokeInternal("getSourceSetName") }
|
||||
|
||||
val sourceRoots = mutableListOf<PSourceRoot>()
|
||||
|
||||
val sourceSets = project.sourceSets
|
||||
if (sourceSets != null) {
|
||||
for (sourceSet in sourceSets) {
|
||||
val kotlinCompileTask = kotlinTasksBySourceSet[sourceSet.name]
|
||||
val kind = if (sourceSet.isTestSourceSet) Kind.TEST else Kind.PRODUCTION
|
||||
|
||||
fun Any.getKotlin(): SourceDirectorySet {
|
||||
val kotlinMethod = javaClass.getMethod("getKotlin")
|
||||
val oldIsAccessible = kotlinMethod.isAccessible
|
||||
try {
|
||||
kotlinMethod.isAccessible = true
|
||||
return kotlinMethod(this) as SourceDirectorySet
|
||||
} finally {
|
||||
kotlinMethod.isAccessible = oldIsAccessible
|
||||
}
|
||||
}
|
||||
|
||||
val kotlinSourceDirectories = (sourceSet as HasConvention).convention
|
||||
.plugins["kotlin"]?.getKotlin()?.srcDirs
|
||||
?: emptySet()
|
||||
|
||||
val directories = (sourceSet.java.sourceDirectories.files + kotlinSourceDirectories).toList()
|
||||
.filter { it.exists() }
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?: continue
|
||||
|
||||
val kotlinOptions = kotlinCompileTask?.let { getKotlinOptions(it) }
|
||||
|
||||
for (resourceRoot in sourceSet.resources.sourceDirectories.files) {
|
||||
if (!resourceRoot.exists() || resourceRoot in directories) {
|
||||
continue
|
||||
}
|
||||
|
||||
val resourceRootKind = when (kind) {
|
||||
Kind.PRODUCTION -> Kind.RESOURCES
|
||||
Kind.TEST -> Kind.TEST_RESOURCES
|
||||
else -> error("Invalid source root kind $kind")
|
||||
}
|
||||
|
||||
sourceRoots += PSourceRoot(resourceRoot, resourceRootKind, kotlinOptions)
|
||||
}
|
||||
|
||||
for (directory in directories) {
|
||||
sourceRoots += PSourceRoot(directory, kind, kotlinOptions)
|
||||
}
|
||||
|
||||
for (root in parseResourceRootsProcessedByProcessResourcesTask(project, sourceSet)) {
|
||||
if (sourceRoots.none { it.path == root.path }) {
|
||||
sourceRoots += root
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sourceRoots
|
||||
}
|
||||
|
||||
private fun parseResourceRootsProcessedByProcessResourcesTask(project: Project, sourceSet: SourceSet): List<PSourceRoot> {
|
||||
val isMainSourceSet = sourceSet.name == SourceSet.MAIN_SOURCE_SET_NAME
|
||||
|
||||
val resourceRootKind = if (sourceSet.isTestSourceSet) PSourceRoot.Kind.TEST_RESOURCES else PSourceRoot.Kind.RESOURCES
|
||||
val taskNameBase = "processResources"
|
||||
val taskName = if (isMainSourceSet) taskNameBase else sourceSet.name + taskNameBase.capitalize()
|
||||
val task = project.tasks.findByName(taskName) as? ProcessResources ?: return emptyList()
|
||||
|
||||
val roots = mutableListOf<File>()
|
||||
fun collectRoots(spec: CopySpecInternal) {
|
||||
if (spec is SingleParentCopySpec && spec.children.none()) {
|
||||
roots += spec.sourcePaths.map { File(project.projectDir, it.toString()) }.filter { it.exists() }
|
||||
return
|
||||
}
|
||||
|
||||
spec.children.forEach(::collectRoots)
|
||||
}
|
||||
collectRoots(task.rootSpec)
|
||||
|
||||
return roots.map { PSourceRoot(it, resourceRootKind, null) }
|
||||
}
|
||||
|
||||
private val SourceSet.isTestSourceSet: Boolean
|
||||
get() = name == SourceSet.TEST_SOURCE_SET_NAME
|
||||
|| name.endsWith("Test")
|
||||
|| name.endsWith("Tests")
|
||||
|
||||
private fun getKotlinOptions(kotlinCompileTask: Any): PSourceRootKotlinOptions? {
|
||||
val compileArguments = run {
|
||||
val method = kotlinCompileTask::class.java.getMethod("getSerializedCompilerArguments")
|
||||
method.isAccessible = true
|
||||
method.invoke(kotlinCompileTask) as List<String>
|
||||
}
|
||||
|
||||
fun parseBoolean(name: String) = compileArguments.contains("-$name")
|
||||
fun parseString(name: String) = compileArguments.dropWhile { it != "-$name" }.drop(1).firstOrNull()
|
||||
|
||||
fun isOptionForScriptingCompilerPlugin(option: String)
|
||||
= option.startsWith("-Xplugin=") && option.contains("kotlin-scripting-compiler")
|
||||
|
||||
val extraArguments = compileArguments.filter {
|
||||
it.startsWith("-X") && !isOptionForScriptingCompilerPlugin(it)
|
||||
}
|
||||
|
||||
return PSourceRootKotlinOptions(
|
||||
parseBoolean("no-stdlib"),
|
||||
parseBoolean("no-reflect"),
|
||||
parseString("module-name"),
|
||||
parseString("api-version"),
|
||||
parseString("language-version"),
|
||||
parseString("jvm-target"),
|
||||
extraArguments
|
||||
)
|
||||
}
|
||||
|
||||
private fun Any.invokeInternal(name: String, instance: Any = this): Any? {
|
||||
val method = javaClass.methods.single { it.name.startsWith(name) && it.parameterTypes.isEmpty() }
|
||||
|
||||
val oldIsAccessible = method.isAccessible
|
||||
try {
|
||||
method.isAccessible = true
|
||||
return method.invoke(instance)
|
||||
} finally {
|
||||
method.isAccessible = oldIsAccessible
|
||||
}
|
||||
}
|
||||
|
||||
private fun ParserContext.parseDependencies(project: Project, forTests: Boolean): List<POrderRoot> {
|
||||
val configurations = project.configurations
|
||||
val configurationMapping = if (forTests) TEST_CONFIGURATION_MAPPING else CONFIGURATION_MAPPING
|
||||
|
||||
val mainRoots = mutableListOf<POrderRoot>()
|
||||
val deferredRoots = mutableListOf<POrderRoot>()
|
||||
|
||||
for ((configurationNames, scope) in configurationMapping) {
|
||||
for (configurationName in configurationNames) {
|
||||
val configuration = configurations.findByName(configurationName) ?: continue
|
||||
val (main, deferred) = project.resolveDependencies(configuration, forTests, dependencyMappers)
|
||||
mainRoots += main.map { POrderRoot(it, scope) }
|
||||
deferredRoots += deferred.map { POrderRoot(it, scope) }
|
||||
}
|
||||
}
|
||||
|
||||
return removeDuplicates(mainRoots + deferredRoots)
|
||||
}
|
||||
|
||||
fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
|
||||
val dependenciesByScope = roots.groupBy { it.scope }.mapValues { it.value.mapTo(mutableSetOf()) { it.dependency } }
|
||||
fun dependenciesFor(scope: Scope) = dependenciesByScope[scope] ?: emptySet<PDependency>()
|
||||
|
||||
val result = mutableSetOf<POrderRoot>()
|
||||
for (root in roots.distinct()) {
|
||||
val scope = root.scope
|
||||
val dependency = root.dependency
|
||||
|
||||
if (root in result) {
|
||||
continue
|
||||
}
|
||||
|
||||
if ((scope == Scope.PROVIDED || scope == Scope.RUNTIME) && dependency in dependenciesFor(Scope.COMPILE)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (scope == Scope.PROVIDED && dependency in dependenciesFor(Scope.RUNTIME)) {
|
||||
result += POrderRoot(dependency, Scope.COMPILE)
|
||||
continue
|
||||
}
|
||||
|
||||
if (scope == Scope.RUNTIME && dependency in dependenciesFor(Scope.PROVIDED)) {
|
||||
result += POrderRoot(dependency, Scope.COMPILE)
|
||||
continue
|
||||
}
|
||||
|
||||
result += root
|
||||
}
|
||||
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
val Project.pillModuleName: String
|
||||
get() = path.removePrefix(":").replace(':', '.')
|
||||
|
||||
val Project.sourceSets: SourceSetContainer?
|
||||
get() {
|
||||
val convention = project.convention.findPlugin(JavaPluginConvention::class.java) ?: return null
|
||||
return convention.sourceSets
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
package org.jetbrains.kotlin.pill
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.BasePluginConvention
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
import shadow.org.jdom2.input.SAXBuilder
|
||||
import shadow.org.jdom2.*
|
||||
import shadow.org.jdom2.output.Format
|
||||
import shadow.org.jdom2.output.XMLOutputter
|
||||
import java.io.File
|
||||
|
||||
class PillConfigurablePlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.configurations.maybeCreate(EmbeddedComponents.CONFIGURATION_NAME)
|
||||
project.extensions.create("pill", PillExtension::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
class JpsCompatiblePlugin : Plugin<Project> {
|
||||
companion object {
|
||||
private fun getDependencyMappers(projectLibraries: List<PLibrary>): List<DependencyMapper> {
|
||||
val mappersForKotlinLibrariesExeptStdlib = projectLibraries
|
||||
.filter { it.name != "kotlin-stdlib" }
|
||||
.map { DependencyMapper.forProject(it.originalName) { MappedDependency(PDependency.Library(it.name)) } }
|
||||
|
||||
val disabledModuleMappers = listOf(
|
||||
":kotlin-stdlib-common",
|
||||
":core:builtins",
|
||||
":kotlin-compiler",
|
||||
":kotlin-compiler-embeddable",
|
||||
":kotlin-test:kotlin-test-common",
|
||||
":kotlin-test:kotlin-test-annotations-common"
|
||||
).map { DependencyMapper.forProject(it) { null } }
|
||||
|
||||
return listOf(
|
||||
DependencyMapper.forProject(":kotlin-stdlib") {
|
||||
MappedDependency(
|
||||
PDependency.Library("kotlin-stdlib"),
|
||||
listOf(PDependency.Library("annotations-13.0"))
|
||||
)
|
||||
},
|
||||
DependencyMapper.forProject(":kotlin-test:kotlin-test-jvm") { MappedDependency(PDependency.Library("kotlin-test-jvm")) },
|
||||
DependencyMapper.forProject(":kotlin-reflect-api") { MappedDependency(PDependency.Library("kotlin-reflect")) }
|
||||
) + mappersForKotlinLibrariesExeptStdlib + disabledModuleMappers
|
||||
}
|
||||
|
||||
fun getProjectLibraries(rootProject: Project): List<PLibrary> {
|
||||
val distLibDir = File(rootProject.extra["distLibDir"].toString())
|
||||
fun distJar(name: String) = File(rootProject.projectDir, "dist/kotlinc/lib/$name.jar")
|
||||
|
||||
val libraries = rootProject.allprojects
|
||||
.mapNotNull { library ->
|
||||
val libraryExtension = library.extensions.findByType(PillExtension::class.java)
|
||||
?.takeIf { it.importAsLibrary }
|
||||
?: return@mapNotNull null
|
||||
|
||||
val libraryPath = libraryExtension.libraryPath ?: distLibDir
|
||||
val archivesBaseName = library.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName ?: library.name
|
||||
|
||||
fun List<File>.filterExisting() = filter { it.exists() }
|
||||
|
||||
PLibrary(
|
||||
library.name,
|
||||
classes = listOf(File(libraryPath, "$archivesBaseName.jar")).filterExisting(),
|
||||
sources = listOf(File(libraryPath, "$archivesBaseName-sources.jar")).filterExisting(),
|
||||
originalName = library.path
|
||||
)
|
||||
}
|
||||
|
||||
return libraries + PLibrary("annotations-13.0", classes = listOf(distJar("annotations-13.0")))
|
||||
}
|
||||
}
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.plugins.apply(PillConfigurablePlugin::class.java)
|
||||
// 'jpsTest' does not require the 'tests-jar' artifact
|
||||
project.configurations.create("jpsTest")
|
||||
|
||||
if (project == project.rootProject) {
|
||||
project.tasks.create("pill") {
|
||||
doLast { pill(project) }
|
||||
|
||||
if (System.getProperty("pill.android.tests", "false") == "true") {
|
||||
TaskUtils.useAndroidSdk(this)
|
||||
TaskUtils.useAndroidJar(this)
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.create("unpill") {
|
||||
doLast { unpill(project) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var projectDir: File
|
||||
private lateinit var platformVersion: String
|
||||
private lateinit var platformBaseNumber: String
|
||||
private lateinit var platformDir: File
|
||||
private lateinit var intellijCoreDir: File
|
||||
private var isAndroidStudioPlatform: Boolean = false
|
||||
|
||||
private fun initEnvironment(project: Project) {
|
||||
projectDir = project.projectDir
|
||||
platformVersion = project.extensions.extraProperties.get("versions.intellijSdk").toString()
|
||||
platformBaseNumber = platformVersion.substringBefore(".", "").takeIf { it.isNotEmpty() }
|
||||
?: platformVersion.substringBefore("-", "").takeIf { it.isNotEmpty() }
|
||||
?: error("Invalid platform version: $platformVersion")
|
||||
platformDir = IntellijRootUtils.getIntellijRootDir(project)
|
||||
intellijCoreDir = File(platformDir.parentFile.parentFile.parentFile, "intellij-core")
|
||||
isAndroidStudioPlatform = project.extensions.extraProperties.has("versions.androidStudioRelease")
|
||||
}
|
||||
|
||||
private fun pill(rootProject: Project) {
|
||||
initEnvironment(rootProject)
|
||||
|
||||
val variantOptionValue = System.getProperty("pill.variant", "base").toUpperCase()
|
||||
val variant = PillExtension.Variant.values().firstOrNull { it.name == variantOptionValue }
|
||||
?: run {
|
||||
rootProject.logger.error("Invalid variant name: $variantOptionValue")
|
||||
return
|
||||
}
|
||||
|
||||
rootProject.logger.lifecycle("Pill: Setting up project for the '${variant.name.toLowerCase()}' variant...")
|
||||
|
||||
if (variant == PillExtension.Variant.NONE || variant == PillExtension.Variant.DEFAULT) {
|
||||
rootProject.logger.error("'none' and 'default' should not be passed as a Pill variant property value")
|
||||
return
|
||||
}
|
||||
|
||||
val projectLibraries = getProjectLibraries(rootProject)
|
||||
val dependencyMappers = getDependencyMappers(projectLibraries)
|
||||
|
||||
val parserContext = ParserContext(dependencyMappers, variant)
|
||||
|
||||
val jpsProject = parse(rootProject, projectLibraries, parserContext)
|
||||
.mapLibraries(this::attachPlatformSources, this::attachAsmSources)
|
||||
|
||||
val files = render(jpsProject)
|
||||
|
||||
removeExistingIdeaLibrariesAndModules()
|
||||
removeJpsAndPillRunConfigurations()
|
||||
removeAllArtifactConfigurations()
|
||||
|
||||
generateKotlinPluginArtifactFile(rootProject, dependencyMappers).write()
|
||||
|
||||
copyRunConfigurations()
|
||||
setOptionsForDefaultJunitRunConfiguration(rootProject)
|
||||
|
||||
files.forEach { it.write() }
|
||||
}
|
||||
|
||||
private fun unpill(project: Project) {
|
||||
initEnvironment(project)
|
||||
|
||||
removeExistingIdeaLibrariesAndModules()
|
||||
removeJpsAndPillRunConfigurations()
|
||||
removeAllArtifactConfigurations()
|
||||
}
|
||||
|
||||
private fun removeExistingIdeaLibrariesAndModules() {
|
||||
File(projectDir, ".idea/libraries").deleteRecursively()
|
||||
File(projectDir, ".idea/modules").deleteRecursively()
|
||||
}
|
||||
|
||||
private fun removeJpsAndPillRunConfigurations() {
|
||||
File(projectDir, ".idea/runConfigurations")
|
||||
.walk()
|
||||
.filter { (it.name.startsWith("JPS_") || it.name.startsWith("Pill_")) && it.extension.toLowerCase() == "xml" }
|
||||
.forEach { it.delete() }
|
||||
}
|
||||
|
||||
private fun removeAllArtifactConfigurations() {
|
||||
File(projectDir, ".idea/artifacts")
|
||||
.walk()
|
||||
.filter { it.extension.toLowerCase() == "xml" }
|
||||
.forEach { it.delete() }
|
||||
}
|
||||
|
||||
private fun copyRunConfigurations() {
|
||||
val runConfigurationsDir = File(projectDir, "buildSrc/src/main/resources/runConfigurations")
|
||||
val targetDir = File(projectDir, ".idea/runConfigurations")
|
||||
val platformDirProjectRelative = "\$PROJECT_DIR\$/" + platformDir.toRelativeString(projectDir)
|
||||
val additionalIdeaArgs = if (isAndroidStudioPlatform) "-Didea.platform.prefix=AndroidStudio" else ""
|
||||
|
||||
targetDir.mkdirs()
|
||||
|
||||
fun substitute(text: String): String {
|
||||
return text
|
||||
.replace("\$IDEA_HOME_PATH\$", platformDirProjectRelative)
|
||||
.replace("\$ADDITIONAL_IDEA_ARGS\$", additionalIdeaArgs)
|
||||
}
|
||||
|
||||
runConfigurationsDir.listFiles()
|
||||
.filter { it.extension == "xml" }
|
||||
.map { it.name to substitute(it.readText()) }
|
||||
.forEach { File(targetDir, it.first).writeText(it.second) }
|
||||
}
|
||||
|
||||
/*
|
||||
This sets a proper (project root) working directory and a "idea.home.path" property to the default JUnit configuration,
|
||||
so one does not need to make these changes manually.
|
||||
*/
|
||||
private fun setOptionsForDefaultJunitRunConfiguration(project: Project) {
|
||||
val workspaceFile = File(projectDir, ".idea/workspace.xml")
|
||||
if (!workspaceFile.exists()) {
|
||||
project.logger.warn("${workspaceFile.name} does not exist, JUnit default run configuration was not modified")
|
||||
return
|
||||
}
|
||||
|
||||
val document = SAXBuilder().build(workspaceFile)
|
||||
val rootElement = document.rootElement
|
||||
|
||||
fun Element.getOrCreateChild(name: String, vararg attributes: Pair<String, String>): Element {
|
||||
for (child in getChildren(name)) {
|
||||
if (attributes.all { (attribute, value) -> child.getAttributeValue(attribute) == value }) {
|
||||
return child
|
||||
}
|
||||
}
|
||||
|
||||
return Element(name).apply {
|
||||
for ((attributeName, value) in attributes) {
|
||||
setAttribute(attributeName, value)
|
||||
}
|
||||
|
||||
this@getOrCreateChild.addContent(this@apply)
|
||||
}
|
||||
}
|
||||
|
||||
val platformDirProjectRelative = "\$PROJECT_DIR\$/" + platformDir.toRelativeString(projectDir)
|
||||
|
||||
val runManagerComponent = rootElement.getOrCreateChild("component", "name" to "RunManager")
|
||||
|
||||
val junitConfiguration = runManagerComponent.getOrCreateChild(
|
||||
"configuration",
|
||||
"default" to "true",
|
||||
"type" to "JUnit",
|
||||
"factoryName" to "JUnit"
|
||||
)
|
||||
|
||||
val kotlinJunitConfiguration = runManagerComponent.getOrCreateChild(
|
||||
"configuration",
|
||||
"default" to "true",
|
||||
"type" to "KotlinJUnit",
|
||||
"factoryName" to "Kotlin JUnit"
|
||||
)
|
||||
|
||||
fun Element.applyJUnitTemplate() {
|
||||
getOrCreateChild("option", "name" to "WORKING_DIRECTORY").setAttribute("value", "file://\$PROJECT_DIR\$")
|
||||
getOrCreateChild("option", "name" to "VM_PARAMETERS").also { vmParams ->
|
||||
var options = vmParams.getAttributeValue("value", "")
|
||||
.split(' ')
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotEmpty() }
|
||||
|
||||
fun addOrReplaceOptionValue(name: String, value: Any?) {
|
||||
val optionsWithoutNewValue = options.filter { !it.startsWith("-D$name=") }
|
||||
options = if (value == null) optionsWithoutNewValue else (optionsWithoutNewValue + listOf("-D$name=$value"))
|
||||
}
|
||||
|
||||
if (options.none { it == "-ea" }) {
|
||||
options += "-ea"
|
||||
}
|
||||
|
||||
addOrReplaceOptionValue("idea.home.path", platformDirProjectRelative)
|
||||
addOrReplaceOptionValue("ideaSdk.androidPlugin.path", platformDirProjectRelative + "/plugins/android/lib")
|
||||
addOrReplaceOptionValue("use.jps", "true")
|
||||
addOrReplaceOptionValue("kotlinVersion", project.rootProject.extra["kotlinVersion"].toString())
|
||||
|
||||
val isAndroidStudioBunch = project.findProperty("versions.androidStudioRelease") != null
|
||||
addOrReplaceOptionValue("idea.platform.prefix", if (isAndroidStudioBunch) "AndroidStudio" else null)
|
||||
|
||||
val androidJarPath = project.configurations.findByName("androidJar")?.singleFile
|
||||
val androidSdkPath = project.configurations.findByName("androidSdk")?.singleFile
|
||||
|
||||
if (androidJarPath != null && androidSdkPath != null) {
|
||||
addOrReplaceOptionValue("android.sdk", "\$PROJECT_DIR\$/" + androidSdkPath.toRelativeString(projectDir))
|
||||
addOrReplaceOptionValue("android.jar", "\$PROJECT_DIR\$/" + androidJarPath.toRelativeString(projectDir))
|
||||
}
|
||||
|
||||
vmParams.setAttribute("value", options.joinToString(" "))
|
||||
}
|
||||
}
|
||||
|
||||
junitConfiguration.applyJUnitTemplate()
|
||||
kotlinJunitConfiguration.applyJUnitTemplate()
|
||||
|
||||
val output = XMLOutputter().also {
|
||||
it.format = Format.getPrettyFormat().apply {
|
||||
setEscapeStrategy { Verifier.isHighSurrogate(it) || it == '"' }
|
||||
setIndent(" ")
|
||||
setTextMode(Format.TextMode.TRIM)
|
||||
setOmitEncoding(false)
|
||||
setOmitDeclaration(false)
|
||||
}
|
||||
}
|
||||
|
||||
val postProcessedXml = output.outputString(document)
|
||||
.replace(""", """)
|
||||
.replace("
", " ")
|
||||
.replace("", " ")
|
||||
|
||||
workspaceFile.writeText(postProcessedXml)
|
||||
}
|
||||
|
||||
private fun attachPlatformSources(library: PLibrary): PLibrary {
|
||||
val platformSourcesJar = File(platformDir, "../../../sources/intellij-$platformVersion-sources.jar")
|
||||
|
||||
if (library.classes.any { it.startsWith(platformDir) || it.startsWith(intellijCoreDir) }) {
|
||||
return library.attachSource(platformSourcesJar)
|
||||
}
|
||||
|
||||
return library
|
||||
}
|
||||
|
||||
private fun attachAsmSources(library: PLibrary): PLibrary {
|
||||
val asmSourcesJar = File(platformDir, "../asm-shaded-sources/asm-src-$platformBaseNumber.jar")
|
||||
val asmAllJar = File(platformDir, "lib/asm-all.jar")
|
||||
|
||||
if (library.classes.any { it == asmAllJar }) {
|
||||
return library.attachSource(asmSourcesJar)
|
||||
}
|
||||
|
||||
return library
|
||||
}
|
||||
|
||||
private fun PProject.mapLibraries(vararg mappers: (PLibrary) -> PLibrary): PProject {
|
||||
fun mapLibrary(root: POrderRoot): POrderRoot {
|
||||
val dependency = root.dependency
|
||||
|
||||
if (dependency is PDependency.ModuleLibrary) {
|
||||
val newLibrary = mappers.fold(dependency.library) { lib, mapper -> mapper(lib) }
|
||||
return root.copy(dependency = dependency.copy(library = newLibrary))
|
||||
}
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
val modules = this.modules.map { it.copy(orderRoots = it.orderRoots.map(::mapLibrary)) }
|
||||
return this.copy(modules = modules)
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,10 @@ android {
|
||||
ktest1 {
|
||||
dimension "box"
|
||||
}
|
||||
|
||||
ktest2 {
|
||||
dimension "box"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -96,4 +100,5 @@ dependencies {
|
||||
|
||||
ktest0Implementation fileTree(dir: 'libs/test', include: ['libtest0.jar'])
|
||||
ktest1Implementation fileTree(dir: 'libs/test', include: ['libtest1.jar'])
|
||||
ktest2Implementation fileTree(dir: 'libs/test', include: ['libtest2.jar'])
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@ dependencies {
|
||||
compile(project(":kotlin-reflect"))
|
||||
compile(projectTests(":compiler:tests-common"))
|
||||
compile(commonDep("junit:junit"))
|
||||
compileOnly(intellijDep()) { includeJars("openapi") }
|
||||
|
||||
Platform[193].orLower {
|
||||
compileOnly(intellijDep()) { includeJars("openapi") }
|
||||
}
|
||||
|
||||
testCompile(project(":compiler:incremental-compilation-impl"))
|
||||
testCompile(project(":core:descriptors"))
|
||||
@@ -21,7 +24,11 @@ dependencies {
|
||||
testCompile(project(":compiler:frontend.java"))
|
||||
testCompile(projectTests(":jps-plugin"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(intellijDep()) { includeJars("openapi", "util", "idea", "idea_rt", "groovy-all", rootProject = rootProject) }
|
||||
Platform[193].orLower {
|
||||
testCompile(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", "groovy-all", rootProject = rootProject) }
|
||||
Platform[191].orLower {
|
||||
testCompile(intellijDep()) { includeJars("jps-builders") }
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class AndroidJpsBuildTestCase extends BaseKotlinJpsBuildTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
protected void runTest() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
@@ -138,12 +138,12 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
private fun writeFiles(filesToCompile: List<KtFile>, environment: KotlinCoreEnvironment) {
|
||||
if (filesToCompile.isEmpty()) return
|
||||
|
||||
//3000 files per folder that would be used by flavor to avoid multidex usage,
|
||||
//2500 files per folder that would be used by flavor to avoid multidex usage,
|
||||
// each folder would be jared by build.gradle script
|
||||
writtenFilesCount += filesToCompile.size
|
||||
val index = writtenFilesCount / 3000
|
||||
val index = writtenFilesCount / 2500
|
||||
val outputDir = File(pathManager.getOutputForCompiledFiles(index))
|
||||
assertTrue("Add flavors for ktest$index", index < 2)
|
||||
assertTrue("Add flavors for ktest$index", index < 3)
|
||||
|
||||
println("Generating ${filesToCompile.size} files into ${outputDir.name}, configuration: '${environment.configuration}'...")
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ public class SpecialFiles {
|
||||
|
||||
//special symbols in names
|
||||
excludedFiles.add("nameWithWhitespace.kt");
|
||||
|
||||
//some classes are moved from stdlib to compatibility package
|
||||
excludedFiles.add("suspendFunction_1_2.kt");
|
||||
}
|
||||
|
||||
private SpecialFiles() {
|
||||
|
||||
@@ -1081,27 +1081,23 @@ public class AsmUtil {
|
||||
}
|
||||
|
||||
public static void pushDefaultValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
||||
v.aconst(null);
|
||||
}
|
||||
else {
|
||||
pushDefaultPrimitiveValueOnStack(type, v);
|
||||
}
|
||||
v.visitInsn(defaultValueOpcode(type));
|
||||
}
|
||||
|
||||
public static void pushDefaultPrimitiveValueOnStack(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
public static int defaultValueOpcode(@NotNull Type type) {
|
||||
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
||||
return ACONST_NULL;
|
||||
}
|
||||
if (type.getSort() == Type.FLOAT) {
|
||||
v.fconst(0);
|
||||
return FCONST_0;
|
||||
}
|
||||
else if (type.getSort() == Type.DOUBLE) {
|
||||
v.dconst(0);
|
||||
if (type.getSort() == Type.DOUBLE) {
|
||||
return DCONST_0;
|
||||
}
|
||||
else if (type.getSort() == Type.LONG) {
|
||||
v.lconst(0);
|
||||
}
|
||||
else {
|
||||
v.iconst(0);
|
||||
if (type.getSort() == Type.LONG) {
|
||||
return LCONST_0;
|
||||
}
|
||||
return ICONST_0;
|
||||
}
|
||||
|
||||
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.coroutines.createCustomCopy
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
|
||||
import org.jetbrains.kotlin.config.JVMAssertionsMode
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isTopLevelInPackage
|
||||
@@ -19,12 +21,15 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.LdcInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
const val ASSERTIONS_DISABLED_FIELD_NAME = "\$assertionsDisabled"
|
||||
@@ -130,7 +135,7 @@ private fun inlineAlwaysInlineAssert(resolvedCall: ResolvedCall<*>, codegen: Exp
|
||||
)
|
||||
}
|
||||
|
||||
fun generateAssertionsDisabledFieldInitialization(classBuilder: ClassBuilder, clInitBuilder: MethodVisitor) {
|
||||
fun generateAssertionsDisabledFieldInitialization(classBuilder: ClassBuilder, clInitBuilder: MethodVisitor, className: String) {
|
||||
classBuilder.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC or Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC, ASSERTIONS_DISABLED_FIELD_NAME,
|
||||
"Z", null, null
|
||||
@@ -139,7 +144,7 @@ fun generateAssertionsDisabledFieldInitialization(classBuilder: ClassBuilder, cl
|
||||
val elseLabel = Label()
|
||||
with(InstructionAdapter(clInitBuilder)) {
|
||||
mark(Label())
|
||||
aconst(Type.getObjectType(classBuilder.thisName))
|
||||
aconst(Type.getObjectType(className))
|
||||
invokevirtual("java/lang/Class", "desiredAssertionStatus", "()Z", false)
|
||||
ifne(thenLabel)
|
||||
iconst(1)
|
||||
@@ -153,6 +158,16 @@ fun generateAssertionsDisabledFieldInitialization(classBuilder: ClassBuilder, cl
|
||||
}
|
||||
}
|
||||
|
||||
fun rewriteAssertionsDisabledFieldInitialization(methodNode: MethodNode, className: String) {
|
||||
InsnSequence(methodNode.instructions).firstOrNull {
|
||||
it is FieldInsnNode && it.opcode == Opcodes.PUTSTATIC && it.name == ASSERTIONS_DISABLED_FIELD_NAME
|
||||
}?.findPreviousOrNull {
|
||||
it is MethodInsnNode && it.opcode == Opcodes.INVOKEVIRTUAL
|
||||
&& it.owner == "java/lang/Class" && it.name == "desiredAssertionStatus" && it.desc == "()Z"
|
||||
}?.previous?.safeAs<LdcInsnNode>()?.cst =
|
||||
Type.getObjectType(className)
|
||||
}
|
||||
|
||||
private fun <D : FunctionDescriptor> ResolvedCall<D>.replaceAssertWithAssertInner(): ResolvedCall<D> {
|
||||
val newCandidateDescriptor = resultingDescriptor.createCustomCopy {
|
||||
setName(Name.identifier(ALWAYS_ENABLED_ASSERT_FUNCTION_NAME))
|
||||
|
||||
@@ -47,7 +47,7 @@ interface BaseExpressionCodegen {
|
||||
functionReferenceReceiver: StackValue?
|
||||
)
|
||||
|
||||
fun markLineNumberAfterInlineIfNeeded()
|
||||
fun markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards: Boolean)
|
||||
|
||||
fun consumeReifiedOperationMarker(typeParameter: TypeParameterMarker)
|
||||
|
||||
|
||||
@@ -677,6 +677,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
generator.checkEmptyLoop(loopExit);
|
||||
|
||||
v.mark(loopEntry);
|
||||
resetLastLineNumber();
|
||||
markStartLineNumber(generator.getForExpression());
|
||||
v.nop();
|
||||
|
||||
generator.checkPreCondition(loopExit);
|
||||
|
||||
// Some forms of for-loop can be optimized as post-condition loops.
|
||||
@@ -1495,10 +1499,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.visitLineNumber(lineNumber, label);
|
||||
}
|
||||
|
||||
//we should generate additional linenumber info after inline call only if it used as argument
|
||||
@Override
|
||||
public void markLineNumberAfterInlineIfNeeded() {
|
||||
if (!shouldMarkLineNumbers) {
|
||||
public void markLineNumberAfterInlineIfNeeded(boolean registerLineNumberAfterwards) {
|
||||
if (!shouldMarkLineNumbers || registerLineNumberAfterwards) {
|
||||
//if it used as general argument
|
||||
if (myLastLineNumber > -1) {
|
||||
Label label = new Label();
|
||||
@@ -1506,11 +1509,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
v.visitLineNumber(myLastLineNumber, label);
|
||||
}
|
||||
} else {
|
||||
//if it used as argument of infix call (in this case lineNumber for simple inlineCall also would be reset)
|
||||
myLastLineNumber = -1;
|
||||
resetLastLineNumber();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetLastLineNumber() {
|
||||
myLastLineNumber = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLastLineNumber() {
|
||||
return myLastLineNumber;
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineOnlyKt;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo;
|
||||
@@ -76,6 +77,7 @@ import static org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.isAccessor;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION;
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAbi.LOCAL_VARIABLE_INLINE_ARGUMENT_SYNTHETIC_LINE_NUMBER;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
|
||||
@@ -636,11 +638,19 @@ public class FunctionCodegen {
|
||||
frameMap.enter(continuationValueDescriptor, typeMapper.mapType(continuationValueDescriptor));
|
||||
}
|
||||
if (context.isInlineMethodContext()) {
|
||||
functionFakeIndex = newFakeTempIndex(mv, frameMap);
|
||||
functionFakeIndex = newFakeTempIndex(mv, frameMap, -1);
|
||||
}
|
||||
|
||||
if (context instanceof InlineLambdaContext) {
|
||||
lambdaFakeIndex = newFakeTempIndex(mv, frameMap);
|
||||
int lineNumber = -1;
|
||||
if (strategy instanceof ClosureGenerationStrategy) {
|
||||
KtDeclarationWithBody declaration = ((ClosureGenerationStrategy) strategy).getDeclaration();
|
||||
BindingContext bindingContext = typeMapper.getBindingContext();
|
||||
if (declaration instanceof KtFunctionLiteral && isLambdaPassedToInlineOnly((KtFunction) declaration, bindingContext)) {
|
||||
lineNumber = LOCAL_VARIABLE_INLINE_ARGUMENT_SYNTHETIC_LINE_NUMBER;
|
||||
}
|
||||
}
|
||||
lambdaFakeIndex = newFakeTempIndex(mv, frameMap, lineNumber);
|
||||
}
|
||||
|
||||
methodEntry = new Label();
|
||||
@@ -704,8 +714,27 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private static int newFakeTempIndex(@NotNull MethodVisitor mv, FrameMap frameMap) {
|
||||
private static boolean isLambdaPassedToInlineOnly(KtFunction lambda, BindingContext bindingContext) {
|
||||
ValueParameterDescriptor parameterDescriptor = InlineUtil.getInlineArgumentDescriptor(lambda, bindingContext);
|
||||
if (parameterDescriptor == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CallableDescriptor containingCallable = parameterDescriptor.getContainingDeclaration();
|
||||
if (containingCallable instanceof FunctionDescriptor) {
|
||||
return InlineOnlyKt.isInlineOnly((MemberDescriptor) containingCallable);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int newFakeTempIndex(@NotNull MethodVisitor mv, @NotNull FrameMap frameMap, int lineNumber) {
|
||||
int fakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
if (lineNumber >= 0) {
|
||||
Label label = new Label();
|
||||
mv.visitLabel(label);
|
||||
mv.visitLineNumber(lineNumber, label);
|
||||
}
|
||||
mv.visitLdcInsn(0);
|
||||
mv.visitVarInsn(ISTORE, fakeIndex);
|
||||
return fakeIndex;
|
||||
|
||||
@@ -965,7 +965,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
|
||||
public void generateAssertField() {
|
||||
if (jvmAssertFieldGenerated) return;
|
||||
AssertCodegenUtilKt.generateAssertionsDisabledFieldInitialization(v, createOrGetClInitCodegen().v);
|
||||
AssertCodegenUtilKt.generateAssertionsDisabledFieldInitialization(v, createOrGetClInitCodegen().v, v.getThisName());
|
||||
jvmAssertFieldGenerated = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ 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.builtins.UnsignedTypes;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
@@ -635,11 +636,8 @@ public abstract class StackValue {
|
||||
if (toType.equals(UNIT_TYPE) || toType.equals(OBJECT_TYPE)) {
|
||||
putUnitInstance(v);
|
||||
}
|
||||
else if (toType.getSort() == Type.OBJECT || toType.getSort() == Type.ARRAY) {
|
||||
v.aconst(null);
|
||||
}
|
||||
else {
|
||||
pushDefaultPrimitiveValueOnStack(toType, v);
|
||||
pushDefaultValueOnStack(toType, v);
|
||||
}
|
||||
}
|
||||
else if (toType.equals(UNIT_TYPE)) {
|
||||
@@ -794,8 +792,11 @@ public abstract class StackValue {
|
||||
ResolvedCall resolvedCall,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
if (stackValue instanceof StackValue.Local && Type.INT_TYPE == stackValue.type) {
|
||||
return preIncrementForLocalVar(((StackValue.Local) stackValue).index, delta, stackValue.kotlinType);
|
||||
KotlinType kotlinType = stackValue.kotlinType;
|
||||
if (stackValue instanceof StackValue.Local && Type.INT_TYPE == stackValue.type &&
|
||||
kotlinType != null && KotlinBuiltIns.isPrimitiveType(kotlinType)
|
||||
) {
|
||||
return preIncrementForLocalVar(((StackValue.Local) stackValue).index, delta, kotlinType);
|
||||
}
|
||||
return new PrefixIncrement(type, stackValue, resolvedCall, codegen);
|
||||
}
|
||||
|
||||
@@ -461,10 +461,18 @@ fun getCallLabelForLambdaArgument(declaration: KtFunctionLiteral, bindingContext
|
||||
lambdaExpressionParent.name?.let { return it }
|
||||
}
|
||||
|
||||
val lambdaArgument = lambdaExpression.parent as? KtLambdaArgument ?: return null
|
||||
val callExpression = lambdaArgument.parent as? KtCallExpression ?: return null
|
||||
val call = callExpression.getResolvedCall(bindingContext) ?: return null
|
||||
val callExpression = when (val argument = lambdaExpression.parent) {
|
||||
is KtLambdaArgument -> {
|
||||
argument.parent as? KtCallExpression ?: return null
|
||||
}
|
||||
is KtValueArgument -> {
|
||||
val valueArgumentList = argument.parent as? KtValueArgumentList ?: return null
|
||||
valueArgumentList.parent as? KtCallExpression ?: return null
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
|
||||
val call = callExpression.getResolvedCall(bindingContext) ?: return null
|
||||
return call.resultingDescriptor.name.asString()
|
||||
}
|
||||
|
||||
|
||||
@@ -307,10 +307,29 @@ class CoroutineCodegenForLambda private constructor(
|
||||
val createArgumentTypes =
|
||||
if (generateErasedCreate || doNotGenerateInvokeBridge) typeMapper.mapAsmMethod(createCoroutineDescriptor).argumentTypes.asList()
|
||||
else parameterTypes
|
||||
var index = 0
|
||||
parameterTypes.withVariableIndices().forEach { (varIndex, type) ->
|
||||
load(varIndex + 1, type)
|
||||
StackValue.coerce(type, createArgumentTypes[index++], this)
|
||||
// invoke is not big arity, but create is. Pass an array to create.
|
||||
if (parameterTypes.size == 22 && createArgumentTypes.size == 1) {
|
||||
iconst(22)
|
||||
newarray(AsmTypes.OBJECT_TYPE)
|
||||
// 0 - this
|
||||
// 1..22 - parameters
|
||||
// 23 - first empy slot
|
||||
val arraySlot = 23
|
||||
store(arraySlot, AsmTypes.OBJECT_TYPE)
|
||||
for ((varIndex, type) in parameterTypes.withVariableIndices()) {
|
||||
load(arraySlot, AsmTypes.OBJECT_TYPE)
|
||||
iconst(varIndex)
|
||||
load(varIndex + 1, type)
|
||||
StackValue.coerce(type, AsmTypes.OBJECT_TYPE, this)
|
||||
astore(AsmTypes.OBJECT_TYPE)
|
||||
}
|
||||
load(arraySlot, AsmTypes.OBJECT_TYPE)
|
||||
} else {
|
||||
var index = 0
|
||||
parameterTypes.withVariableIndices().forEach { (varIndex, type) ->
|
||||
load(varIndex + 1, type)
|
||||
StackValue.coerce(type, createArgumentTypes[index++], this)
|
||||
}
|
||||
}
|
||||
|
||||
// this.create(..)
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.DEBUG_METADATA_ANNOTATION_ASM_TYPE
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodName
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
||||
@@ -154,6 +153,11 @@ class AnonymousObjectTransformer(
|
||||
coroutineTransformer.shouldGenerateStateMachine(next) -> coroutineTransformer.newMethod(next)
|
||||
else -> newMethod(classBuilder, next)
|
||||
}
|
||||
|
||||
if (next.name == "<clinit>") {
|
||||
rewriteAssertionsDisabledFieldInitialization(next, inliningContext.root.callSiteInfo.ownerClassName)
|
||||
}
|
||||
|
||||
val funResult = inlineMethodAndUpdateGlobalResult(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false)
|
||||
|
||||
val returnType = Type.getReturnType(next.desc)
|
||||
@@ -195,7 +199,7 @@ class AnonymousObjectTransformer(
|
||||
|
||||
if (inliningContext.generateAssertField && fieldNames.none { it.key == ASSERTIONS_DISABLED_FIELD_NAME }) {
|
||||
val clInitBuilder = classBuilder.newMethod(NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
|
||||
generateAssertionsDisabledFieldInitialization(classBuilder, clInitBuilder)
|
||||
generateAssertionsDisabledFieldInitialization(classBuilder, clInitBuilder, inliningContext.root.callSiteInfo.ownerClassName)
|
||||
clInitBuilder.visitInsn(Opcodes.RETURN)
|
||||
clInitBuilder.visitEnd()
|
||||
}
|
||||
@@ -521,10 +525,8 @@ class AnonymousObjectTransformer(
|
||||
alreadyAddedParam?.newFieldName ?: getNewFieldName(desc.fieldName, false),
|
||||
alreadyAddedParam != null
|
||||
)
|
||||
if (info is PsiExpressionLambda && info.closure.captureVariables.any { it.value.fieldName == desc.fieldName }) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend(
|
||||
isCapturedSuspendLambda(info.closure, desc.fieldName, inliningContext.state.bindingContext)
|
||||
)
|
||||
if (info is ExpressionLambda && info.isCapturedSuspend(desc, inliningContext)) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
}
|
||||
val composed = StackValue.field(
|
||||
desc.type,
|
||||
|
||||
@@ -118,28 +118,29 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
AsmUtil.genThrow(codegen.v, "java/lang/UnsupportedOperationException", message)
|
||||
}
|
||||
|
||||
protected fun endCall(result: InlineResult) {
|
||||
protected fun endCall(result: InlineResult, registerLineNumberAfterwards: Boolean) {
|
||||
leaveTemps()
|
||||
|
||||
codegen.propagateChildReifiedTypeParametersUsages(result.reifiedTypeParametersUsages)
|
||||
|
||||
state.factory.removeClasses(result.calcClassesToRemove())
|
||||
|
||||
codegen.markLineNumberAfterInlineIfNeeded()
|
||||
codegen.markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards)
|
||||
}
|
||||
|
||||
fun performInline(
|
||||
typeArguments: List<TypeParameterMarker>?,
|
||||
inlineDefaultLambdas: Boolean,
|
||||
mapDefaultSignature: Boolean,
|
||||
typeSystem: TypeSystemCommonBackendContext
|
||||
typeSystem: TypeSystemCommonBackendContext,
|
||||
registerLineNumberAfterwards: Boolean
|
||||
) {
|
||||
var nodeAndSmap: SMAPAndMethodNode? = null
|
||||
try {
|
||||
nodeAndSmap = createInlineMethodNode(
|
||||
functionDescriptor, methodOwner, jvmSignature, mapDefaultSignature, typeArguments, typeSystem, state, sourceCompiler
|
||||
)
|
||||
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas))
|
||||
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards)
|
||||
} catch (e: CompilationException) {
|
||||
throw e
|
||||
} catch (e: InlineException) {
|
||||
@@ -149,12 +150,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNREACHABLE_CODE")
|
||||
private fun canSkipStackSpillingOnInline(methodNode: MethodNode): Boolean {
|
||||
// TODO: Temporary disable this optimization until
|
||||
// https://issuetracker.google.com/issues/68796377 is fixed
|
||||
// or until d8 substitute dex
|
||||
return false
|
||||
// Stack spilling before inline function 'f' call is required if:
|
||||
// - 'f' is a suspend function
|
||||
// - 'f' has try-catch blocks
|
||||
@@ -395,7 +391,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
info = invocationParamBuilder.addNextValueParameter(jvmType, false, remappedValue, parameterIndex)
|
||||
info.functionalArgument = when (kind) {
|
||||
ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND ->
|
||||
NonInlineableArgumentForInlineableParameterCalledInSuspend(kotlinType?.isSuspendFunctionTypeOrSubtype == true)
|
||||
NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER -> NonInlineableArgumentForInlineableSuspendParameter
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding.*
|
||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
@@ -82,7 +83,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
}
|
||||
}
|
||||
|
||||
class NonInlineableArgumentForInlineableParameterCalledInSuspend(val isSuspend: Boolean) : FunctionalArgument
|
||||
object NonInlineableArgumentForInlineableParameterCalledInSuspend : FunctionalArgument
|
||||
object NonInlineableArgumentForInlineableSuspendParameter : FunctionalArgument
|
||||
|
||||
|
||||
@@ -215,6 +216,7 @@ abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInli
|
||||
}
|
||||
|
||||
abstract fun getInlineSuspendLambdaViewDescriptor(): FunctionDescriptor
|
||||
abstract fun isCapturedSuspend(desc: CapturedParamDesc, inliningContext: InliningContext): Boolean
|
||||
}
|
||||
|
||||
class PsiExpressionLambda(
|
||||
@@ -328,4 +330,7 @@ class PsiExpressionLambda(
|
||||
typeMapper.bindingContext
|
||||
)
|
||||
}
|
||||
|
||||
override fun isCapturedSuspend(desc: CapturedParamDesc, inliningContext: InliningContext): Boolean =
|
||||
isCapturedSuspendLambda(closure, desc.fieldName, inliningContext.state.bindingContext)
|
||||
}
|
||||
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtIfExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
@@ -66,12 +69,19 @@ class PsiInlineCodegen(
|
||||
return
|
||||
}
|
||||
try {
|
||||
performInline(resolvedCall?.typeArguments?.keys?.toList(), callDefault, callDefault, codegen.typeSystem)
|
||||
val registerLineNumber = registerLineNumberAfterwards(resolvedCall)
|
||||
performInline(resolvedCall?.typeArguments?.keys?.toList(), callDefault, callDefault, codegen.typeSystem, registerLineNumber)
|
||||
} finally {
|
||||
state.globalInlineContext.exitFromInliningOf(inlineCall)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerLineNumberAfterwards(resolvedCall: ResolvedCall<*>?): Boolean {
|
||||
val callElement = resolvedCall?.call?.callElement ?: return false
|
||||
val parentIfCondition = callElement.getParentOfType<KtIfExpression>(true)?.condition ?: return false
|
||||
return parentIfCondition.isAncestor(callElement, false)
|
||||
}
|
||||
|
||||
override fun processAndPutHiddenParameters(justProcess: Boolean) {
|
||||
if (getMethodAsmFlags(functionDescriptor, sourceCompiler.contextKind, state) and Opcodes.ACC_STATIC == 0) {
|
||||
invocationParamBuilder.addNextParameter(methodOwner, false, actualDispatchReceiver)
|
||||
@@ -146,7 +156,8 @@ class PsiInlineCodegen(
|
||||
} else {
|
||||
val value = codegen.gen(argumentExpression)
|
||||
val kind = when {
|
||||
isCallSiteIsSuspend(valueParameterDescriptor) -> ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND
|
||||
isCallSiteIsSuspend(valueParameterDescriptor) && parameterType.kotlinType?.isSuspendFunctionTypeOrSubtype == true ->
|
||||
ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND
|
||||
isInlineSuspendParameter(valueParameterDescriptor) -> ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER
|
||||
else -> ValueKind.GENERAL
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.END
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.FILE_SECTION
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.LINE_SECTION
|
||||
import org.jetbrains.kotlin.codegen.inline.SMAP.Companion.STRATA_SECTION
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
||||
@@ -92,6 +93,10 @@ open class NestedSourceMapper(
|
||||
private var lastVisitedRange: RangeMapping? = null
|
||||
|
||||
override fun mapLineNumber(lineNumber: Int): Int {
|
||||
if (lineNumber in JvmAbi.SYNTHETIC_MARKER_LINE_NUMBERS) {
|
||||
return lineNumber
|
||||
}
|
||||
|
||||
val mappedLineNumber = visitedLines.get(lineNumber)
|
||||
|
||||
return if (mappedLineNumber > 0) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.org.objectweb.asm.tree.LineNumberNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.util.*
|
||||
@@ -30,7 +31,13 @@ class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) {
|
||||
|
||||
private fun createLineNumberSequence(node: MethodNode, classSMAP: SMAP): Sequence<RangeMapping> {
|
||||
return InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map { lineNumber ->
|
||||
val index = classSMAP.intervals.binarySearch(RangeMapping(lineNumber.line, lineNumber.line, 1), Comparator { value, key ->
|
||||
val mapping = RangeMapping(lineNumber.line, lineNumber.line, 1)
|
||||
|
||||
if (lineNumber.line in JvmAbi.SYNTHETIC_MARKER_LINE_NUMBERS) {
|
||||
return@map mapping
|
||||
}
|
||||
|
||||
val index = classSMAP.intervals.binarySearch(mapping, Comparator { value, key ->
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
if (index < 0) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.codegen.inline.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
||||
@@ -19,18 +18,7 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransfor
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -291,8 +279,7 @@ class SurroundSuspendLambdaCallsWithSuspendMarkersMethodVisitor(
|
||||
}
|
||||
|
||||
private fun FunctionalArgument.isSuspendLambda(): Boolean =
|
||||
(this is NonInlineableArgumentForInlineableParameterCalledInSuspend && isSuspend) ||
|
||||
(this is PsiExpressionLambda && isSuspend)
|
||||
this is NonInlineableArgumentForInlineableParameterCalledInSuspend || (this is ExpressionLambda && isSuspend)
|
||||
|
||||
fun surroundInvokesWithSuspendMarkers(
|
||||
methodNode: MethodNode,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen.optimization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
@@ -207,13 +208,6 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
refValue.localVarIndex = localVar.index
|
||||
}
|
||||
|
||||
val startIndex = localVar.start.getIndex()
|
||||
val initFieldInsns = refValue.putFieldInsns.filter { it.getIndex() < startIndex }
|
||||
if (initFieldInsns.size != 1) {
|
||||
refValue.hazard = true
|
||||
continue
|
||||
}
|
||||
|
||||
val cleanInstructions = findCleanInstructions(refValue, oldVarIndex, methodNode.instructions)
|
||||
if (cleanInstructions.size > 1) {
|
||||
refValue.hazard = true
|
||||
@@ -227,14 +221,14 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
return InsnSequence(instructions).filterIsInstance<VarInsnNode>().filter {
|
||||
it.opcode == Opcodes.ASTORE && it.`var` == oldVarIndex
|
||||
}.filter {
|
||||
it.previous?.opcode == Opcodes.ACONST_NULL
|
||||
}.filter {
|
||||
val operationIndex = instructions.indexOf(it)
|
||||
val localVariableNode = refValue.localVar!!
|
||||
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(
|
||||
localVariableNode.end
|
||||
)
|
||||
}.toList()
|
||||
it.previous?.opcode == Opcodes.ACONST_NULL
|
||||
}.filter {
|
||||
val operationIndex = instructions.indexOf(it)
|
||||
val localVariableNode = refValue.localVar!!
|
||||
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(
|
||||
localVariableNode.end
|
||||
)
|
||||
}.toList()
|
||||
}
|
||||
|
||||
private fun rewrite() {
|
||||
@@ -250,9 +244,17 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
|
||||
private fun rewriteRefValue(capturedVar: CapturedVarDescriptor) {
|
||||
methodNode.instructions.run {
|
||||
capturedVar.localVar!!.let {
|
||||
it.signature = null
|
||||
it.desc = capturedVar.valueType.descriptor
|
||||
val localVar = capturedVar.localVar!!
|
||||
localVar.signature = null
|
||||
localVar.desc = capturedVar.valueType.descriptor
|
||||
|
||||
val loadOpcode = capturedVar.valueType.getOpcode(Opcodes.ILOAD)
|
||||
val storeOpcode = capturedVar.valueType.getOpcode(Opcodes.ISTORE)
|
||||
|
||||
if (capturedVar.putFieldInsns.none { it.getIndex() < localVar.start.getIndex() }) {
|
||||
// variable needs to be initialized before its live range can begin
|
||||
insertBefore(capturedVar.newInsn, InsnNode(AsmUtil.defaultValueOpcode(capturedVar.valueType)))
|
||||
insertBefore(capturedVar.newInsn, VarInsnNode(storeOpcode, capturedVar.localVarIndex))
|
||||
}
|
||||
|
||||
remove(capturedVar.newInsn)
|
||||
@@ -260,14 +262,8 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
|
||||
capturedVar.stackInsns.forEach { remove(it) }
|
||||
capturedVar.aloadInsns.forEach { remove(it) }
|
||||
capturedVar.astoreInsns.forEach { remove(it) }
|
||||
|
||||
capturedVar.getFieldInsns.forEach {
|
||||
set(it, VarInsnNode(capturedVar.valueType.getOpcode(Opcodes.ILOAD), capturedVar.localVarIndex))
|
||||
}
|
||||
|
||||
capturedVar.putFieldInsns.forEach {
|
||||
set(it, VarInsnNode(capturedVar.valueType.getOpcode(Opcodes.ISTORE), capturedVar.localVarIndex))
|
||||
}
|
||||
capturedVar.getFieldInsns.forEach { set(it, VarInsnNode(loadOpcode, capturedVar.localVarIndex)) }
|
||||
capturedVar.putFieldInsns.forEach { set(it, VarInsnNode(storeOpcode, capturedVar.localVarIndex)) }
|
||||
|
||||
//after visiting block codegen tries to delete all allocated references:
|
||||
// see ExpressionCodegen.addLeaveTaskToRemoveLocalVariableFromFrameMap
|
||||
|
||||
@@ -103,16 +103,16 @@ class RedundantNopsCleanupMethodTransformer : MethodTransformer() {
|
||||
|
||||
|
||||
internal fun getRequiredNopInRange(firstInclusive: AbstractInsnNode, lastExclusive: AbstractInsnNode?): AbstractInsnNode? {
|
||||
var lastNop: AbstractInsnNode? = null
|
||||
var firstNop: AbstractInsnNode? = null
|
||||
var current: AbstractInsnNode? = firstInclusive
|
||||
while (current != null && current != lastExclusive) {
|
||||
if (current.isMeaningful && current.opcode != Opcodes.NOP) {
|
||||
return null
|
||||
} else if (current.opcode == Opcodes.NOP) {
|
||||
lastNop = current
|
||||
} else if (current.opcode == Opcodes.NOP && firstNop == null) {
|
||||
firstNop = current
|
||||
}
|
||||
current = current.next
|
||||
}
|
||||
|
||||
return lastNop
|
||||
return firstNop
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ class GenerationState private constructor(
|
||||
|
||||
val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace
|
||||
val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics {
|
||||
duplicateSignatureFactory.reportDiagnostics()
|
||||
duplicateSignatureFactory?.reportDiagnostics()
|
||||
extraJvmDiagnosticsTrace.bindingContext.diagnostics
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ class GenerationState private constructor(
|
||||
val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||
val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes(module, configuration.languageVersionSettings)
|
||||
val factory: ClassFileFactory
|
||||
private lateinit var duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics
|
||||
private var duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics? = null
|
||||
|
||||
val scriptSpecific = ForScript()
|
||||
|
||||
@@ -284,11 +284,16 @@ class GenerationState private constructor(
|
||||
it
|
||||
},
|
||||
{
|
||||
BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
it, this.bindingContext, diagnostics, this.moduleName, this.languageVersionSettings,
|
||||
shouldGenerate = { !shouldOnlyCollectSignatures(it) },
|
||||
mapAsmMethod = if (isIrBackend) { descriptor: FunctionDescriptor -> irBasedMapAsmMethod(descriptor) } else null
|
||||
).apply { duplicateSignatureFactory = this }
|
||||
// In IR backend, we have more precise information about classes and methods we are going to generate,
|
||||
// and report signature conflict errors in JvmSignatureClashTracker.
|
||||
if (isIrBackend)
|
||||
it
|
||||
else
|
||||
BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
it, this.bindingContext, diagnostics, this.moduleName, this.languageVersionSettings,
|
||||
shouldGenerate = { origin -> !shouldOnlyCollectSignatures(origin) },
|
||||
mapAsmMethod = if (isIrBackend) { descriptor: FunctionDescriptor -> irBasedMapAsmMethod(descriptor) } else null
|
||||
).apply { duplicateSignatureFactory = this }
|
||||
},
|
||||
{ BuilderFactoryForDuplicateClassNameDiagnostics(it, diagnostics) },
|
||||
{
|
||||
|
||||
@@ -67,7 +67,10 @@ dependencies {
|
||||
testCompileOnly(project(it))
|
||||
}
|
||||
testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi", "idea", "idea_rt", "util", "asm-all", rootProject = rootProject) }
|
||||
Platform[193].orLower {
|
||||
testCompileOnly(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
|
||||
}
|
||||
testCompileOnly(intellijDep()) { includeJars("idea", "idea_rt", "util", "asm-all", rootProject = rootProject) }
|
||||
|
||||
Platform[192].orHigher {
|
||||
testRuntimeOnly(intellijPluginDep("java"))
|
||||
|
||||
@@ -31,7 +31,7 @@ if not "%_KOTLIN_RUNNER%"=="" (
|
||||
"%_JAVACMD%" %JAVA_OPTS% "-Dkotlin.home=%_KOTLIN_HOME%" -cp "%_KOTLIN_HOME%\lib\kotlin-runner.jar" ^
|
||||
org.jetbrains.kotlin.runner.Main %*
|
||||
) else (
|
||||
SET _ADDITIONAL_CLASSPATH=""
|
||||
SET _ADDITIONAL_CLASSPATH=
|
||||
|
||||
if not "%_KOTLIN_TOOL%"=="" (
|
||||
set _ADDITIONAL_CLASSPATH=;%_KOTLIN_HOME%\lib\%_KOTLIN_TOOL%
|
||||
|
||||
@@ -30,7 +30,7 @@ dependencies {
|
||||
compile(project(":kotlin-util-io"))
|
||||
compile(project(":compiler:ir.serialization.common"))
|
||||
|
||||
compile(toolsJar())
|
||||
compileOnly(toolsJar())
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
|
||||
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.DevModeOverwritingStrategies.ALL
|
||||
import org.jetbrains.kotlin.cli.common.arguments.DevModeOverwritingStrategies.OLDER
|
||||
|
||||
class K2JSDceArguments : CommonToolArguments() {
|
||||
companion object {
|
||||
@JvmStatic private val serialVersionUID = 0L
|
||||
@@ -48,4 +40,16 @@ class K2JSDceArguments : CommonToolArguments() {
|
||||
)
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
var devMode: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xdev-mode-overwriting-strategy",
|
||||
valueDescription = "{$OLDER|$ALL}",
|
||||
description = "Overwriting strategy during copy dependencies in development mode"
|
||||
)
|
||||
var devModeOverwritingStrategy: String? by NullableStringFreezableVar(null)
|
||||
}
|
||||
|
||||
object DevModeOverwritingStrategies {
|
||||
const val OLDER = "older"
|
||||
const val ALL = "all"
|
||||
}
|
||||
|
||||
@@ -360,8 +360,9 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
|| languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_3
|
||||
) {
|
||||
collector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"IR backend cannot be used with language or API version below 1.3"
|
||||
CompilerMessageSeverity.STRONG_WARNING,
|
||||
"IR backend does not support language or API version lower than 1.3. " +
|
||||
"This can lead to unexpected behavior or compilation failures"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@ dependencies {
|
||||
compile(project(":compiler:cli"))
|
||||
compile(project(":compiler:ir.serialization.js"))
|
||||
runtime(project(":kotlin-reflect"))
|
||||
compile(intellijDep()) { includeJars("picocontainer", "trove4j", "guava", "jdom", rootProject = rootProject) }
|
||||
if (Platform[193].orLower()) {
|
||||
compile(intellijDep()) { includeJars("picocontainer", rootProject = rootProject) }
|
||||
}
|
||||
compile(intellijDep()) { includeJars("trove4j", "guava", "jdom", rootProject = rootProject) }
|
||||
compile(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.js
|
||||
|
||||
import org.jetbrains.kotlin.config.*
|
||||
|
||||
class JSLanguageVersionSettings(private val delegate: LanguageVersionSettings) : LanguageVersionSettings {
|
||||
companion object {
|
||||
private val disabledFeatures = setOf(
|
||||
LanguageFeature.NewInference,
|
||||
LanguageFeature.FunctionalInterfaceConversion,
|
||||
LanguageFeature.SamConversionForKotlinFunctions,
|
||||
LanguageFeature.SamConversionPerArgument,
|
||||
LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType,
|
||||
LanguageFeature.NonStrictOnlyInputTypesChecks
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State {
|
||||
return if (feature in disabledFeatures)
|
||||
LanguageFeature.State.DISABLED
|
||||
else
|
||||
delegate.getFeatureSupport(feature)
|
||||
}
|
||||
|
||||
override fun isPreRelease(): Boolean = delegate.isPreRelease()
|
||||
|
||||
override fun <T> getFlag(flag: AnalysisFlag<T>): T = delegate.getFlag(flag)
|
||||
|
||||
override val apiVersion: ApiVersion
|
||||
get() = delegate.apiVersion
|
||||
|
||||
override val languageVersion: LanguageVersion
|
||||
get() = delegate.languageVersion
|
||||
}
|
||||
@@ -246,6 +246,13 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, FileUtil.getNameWithoutExtension(outputFile));
|
||||
|
||||
if (!arguments.getNewInference()) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(
|
||||
configuration,
|
||||
new JSLanguageVersionSettings(CommonConfigurationKeysKt.getLanguageVersionSettings(configuration))
|
||||
);
|
||||
}
|
||||
|
||||
JsConfig config = new JsConfig(project, configuration);
|
||||
JsConfig.Reporter reporter = new JsConfig.Reporter() {
|
||||
@Override
|
||||
|
||||
@@ -24,10 +24,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||
|
||||
@@ -1,23 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.js.dce
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.CLITool
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.DevModeOverwritingStrategies
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
@@ -63,7 +53,13 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
return if (!arguments.devMode) {
|
||||
performDce(files, arguments, messageCollector)
|
||||
} else {
|
||||
copyFiles(files)
|
||||
val devModeOverwritingStrategy =
|
||||
arguments.devModeOverwritingStrategy ?:
|
||||
System.getProperty("kotlin.js.dce.devmode.overwriting.strategy", DevModeOverwritingStrategies.OLDER)
|
||||
|
||||
val overwriteOnlyOlderFiles = devModeOverwritingStrategy == DevModeOverwritingStrategies.OLDER
|
||||
|
||||
copyFiles(files, overwriteOnlyOlderFiles)
|
||||
ExitCode.OK
|
||||
}
|
||||
}
|
||||
@@ -96,21 +92,22 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
return ExitCode.OK
|
||||
}
|
||||
|
||||
private fun copyFiles(files: List<InputFile>) {
|
||||
private fun copyFiles(files: List<InputFile>, overwriteOnlyOlderFiles: Boolean) {
|
||||
for (file in files) {
|
||||
copyResource(file.resource, File(file.outputPath))
|
||||
copyResource(file.resource, File(file.outputPath), overwriteOnlyOlderFiles)
|
||||
file.sourceMapResource?.let { sourceMap ->
|
||||
val sourceMapTarget = File(file.outputPath + ".map")
|
||||
val inputFile = File(sourceMap.name)
|
||||
if (!inputFile.exists() || !mapSourcePaths(inputFile, sourceMapTarget)) {
|
||||
copyResource(sourceMap, sourceMapTarget)
|
||||
copyResource(sourceMap, sourceMapTarget, overwriteOnlyOlderFiles)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyResource(resource: InputResource, targetFile: File) {
|
||||
if (targetFile.exists() && resource.lastModified() < targetFile.lastModified()) return
|
||||
private fun copyResource(resource: InputResource, targetFile: File, overwriteOnlyOlderFiles: Boolean) {
|
||||
// TODO shouldn't it be "<="?
|
||||
if (overwriteOnlyOlderFiles && targetFile.exists() && resource.lastModified() < targetFile.lastModified()) return
|
||||
|
||||
targetFile.parentFile.mkdirs()
|
||||
resource.reader().use { input ->
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.cli.common.messages.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.setupIdeaStandaloneExecution
|
||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.Kind.BUG_FIX
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.State.ENABLED
|
||||
@@ -204,6 +205,9 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
if (System.getProperty(PlainTextMessageRenderer.KOTLIN_COLORS_ENABLED_PROPERTY) == null) {
|
||||
System.setProperty(PlainTextMessageRenderer.KOTLIN_COLORS_ENABLED_PROPERTY, "true")
|
||||
}
|
||||
|
||||
setupIdeaStandaloneExecution()
|
||||
|
||||
val exitCode = doMainNoExit(compiler, args)
|
||||
if (exitCode != ExitCode.OK) {
|
||||
exitProcess(exitCode.code)
|
||||
|
||||
@@ -30,15 +30,14 @@ import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.KeyWithDefaultValue;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.TypeAnnotationModifier;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.impl.PsiSubstitutorFactoryImpl;
|
||||
import com.intellij.psi.impl.LanguageConstantExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiSubstitutorFactoryImpl;
|
||||
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
|
||||
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
|
||||
import com.intellij.psi.impl.search.MethodSuperSearcher;
|
||||
@@ -53,9 +52,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
|
||||
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.DynamicBundle;
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.FileContextProvider;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
registerExtensionPoints();
|
||||
return environment;
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private static void registerExtensionPoints() {
|
||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
registerApplicationExtensionPoint(ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.JavaContainerProvider;
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsBase;
|
||||
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilderBase;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.CoreApplicationEnvironment;
|
||||
import com.intellij.core.CoreJavaDirectoryService;
|
||||
import com.intellij.core.CorePsiPackageImplementationHelper;
|
||||
import com.intellij.ide.highlighter.ArchiveFileType;
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.lang.LanguageASTFactory;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.lang.folding.LanguageFolding;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.navigation.ItemPresentationProviders;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.extensions.ExtensionsArea;
|
||||
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
|
||||
import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.util.KeyWithDefaultValue;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.augment.TypeAnnotationModifier;
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||
import com.intellij.psi.impl.EmptySubstitutorImpl;
|
||||
import com.intellij.psi.impl.LanguageConstantExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiExpressionEvaluator;
|
||||
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
|
||||
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
|
||||
import com.intellij.psi.impl.search.MethodSuperSearcher;
|
||||
import com.intellij.psi.impl.source.tree.JavaASTFactory;
|
||||
import com.intellij.psi.impl.source.tree.PlainTextASTFactory;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import com.intellij.psi.presentation.java.*;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.stubs.BinaryFileStubBuilders;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
|
||||
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
|
||||
*/
|
||||
public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment {
|
||||
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
return new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
|
||||
registerExtensionPoints();
|
||||
|
||||
registerExtensions();
|
||||
}
|
||||
|
||||
private void registerExtensionPoints() {
|
||||
ExtensionsArea area = Extensions.getRootArea();
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier.class);
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(area);
|
||||
}
|
||||
|
||||
private void registerExtensions() {
|
||||
registerFileType(JavaClassFileType.INSTANCE, "class");
|
||||
registerFileType(JavaFileType.INSTANCE, "java");
|
||||
registerFileType(ArchiveFileType.INSTANCE, "jar;zip");
|
||||
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
|
||||
|
||||
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
|
||||
registerParserDefinition(new PlainTextParserDefinition());
|
||||
|
||||
addExplicitExtension(FileTypeFileViewProviders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileViewProviderFactory());
|
||||
addExplicitExtension(BinaryFileStubBuilders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileStubBuilder());
|
||||
|
||||
addExplicitExtension(LanguageASTFactory.INSTANCE, JavaLanguage.INSTANCE, new JavaASTFactory());
|
||||
registerParserDefinition(new JavaParserDefinition());
|
||||
addExplicitExtension(LanguageConstantExpressionEvaluator.INSTANCE, JavaLanguage.INSTANCE, new PsiExpressionEvaluator());
|
||||
|
||||
addExtension(ContainerProvider.EP_NAME, new JavaContainerProvider());
|
||||
|
||||
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
|
||||
|
||||
EmptySubstitutorImpl emptySubstitutor = new EmptySubstitutorImpl();
|
||||
myApplication.registerService(EmptySubstitutor.class, emptySubstitutor);
|
||||
|
||||
// Patch null values obtained because of cyclic dependency during initialization
|
||||
updateInterfaceField(PsiSubstitutor.class, "EMPTY", emptySubstitutor);
|
||||
updateInterfaceField(PsiSubstitutor.class, "UNKNOWN", PsiSubstitutor.EMPTY);
|
||||
|
||||
myApplication.registerService(JavaDirectoryService.class, createJavaDirectoryService());
|
||||
myApplication.registerService(JavaVersionService.class, new JavaVersionService());
|
||||
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiPackage.class, new PackagePresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiClass.class, new ClassPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiMethod.class, new MethodPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiField.class, new FieldPresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider());
|
||||
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider());
|
||||
|
||||
registerApplicationService(JavaCodeFoldingSettings.class, new JavaCodeFoldingSettingsBase());
|
||||
addExplicitExtension(LanguageFolding.INSTANCE, JavaLanguage.INSTANCE, new JavaFoldingBuilderBase() {
|
||||
@Override
|
||||
protected boolean shouldShowExplicitLambdaType(@NotNull PsiAnonymousClass anonymousClass, @NotNull PsiNewExpression expression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isBelowRightMargin(@NotNull PsiFile file, int lineLength) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
registerApplicationExtensionPoint(SuperMethodsSearch.EP_NAME, QueryExecutor.class);
|
||||
addExtension(SuperMethodsSearch.EP_NAME, new MethodSuperSearcher());
|
||||
}
|
||||
|
||||
// overridden in upsource
|
||||
protected CoreJavaDirectoryService createJavaDirectoryService() {
|
||||
return new CoreJavaDirectoryService();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
|
||||
private static void updateInterfaceField(Class<?> klass, String name, Object value) {
|
||||
try {
|
||||
Field field = klass.getDeclaredField(name);
|
||||
|
||||
boolean wasAccessible = field.isAccessible();
|
||||
|
||||
try {
|
||||
if (!wasAccessible) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
|
||||
int modifiers = field.getModifiers();
|
||||
|
||||
try {
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, modifiers & ~Modifier.FINAL);
|
||||
|
||||
field.set(null, value);
|
||||
}
|
||||
finally {
|
||||
modifiersField.setInt(field, modifiers);
|
||||
modifiersField.setAccessible(false);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (!wasAccessible) {
|
||||
field.setAccessible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
)
|
||||
|
||||
val (initialRoots, javaModules) =
|
||||
classpathRootsResolver.convertClasspathRoots(configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS))
|
||||
classpathRootsResolver.convertClasspathRoots(configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS))
|
||||
this.initialRoots.addAll(initialRoots)
|
||||
|
||||
if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) {
|
||||
@@ -228,7 +228,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
val (roots, singleJavaFileRoots) =
|
||||
initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION }
|
||||
initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION }
|
||||
|
||||
// REPL and kapt2 update classpath dynamically
|
||||
rootsIndex = JvmDependenciesDynamicCompoundIndex().apply {
|
||||
@@ -421,6 +421,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
fun createForProduction(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles
|
||||
): KotlinCoreEnvironment {
|
||||
setupIdeaStandaloneExecution()
|
||||
val appEnv = getOrCreateApplicationEnvironmentForProduction(parentDisposable, configuration)
|
||||
val projectEnv = ProjectEnvironment(parentDisposable, appEnv)
|
||||
val environment = KotlinCoreEnvironment(projectEnv, configuration, configFiles)
|
||||
@@ -528,7 +529,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
false
|
||||
}
|
||||
|
||||
val pluginRoot =
|
||||
val pluginRoot: File =
|
||||
configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File)
|
||||
?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) }
|
||||
// hack for load extensions when compiler run directly from project directory (e.g. in tests)
|
||||
@@ -538,7 +539,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
"(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})"
|
||||
)
|
||||
|
||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, configFilePath, Extensions.getRootArea())
|
||||
registerExtensionPointAndExtensionsEx(pluginRoot, configFilePath, Extensions.getRootArea())
|
||||
}
|
||||
|
||||
private fun workaroundIbmJdkStaxReportCdataEventIssue() {
|
||||
@@ -714,5 +715,4 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||
import org.jetbrains.kotlin.backend.jvm.jvmPhases
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
@@ -59,6 +60,7 @@ import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc
|
||||
import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
@@ -339,8 +341,11 @@ object KotlinToJVMBytecodeCompiler {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
val signaturer = IdSignatureDescriptor(JvmManglerDesc())
|
||||
|
||||
val (moduleFragment, symbolTable, sourceManager) =
|
||||
Fir2IrConverter.createModuleFragment(session, firFiles, moduleConfiguration.languageVersionSettings)
|
||||
Fir2IrConverter.createModuleFragment(session, firFiles, moduleConfiguration.languageVersionSettings, signaturer = signaturer)
|
||||
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
|
||||
|
||||
val codegenFactory = JvmIrCodegenFactory(moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
|
||||
|
||||
@@ -71,7 +71,7 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtens
|
||||
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
|
||||
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import java.util.*
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
fun setupIdeaStandaloneExecution() {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
fun setupIdeaStandaloneExecution() {
|
||||
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
|
||||
System.getProperties().setProperty("project.structure.add.tools.jar.to.new.jdk", "false")
|
||||
System.getProperties().setProperty("psi.track.invalidation", "true")
|
||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
import java.io.File
|
||||
|
||||
// BUNCH: 193
|
||||
fun registerExtensionPointAndExtensionsEx(pluginFile: File, fileName: String, area: ExtensionsArea) {
|
||||
@Suppress("MissingRecentApi")
|
||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginFile, fileName, area)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
import java.io.File
|
||||
import java.nio.file.FileSystems
|
||||
|
||||
// BUNCH: 193
|
||||
fun registerExtensionPointAndExtensionsEx(pluginFile: File, fileName: String, area: ExtensionsArea) {
|
||||
val pluginRoot = FileSystems.getDefault().getPath(pluginFile.path)
|
||||
@Suppress("MissingRecentApi")
|
||||
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, fileName, area)
|
||||
}
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.cli.metadata
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
@@ -27,7 +26,8 @@ import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||
import org.jetbrains.kotlin.library.*
|
||||
import org.jetbrains.kotlin.library.impl.buildKoltinLibrary
|
||||
import org.jetbrains.kotlin.library.impl.createKotlinLibraryComponents
|
||||
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
|
||||
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
|
||||
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -68,7 +68,6 @@ internal class K2MetadataKlibSerializer(private val metadataVersion: BuiltInsBin
|
||||
val serializedMetadata: SerializedMetadata = KlibMetadataMonolithicSerializer(
|
||||
configuration.languageVersionSettings,
|
||||
metadataVersion,
|
||||
DescriptorTable.createDefault(),
|
||||
skipExpects = false,
|
||||
includeOnlyModuleContent = true
|
||||
).serializeModule(module)
|
||||
@@ -167,7 +166,8 @@ private class KlibMetadataDependencyContainer(
|
||||
KlibMetadataModuleDescriptorFactoryImpl(
|
||||
MetadataFactories.DefaultDescriptorFactory,
|
||||
MetadataFactories.DefaultPackageFragmentsFactory,
|
||||
MetadataFactories.flexibleTypeDeserializer
|
||||
MetadataFactories.flexibleTypeDeserializer,
|
||||
MetadataFactories.platformDependentTypeTransformer
|
||||
)
|
||||
}
|
||||
|
||||
@@ -197,5 +197,6 @@ private class KlibMetadataDependencyContainer(
|
||||
private val MetadataFactories =
|
||||
KlibMetadataFactories(
|
||||
{ DefaultBuiltIns.Instance },
|
||||
org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer
|
||||
NullFlexibleTypeDeserializer,
|
||||
NativeTypeTransformer()
|
||||
)
|
||||
@@ -49,11 +49,7 @@ sourceSets {
|
||||
|
||||
publish()
|
||||
|
||||
noDefaultJar()
|
||||
|
||||
runtimeJar(tasks.register<ShadowJar>("shadowJar")) {
|
||||
from(mainSourceSet.output)
|
||||
}
|
||||
runtimeJar()
|
||||
|
||||
sourcesJar()
|
||||
|
||||
|
||||
@@ -63,11 +63,7 @@ sourceSets {
|
||||
|
||||
publish()
|
||||
|
||||
noDefaultJar()
|
||||
|
||||
runtimeJar(tasks.register<ShadowJar>("shadowJar")) {
|
||||
from(mainSourceSet.output)
|
||||
}
|
||||
runtimeJar()
|
||||
|
||||
sourcesJar()
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ class RemoteIncrementalResultsConsumer(val facade: CompilerCallbackServicesFacad
|
||||
override fun processIrFile(
|
||||
sourceFile: File,
|
||||
fileData: ByteArray,
|
||||
symbols: ByteArray,
|
||||
types: ByteArray,
|
||||
signatures: ByteArray,
|
||||
strings: ByteArray,
|
||||
declarations: ByteArray,
|
||||
bodies: ByteArray,
|
||||
@@ -29,8 +29,7 @@ class RemoteIncrementalResultsConsumer(val facade: CompilerCallbackServicesFacad
|
||||
}
|
||||
|
||||
init {
|
||||
eventManager.
|
||||
onCompilationFinished(this::flush)
|
||||
eventManager.onCompilationFinished(this::flush)
|
||||
}
|
||||
|
||||
override fun processHeader(headerMetadata: ByteArray) {
|
||||
|
||||
@@ -25,27 +25,25 @@ enum class ProjectionKind {
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
|
||||
sealed class ConeTypeProjection : TypeArgumentMarker {
|
||||
abstract val kind: ProjectionKind
|
||||
|
||||
companion object {
|
||||
val EMPTY_ARRAY = arrayOf<ConeKotlinTypeProjection>()
|
||||
val EMPTY_ARRAY = arrayOf<ConeTypeProjection>()
|
||||
}
|
||||
}
|
||||
|
||||
object ConeStarProjection : ConeKotlinTypeProjection() {
|
||||
object ConeStarProjection : ConeTypeProjection() {
|
||||
override val kind: ProjectionKind
|
||||
get() = ProjectionKind.STAR
|
||||
}
|
||||
|
||||
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection(),
|
||||
ConeTypedProjection {
|
||||
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection() {
|
||||
override val kind: ProjectionKind
|
||||
get() = ProjectionKind.IN
|
||||
}
|
||||
|
||||
data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : ConeKotlinTypeProjection(),
|
||||
ConeTypedProjection {
|
||||
data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : ConeKotlinTypeProjection() {
|
||||
override val kind: ProjectionKind
|
||||
get() = ProjectionKind.OUT
|
||||
}
|
||||
@@ -53,13 +51,12 @@ data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : Cone
|
||||
// We assume type IS an invariant type projection to prevent additional wrapper here
|
||||
// (more exactly, invariant type projection contains type)
|
||||
sealed class ConeKotlinType : ConeKotlinTypeProjection(),
|
||||
ConeTypedProjection,
|
||||
KotlinTypeMarker,
|
||||
TypeArgumentListMarker {
|
||||
override val kind: ProjectionKind
|
||||
get() = ProjectionKind.INVARIANT
|
||||
|
||||
abstract val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
abstract val typeArguments: Array<out ConeTypeProjection>
|
||||
|
||||
override val type: ConeKotlinType
|
||||
get() = this
|
||||
@@ -73,8 +70,8 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(),
|
||||
|
||||
sealed class ConeSimpleKotlinType : ConeKotlinType(), SimpleTypeMarker
|
||||
|
||||
interface ConeTypedProjection {
|
||||
val type: ConeKotlinType
|
||||
sealed class ConeKotlinTypeProjection : ConeTypeProjection() {
|
||||
abstract val type: ConeKotlinType
|
||||
}
|
||||
|
||||
typealias ConeKotlinErrorType = ConeClassErrorType
|
||||
@@ -85,7 +82,7 @@ class ConeClassErrorType(val reason: String) : ConeClassLikeType() {
|
||||
override val lookupTag: ConeClassLikeLookupTag
|
||||
get() = ConeClassLikeErrorLookupTag(ClassId.fromString("<error>"))
|
||||
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = EMPTY_ARRAY
|
||||
|
||||
override val nullability: ConeNullability
|
||||
@@ -109,7 +106,7 @@ open class ConeFlexibleType(val lowerBound: ConeKotlinType, val upperBound: Cone
|
||||
require(upperBound is SimpleTypeMarker, message)
|
||||
}
|
||||
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = emptyArray()
|
||||
|
||||
override val nullability: ConeNullability
|
||||
@@ -139,7 +136,7 @@ fun ConeKotlinType.upperBoundIfFlexible() = (this as? ConeFlexibleType)?.upperBo
|
||||
fun ConeKotlinType.lowerBoundIfFlexible() = (this as? ConeFlexibleType)?.lowerBound ?: this
|
||||
|
||||
class ConeCapturedTypeConstructor(
|
||||
val projection: ConeKotlinTypeProjection,
|
||||
val projection: ConeTypeProjection,
|
||||
var supertypes: List<ConeKotlinType>? = null,
|
||||
val typeParameterMarker: TypeParameterMarker? = null
|
||||
) : CapturedTypeConstructorMarker
|
||||
@@ -151,7 +148,7 @@ class ConeCapturedType(
|
||||
val constructor: ConeCapturedTypeConstructor
|
||||
) : ConeSimpleKotlinType(), CapturedTypeMarker {
|
||||
constructor(
|
||||
captureStatus: CaptureStatus, lowerType: ConeKotlinType?, projection: ConeKotlinTypeProjection,
|
||||
captureStatus: CaptureStatus, lowerType: ConeKotlinType?, projection: ConeTypeProjection,
|
||||
typeParameterMarker: TypeParameterMarker
|
||||
) : this(
|
||||
captureStatus,
|
||||
@@ -162,7 +159,7 @@ class ConeCapturedType(
|
||||
)
|
||||
)
|
||||
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = emptyArray()
|
||||
}
|
||||
|
||||
@@ -170,11 +167,11 @@ data class ConeTypeVariableType(
|
||||
override val nullability: ConeNullability,
|
||||
override val lookupTag: ConeClassifierLookupTag
|
||||
) : ConeLookupTagBasedType() {
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection> get() = emptyArray()
|
||||
override val typeArguments: Array<out ConeTypeProjection> get() = emptyArray()
|
||||
}
|
||||
|
||||
data class ConeDefinitelyNotNullType(val original: ConeKotlinType) : ConeSimpleKotlinType(), DefinitelyNotNullTypeMarker {
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = original.typeArguments
|
||||
override val nullability: ConeNullability
|
||||
get() = ConeNullability.NOT_NULL
|
||||
@@ -193,7 +190,7 @@ class ConeRawType(lowerBound: ConeKotlinType, upperBound: ConeKotlinType) : Cone
|
||||
class ConeIntersectionType(
|
||||
val intersectedTypes: Collection<ConeKotlinType>
|
||||
) : ConeSimpleKotlinType(), TypeConstructorMarker {
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = emptyArray()
|
||||
|
||||
override val nullability: ConeNullability
|
||||
@@ -205,7 +202,7 @@ fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): Con
|
||||
}
|
||||
|
||||
class ConeStubType(val variable: ConeTypeVariable, override val nullability: ConeNullability) : StubTypeMarker, ConeSimpleKotlinType() {
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>
|
||||
override val typeArguments: Array<out ConeTypeProjection>
|
||||
get() = emptyArray()
|
||||
}
|
||||
|
||||
@@ -226,7 +223,7 @@ abstract class ConeIntegerLiteralType(val value: Long) : ConeSimpleKotlinType(),
|
||||
abstract val possibleTypes: Collection<ConeClassLikeType>
|
||||
abstract val supertypes: List<ConeClassLikeType>
|
||||
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection> = emptyArray()
|
||||
override val typeArguments: Array<out ConeTypeProjection> = emptyArray()
|
||||
override val nullability: ConeNullability = ConeNullability.NOT_NULL
|
||||
|
||||
abstract fun getApproximatedType(expectedType: ConeKotlinType? = null): ConeClassLikeType
|
||||
|
||||
@@ -15,7 +15,7 @@ fun ConeKotlinType.render(): String {
|
||||
is ConeTypeVariableType -> "TypeVariable(${this.lookupTag.name})"
|
||||
is ConeDefinitelyNotNullType -> "${original.render()}!!"
|
||||
is ConeClassErrorType -> "ERROR CLASS: $reason"
|
||||
is ConeCapturedType -> "captured type: lowerType = ${lowerType?.render()}"
|
||||
is ConeCapturedType -> "CapturedType(${constructor.projection.render()})"
|
||||
is ConeClassLikeType -> {
|
||||
buildString {
|
||||
append(lookupTag.classId.asString())
|
||||
@@ -45,12 +45,12 @@ fun ConeKotlinType.render(): String {
|
||||
postfix = ")"
|
||||
)
|
||||
}
|
||||
is ConeStubType -> "stub type: $variable"
|
||||
is ConeStubType -> "Stub: $variable"
|
||||
is ConeIntegerLiteralType -> "ILT: $value"
|
||||
} + nullabilitySuffix
|
||||
}
|
||||
|
||||
private fun ConeKotlinTypeProjection.render(): String {
|
||||
private fun ConeTypeProjection.render(): String {
|
||||
return when (this) {
|
||||
ConeStarProjection -> "*"
|
||||
is ConeKotlinTypeProjectionIn -> "in ${type.render()}"
|
||||
|
||||
@@ -7,12 +7,12 @@ package org.jetbrains.kotlin.fir.types.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||
|
||||
class ConeClassLikeTypeImpl(
|
||||
override val lookupTag: ConeClassLikeLookupTag,
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection>,
|
||||
override val typeArguments: Array<out ConeTypeProjection>,
|
||||
isNullable: Boolean
|
||||
) : ConeClassLikeType() {
|
||||
override val nullability: ConeNullability = ConeNullability.create(isNullable)
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.backend.left
|
||||
import org.jetbrains.kotlin.fir.backend.right
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
|
||||
@@ -22,9 +24,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.directExpansionType
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirInapplicableCandidateError
|
||||
@@ -698,10 +698,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
generate(variableAssignment.rValue)
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(projection: ConeKotlinTypeProjection) {
|
||||
private fun FlowContent.generate(projection: ConeTypeProjection) {
|
||||
when (projection) {
|
||||
is ConeStarProjection -> +"*"
|
||||
is ConeTypedProjection -> {
|
||||
is ConeKotlinTypeProjection -> {
|
||||
when (projection.kind) {
|
||||
ProjectionKind.IN -> keyword("in ")
|
||||
ProjectionKind.OUT -> keyword("out ")
|
||||
@@ -1412,11 +1412,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
|
||||
private fun FlowContent.generate(resolvedQualifier: FirResolvedQualifier) {
|
||||
resolved {
|
||||
val symbolProvider = session.firSymbolProvider
|
||||
val classId = resolvedQualifier.classId
|
||||
if (classId != null) {
|
||||
symbolRef(symbolProvider.getClassLikeSymbolByFqName(classId)) {
|
||||
fqn(classId.relativeClassName)
|
||||
val symbol = resolvedQualifier.symbol
|
||||
if (symbol != null) {
|
||||
symbolRef(symbol) {
|
||||
fqn(resolvedQualifier.classId?.relativeClassName ?: FqName("<???>"))
|
||||
}
|
||||
} else {
|
||||
fqn(resolvedQualifier.packageFqName)
|
||||
@@ -1476,11 +1475,29 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
is FirOperatorCall -> generate(expression)
|
||||
is FirBinaryLogicExpression -> generate(expression)
|
||||
is FirCheckNotNullCall -> generate(expression)
|
||||
is FirVarargArgumentsExpression -> generate(expression)
|
||||
is FirResolvedReifiedParameterReference -> generate(expression)
|
||||
is FirComparisonExpression -> generate(expression)
|
||||
else -> inlineUnsupported(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(comparisonExpression: FirComparisonExpression) {
|
||||
generate(comparisonExpression.left)
|
||||
+" ${comparisonExpression.operation.operator} "
|
||||
generate(comparisonExpression.right)
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(resolvedReifiedParameterReference: FirResolvedReifiedParameterReference) {
|
||||
val typeParameter = resolvedReifiedParameterReference.symbol.fir
|
||||
+typeParameter.name.identifier
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(varargArgumentExpression: FirVarargArgumentsExpression) {
|
||||
generateList(varargArgumentExpression.arguments, separator = ",") { generate(it) }
|
||||
}
|
||||
|
||||
private fun FlowContent.generate(binaryLogicExpression: FirBinaryLogicExpression) {
|
||||
generate(binaryLogicExpression.leftOperand)
|
||||
+" ${binaryLogicExpression.kind.token} "
|
||||
|
||||
@@ -8,6 +8,9 @@ package org.jetbrains.kotlin.fir.backend
|
||||
import com.intellij.psi.PsiCompiledElement
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
@@ -31,6 +34,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -46,47 +50,72 @@ internal fun <T : IrElement> FirElement.convertWithOffsets(
|
||||
|
||||
internal fun createErrorType(): IrErrorType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||
|
||||
fun FirTypeRef.toIrType(session: FirSession, declarationStorage: Fir2IrDeclarationStorage, irBuiltIns: IrBuiltIns): IrType {
|
||||
internal enum class ConversionTypeOrigin {
|
||||
DEFAULT,
|
||||
SETTER
|
||||
}
|
||||
|
||||
class ConversionTypeContext internal constructor(
|
||||
internal val definitelyNotNull: Boolean,
|
||||
internal val origin: ConversionTypeOrigin
|
||||
) {
|
||||
fun definitelyNotNull() = ConversionTypeContext(true, origin)
|
||||
|
||||
fun inSetter() = ConversionTypeContext(definitelyNotNull, ConversionTypeOrigin.SETTER)
|
||||
|
||||
companion object {
|
||||
internal val DEFAULT = ConversionTypeContext(
|
||||
definitelyNotNull = false, origin = ConversionTypeOrigin.DEFAULT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeRef.toIrType(
|
||||
session: FirSession,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
): IrType {
|
||||
if (this !is FirResolvedTypeRef) {
|
||||
return createErrorType()
|
||||
}
|
||||
return type.toIrType(session, declarationStorage, irBuiltIns)
|
||||
return type.toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.toIrType(
|
||||
session: FirSession,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
definitelyNotNull: Boolean = false
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
): IrType {
|
||||
return when (this) {
|
||||
is ConeKotlinErrorType -> createErrorType()
|
||||
is ConeLookupTagBasedType -> {
|
||||
val irSymbol = getArrayType(this.classId, irBuiltIns) ?: run {
|
||||
val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType()
|
||||
firSymbol.toIrSymbol(session, declarationStorage)
|
||||
firSymbol.toIrSymbol(session, declarationStorage, typeContext)
|
||||
}
|
||||
// TODO: annotations
|
||||
IrSimpleTypeImpl(
|
||||
irSymbol, !definitelyNotNull && this.isMarkedNullable,
|
||||
irSymbol, !typeContext.definitelyNotNull && this.isMarkedNullable,
|
||||
typeArguments.map { it.toIrTypeArgument(session, declarationStorage, irBuiltIns) },
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
is ConeFlexibleType -> {
|
||||
// TODO: yet we take more general type. Not quite sure it's Ok
|
||||
upperBound.toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull)
|
||||
upperBound.toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||
}
|
||||
is ConeCapturedType -> TODO()
|
||||
is ConeDefinitelyNotNullType -> {
|
||||
original.toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull = true)
|
||||
original.toIrType(session, declarationStorage, irBuiltIns, typeContext.definitelyNotNull())
|
||||
}
|
||||
is ConeIntersectionType -> {
|
||||
// TODO: add intersectionTypeApproximation
|
||||
intersectedTypes.first().toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull)
|
||||
intersectedTypes.first().toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||
}
|
||||
is ConeStubType -> createErrorType()
|
||||
is ConeIntegerLiteralType -> getApproximatedType().toIrType(session, declarationStorage, irBuiltIns, definitelyNotNull)
|
||||
is ConeIntegerLiteralType -> getApproximatedType().toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +135,7 @@ private fun getArrayType(classId: ClassId?, irBuiltIns: IrBuiltIns): IrClassifie
|
||||
return irType?.let { irBuiltIns.primitiveArrayForType.getValue(it) }
|
||||
}
|
||||
|
||||
fun ConeKotlinTypeProjection.toIrTypeArgument(
|
||||
fun ConeTypeProjection.toIrTypeArgument(
|
||||
session: FirSession,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
irBuiltIns: IrBuiltIns
|
||||
@@ -128,10 +157,14 @@ fun ConeKotlinTypeProjection.toIrTypeArgument(
|
||||
}
|
||||
}
|
||||
|
||||
fun FirClassifierSymbol<*>.toIrSymbol(session: FirSession, declarationStorage: Fir2IrDeclarationStorage): IrClassifierSymbol {
|
||||
fun FirClassifierSymbol<*>.toIrSymbol(
|
||||
session: FirSession,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
): IrClassifierSymbol {
|
||||
return when (this) {
|
||||
is FirTypeParameterSymbol -> {
|
||||
toTypeParameterSymbol(declarationStorage)
|
||||
toTypeParameterSymbol(declarationStorage, typeContext)
|
||||
}
|
||||
is FirTypeAliasSymbol -> {
|
||||
val typeAlias = fir
|
||||
@@ -147,7 +180,18 @@ fun FirClassifierSymbol<*>.toIrSymbol(session: FirSession, declarationStorage: F
|
||||
|
||||
fun FirReference.toSymbol(declarationStorage: Fir2IrDeclarationStorage): IrSymbol? {
|
||||
return when (this) {
|
||||
is FirResolvedNamedReference -> resolvedSymbol.toSymbol(declarationStorage)
|
||||
is FirResolvedNamedReference -> {
|
||||
when (val resolvedSymbol = resolvedSymbol) {
|
||||
is FirCallableSymbol<*> -> {
|
||||
val originalCallableSymbol =
|
||||
resolvedSymbol.overriddenSymbol?.takeIf { it.callableId == resolvedSymbol.callableId } ?: resolvedSymbol
|
||||
originalCallableSymbol.toSymbol(declarationStorage)
|
||||
}
|
||||
else -> {
|
||||
resolvedSymbol.toSymbol(declarationStorage)
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirThisReference -> {
|
||||
when (val boundSymbol = boundSymbol?.toSymbol(declarationStorage)) {
|
||||
is IrClassSymbol -> boundSymbol.owner.thisReceiver?.symbol
|
||||
@@ -174,8 +218,11 @@ fun FirClassSymbol<*>.toClassSymbol(declarationStorage: Fir2IrDeclarationStorage
|
||||
return declarationStorage.getIrClassSymbol(this)
|
||||
}
|
||||
|
||||
fun FirTypeParameterSymbol.toTypeParameterSymbol(declarationStorage: Fir2IrDeclarationStorage): IrTypeParameterSymbol {
|
||||
return declarationStorage.getIrTypeParameterSymbol(this)
|
||||
fun FirTypeParameterSymbol.toTypeParameterSymbol(
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
): IrTypeParameterSymbol {
|
||||
return declarationStorage.getIrTypeParameterSymbol(this, typeContext)
|
||||
}
|
||||
|
||||
fun FirFunctionSymbol<*>.toFunctionSymbol(declarationStorage: Fir2IrDeclarationStorage): IrFunctionSymbol {
|
||||
@@ -215,3 +262,43 @@ private fun FirConstKind<*>.toIrConstKind(): IrConstKind<*> = when (this) {
|
||||
FirConstKind.Double -> IrConstKind.Double
|
||||
FirConstKind.IntegerLiteral -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
internal fun FirClass<*>.collectCallableNamesFromSupertypes(session: FirSession, result: MutableList<Name> = mutableListOf()): List<Name> {
|
||||
for (superTypeRef in superTypeRefs) {
|
||||
superTypeRef.collectCallableNamesFromThisAndSupertypes(session, result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FirTypeRef.collectCallableNamesFromThisAndSupertypes(
|
||||
session: FirSession,
|
||||
result: MutableList<Name> = mutableListOf()
|
||||
): List<Name> {
|
||||
if (this is FirResolvedTypeRef) {
|
||||
val superType = type
|
||||
if (superType is ConeClassLikeType) {
|
||||
when (val superSymbol = superType.lookupTag.toSymbol(session)) {
|
||||
is FirClassSymbol -> {
|
||||
val superClass = superSymbol.fir as FirClass<*>
|
||||
for (declaration in superClass.declarations) {
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> result += declaration.name
|
||||
is FirVariable<*> -> result += declaration.name
|
||||
}
|
||||
}
|
||||
superClass.collectCallableNamesFromSupertypes(session, result)
|
||||
}
|
||||
is FirTypeAliasSymbol -> {
|
||||
val superAlias = superSymbol.fir
|
||||
superAlias.expandedTypeRef.collectCallableNamesFromThisAndSupertypes(session, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
internal tailrec fun FirCallableSymbol<*>.deepestOverriddenSymbol(): FirCallableSymbol<*> {
|
||||
val overriddenSymbol = overriddenSymbol ?: return this
|
||||
return overriddenSymbol.deepestOverriddenSymbol()
|
||||
}
|
||||
@@ -24,15 +24,16 @@ object Fir2IrConverter {
|
||||
session: FirSession,
|
||||
firFiles: List<FirFile>,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
fakeOverrideMode: FakeOverrideMode = FakeOverrideMode.NORMAL
|
||||
fakeOverrideMode: FakeOverrideMode = FakeOverrideMode.NORMAL,
|
||||
signaturer: IdSignatureComposer
|
||||
): Fir2IrResult {
|
||||
val moduleDescriptor = FirModuleDescriptor(session)
|
||||
val symbolTable = SymbolTable()
|
||||
val symbolTable = SymbolTable(signaturer)
|
||||
val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, symbolTable)
|
||||
val typeTranslator = TypeTranslator(symbolTable, languageVersionSettings, moduleDescriptor.builtIns)
|
||||
constantValueGenerator.typeTranslator = typeTranslator
|
||||
typeTranslator.constantValueGenerator = constantValueGenerator
|
||||
val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable)
|
||||
val builtIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, signaturer, symbolTable)
|
||||
val sourceManager = PsiSourceManager()
|
||||
val fir2irTransformer = Fir2IrVisitor(session, moduleDescriptor, symbolTable, sourceManager, builtIns, fakeOverrideMode)
|
||||
val irFiles = mutableListOf<IrFile>()
|
||||
|
||||
@@ -14,15 +14,12 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.getOrPut
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||
@@ -64,6 +61,8 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
private val typeParameterCache = mutableMapOf<FirTypeParameter, IrTypeParameter>()
|
||||
|
||||
private val typeParameterCacheForSetter = mutableMapOf<FirTypeParameter, IrTypeParameter>()
|
||||
|
||||
private val functionCache = mutableMapOf<FirSimpleFunction, IrSimpleFunction>()
|
||||
|
||||
private val constructorCache = mutableMapOf<FirConstructor, IrConstructor>()
|
||||
@@ -103,8 +102,11 @@ class Fir2IrDeclarationStorage(
|
||||
irSymbolTable.leaveScope(descriptor)
|
||||
}
|
||||
|
||||
private fun FirTypeRef.toIrType(session: FirSession, declarationStorage: Fir2IrDeclarationStorage) =
|
||||
toIrType(session, declarationStorage, irBuiltIns)
|
||||
private fun FirTypeRef.toIrType(
|
||||
session: FirSession,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
) = toIrType(session, declarationStorage, irBuiltIns, typeContext)
|
||||
|
||||
private fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment {
|
||||
return fragmentCache.getOrPut(fqName) {
|
||||
@@ -113,13 +115,15 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrClass.declareThisReceiver() {
|
||||
enterScope(descriptor)
|
||||
val thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
|
||||
val thisType = IrSimpleTypeImpl(symbol, false, emptyList(), emptyList())
|
||||
val parent = this
|
||||
private fun IrDeclaration.declareThisReceiverParameter(
|
||||
parent: IrDeclarationParent,
|
||||
thisType: IrType,
|
||||
thisOrigin: IrDeclarationOrigin,
|
||||
startOffset: Int = this.startOffset,
|
||||
endOffset: Int = this.endOffset
|
||||
): IrValueParameter {
|
||||
val receiverDescriptor = WrappedReceiverParameterDescriptor()
|
||||
thisReceiver = irSymbolTable.declareValueParameter(
|
||||
return irSymbolTable.declareValueParameter(
|
||||
startOffset, endOffset, thisOrigin, receiverDescriptor, thisType
|
||||
) { symbol ->
|
||||
IrValueParameterImpl(
|
||||
@@ -131,32 +135,59 @@ class Fir2IrDeclarationStorage(
|
||||
receiverDescriptor.bind(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrClass.setThisReceiver() {
|
||||
enterScope(descriptor)
|
||||
val typeArguments = this.typeParameters.map {
|
||||
IrSimpleTypeImpl(it.symbol, false, emptyList(), emptyList())
|
||||
}
|
||||
thisReceiver = declareThisReceiverParameter(
|
||||
parent = this,
|
||||
thisType = IrSimpleTypeImpl(symbol, false, typeArguments, emptyList()),
|
||||
thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER
|
||||
)
|
||||
leaveScope(descriptor)
|
||||
}
|
||||
|
||||
private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass {
|
||||
for (superTypeRef in klass.superTypeRefs) {
|
||||
superTypes += superTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
||||
}
|
||||
if (klass is FirRegularClass) {
|
||||
for ((index, typeParameter) in klass.typeParameters.withIndex()) {
|
||||
typeParameters += getIrTypeParameter(typeParameter, index).apply {
|
||||
parent = this@declareSupertypesAndTypeParameters
|
||||
}
|
||||
private fun preCacheTypeParameters(owner: FirTypeParametersOwner) {
|
||||
owner.typeParameters.mapIndexed { index, typeParameter ->
|
||||
getIrTypeParameter(typeParameter, index)
|
||||
if (owner is FirProperty && owner.isVar) {
|
||||
getIrTypeParameter(typeParameter, index, ConversionTypeContext.DEFAULT.inSetter())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrTypeParametersContainer.setTypeParameters(
|
||||
owner: FirTypeParametersOwner,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
) {
|
||||
typeParameters = owner.typeParameters.mapIndexed { index, typeParameter ->
|
||||
getIrTypeParameter(typeParameter, index, typeContext).apply { parent = this@setTypeParameters }
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrClass.declareSupertypesAndTypeParameters(klass: FirClass<*>): IrClass {
|
||||
if (klass is FirRegularClass) {
|
||||
setTypeParameters(klass)
|
||||
}
|
||||
superTypes = klass.superTypeRefs.map { superTypeRef ->
|
||||
superTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun getIrClass(klass: FirClass<*>, setParent: Boolean = true): IrClass {
|
||||
fun getIrClass(klass: FirClass<*>, setParentAndContent: Boolean = true): IrClass {
|
||||
val regularClass = klass as? FirRegularClass
|
||||
|
||||
fun create(): IrClass {
|
||||
val descriptor = WrappedClassDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val modality = regularClass?.modality ?: Modality.FINAL
|
||||
val visibility = regularClass?.visibility ?: Visibilities.PUBLIC
|
||||
return klass.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality) { symbol ->
|
||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
||||
IrClassImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
@@ -175,7 +206,7 @@ class Fir2IrDeclarationStorage(
|
||||
isFun = false // TODO FirRegularClass.isFun
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
if (setParent && regularClass != null) {
|
||||
if (setParentAndContent && regularClass != null) {
|
||||
val classId = regularClass.classId
|
||||
val parentId = classId.outerClassId
|
||||
if (parentId != null) {
|
||||
@@ -189,7 +220,6 @@ class Fir2IrDeclarationStorage(
|
||||
parent = getIrExternalPackageFragment(packageFqName)
|
||||
}
|
||||
}
|
||||
declareThisReceiver()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,11 +231,61 @@ class Fir2IrDeclarationStorage(
|
||||
val created = create()
|
||||
localStorage.putLocalClass(klass, created)
|
||||
created.declareSupertypesAndTypeParameters(klass)
|
||||
created.setThisReceiver()
|
||||
return created
|
||||
}
|
||||
// NB: klass can be either FirRegularClass or FirAnonymousObject
|
||||
return classCache.getOrPut(klass as FirRegularClass, { create() }) {
|
||||
it.declareSupertypesAndTypeParameters(klass)
|
||||
return classCache.getOrPut(klass as FirRegularClass, { create() }) { irClass ->
|
||||
irClass.declareSupertypesAndTypeParameters(klass)
|
||||
irClass.setThisReceiver()
|
||||
if (setParentAndContent && regularClass != null &&
|
||||
regularClass.symbol.classId.packageFqName.startsWith(Name.identifier("kotlin"))
|
||||
) {
|
||||
// Note: yet this is necessary only for *Range / *Progression classes
|
||||
// due to BE optimizations (for lowering) that use their first / last / step members
|
||||
// TODO: think how to refactor this piece of code and/or merge it with similar Fir2IrVisitor fragment
|
||||
val processedNames = mutableSetOf<Name>()
|
||||
for (declaration in regularClass.declarations) {
|
||||
irClass.declarations += when (declaration) {
|
||||
is FirSimpleFunction -> {
|
||||
processedNames += declaration.name
|
||||
getIrFunction(declaration, irClass, shouldLeaveScope = true)
|
||||
}
|
||||
is FirProperty -> {
|
||||
processedNames += declaration.name
|
||||
getIrProperty(declaration, irClass)
|
||||
}
|
||||
is FirConstructor -> getIrConstructor(declaration, irClass, shouldLeaveScope = true)
|
||||
is FirRegularClass -> getIrClass(declaration)
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
val allNames = regularClass.collectCallableNamesFromSupertypes(session)
|
||||
val scope = regularClass.buildUseSiteMemberScope(session, ScopeSession())
|
||||
if (scope != null) {
|
||||
for (name in allNames) {
|
||||
if (name in processedNames) continue
|
||||
processedNames += name
|
||||
scope.processFunctionsByName(name) { functionSymbol ->
|
||||
if (functionSymbol is FirNamedFunctionSymbol) {
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideFunction(session, functionSymbol.fir, functionSymbol)
|
||||
irClass.declarations += getIrFunction(fakeOverrideSymbol.fir, irClass, shouldLeaveScope = true)
|
||||
}
|
||||
}
|
||||
scope.processPropertiesByName(name) { propertySymbol ->
|
||||
if (propertySymbol is FirPropertySymbol) {
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideProperty(session, propertySymbol.fir, propertySymbol)
|
||||
irClass.declarations += getIrProperty(fakeOverrideSymbol.fir, irClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (irDeclaration in irClass.declarations) {
|
||||
irDeclaration.parent = irClass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,17 +293,18 @@ class Fir2IrDeclarationStorage(
|
||||
val descriptor = WrappedClassDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val modality = Modality.FINAL
|
||||
val visibility = Visibilities.LOCAL
|
||||
return anonymousObject.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality) { symbol ->
|
||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
||||
IrClassImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
Name.special("<no name provided>"), anonymousObject.classKind,
|
||||
Visibilities.LOCAL, modality,
|
||||
visibility, modality,
|
||||
isCompanion = false, isInner = false, isData = false,
|
||||
isExternal = false, isInline = false, isExpect = false, isFun = false
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
declareThisReceiver()
|
||||
setThisReceiver()
|
||||
}
|
||||
}
|
||||
}.declareSupertypesAndTypeParameters(anonymousObject)
|
||||
@@ -233,17 +314,18 @@ class Fir2IrDeclarationStorage(
|
||||
val descriptor = WrappedClassDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val modality = Modality.FINAL
|
||||
val visibility = Visibilities.PRIVATE
|
||||
return anonymousObject.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality) { symbol ->
|
||||
irSymbolTable.declareClass(startOffset, endOffset, origin, descriptor, modality, visibility) { symbol ->
|
||||
IrClassImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
enumEntry.name, anonymousObject.classKind,
|
||||
Visibilities.LOCAL, modality,
|
||||
visibility, modality,
|
||||
isCompanion = false, isInner = false, isData = false,
|
||||
isExternal = false, isInline = false, isExpect = false, isFun = false
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
declareThisReceiver()
|
||||
setThisReceiver()
|
||||
if (irParent != null) {
|
||||
this.parent = irParent
|
||||
}
|
||||
@@ -252,8 +334,33 @@ class Fir2IrDeclarationStorage(
|
||||
}.declareSupertypesAndTypeParameters(anonymousObject)
|
||||
}
|
||||
|
||||
private fun getIrTypeParameter(typeParameter: FirTypeParameter, index: Int = 0): IrTypeParameter {
|
||||
return typeParameterCache[typeParameter] ?: typeParameter.run {
|
||||
private fun getIrTypeParameter(
|
||||
typeParameter: FirTypeParameter,
|
||||
index: Int = -1,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
): IrTypeParameter {
|
||||
// Here transformation is a bit difficult because one FIR property type parameter
|
||||
// can be transformed to two different type parameters: one for getter and another one for setter
|
||||
val simpleCachedParameter = typeParameterCache[typeParameter]
|
||||
if (simpleCachedParameter != null) {
|
||||
if (typeContext.origin != ConversionTypeOrigin.SETTER) {
|
||||
return simpleCachedParameter
|
||||
}
|
||||
if (index < 0) {
|
||||
val parent = simpleCachedParameter.parent
|
||||
if (parent !is IrSimpleFunction || parent.returnType == unitType) {
|
||||
return simpleCachedParameter
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
||||
typeParameterCacheForSetter[typeParameter]?.let { return it }
|
||||
}
|
||||
return typeParameter.run {
|
||||
// Yet I don't want to enable this requirement because it breaks some tests
|
||||
// However, if we get here it *should* mean that type parameter index is given explicitly
|
||||
// At this moment (20.02.2020) this requirement breaks 11/355 Fir2IrText tests
|
||||
// require(index != -1)
|
||||
val descriptor = WrappedTypeParameterDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val irTypeParameter =
|
||||
@@ -261,7 +368,7 @@ class Fir2IrDeclarationStorage(
|
||||
irSymbolTable.declareGlobalTypeParameter(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||
IrTypeParameterImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
name, index,
|
||||
name, if (index < 0) 0 else index,
|
||||
isReified,
|
||||
variance
|
||||
).apply {
|
||||
@@ -271,7 +378,11 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
|
||||
// Cache the type parameter BEFORE processing its bounds/supertypes, to properly handle recursive type bounds.
|
||||
typeParameterCache[typeParameter] = irTypeParameter
|
||||
if (typeContext.origin == ConversionTypeOrigin.SETTER) {
|
||||
typeParameterCacheForSetter[typeParameter] = irTypeParameter
|
||||
} else {
|
||||
typeParameterCache[typeParameter] = irTypeParameter
|
||||
}
|
||||
bounds.mapTo(irTypeParameter.superTypes) { it.toIrType(session, this@Fir2IrDeclarationStorage) }
|
||||
irTypeParameter
|
||||
}
|
||||
@@ -314,75 +425,76 @@ class Fir2IrDeclarationStorage(
|
||||
private fun <T : IrFunction> T.declareDefaultSetterParameter(type: IrType): T {
|
||||
val parent = this
|
||||
val descriptor = WrappedValueParameterDescriptor()
|
||||
valueParameters += irSymbolTable.declareValueParameter(
|
||||
startOffset, endOffset, origin, descriptor, type
|
||||
) { symbol ->
|
||||
IrValueParameterImpl(
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, symbol,
|
||||
Name.special("<set-?>"), 0, type,
|
||||
varargElementType = null,
|
||||
isCrossinline = false, isNoinline = false
|
||||
).apply {
|
||||
this.parent = parent
|
||||
descriptor.bind(this)
|
||||
valueParameters = listOf(
|
||||
irSymbolTable.declareValueParameter(
|
||||
startOffset, endOffset, origin, descriptor, type
|
||||
) { symbol ->
|
||||
IrValueParameterImpl(
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, symbol,
|
||||
Name.special("<set-?>"), 0, type,
|
||||
varargElementType = null,
|
||||
isCrossinline = false, isNoinline = false
|
||||
).apply {
|
||||
this.parent = parent
|
||||
descriptor.bind(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
return this
|
||||
}
|
||||
|
||||
private fun <T : IrFunction> T.declareParameters(function: FirFunction<*>?, containingClass: IrClass?, isStatic: Boolean) {
|
||||
private fun <T : IrFunction> T.declareParameters(
|
||||
function: FirFunction<*>?,
|
||||
containingClass: IrClass?,
|
||||
isStatic: Boolean,
|
||||
// Can be not-null only for property accessors
|
||||
parentPropertyReceiverType: FirTypeRef?
|
||||
) {
|
||||
val parent = this
|
||||
if (function is FirSimpleFunction) {
|
||||
setTypeParameters(function)
|
||||
}
|
||||
val forSetter = function is FirPropertyAccessor && function.isSetter
|
||||
val typeContext = ConversionTypeContext(
|
||||
definitelyNotNull = false,
|
||||
origin = if (forSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||
)
|
||||
if (function is FirDefaultPropertySetter) {
|
||||
val type = function.valueParameters.first().returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
||||
val type = function.valueParameters.first().returnTypeRef.toIrType(
|
||||
session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter()
|
||||
)
|
||||
declareDefaultSetterParameter(type)
|
||||
} else if (function != null) {
|
||||
for ((index, valueParameter) in function.valueParameters.withIndex()) {
|
||||
valueParameters += createAndSaveIrParameter(valueParameter, index).apply { this.parent = parent }
|
||||
valueParameters = function.valueParameters.mapIndexed { index, valueParameter ->
|
||||
createAndSaveIrParameter(
|
||||
valueParameter, index,
|
||||
useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"),
|
||||
typeContext
|
||||
).apply {
|
||||
this.parent = parent
|
||||
}
|
||||
}
|
||||
}
|
||||
if (function !is FirConstructor) {
|
||||
val thisOrigin = IrDeclarationOrigin.DEFINED
|
||||
if (function is FirSimpleFunction) {
|
||||
for ((index, typeParameter) in function.typeParameters.withIndex()) {
|
||||
typeParameters += getIrTypeParameter(typeParameter, index).apply { this.parent = parent }
|
||||
}
|
||||
}
|
||||
val receiverTypeRef = function?.receiverTypeRef
|
||||
val receiverTypeRef = if (function !is FirPropertyAccessor) function?.receiverTypeRef else parentPropertyReceiverType
|
||||
if (receiverTypeRef != null) {
|
||||
extensionReceiverParameter = receiverTypeRef.convertWithOffsets { startOffset, endOffset ->
|
||||
val type = receiverTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
||||
val receiverDescriptor = WrappedReceiverParameterDescriptor()
|
||||
irSymbolTable.declareValueParameter(
|
||||
startOffset, endOffset, thisOrigin,
|
||||
receiverDescriptor, type
|
||||
) { symbol ->
|
||||
IrValueParameterImpl(
|
||||
startOffset, endOffset, thisOrigin, symbol,
|
||||
Name.special("<this>"), -1, type,
|
||||
varargElementType = null, isCrossinline = false, isNoinline = false
|
||||
).apply {
|
||||
this.parent = parent
|
||||
receiverDescriptor.bind(this)
|
||||
}
|
||||
}
|
||||
declareThisReceiverParameter(
|
||||
parent,
|
||||
thisType = receiverTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, typeContext),
|
||||
thisOrigin = thisOrigin,
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset
|
||||
)
|
||||
}
|
||||
}
|
||||
if (containingClass != null && !isStatic) {
|
||||
val thisType = containingClass.thisReceiver!!.type
|
||||
val descriptor = WrappedReceiverParameterDescriptor()
|
||||
dispatchReceiverParameter = irSymbolTable.declareValueParameter(
|
||||
startOffset, endOffset, thisOrigin, descriptor,
|
||||
thisType
|
||||
) { symbol ->
|
||||
IrValueParameterImpl(
|
||||
startOffset, endOffset, thisOrigin, symbol,
|
||||
Name.special("<this>"), -1, thisType,
|
||||
varargElementType = null, isCrossinline = false, isNoinline = false
|
||||
).apply {
|
||||
this.parent = parent
|
||||
descriptor.bind(this)
|
||||
}
|
||||
}
|
||||
dispatchReceiverParameter = declareThisReceiverParameter(
|
||||
parent,
|
||||
thisType = containingClass.thisReceiver!!.type,
|
||||
thisOrigin = thisOrigin
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -392,11 +504,12 @@ class Fir2IrDeclarationStorage(
|
||||
descriptor: WrappedCallableDescriptor<T>,
|
||||
irParent: IrDeclarationParent?,
|
||||
isStatic: Boolean,
|
||||
shouldLeaveScope: Boolean
|
||||
shouldLeaveScope: Boolean,
|
||||
parentPropertyReceiverType: FirTypeRef? = null
|
||||
): T {
|
||||
descriptor.bind(this)
|
||||
enterScope(descriptor)
|
||||
declareParameters(function, containingClass = irParent as? IrClass, isStatic = isStatic)
|
||||
declareParameters(function, irParent as? IrClass, isStatic, parentPropertyReceiverType)
|
||||
if (shouldLeaveScope) {
|
||||
leaveScope(descriptor)
|
||||
}
|
||||
@@ -421,11 +534,13 @@ class Fir2IrDeclarationStorage(
|
||||
fun create(): IrSimpleFunction {
|
||||
val containerSource = function.containerSource
|
||||
val descriptor = containerSource?.let { WrappedFunctionDescriptorWithContainerSource(it) } ?: WrappedSimpleFunctionDescriptor()
|
||||
val updatedOrigin = if (function.symbol.callableId.isKFunctionInvoke()) IrDeclarationOrigin.FAKE_OVERRIDE else origin
|
||||
preCacheTypeParameters(function)
|
||||
return function.convertWithOffsets { startOffset, endOffset ->
|
||||
enterScope(descriptor)
|
||||
val result = irSymbolTable.declareSimpleFunction(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||
IrFunctionImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
startOffset, endOffset, updatedOrigin, symbol,
|
||||
function.name, function.visibility, function.modality!!,
|
||||
function.returnTypeRef.toIrType(session, this),
|
||||
isInline = function.isInline,
|
||||
@@ -433,7 +548,7 @@ class Fir2IrDeclarationStorage(
|
||||
isTailrec = function.isTailRec,
|
||||
isSuspend = function.isSuspend,
|
||||
isExpect = function.isExpect,
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
isFakeOverride = updatedOrigin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
isOperator = function.isOperator
|
||||
)
|
||||
}
|
||||
@@ -456,6 +571,11 @@ class Fir2IrDeclarationStorage(
|
||||
return if (shouldLeaveScope) cached else cached.enterLocalScope(function)
|
||||
}
|
||||
val created = create()
|
||||
if (function.symbol.callableId.isKFunctionInvoke()) {
|
||||
(function.symbol.overriddenSymbol as? FirNamedFunctionSymbol)?.let {
|
||||
created.overriddenSymbols += (it.toFunctionSymbol(this) as IrSimpleFunctionSymbol)
|
||||
}
|
||||
}
|
||||
functionCache[function] = created
|
||||
return created
|
||||
}
|
||||
@@ -521,6 +641,7 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
private fun createIrPropertyAccessor(
|
||||
propertyAccessor: FirPropertyAccessor?,
|
||||
property: FirProperty,
|
||||
correspondingProperty: IrProperty,
|
||||
propertyType: IrType,
|
||||
irParent: IrDeclarationParent?,
|
||||
@@ -529,7 +650,11 @@ class Fir2IrDeclarationStorage(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
): IrSimpleFunction {
|
||||
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||
val propertyDescriptor = correspondingProperty.descriptor
|
||||
val descriptor =
|
||||
if (propertyDescriptor is WrappedPropertyDescriptorWithContainerSource)
|
||||
WrappedFunctionDescriptorWithContainerSource(propertyDescriptor.containerSource)
|
||||
else WrappedSimpleFunctionDescriptor()
|
||||
val prefix = if (isSetter) "set" else "get"
|
||||
return irSymbolTable.declareSimpleFunction(
|
||||
propertyAccessor?.psi?.startOffsetSkippingComments ?: startOffset,
|
||||
@@ -546,11 +671,18 @@ class Fir2IrDeclarationStorage(
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
isOperator = false
|
||||
).apply {
|
||||
setTypeParameters(property, ConversionTypeContext(
|
||||
definitelyNotNull = false,
|
||||
origin = if (isSetter) ConversionTypeOrigin.SETTER else ConversionTypeOrigin.DEFAULT
|
||||
))
|
||||
if (propertyAccessor == null && isSetter) {
|
||||
declareDefaultSetterParameter(propertyType)
|
||||
declareDefaultSetterParameter(
|
||||
property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage, ConversionTypeContext.DEFAULT.inSetter())
|
||||
)
|
||||
}
|
||||
}.bindAndDeclareParameters(
|
||||
propertyAccessor, descriptor, irParent, isStatic = irParent !is IrClass, shouldLeaveScope = true
|
||||
propertyAccessor, descriptor, irParent, isStatic = irParent !is IrClass, shouldLeaveScope = true,
|
||||
parentPropertyReceiverType = property.receiverTypeRef
|
||||
).apply {
|
||||
if (irParent != null) {
|
||||
parent = irParent
|
||||
@@ -586,8 +718,9 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
this.correspondingClass = klass
|
||||
} else if (irParent != null) {
|
||||
this.initializerExpression =
|
||||
IrExpressionBodyImpl(IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol))
|
||||
this.initializerExpression = IrExpressionBodyImpl(
|
||||
IrEnumConstructorCallImpl(startOffset, endOffset, irType, irParent.constructors.first().symbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,6 +738,7 @@ class Fir2IrDeclarationStorage(
|
||||
return propertyCache.getOrPut(property) {
|
||||
val containerSource = property.containerSource
|
||||
val descriptor = containerSource?.let { WrappedPropertyDescriptorWithContainerSource(it) } ?: WrappedPropertyDescriptor()
|
||||
preCacheTypeParameters(property)
|
||||
property.convertWithOffsets { startOffset, endOffset ->
|
||||
enterScope(descriptor)
|
||||
val result = irSymbolTable.declareProperty(
|
||||
@@ -626,7 +760,7 @@ class Fir2IrDeclarationStorage(
|
||||
descriptor.bind(this)
|
||||
val type = property.returnTypeRef.toIrType(session, this@Fir2IrDeclarationStorage)
|
||||
getter = createIrPropertyAccessor(
|
||||
property.getter, this, type, irParent, false,
|
||||
property.getter, property, this, type, irParent, false,
|
||||
when {
|
||||
property.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
|
||||
property.getter is FirDefaultPropertyGetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||
@@ -636,7 +770,7 @@ class Fir2IrDeclarationStorage(
|
||||
)
|
||||
if (property.isVar) {
|
||||
setter = createIrPropertyAccessor(
|
||||
property.setter, this, type, irParent, true,
|
||||
property.setter, property, this, type, irParent, true,
|
||||
when {
|
||||
property.delegate != null -> IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
|
||||
property.setter is FirDefaultPropertySetter -> IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||
@@ -678,7 +812,12 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createAndSaveIrParameter(valueParameter: FirValueParameter, index: Int = -1): IrValueParameter {
|
||||
private fun createAndSaveIrParameter(
|
||||
valueParameter: FirValueParameter,
|
||||
index: Int = -1,
|
||||
useStubForDefaultValueStub: Boolean = true,
|
||||
typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT
|
||||
): IrValueParameter {
|
||||
val descriptor = WrappedValueParameterDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
val type = valueParameter.returnTypeRef.toIrType(session, this)
|
||||
@@ -690,11 +829,16 @@ class Fir2IrDeclarationStorage(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
valueParameter.name, index, type,
|
||||
if (!valueParameter.isVararg) null
|
||||
else valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.arrayElementType(session)?.toIrType(session, this, irBuiltIns),
|
||||
else valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.arrayElementType(session)?.toIrType(
|
||||
session, this, irBuiltIns, typeContext
|
||||
),
|
||||
valueParameter.isCrossinline, valueParameter.isNoinline
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
if (valueParameter.defaultValue != null) {
|
||||
if (valueParameter.defaultValue.let {
|
||||
it != null && (useStubForDefaultValueStub || it !is FirExpressionStub)
|
||||
}
|
||||
) {
|
||||
this.defaultValue = IrExpressionBodyImpl(
|
||||
IrErrorExpressionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, type,
|
||||
@@ -733,11 +877,15 @@ class Fir2IrDeclarationStorage(
|
||||
}
|
||||
}
|
||||
|
||||
fun createAndSaveIrVariable(variable: FirVariable<*>): IrVariable {
|
||||
fun createAndSaveIrVariable(variable: FirVariable<*>, givenOrigin: IrDeclarationOrigin? = null): IrVariable {
|
||||
val type = variable.returnTypeRef.toIrType(session, this)
|
||||
// Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them.
|
||||
val origin =
|
||||
if (variable.name.isSpecial) IrDeclarationOrigin.IR_TEMPORARY_VARIABLE else IrDeclarationOrigin.DEFINED
|
||||
val origin = when {
|
||||
givenOrigin != null -> givenOrigin
|
||||
variable.name == Name.special("<iterator>") -> IrDeclarationOrigin.FOR_LOOP_ITERATOR
|
||||
variable.name.isSpecial -> IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
|
||||
else -> IrDeclarationOrigin.DEFINED
|
||||
}
|
||||
val irVariable = variable.convertWithOffsets { startOffset, endOffset ->
|
||||
declareIrVariable(
|
||||
startOffset, endOffset, origin,
|
||||
@@ -763,8 +911,11 @@ class Fir2IrDeclarationStorage(
|
||||
return irSymbolTable.referenceClass(irClass.descriptor)
|
||||
}
|
||||
|
||||
fun getIrTypeParameterSymbol(firTypeParameterSymbol: FirTypeParameterSymbol): IrTypeParameterSymbol {
|
||||
val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir)
|
||||
fun getIrTypeParameterSymbol(
|
||||
firTypeParameterSymbol: FirTypeParameterSymbol,
|
||||
typeContext: ConversionTypeContext
|
||||
): IrTypeParameterSymbol {
|
||||
val irTypeParameter = getIrTypeParameter(firTypeParameterSymbol.fir, typeContext = typeContext)
|
||||
return irSymbolTable.referenceTypeParameter(irTypeParameter.descriptor)
|
||||
}
|
||||
|
||||
@@ -836,7 +987,14 @@ class Fir2IrDeclarationStorage(
|
||||
fun getIrValueSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol {
|
||||
return when (val firDeclaration = firVariableSymbol.fir) {
|
||||
is FirEnumEntry -> {
|
||||
val irEnumEntry = getIrEnumEntry(firDeclaration)
|
||||
val containingFile = firProvider.getFirCallableContainerFile(firVariableSymbol)
|
||||
val parentClassSymbol = firVariableSymbol.callableId.classId?.let { firSymbolProvider.getClassLikeSymbolByFqName(it) }
|
||||
val irParentClass = (parentClassSymbol?.fir as? FirClass<*>)?.let { getIrClass(it, setParentAndContent = false) }
|
||||
val irEnumEntry = getIrEnumEntry(
|
||||
firDeclaration,
|
||||
irParent = irParentClass,
|
||||
origin = if (containingFile == null) IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB else IrDeclarationOrigin.DEFINED
|
||||
)
|
||||
irSymbolTable.referenceEnumEntry(irEnumEntry.descriptor)
|
||||
}
|
||||
is FirValueParameter -> {
|
||||
|
||||
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
@@ -24,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproxima
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
||||
import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||
@@ -44,12 +47,9 @@ import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
||||
import java.util.*
|
||||
|
||||
class Fir2IrVisitor(
|
||||
@@ -163,9 +163,8 @@ class Fir2IrVisitor(
|
||||
declarations += irDeclaration
|
||||
}
|
||||
|
||||
file.annotations.forEach {
|
||||
val irCall = it.accept(this@Fir2IrVisitor, data) as? IrConstructorCall ?: return@forEach
|
||||
annotations += irCall
|
||||
annotations = file.annotations.mapNotNull {
|
||||
it.accept(this@Fir2IrVisitor, data) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,44 +183,12 @@ class Fir2IrVisitor(
|
||||
return irEnumEntry.setParentByParentStack()
|
||||
}
|
||||
|
||||
private fun FirTypeRef.collectCallableNamesFromThisAndSupertypes(result: MutableList<Name> = mutableListOf()): List<Name> {
|
||||
if (this is FirResolvedTypeRef) {
|
||||
val superType = type
|
||||
if (superType is ConeClassLikeType) {
|
||||
when (val superSymbol = superType.lookupTag.toSymbol(this@Fir2IrVisitor.session)) {
|
||||
is FirClassSymbol -> {
|
||||
val superClass = superSymbol.fir as FirClass<*>
|
||||
for (declaration in superClass.declarations) {
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> result += declaration.name
|
||||
is FirVariable<*> -> result += declaration.name
|
||||
}
|
||||
}
|
||||
superClass.collectCallableNamesFromSupertypes(result)
|
||||
}
|
||||
is FirTypeAliasSymbol -> {
|
||||
val superAlias = superSymbol.fir
|
||||
superAlias.expandedTypeRef.collectCallableNamesFromThisAndSupertypes(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FirClass<*>.collectCallableNamesFromSupertypes(result: MutableList<Name> = mutableListOf()): List<Name> {
|
||||
for (superTypeRef in superTypeRefs) {
|
||||
superTypeRef.collectCallableNamesFromThisAndSupertypes(result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FirClass<*>.getPrimaryConstructorIfAny(): FirConstructor? =
|
||||
declarations.filterIsInstance<FirConstructor>().firstOrNull()?.takeIf { it.isPrimary }
|
||||
|
||||
private fun IrClass.addFakeOverrides(klass: FirClass<*>, processedCallableNames: MutableList<Name>) {
|
||||
if (fakeOverrideMode == FakeOverrideMode.NONE) return
|
||||
val superTypesCallableNames = klass.collectCallableNamesFromSupertypes()
|
||||
val superTypesCallableNames = klass.collectCallableNamesFromSupertypes(session)
|
||||
val useSiteMemberScope = (klass as? FirRegularClass)?.buildUseSiteMemberScope(session, ScopeSession()) ?: return
|
||||
for (name in superTypesCallableNames) {
|
||||
if (name in processedCallableNames) continue
|
||||
@@ -239,7 +206,7 @@ class Fir2IrVisitor(
|
||||
declarations += irFunction.setParentByParentStack().withFunction {
|
||||
setFunctionContent(irFunction.descriptor, originalFunction, firOverriddenSymbol = baseSymbol)
|
||||
}
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION) {
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalFunction.visibility != Visibilities.PRIVATE) {
|
||||
// Trivial fake override case
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideFunction(session, originalFunction, functionSymbol)
|
||||
@@ -267,7 +234,7 @@ class Fir2IrVisitor(
|
||||
declarations += irProperty.setParentByParentStack().withProperty {
|
||||
setPropertyContent(irProperty.descriptor, originalProperty, firOverriddenSymbol = baseSymbol)
|
||||
}
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION) {
|
||||
} else if (fakeOverrideMode != FakeOverrideMode.SUBSTITUTION && originalProperty.visibility != Visibilities.PRIVATE) {
|
||||
// Trivial fake override case
|
||||
val fakeOverrideSymbol =
|
||||
FirClassSubstitutionScope.createFakeOverrideProperty(session, originalProperty, propertySymbol)
|
||||
@@ -305,9 +272,8 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
addFakeOverrides(klass, processedCallableNames)
|
||||
klass.annotations.forEach {
|
||||
val irCall = it.accept(this@Fir2IrVisitor, null) as? IrConstructorCall ?: return@forEach
|
||||
annotations += irCall
|
||||
annotations = klass.annotations.mapNotNull {
|
||||
it.accept(this@Fir2IrVisitor, null) as? IrConstructorCall
|
||||
}
|
||||
}
|
||||
if (irPrimaryConstructor != null) {
|
||||
@@ -317,7 +283,7 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass, data: Any?): IrElement {
|
||||
return declarationStorage.getIrClass(regularClass, setParent = false)
|
||||
return declarationStorage.getIrClass(regularClass, setParentAndContent = false)
|
||||
.setParentByParentStack()
|
||||
.withParent {
|
||||
setClassContent(regularClass)
|
||||
@@ -352,7 +318,7 @@ class Fir2IrVisitor(
|
||||
val containingClass = if (firOverriddenSymbol == null || firFunctionSymbol == null) {
|
||||
lastClass
|
||||
} else {
|
||||
val callableId = firFunctionSymbol.callableId
|
||||
val callableId = firFunctionSymbol.deepestOverriddenSymbol().callableId
|
||||
val ownerClassId = callableId.classId
|
||||
if (ownerClassId == null) {
|
||||
lastClass
|
||||
@@ -362,7 +328,7 @@ class Fir2IrVisitor(
|
||||
lastClass
|
||||
} else {
|
||||
val firClass = classLikeSymbol.fir as FirClass<*>
|
||||
declarationStorage.getIrClass(firClass, setParent = false)
|
||||
declarationStorage.getIrClass(firClass, setParentAndContent = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,7 +343,7 @@ class Fir2IrVisitor(
|
||||
if (firOverriddenSymbol != null && this is IrSimpleFunction && firFunctionSymbol != null) {
|
||||
val overriddenSymbol = declarationStorage.getIrFunctionSymbol(firOverriddenSymbol)
|
||||
if (overriddenSymbol is IrSimpleFunctionSymbol) {
|
||||
overriddenSymbols += overriddenSymbol
|
||||
overriddenSymbols = listOf(overriddenSymbol)
|
||||
}
|
||||
}
|
||||
var body = firFunction?.body?.convertToIrBlockBody()
|
||||
@@ -438,32 +404,31 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrDelegatingConstructorCall? {
|
||||
val constructedClassSymbol = with(typeContext) {
|
||||
(constructedTypeRef as FirResolvedTypeRef).type.typeConstructor()
|
||||
} as? FirClassSymbol<*> ?: return null
|
||||
private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrCallWithIndexedArgumentsBase? {
|
||||
val constructedIrType = constructedTypeRef.toIrType(this@Fir2IrVisitor.session, declarationStorage)
|
||||
// TODO: find delegated constructor correctly
|
||||
val classId = constructedClassSymbol.classId
|
||||
var constructorSymbol: FirConstructorSymbol? = null
|
||||
constructedClassSymbol.buildUseSiteMemberScope(this@Fir2IrVisitor.session, ScopeSession())!!.processFunctionsByName(
|
||||
classId.shortClassName
|
||||
) {
|
||||
when {
|
||||
it !is FirConstructorSymbol -> {
|
||||
}
|
||||
arguments.size <= it.fir.valueParameters.size && constructorSymbol == null -> {
|
||||
constructorSymbol = it
|
||||
}
|
||||
}
|
||||
}
|
||||
val foundConstructorSymbol = constructorSymbol ?: return null
|
||||
val constructorSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol
|
||||
?: return null
|
||||
return convertWithOffsets { startOffset, endOffset ->
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
constructedIrType,
|
||||
declarationStorage.getIrFunctionSymbol(foundConstructorSymbol) as IrConstructorSymbol
|
||||
).apply {
|
||||
val irConstructorSymbol = declarationStorage.getIrFunctionSymbol(constructorSymbol) as IrConstructorSymbol
|
||||
if (constructorSymbol.fir.isFromEnumClass || constructorSymbol.fir.returnTypeRef.isEnum) {
|
||||
IrEnumConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
constructedIrType,
|
||||
irConstructorSymbol
|
||||
).apply {
|
||||
val typeArguments = (constructedTypeRef as? FirResolvedTypeRef)?.type?.typeArguments
|
||||
if (typeArguments?.isNotEmpty() == true) {
|
||||
val irType = (typeArguments.first() as ConeKotlinTypeProjection).type.toIrType(session, declarationStorage, irBuiltIns)
|
||||
putTypeArgument(0, irType)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
constructedIrType,
|
||||
irConstructorSymbol
|
||||
)
|
||||
}.apply {
|
||||
for ((index, argument) in arguments.withIndex()) {
|
||||
val argumentExpression = argument.toIrExpression()
|
||||
putValueArgument(index, argumentExpression)
|
||||
@@ -503,9 +468,14 @@ class Fir2IrVisitor(
|
||||
|
||||
private fun visitLocalVariable(variable: FirProperty): IrElement {
|
||||
assert(variable.isLocal)
|
||||
val irVariable = declarationStorage.createAndSaveIrVariable(variable)
|
||||
val initializer = variable.initializer
|
||||
val isNextVariable = initializer is FirFunctionCall &&
|
||||
initializer.resolvedNamedFunctionSymbol()?.callableId?.isIteratorNext() == true &&
|
||||
variable.source.psi?.parent is KtForExpression
|
||||
val irVariable = declarationStorage.createAndSaveIrVariable(
|
||||
variable, if (isNextVariable) IrDeclarationOrigin.FOR_LOOP_VARIABLE else null
|
||||
)
|
||||
return irVariable.setParentByParentStack().apply {
|
||||
val initializer = variable.initializer
|
||||
if (initializer != null) {
|
||||
this.initializer = initializer.toIrExpression()
|
||||
}
|
||||
@@ -581,18 +551,18 @@ class Fir2IrVisitor(
|
||||
property.getter, this, propertyType, property.getter is FirDefaultPropertyGetter, property.getter == null
|
||||
)
|
||||
getter?.apply {
|
||||
overriddenProperty?.owner?.getter?.symbol?.let { overriddenSymbols += it }
|
||||
overriddenProperty?.owner?.getter?.symbol?.let { overriddenSymbols = listOf(it) }
|
||||
}
|
||||
if (property.isVar) {
|
||||
setter?.setPropertyAccessorContent(
|
||||
property.setter, this, propertyType, property.setter is FirDefaultPropertySetter, property.setter == null
|
||||
)
|
||||
setter?.apply {
|
||||
overriddenProperty?.owner?.setter?.symbol?.let { overriddenSymbols += it }
|
||||
overriddenProperty?.owner?.setter?.symbol?.let { overriddenSymbols = listOf(it) }
|
||||
}
|
||||
}
|
||||
property.annotations.forEach {
|
||||
annotations += it.accept(this@Fir2IrVisitor, null) as IrConstructorCall
|
||||
annotations = property.annotations.mapNotNull {
|
||||
it.accept(this@Fir2IrVisitor, null) as? IrConstructorCall
|
||||
}
|
||||
declarationStorage.leaveScope(descriptor)
|
||||
return this
|
||||
@@ -705,7 +675,13 @@ class Fir2IrVisitor(
|
||||
is FirPropertyFromParameterResolvedNamedReference -> IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
is FirResolvedNamedReference -> when (resolvedSymbol) {
|
||||
is AccessorSymbol, is SyntheticPropertySymbol -> IrStatementOrigin.GET_PROPERTY
|
||||
is FirNamedFunctionSymbol -> if (resolvedSymbol.callableId.isInvoke()) IrStatementOrigin.INVOKE else null
|
||||
is FirNamedFunctionSymbol -> when {
|
||||
resolvedSymbol.callableId.isInvoke() -> IrStatementOrigin.INVOKE
|
||||
source.psi is KtForExpression && resolvedSymbol.callableId.isIteratorNext() -> IrStatementOrigin.FOR_LOOP_NEXT
|
||||
source.psi is KtForExpression && resolvedSymbol.callableId.isIteratorHasNext() -> IrStatementOrigin.FOR_LOOP_HAS_NEXT
|
||||
source.psi is KtForExpression && resolvedSymbol.callableId.isIterator() -> IrStatementOrigin.FOR_LOOP_ITERATOR
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
@@ -732,7 +708,7 @@ class Fir2IrVisitor(
|
||||
symbol is IrPropertySymbol && symbol.isBound -> {
|
||||
val getter = symbol.owner.getter
|
||||
if (getter != null) {
|
||||
IrCallImpl(startOffset, endOffset, type, getter.symbol)
|
||||
IrCallImpl(startOffset, endOffset, type, getter.symbol, origin = IrStatementOrigin.GET_PROPERTY)
|
||||
} else {
|
||||
IrErrorCallExpressionImpl(startOffset, endOffset, type, "No getter found for ${calleeReference.render()}")
|
||||
}
|
||||
@@ -809,13 +785,13 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.applyTypeArguments(call: FirFunctionCall): IrExpression {
|
||||
private fun IrExpression.applyTypeArguments(access: FirQualifiedAccess): IrExpression {
|
||||
return when (this) {
|
||||
is IrCallWithIndexedArgumentsBase -> {
|
||||
val argumentsCount = call.typeArguments.size
|
||||
val argumentsCount = access.typeArguments.size
|
||||
if (argumentsCount <= typeArgumentsCount) {
|
||||
apply {
|
||||
for ((index, argument) in call.typeArguments.withIndex()) {
|
||||
for ((index, argument) in access.typeArguments.withIndex()) {
|
||||
val argumentIrType = (argument as FirTypeProjectionWithVariance).typeRef.toIrType(
|
||||
session,
|
||||
declarationStorage
|
||||
@@ -852,7 +828,7 @@ class Fir2IrVisitor(
|
||||
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
||||
}
|
||||
firClass?.convertWithOffsets { startOffset, endOffset ->
|
||||
val irClass = declarationStorage.getIrClass(firClass, setParent = false)
|
||||
val irClass = declarationStorage.getIrClass(firClass, setParentAndContent = false)
|
||||
IrGetObjectValueImpl(startOffset, endOffset, irClass.defaultType, irClass.symbol)
|
||||
}
|
||||
}
|
||||
@@ -871,7 +847,8 @@ class Fir2IrVisitor(
|
||||
val ownerFunction = symbol.owner
|
||||
if (ownerFunction.dispatchReceiverParameter != null) {
|
||||
dispatchReceiver = qualifiedAccess.findIrDispatchReceiver()
|
||||
} else if (ownerFunction.extensionReceiverParameter != null) {
|
||||
}
|
||||
if (ownerFunction.extensionReceiverParameter != null) {
|
||||
extensionReceiver = qualifiedAccess.findIrExtensionReceiver()
|
||||
}
|
||||
this
|
||||
@@ -887,32 +864,39 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrElement {
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression {
|
||||
val convertibleCall = if (functionCall.toResolvedCallableSymbol()?.fir is FirIntegerOperator) {
|
||||
functionCall.copy().transformSingle(integerApproximator, null)
|
||||
} else {
|
||||
checkIfInvoke(functionCall)
|
||||
val resolvedSymbol = functionCall.resolvedNamedFunctionSymbol()
|
||||
if (resolvedSymbol != null) {
|
||||
functionCall.replaceCalleeReferenceWithOverridden(resolvedSymbol)
|
||||
} else {
|
||||
functionCall
|
||||
}
|
||||
}
|
||||
return convertibleCall.toIrExpression(convertibleCall.typeRef)
|
||||
.applyCallArguments(convertibleCall).applyTypeArguments(convertibleCall).applyReceivers(convertibleCall)
|
||||
}
|
||||
|
||||
// Use the generic invoke method in Function classes, to match bridges generated by the backend.
|
||||
private fun checkIfInvoke(functionCall: FirFunctionCall): FirFunctionCall {
|
||||
if (functionCall !is FirFunctionCallImpl) {
|
||||
return functionCall
|
||||
}
|
||||
val calleeReference = (functionCall.calleeReference as? FirResolvedNamedReference) ?: return functionCall
|
||||
val resolvedSymbol = (calleeReference.resolvedSymbol as? FirNamedFunctionSymbol) ?: return functionCall
|
||||
if (resolvedSymbol.callableId.isInvoke()) {
|
||||
functionCall.calleeReference =
|
||||
buildResolvedNamedReference {
|
||||
private fun FirFunctionCall.resolvedNamedFunctionSymbol(): FirNamedFunctionSymbol? {
|
||||
val calleeReference = (calleeReference as? FirResolvedNamedReference) ?: return null
|
||||
return calleeReference.resolvedSymbol as? FirNamedFunctionSymbol
|
||||
}
|
||||
|
||||
// Use the generic invoke & next methods to match bridges generated by the backend.
|
||||
private fun FirFunctionCall.replaceCalleeReferenceWithOverridden(resolvedSymbol: FirNamedFunctionSymbol): FirFunctionCall {
|
||||
val overriddenSymbol = resolvedSymbol.overriddenSymbol ?: return this
|
||||
if (resolvedSymbol.callableId.isInvoke() || resolvedSymbol.callableId.isIteratorNext()) {
|
||||
return copy(
|
||||
calleeReference = buildResolvedNamedReference {
|
||||
source = calleeReference.source
|
||||
name = calleeReference.name
|
||||
this.resolvedSymbol = resolvedSymbol.overriddenSymbol!!
|
||||
this.resolvedSymbol = overriddenSymbol
|
||||
}
|
||||
)
|
||||
}
|
||||
return functionCall
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: Any?): IrElement {
|
||||
@@ -920,7 +904,8 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: Any?): IrElement {
|
||||
return qualifiedAccessExpression.toIrExpression(qualifiedAccessExpression.typeRef).applyReceivers(qualifiedAccessExpression)
|
||||
return qualifiedAccessExpression.toIrExpression(qualifiedAccessExpression.typeRef)
|
||||
.applyTypeArguments(qualifiedAccessExpression).applyReceivers(qualifiedAccessExpression)
|
||||
}
|
||||
|
||||
override fun visitThisReceiverExpression(thisReceiverExpression: FirThisReceiverExpression, data: Any?): IrElement {
|
||||
@@ -931,7 +916,7 @@ class Fir2IrVisitor(
|
||||
it is FirAnonymousObject || it is FirRegularClass && it.classKind == ClassKind.OBJECT
|
||||
}
|
||||
if (firObject != null) {
|
||||
val irObject = declarationStorage.getIrClass(firObject, setParent = false)
|
||||
val irObject = declarationStorage.getIrClass(firObject, setParentAndContent = false)
|
||||
if (irObject != classStack.lastOrNull()) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetObjectValueImpl(startOffset, endOffset, irObject.defaultType, irObject.symbol)
|
||||
@@ -952,7 +937,7 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement {
|
||||
// Generate the expression with the original type and then cast it to the smart cast type.
|
||||
val value = expressionWithSmartcast.toIrExpression(expressionWithSmartcast.originalType).applyReceivers(expressionWithSmartcast)
|
||||
val value = expressionWithSmartcast.originalExpression.toIrExpression()
|
||||
val castType = expressionWithSmartcast.typeRef.toIrType(session, declarationStorage)
|
||||
if (value.type == castType) return value
|
||||
return IrTypeOperatorCallImpl(
|
||||
@@ -1032,7 +1017,7 @@ class Fir2IrVisitor(
|
||||
}
|
||||
is IrVariableSymbol -> {
|
||||
IrSetVariableImpl(
|
||||
startOffset, endOffset, symbol.owner.type, symbol, variableAssignment.rValue.toIrExpression(), null
|
||||
startOffset, endOffset, irBuiltIns.unitType, symbol, variableAssignment.rValue.toIrExpression(), null
|
||||
)
|
||||
}
|
||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||
@@ -1110,9 +1095,32 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirBlock.mapToIrStatements(): List<IrStatement?> {
|
||||
val irRawStatements = statements.map { it.toIrStatement() }
|
||||
val result = mutableListOf<IrStatement?>()
|
||||
var missNext = false
|
||||
for ((index, irRawStatement) in irRawStatements.withIndex()) {
|
||||
if (missNext) {
|
||||
missNext = false
|
||||
continue
|
||||
} else if (irRawStatement is IrVariable && irRawStatement.origin == IrDeclarationOrigin.FOR_LOOP_ITERATOR) {
|
||||
missNext = true
|
||||
val irNextStatement = irRawStatements[index + 1]!!
|
||||
result += IrBlockImpl(
|
||||
irRawStatement.startOffset, irNextStatement.endOffset,
|
||||
(irNextStatement as IrExpression).type, IrStatementOrigin.FOR_LOOP,
|
||||
listOf(irRawStatement, irNextStatement)
|
||||
)
|
||||
} else {
|
||||
result += irRawStatement
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FirBlock.convertToIrBlockBody(): IrBlockBody {
|
||||
return convertWithOffsets { startOffset, endOffset ->
|
||||
val irStatements = statements.map { it.toIrStatement() }
|
||||
val irStatements = mapToIrStatements()
|
||||
IrBlockBodyImpl(
|
||||
startOffset, endOffset,
|
||||
if (irStatements.isNotEmpty()) {
|
||||
@@ -1125,7 +1133,7 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirBlock.convertToIrExpressionOrBlock(): IrExpression {
|
||||
private fun FirBlock.convertToIrExpressionOrBlock(origin: IrStatementOrigin? = null): IrExpression {
|
||||
if (statements.size == 1) {
|
||||
val firStatement = statements.single()
|
||||
if (firStatement is FirExpression) {
|
||||
@@ -1136,8 +1144,8 @@ class Fir2IrVisitor(
|
||||
(statements.lastOrNull() as? FirExpression)?.typeRef?.toIrType(this@Fir2IrVisitor.session, declarationStorage) ?: unitType
|
||||
return convertWithOffsets { startOffset, endOffset ->
|
||||
IrBlockImpl(
|
||||
startOffset, endOffset, type, null,
|
||||
statements.mapNotNull { it.toIrStatement() }
|
||||
startOffset, endOffset, type, origin,
|
||||
mapToIrStatements().filterNotNull()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1239,15 +1247,13 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun visitWhileLoop(whileLoop: FirWhileLoop, data: Any?): IrElement {
|
||||
return whileLoop.convertWithOffsets { startOffset, endOffset ->
|
||||
IrWhileLoopImpl(
|
||||
startOffset, endOffset, unitType,
|
||||
if (whileLoop.psi is KtForExpression) IrStatementOrigin.FOR_LOOP_INNER_WHILE
|
||||
else IrStatementOrigin.WHILE_LOOP
|
||||
).apply {
|
||||
val origin = if (whileLoop.psi is KtForExpression) IrStatementOrigin.FOR_LOOP_INNER_WHILE
|
||||
else IrStatementOrigin.WHILE_LOOP
|
||||
IrWhileLoopImpl(startOffset, endOffset, unitType, origin).apply {
|
||||
loopMap[whileLoop] = this
|
||||
label = whileLoop.label?.name
|
||||
condition = whileLoop.condition.toIrExpression()
|
||||
body = whileLoop.block.convertToIrExpressionOrBlock()
|
||||
body = whileLoop.block.convertToIrExpressionOrBlock(origin)
|
||||
loopMap.remove(whileLoop)
|
||||
}
|
||||
}
|
||||
@@ -1307,50 +1313,72 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateComparisonCall(
|
||||
startOffset: Int, endOffset: Int, operation: FirOperation, first: FirExpression, second: FirExpression
|
||||
): IrExpression {
|
||||
val firstType = first.typeRef as? FirResolvedTypeRef
|
||||
val secondType = second.typeRef as? FirResolvedTypeRef
|
||||
if (firstType == null || secondType == null) {
|
||||
return IrErrorCallExpressionImpl(startOffset, endOffset, booleanType, "Comparison of arguments with unresolved types")
|
||||
override fun visitComparisonExpression(comparisonExpression: FirComparisonExpression, data: Any?): IrElement {
|
||||
return comparisonExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
generateComparisonCall(startOffset, endOffset, comparisonExpression)
|
||||
}
|
||||
if (!AbstractStrictEqualityTypeChecker.strictEqualTypes(typeContext, firstType.type, secondType.type)) {
|
||||
return IrErrorCallExpressionImpl(
|
||||
startOffset, endOffset, booleanType,
|
||||
"Comparison of arguments with different types: ${firstType.type.render()}, ${secondType.type.render()}"
|
||||
}
|
||||
|
||||
private fun generateComparisonCall(
|
||||
startOffset: Int, endOffset: Int,
|
||||
comparisonExpression: FirComparisonExpression
|
||||
): IrExpression {
|
||||
val operation = comparisonExpression.operation
|
||||
|
||||
fun fallbackToRealCall(): IrExpression {
|
||||
val (symbol, origin) = getSymbolAndOriginForComparison(operation, irBuiltIns.intType.classifierOrFail)
|
||||
return primitiveOp2(
|
||||
startOffset, endOffset,
|
||||
symbol!!,
|
||||
booleanType,
|
||||
origin,
|
||||
visitFunctionCall(comparisonExpression.compareToCall, null),
|
||||
IrConstImpl.int(startOffset, endOffset, irBuiltIns.intType, 0)
|
||||
)
|
||||
}
|
||||
// TODO: it's temporary hack which should be refactored
|
||||
val simpleType = when (val classId = (firstType.type as? ConeClassLikeType)?.lookupTag?.classId) {
|
||||
ClassId(FqName("kotlin"), FqName("Long"), false) -> irBuiltIns.longType
|
||||
ClassId(FqName("kotlin"), FqName("Int"), false) -> irBuiltIns.intType
|
||||
ClassId(FqName("kotlin"), FqName("Float"), false) -> irBuiltIns.floatType
|
||||
ClassId(FqName("kotlin"), FqName("Double"), false) -> irBuiltIns.doubleType
|
||||
ClassId(FqName("kotlin"), FqName("Char"), false) -> irBuiltIns.charType
|
||||
else -> {
|
||||
return IrErrorCallExpressionImpl(
|
||||
startOffset, endOffset, booleanType, "Comparison of arguments with unsupported type: $classId"
|
||||
)
|
||||
}
|
||||
|
||||
val comparisonInfo = comparisonExpression.inferPrimitiveNumericComparisonInfo() ?: return fallbackToRealCall()
|
||||
val comparisonType = comparisonInfo.comparisonType
|
||||
|
||||
// Currently inferPrimitiveNumericComparisonInfo returns null for different primitive values
|
||||
// TODO: Support different primitive types as well and fix inferPrimitiveNumericComparisonInfo
|
||||
require(comparisonInfo.leftPrimitiveType == comparisonInfo.rightPrimitiveType && comparisonInfo.leftType == comparisonInfo.rightType) {
|
||||
"Contract for inferPrimitiveNumericComparisonInfo is violated"
|
||||
}
|
||||
val classifier = simpleType.classifierOrFail
|
||||
val (symbol, origin) = when (operation) {
|
||||
|
||||
val simpleType = when ((comparisonType.type as? ConeClassLikeType)?.lookupTag?.classId) {
|
||||
StandardClassIds.Long -> irBuiltIns.longType
|
||||
StandardClassIds.Int -> irBuiltIns.intType
|
||||
StandardClassIds.Float -> irBuiltIns.floatType
|
||||
StandardClassIds.Double -> irBuiltIns.doubleType
|
||||
StandardClassIds.Char -> irBuiltIns.charType
|
||||
else -> return fallbackToRealCall()
|
||||
}
|
||||
|
||||
val (symbol, origin) = getSymbolAndOriginForComparison(operation, simpleType.classifierOrFail)
|
||||
|
||||
return primitiveOp2(
|
||||
startOffset, endOffset, symbol!!, booleanType, origin,
|
||||
comparisonExpression.left.toIrExpression(), comparisonExpression.right.toIrExpression()
|
||||
)
|
||||
}
|
||||
|
||||
private fun getSymbolAndOriginForComparison(
|
||||
operation: FirOperation,
|
||||
classifier: IrClassifierSymbol
|
||||
): Pair<IrSimpleFunctionSymbol?, IrStatementOriginImpl> {
|
||||
return when (operation) {
|
||||
FirOperation.LT -> irBuiltIns.lessFunByOperandType[classifier] to IrStatementOrigin.LT
|
||||
FirOperation.GT -> irBuiltIns.greaterFunByOperandType[classifier] to IrStatementOrigin.GT
|
||||
FirOperation.LT_EQ -> irBuiltIns.lessOrEqualFunByOperandType[classifier] to IrStatementOrigin.LTEQ
|
||||
FirOperation.GT_EQ -> irBuiltIns.greaterOrEqualFunByOperandType[classifier] to IrStatementOrigin.GTEQ
|
||||
else -> throw AssertionError("Unexpected comparison operation: $operation")
|
||||
else -> error("Unexpected comparison operation: $operation")
|
||||
}
|
||||
return primitiveOp2(startOffset, endOffset, symbol!!, booleanType, origin, first.toIrExpression(), second.toIrExpression())
|
||||
}
|
||||
|
||||
private fun generateOperatorCall(
|
||||
startOffset: Int, endOffset: Int, operation: FirOperation, arguments: List<FirExpression>
|
||||
): IrExpression {
|
||||
if (operation in FirOperation.COMPARISONS) {
|
||||
return generateComparisonCall(startOffset, endOffset, operation, arguments[0], arguments[1])
|
||||
}
|
||||
val (type, symbol, origin) = when (operation) {
|
||||
FirOperation.EQ -> Triple(booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ)
|
||||
FirOperation.NOT_EQ -> Triple(booleanType, irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ)
|
||||
@@ -1363,7 +1391,8 @@ class Fir2IrVisitor(
|
||||
FirOperation.MINUS_ASSIGN, FirOperation.TIMES_ASSIGN,
|
||||
FirOperation.DIV_ASSIGN, FirOperation.REM_ASSIGN,
|
||||
FirOperation.IS, FirOperation.NOT_IS,
|
||||
FirOperation.AS, FirOperation.SAFE_AS -> {
|
||||
FirOperation.AS, FirOperation.SAFE_AS
|
||||
-> {
|
||||
TODO("Should not be here: incompatible operation in FirOperatorCall: $operation")
|
||||
}
|
||||
}
|
||||
@@ -1452,9 +1481,8 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Any?): IrElement {
|
||||
val classId = resolvedQualifier.classId
|
||||
if (classId != null) {
|
||||
val classSymbol = ConeClassLikeLookupTagImpl(classId).toSymbol(session)!!
|
||||
val classSymbol = resolvedQualifier.symbol
|
||||
if (classSymbol != null) {
|
||||
return resolvedQualifier.convertWithOffsets { startOffset, endOffset ->
|
||||
IrGetObjectValueImpl(
|
||||
startOffset, endOffset,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.backend
|
||||
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
class PrimitiveConeNumericComparisonInfo(
|
||||
val comparisonType: ConeKotlinType,
|
||||
val leftPrimitiveType: ConeClassLikeType,
|
||||
val rightPrimitiveType: ConeClassLikeType,
|
||||
val leftType: ConeKotlinType,
|
||||
val rightType: ConeKotlinType
|
||||
)
|
||||
|
||||
val FirComparisonExpression.left: FirExpression
|
||||
get() = compareToCall.explicitReceiver ?: error("There should be an explicit receiver for ${compareToCall.render()}")
|
||||
|
||||
val FirComparisonExpression.right: FirExpression
|
||||
get() = compareToCall.arguments.getOrNull(0) ?: error("There should be a first arg for ${compareToCall.render()}")
|
||||
|
||||
fun FirComparisonExpression.inferPrimitiveNumericComparisonInfo(): PrimitiveConeNumericComparisonInfo? {
|
||||
val leftType = left.typeRef.coneTypeSafe<ConeKotlinType>() ?: return null
|
||||
val rightType = right.typeRef.coneTypeSafe<ConeKotlinType>() ?: return null
|
||||
val leftPrimitiveOrNullableType = leftType.getPrimitiveTypeOrSupertype() ?: return null
|
||||
val rightPrimitiveOrNullableType = rightType.getPrimitiveTypeOrSupertype() ?: return null
|
||||
val leftPrimitiveType = leftPrimitiveOrNullableType.withNullability(ConeNullability.NOT_NULL)
|
||||
val rightPrimitiveType = rightPrimitiveOrNullableType.withNullability(ConeNullability.NOT_NULL)
|
||||
|
||||
// TODO: Support different types with coercion
|
||||
if (leftPrimitiveType != rightPrimitiveType) return null
|
||||
val leastCommonType = rightPrimitiveType
|
||||
|
||||
return PrimitiveConeNumericComparisonInfo(
|
||||
leastCommonType,
|
||||
leftPrimitiveType, rightPrimitiveType,
|
||||
leftPrimitiveOrNullableType, rightPrimitiveOrNullableType
|
||||
)
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.getPrimitiveTypeOrSupertype(): ConeClassLikeType? =
|
||||
when {
|
||||
this is ConeTypeParameterType ->
|
||||
this.lookupTag.typeParameterSymbol.fir.bounds.firstNotNullResult {
|
||||
it.coneTypeSafe<ConeKotlinType>()?.getPrimitiveTypeOrSupertype()
|
||||
}
|
||||
this is ConeClassLikeType && isPrimitiveNumberType() ->
|
||||
this
|
||||
else ->
|
||||
null
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class FirPackageFragmentDescriptor(override val fqName: FqName, val moduleDescri
|
||||
}
|
||||
|
||||
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R {
|
||||
TODO("not implemented")
|
||||
return visitor?.visitPackageFragmentDescriptor(this, data) as R
|
||||
}
|
||||
|
||||
override fun getSource(): SourceElement {
|
||||
@@ -38,7 +38,7 @@ class FirPackageFragmentDescriptor(override val fqName: FqName, val moduleDescri
|
||||
}
|
||||
|
||||
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
|
||||
TODO("not implemented")
|
||||
visitor?.visitPackageFragmentDescriptor(this, null)
|
||||
}
|
||||
|
||||
override val annotations: Annotations
|
||||
|
||||
@@ -216,11 +216,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/annotations/varargInAnnotationParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wrongAnnotationArgumentInCtor.kt")
|
||||
public void testWrongAnnotationArgumentInCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/wrongAnnotationArgumentInCtor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/annotatedLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1701,6 +1696,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/builderInference")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class BuilderInference extends AbstractFirBlackBoxCodegenTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInBuilderInference() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/builderInference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("lackOfNullCheckOnNullableInsideBuild.kt")
|
||||
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1955,6 +1968,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nested.kt")
|
||||
public void testNested() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/nested.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/callableReference/bound")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -2148,6 +2166,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/function"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("argumentTypes.kt")
|
||||
public void testArgumentTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("booleanNotIntrinsic.kt")
|
||||
public void testBooleanNotIntrinsic() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");
|
||||
@@ -2795,6 +2818,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/varargAndDefaults/simpleEmptyVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unboundReferences.kt")
|
||||
public void testUnboundReferences() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/varargAndDefaults/unboundReferences.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("varargViewedAsArray.kt")
|
||||
public void testVarargViewedAsArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/varargAndDefaults/varargViewedAsArray.kt");
|
||||
@@ -3438,6 +3466,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/classes/initializerBlockDImpl.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("initializerBlockResetToDefault.kt")
|
||||
public void testInitializerBlockResetToDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/classes/initializerBlockResetToDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("innerClass.kt")
|
||||
public void testInnerClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/classes/innerClass.kt");
|
||||
@@ -5982,6 +6015,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/builderInferenceAndGenericArrayAcessCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("captureMutableLocalVariableInsideCoroutineBlock.kt")
|
||||
public void testCaptureMutableLocalVariableInsideCoroutineBlock() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/captureMutableLocalVariableInsideCoroutineBlock.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedVarInSuspendLambda.kt")
|
||||
public void testCapturedVarInSuspendLambda_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/capturedVarInSuspendLambda.kt", "kotlin.coroutines");
|
||||
@@ -6027,6 +6065,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/crossInlineWithCapturedOuterReceiver.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParametersInSuspendWithJvmOverloads.kt")
|
||||
public void testDefaultParametersInSuspendWithJvmOverloads() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/defaultParametersInSuspendWithJvmOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParametersInSuspend.kt")
|
||||
public void testDefaultParametersInSuspend_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/defaultParametersInSuspend.kt", "kotlin.coroutines");
|
||||
@@ -6047,6 +6090,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt")
|
||||
public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("epam.kt")
|
||||
public void testEpam_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines");
|
||||
@@ -6357,6 +6405,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendFunImportedFromObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendImplBridge.kt")
|
||||
public void testSuspendImplBridge() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendImplBridge.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendInCycle.kt")
|
||||
public void testSuspendInCycle_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspendInCycle.kt", "kotlin.coroutines");
|
||||
@@ -6382,6 +6435,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendJavaOverrides.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendReturningPlatformType.kt")
|
||||
public void testSuspendReturningPlatformType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendReturningPlatformType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspensionInsideSafeCallWithElvis.kt")
|
||||
public void testSuspensionInsideSafeCallWithElvis_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/suspensionInsideSafeCallWithElvis.kt", "kotlin.coroutines");
|
||||
@@ -6443,6 +6501,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/bridges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceSpecialization.kt")
|
||||
public void testInterfaceSpecialization_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/bridges/interfaceSpecialization.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaWithLongReceiver.kt")
|
||||
public void testLambdaWithLongReceiver_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/bridges/lambdaWithLongReceiver.kt", "kotlin.coroutines");
|
||||
@@ -7597,6 +7660,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("functionReference.kt")
|
||||
public void testFunctionReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/functionReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override.kt")
|
||||
public void testOverride() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unit/override.kt");
|
||||
@@ -8181,6 +8249,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/defaultArguments/superCallCheck.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("superCallHandlerOrder.kt")
|
||||
public void testSuperCallHandlerOrder() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/defaultArguments/superCallHandlerOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("useNextParamInLambda.kt")
|
||||
public void testUseNextParamInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/defaultArguments/useNextParamInLambda.kt");
|
||||
@@ -8719,6 +8792,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/useReflectionOnKProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("valByMapDelegatedProperty.kt")
|
||||
public void testValByMapDelegatedProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/valByMapDelegatedProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("valInInnerClass.kt")
|
||||
public void testValInInnerClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/delegatedProperty/valInInnerClass.kt");
|
||||
@@ -10525,11 +10603,21 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/funInterface/castFromAny.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterfaceInheritance.kt")
|
||||
public void testFunInterfaceInheritance() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/funInterfaceInheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlinedSamWrapper.kt")
|
||||
public void testInlinedSamWrapper() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multimodule.kt")
|
||||
public void testMultimodule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
@@ -10540,6 +10628,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/funInterface/partialSam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primitiveConversions.kt")
|
||||
public void testPrimitiveConversions() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/primitiveConversions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiverEvaluatedOnce.kt")
|
||||
public void testReceiverEvaluatedOnce() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/receiverEvaluatedOnce.kt");
|
||||
@@ -11469,6 +11562,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/increment/genericClassWithGetSet.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt36956.kt")
|
||||
public void testKt36956() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/increment/kt36956.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberExtOnLong.kt")
|
||||
public void testMemberExtOnLong() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/increment/memberExtOnLong.kt");
|
||||
@@ -11562,11 +11660,26 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("builderInferenceLeakingVariable.kt")
|
||||
public void testBuilderInferenceLeakingVariable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInferenceLeakingVariable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedStarProjection.kt")
|
||||
public void testCapturedStarProjection() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("coercionToUnitWithLastLambdaExpression.kt")
|
||||
public void testCoercionToUnitWithLastLambdaExpression() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/coercionToUnitWithLastLambdaExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("coerctionToUnitForLastExpressionWithStarProjection.kt")
|
||||
public void testCoerctionToUnitForLastExpressionWithStarProjection() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/coerctionToUnitForLastExpressionWithStarProjection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("integerLiteralTypeInLamdaReturnType.kt")
|
||||
public void testIntegerLiteralTypeInLamdaReturnType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
|
||||
@@ -11587,6 +11700,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inference/kt35684.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt36446.kt")
|
||||
public void testKt36446() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/kt36446.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lastExpressionOfLambdaWithNothingConstraint.kt")
|
||||
public void testLastExpressionOfLambdaWithNothingConstraint() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/lastExpressionOfLambdaWithNothingConstraint.kt");
|
||||
@@ -11610,6 +11728,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/annotatedMemberExtensionProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("anySuperCall.kt")
|
||||
public void testAnySuperCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/anySuperCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boundCallableReferencePassedToInlineFunction.kt")
|
||||
public void testBoundCallableReferencePassedToInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boundCallableReferencePassedToInlineFunction.kt");
|
||||
@@ -11890,6 +12013,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericInlineClassSynthMembers.kt")
|
||||
public void testGenericInlineClassSynthMembers() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/genericInlineClassSynthMembers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassAsLastExpressionInInLambda.kt")
|
||||
public void testInlineClassAsLastExpressionInInLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/inlineClassAsLastExpressionInInLambda.kt");
|
||||
@@ -12150,6 +12278,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt28920_javaPrimitiveType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt33119.kt")
|
||||
public void testKt33119() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt33119.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt34268.kt")
|
||||
public void testKt34268() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
@@ -12598,6 +12731,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/defaultParameterValues/inlineClassPrimaryConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassPrimaryConstructorWithInlineClassValue.kt")
|
||||
public void testInlineClassPrimaryConstructorWithInlineClassValue() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/defaultParameterValues/inlineClassPrimaryConstructorWithInlineClassValue.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassSecondaryConstructor.kt")
|
||||
public void testInlineClassSecondaryConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/defaultParameterValues/inlineClassSecondaryConstructor.kt");
|
||||
@@ -12852,6 +12990,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/interfaceMethodCalls/genericMethodWithInlineClassOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceSuperCall.kt")
|
||||
public void testInterfaceSuperCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/interfaceMethodCalls/interfaceSuperCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overriddenDefaultInterfaceMethodCall.kt")
|
||||
public void testOverriddenDefaultInterfaceMethodCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/interfaceMethodCalls/overriddenDefaultInterfaceMethodCall.kt");
|
||||
@@ -13311,6 +13454,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/intrinsics/nonShortCircuitAnd.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullPlusString.kt")
|
||||
public void testNullPlusString() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/nullPlusString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("prefixIncDec.kt")
|
||||
public void testPrefixIncDec() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
@@ -16329,6 +16477,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/objects/initializationOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("initializerBlockResetToDefault.kt")
|
||||
public void testInitializerBlockResetToDefault() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/objects/initializerBlockResetToDefault.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("interfaceCompanion.kt")
|
||||
public void testInterfaceCompanion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/objects/interfaceCompanion.kt");
|
||||
@@ -17232,11 +17385,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/platformTypes/primitives/equalsNull.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalsNull_withExplicitFlag.kt")
|
||||
public void testEqualsNull_withExplicitFlag() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/platformTypes/primitives/equalsNull_withExplicitFlag.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("hashCode.kt")
|
||||
public void testHashCode() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/platformTypes/primitives/hashCode.kt");
|
||||
@@ -18054,6 +18202,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericWithSameName.kt")
|
||||
public void testGenericWithSameName() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/genericWithSameName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("initOrderMultiModule.kt")
|
||||
public void testInitOrderMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/initOrderMultiModule.kt");
|
||||
@@ -22884,6 +23037,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testSignatureOfSimpleInnerSimpleOuter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/genericSignature/signatureOfSimpleInnerSimpleOuter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunctionLiteralGenericSignature.kt")
|
||||
public void testSuspendFunctionLiteralGenericSignature() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/genericSignature/suspendFunctionLiteralGenericSignature.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/isInstance")
|
||||
@@ -24890,6 +25048,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/reified/reifiedInlineIntoNonInlineableLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reifiedIntersectionType.kt")
|
||||
public void testReifiedIntersectionType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safecast.kt")
|
||||
public void testSafecast() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||
@@ -25720,6 +25883,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/specialBuiltins/removeSetInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("specialBridgeModality.kt")
|
||||
public void testSpecialBridgeModality() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/specialBuiltins/specialBridgeModality.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("throwable.kt")
|
||||
public void testThrowable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/specialBuiltins/throwable.kt");
|
||||
@@ -25994,6 +26162,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/strings/stringBuilderAppend.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("stringFromJavaPlus.kt")
|
||||
public void testStringFromJavaPlus() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/strings/stringFromJavaPlus.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("stringPlusOnlyWorksOnString.kt")
|
||||
public void testStringPlusOnlyWorksOnString() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/strings/stringPlusOnlyWorksOnString.kt");
|
||||
@@ -26142,6 +26315,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/super/multipleSuperTraits.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("superCallToNonGenericImplThroughGenericDefaultImpls.kt")
|
||||
public void testSuperCallToNonGenericImplThroughGenericDefaultImpls() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/super/superCallToNonGenericImplThroughGenericDefaultImpls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("traitproperty.kt")
|
||||
public void testTraitproperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/super/traitproperty.kt");
|
||||
@@ -26541,6 +26719,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/traits/diamondPropertyAccessors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("doubleDiamond.kt")
|
||||
public void testDoubleDiamond() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/traits/doubleDiamond.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericMethod.kt")
|
||||
public void testGenericMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/traits/genericMethod.kt");
|
||||
@@ -26641,6 +26824,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/traits/multiple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleImplFromJava.kt")
|
||||
public void testMultipleImplFromJava() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/traits/multipleImplFromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noPrivateDelegation.kt")
|
||||
public void testNoPrivateDelegation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/traits/noPrivateDelegation.kt");
|
||||
@@ -26651,6 +26839,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/traits/privateInterfaceMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiverOfIntersectionType.kt")
|
||||
public void testReceiverOfIntersectionType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/traits/receiverOfIntersectionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticAccessor.kt")
|
||||
public void testSyntheticAccessor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/traits/syntheticAccessor.kt");
|
||||
@@ -11,6 +11,7 @@ import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
|
||||
import org.jetbrains.kotlin.ir.AbstractIrTextTestCase
|
||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmManglerDesc
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import java.io.File
|
||||
|
||||
@@ -92,8 +94,10 @@ abstract class AbstractFir2IrTextTest : AbstractIrTextTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
val signaturer = IdSignatureDescriptor(JvmManglerDesc())
|
||||
|
||||
return Fir2IrConverter.createModuleFragment(
|
||||
session, firFiles, myEnvironment.configuration.languageVersionSettings
|
||||
session, firFiles, myEnvironment.configuration.languageVersionSettings, signaturer = signaturer
|
||||
).irModuleFragment
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/classes/enumWithSecondaryCtor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("fakeOverridesForJavaStaticMembers.kt")
|
||||
public void testFakeOverridesForJavaStaticMembers() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/classes/fakeOverridesForJavaStaticMembers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitNotNullOnDelegatedImplementation.kt")
|
||||
public void testImplicitNotNullOnDelegatedImplementation() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.kt");
|
||||
@@ -161,6 +166,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/classes/inlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassSyntheticMethods.kt")
|
||||
public void testInlineClassSyntheticMethods() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/classes/inlineClassSyntheticMethods.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("innerClass.kt")
|
||||
public void testInnerClass() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/classes/innerClass.kt");
|
||||
@@ -1052,6 +1062,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/expressions/kt30796.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt36956.kt")
|
||||
public void testKt36956() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/kt36956.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaInCAO.kt")
|
||||
public void testLambdaInCAO() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");
|
||||
@@ -1485,6 +1500,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions/funInterface"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayAsVarargAfterSamArgument_fi.kt")
|
||||
public void testArrayAsVarargAfterSamArgument_fi() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/funInterface/arrayAsVarargAfterSamArgument_fi.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basicFunInterfaceConversion.kt")
|
||||
public void testBasicFunInterfaceConversion() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/funInterface/basicFunInterfaceConversion.kt");
|
||||
@@ -1528,6 +1548,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/expressions/sam"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("arrayAsVarargAfterSamArgument.kt")
|
||||
public void testArrayAsVarargAfterSamArgument() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/sam/arrayAsVarargAfterSamArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericSamProjectedOut.kt")
|
||||
public void testGenericSamProjectedOut() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/sam/genericSamProjectedOut.kt");
|
||||
@@ -1807,11 +1832,26 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/types/asOnPlatformType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("castsInsideCoroutineInference.kt")
|
||||
public void testCastsInsideCoroutineInference() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/castsInsideCoroutineInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("coercionToUnitInLambdaReturnValue.kt")
|
||||
public void testCoercionToUnitInLambdaReturnValue() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/coercionToUnitInLambdaReturnValue.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericPropertyReferenceType.kt")
|
||||
public void testGenericPropertyReferenceType() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/genericPropertyReferenceType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inStarProjectionInReceiverType.kt")
|
||||
public void testInStarProjectionInReceiverType() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/inStarProjectionInReceiverType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("intersectionType1_NI.kt")
|
||||
public void testIntersectionType1_NI() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/intersectionType1_NI.kt");
|
||||
@@ -1842,11 +1882,21 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/types/intersectionType3_OI.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt36143.kt")
|
||||
public void testKt36143() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/kt36143.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localVariableOfIntersectionType_NI.kt")
|
||||
public void testLocalVariableOfIntersectionType_NI() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/localVariableOfIntersectionType_NI.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiverOfIntersectionType.kt")
|
||||
public void testReceiverOfIntersectionType() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/receiverOfIntersectionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastOnFakeOverrideReceiver.kt")
|
||||
public void testSmartCastOnFakeOverrideReceiver() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt");
|
||||
@@ -1862,6 +1912,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/types/smartCastOnReceiverOfGenericType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("starProjection_OI.kt")
|
||||
public void testStarProjection_OI() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/types/starProjection_OI.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/types/nullChecks")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
@@ -33,7 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker
|
||||
|
||||
@@ -68,8 +66,7 @@ class FirJavaElementFinder(
|
||||
firProvider.getFirClassifierByFqName(classId) as? FirRegularClass
|
||||
?: return null
|
||||
|
||||
val ktFile = firClass.psi?.containingFile as? KtFile ?: return null
|
||||
val fileStub = createJavaFileStub(classId.packageFqName, listOf(ktFile))
|
||||
val fileStub = createJavaFileStub(classId.packageFqName, psiManager)
|
||||
|
||||
return buildStub(firClass, fileStub).psi
|
||||
}
|
||||
@@ -187,20 +184,16 @@ private fun newTypeParameterList(parent: StubElement<*>, parameters: List<Pair<S
|
||||
}
|
||||
}
|
||||
|
||||
private fun createJavaFileStub(packageFqName: FqName, files: Collection<KtFile>): PsiJavaFileStub {
|
||||
private fun createJavaFileStub(packageFqName: FqName, psiManager: PsiManager): PsiJavaFileStub {
|
||||
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /*compiled = */true)
|
||||
javaFileStub.psiFactory = ClsStubPsiFactory.INSTANCE
|
||||
|
||||
val fakeFile = object : ClsFileImpl(files.first().viewProvider) {
|
||||
val fakeFile = object : ClsFileImpl(DummyHolderViewProvider(psiManager)) {
|
||||
override fun getStub() = javaFileStub
|
||||
|
||||
override fun getPackageName() = packageFqName.asString()
|
||||
|
||||
override fun isPhysical() = false
|
||||
|
||||
override fun getText(): String {
|
||||
return files.singleOrNull()?.text ?: super.getText()
|
||||
}
|
||||
}
|
||||
|
||||
javaFileStub.psi = fakeFile
|
||||
@@ -239,7 +232,7 @@ private fun ConeClassLikeType.mapToCanonicalNoExpansionString(session: FirSessio
|
||||
if (lookupTag.classId == StandardClassIds.Array) {
|
||||
return when (val typeProjection = typeArguments[0]) {
|
||||
is ConeStarProjection -> CommonClassNames.JAVA_LANG_OBJECT
|
||||
is ConeTypedProjection -> {
|
||||
is ConeKotlinTypeProjection -> {
|
||||
if (typeProjection.kind == ProjectionKind.IN)
|
||||
CommonClassNames.JAVA_LANG_VOID
|
||||
else
|
||||
@@ -266,10 +259,10 @@ private fun ConeClassLikeType.mapToCanonicalNoExpansionString(session: FirSessio
|
||||
|
||||
}
|
||||
|
||||
private fun ConeKotlinTypeProjection.mapToCanonicalString(session: FirSession): String {
|
||||
private fun ConeTypeProjection.mapToCanonicalString(session: FirSession): String {
|
||||
return when (this) {
|
||||
is ConeStarProjection -> "?"
|
||||
is ConeTypedProjection -> {
|
||||
is ConeKotlinTypeProjection -> {
|
||||
val wildcard = when (kind) {
|
||||
ProjectionKind.STAR -> error("Should be handled in the case above")
|
||||
ProjectionKind.IN -> "? super "
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.java
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope
|
||||
@@ -76,7 +77,9 @@ class JavaScopeProvider(
|
||||
// We need JavaClassEnhancementScope here to have already enhanced signatures from supertypes
|
||||
val scope = buildJavaEnhancementScope(useSiteSession, symbol, scopeSession, visitedSymbols)
|
||||
visitedSymbols.remove(symbol)
|
||||
useSiteSuperType.wrapSubstitutionScopeIfNeed(useSiteSession, scope, symbol.fir, scopeSession)
|
||||
useSiteSuperType.wrapSubstitutionScopeIfNeed(
|
||||
useSiteSession, scope, symbol.fir, scopeSession, regularClass.classId
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -111,7 +114,15 @@ class JavaScopeProvider(
|
||||
)
|
||||
)
|
||||
}
|
||||
return FirStaticScope(enhancementScope)
|
||||
return FirOnlyCallablesScope(FirStaticScope(enhancementScope))
|
||||
}
|
||||
|
||||
override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
|
||||
return lazyNestedClassifierScope(
|
||||
klass.classId,
|
||||
(klass as FirJavaClass).existingNestedClassifierNames,
|
||||
useSiteSession.firSymbolProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.addDefaultBoundIfNecessary
|
||||
@@ -19,14 +19,17 @@ import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.generateValueOfFunction
|
||||
import org.jetbrains.kotlin.fir.generateValuesFunction
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.lazyNestedClassifierScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.toFirSourceElement
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
@@ -73,39 +76,52 @@ class JavaSymbolProvider(
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaTypeParameter.toFirTypeParameter(javaTypeParameterStack: JavaTypeParameterStack): FirTypeParameterBuilder {
|
||||
javaTypeParameterStack.getBuilder(this)?.let { return it }
|
||||
private fun JavaTypeParameter.toFirTypeParameterSymbol(
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
): Pair<FirTypeParameterSymbol, Boolean> {
|
||||
val stored = javaTypeParameterStack.safeGet(this)
|
||||
if (stored != null) return stored to true
|
||||
val firSymbol = FirTypeParameterSymbol()
|
||||
javaTypeParameterStack.add(this, firSymbol)
|
||||
return firSymbol to false
|
||||
}
|
||||
|
||||
private fun JavaTypeParameter.toFirTypeParameter(
|
||||
firSymbol: FirTypeParameterSymbol,
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
): FirTypeParameter {
|
||||
return FirTypeParameterBuilder().apply {
|
||||
session = this@JavaSymbolProvider.session
|
||||
name = this@toFirTypeParameter.name
|
||||
this.session = this@JavaSymbolProvider.session
|
||||
this.name = this@toFirTypeParameter.name
|
||||
symbol = firSymbol
|
||||
variance = INVARIANT
|
||||
isReified = false
|
||||
}.also {
|
||||
javaTypeParameterStack.add(this, it)
|
||||
}
|
||||
addBounds(this@toFirTypeParameter, javaTypeParameterStack)
|
||||
}.build()
|
||||
}
|
||||
|
||||
private fun FirTypeParameterBuilder.addBounds(
|
||||
javaTypeParameter: JavaTypeParameter,
|
||||
stack: JavaTypeParameterStack,
|
||||
stack: JavaTypeParameterStack
|
||||
) {
|
||||
for (upperBound in javaTypeParameter.upperBounds) {
|
||||
bounds += upperBound.toFirResolvedTypeRef(this@JavaSymbolProvider.session, stack, nullability = ConeNullability.NULLABLE)
|
||||
bounds += upperBound.toFirResolvedTypeRef(
|
||||
this@JavaSymbolProvider.session,
|
||||
stack,
|
||||
isForSupertypes = false,
|
||||
forTypeParameterBounds = true
|
||||
)
|
||||
}
|
||||
addDefaultBoundIfNecessary()
|
||||
}
|
||||
|
||||
private fun List<JavaTypeParameter>.convertTypeParameters(stack: JavaTypeParameterStack): List<FirTypeParameter> {
|
||||
return this
|
||||
.map { it.toFirTypeParameter(stack) }
|
||||
.mapIndexed { index, typeParameterBuilder ->
|
||||
if (typeParameterBuilder.bounds.isEmpty()) {
|
||||
typeParameterBuilder.addBounds(this[index], stack)
|
||||
}
|
||||
typeParameterBuilder.build()
|
||||
}
|
||||
return map { it.toFirTypeParameterSymbol(stack) }.mapIndexed { index, (symbol, initialized) ->
|
||||
// This nasty logic is required, because type parameter bound can refer other type parameter from the list
|
||||
// So we have to create symbols first, and type parameters themselves after them
|
||||
if (initialized) symbol.fir
|
||||
else this[index].toFirTypeParameter(symbol, stack)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirRegularClassSymbol? {
|
||||
@@ -122,7 +138,10 @@ class JavaSymbolProvider(
|
||||
classId,
|
||||
{
|
||||
val foundClass = findClass(classId, content)
|
||||
if (foundClass == null || foundClass.annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME }) {
|
||||
if (foundClass == null || foundClass.annotations.any {
|
||||
it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME
|
||||
}
|
||||
) {
|
||||
null to null
|
||||
} else {
|
||||
FirRegularClassSymbol(classId) to foundClass
|
||||
@@ -136,13 +155,13 @@ class JavaSymbolProvider(
|
||||
if (!isTopLevel) {
|
||||
val parentId = ClassId(classId.packageFqName, parentFqName, false)
|
||||
val parentClassSymbol = getClassLikeSymbolByFqName(parentId)
|
||||
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol] ?:
|
||||
(parentClassSymbol?.fir as? FirJavaClass)?.javaTypeParameterStack
|
||||
val parentStack = parentClassTypeParameterStackCache[parentClassSymbol]
|
||||
?: (parentClassSymbol?.fir as? FirJavaClass)?.javaTypeParameterStack
|
||||
if (parentStack != null) {
|
||||
javaTypeParameterStack.addStack(parentStack)
|
||||
}
|
||||
}
|
||||
buildJavaClass {
|
||||
val firJavaClass = buildJavaClass {
|
||||
source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = firSymbol
|
||||
@@ -158,11 +177,6 @@ class JavaSymbolProvider(
|
||||
scopeProvider = this@JavaSymbolProvider.scopeProvider
|
||||
typeParameters += foundClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
addAnnotationsFrom(this@JavaSymbolProvider.session, javaClass, javaTypeParameterStack)
|
||||
for (supertype in javaClass.supertypes) {
|
||||
superTypeRefs += supertype.toFirResolvedTypeRef(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack, typeParametersNullability = ConeNullability.UNKNOWN
|
||||
)
|
||||
}
|
||||
// TODO: may be we can process fields & methods later.
|
||||
// However, they should be built up to override resolve stage
|
||||
for (javaField in javaClass.fields) {
|
||||
@@ -218,13 +232,13 @@ class JavaSymbolProvider(
|
||||
): FirJavaConstructorBuilder {
|
||||
val constructorSymbol = FirConstructorSymbol(constructorId)
|
||||
val classTypeParameters = javaClass.typeParameters.convertTypeParameters(javaTypeParameterStack)
|
||||
val firJavaConstructor = FirJavaConstructorBuilder().apply {
|
||||
return FirJavaConstructorBuilder().apply {
|
||||
source = psi?.toFirSourceElement()
|
||||
session = this@JavaSymbolProvider.session
|
||||
symbol = constructorSymbol
|
||||
this.visibility = visibility
|
||||
this.isPrimary = isPrimary
|
||||
isInner = !javaClass.isStatic
|
||||
isInner = javaClass.outerClass != null && !javaClass.isStatic
|
||||
returnTypeRef = buildResolvedTypeRef {
|
||||
type = firSymbol.constructType(
|
||||
classTypeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
|
||||
@@ -233,7 +247,6 @@ class JavaSymbolProvider(
|
||||
}
|
||||
typeParameters += classTypeParameters
|
||||
}
|
||||
return firJavaConstructor
|
||||
}
|
||||
|
||||
if (javaClassDeclaredConstructors.isEmpty() && javaClass.classKind == ClassKind.CLASS) {
|
||||
@@ -257,9 +270,15 @@ class JavaSymbolProvider(
|
||||
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
|
||||
}
|
||||
isNotSam = isNotSam()
|
||||
parentClassTypeParameterStackCache.remove(firSymbol)
|
||||
}
|
||||
firJavaClass.replaceSuperTypeRefs(
|
||||
javaClass.supertypes.map { supertype ->
|
||||
supertype.toFirResolvedTypeRef(
|
||||
this@JavaSymbolProvider.session, javaTypeParameterStack, isForSupertypes = true, forTypeParameterBounds = false
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||
|
||||
internal class JavaTypeParameterStack {
|
||||
|
||||
private val typeParameterMap = mutableMapOf<JavaTypeParameter, FirTypeParameterBuilder>()
|
||||
private val typeParameterMap = mutableMapOf<JavaTypeParameter, FirTypeParameterSymbol>()
|
||||
|
||||
fun add(javaTypeParameter: JavaTypeParameter, firTypeParameterBuilder: FirTypeParameterBuilder) {
|
||||
typeParameterMap[javaTypeParameter] = firTypeParameterBuilder
|
||||
fun add(javaTypeParameter: JavaTypeParameter, symbol: FirTypeParameterSymbol) {
|
||||
typeParameterMap[javaTypeParameter] = symbol
|
||||
}
|
||||
|
||||
fun addStack(javaTypeParameterStack: JavaTypeParameterStack) {
|
||||
@@ -30,9 +29,7 @@ internal class JavaTypeParameterStack {
|
||||
?: throw IllegalArgumentException("Cannot find Java type parameter $javaTypeParameter in stack")
|
||||
}
|
||||
|
||||
fun safeGet(javaTypeParameter: JavaTypeParameter) = typeParameterMap[javaTypeParameter]?.symbol
|
||||
|
||||
fun getBuilder(javaTypeParameter: JavaTypeParameter) = typeParameterMap[javaTypeParameter]
|
||||
fun safeGet(javaTypeParameter: JavaTypeParameter) = typeParameterMap[javaTypeParameter]
|
||||
|
||||
companion object {
|
||||
val EMPTY: JavaTypeParameterStack = JavaTypeParameterStack()
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
@@ -24,9 +25,11 @@ import org.jetbrains.kotlin.fir.java.declarations.buildJavaValueParameter
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
@@ -39,6 +42,7 @@ import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.jvm.buildJavaTypeRef
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.TypeComponentPosition
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
@@ -59,31 +63,24 @@ internal val JavaClass.classKind: ClassKind
|
||||
}
|
||||
|
||||
internal fun ClassId.toConeKotlinType(
|
||||
typeArguments: Array<ConeKotlinTypeProjection>,
|
||||
typeArguments: Array<ConeTypeProjection>,
|
||||
isNullable: Boolean
|
||||
): ConeLookupTagBasedType {
|
||||
val lookupTag = ConeClassLikeLookupTagImpl(this)
|
||||
return ConeClassLikeTypeImpl(lookupTag, typeArguments, isNullable)
|
||||
}
|
||||
|
||||
internal fun FirTypeRef.toNotNullConeKotlinType(
|
||||
internal fun FirTypeRef.toConeKotlinTypeProbablyFlexible(
|
||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||
): ConeKotlinType =
|
||||
when (this) {
|
||||
is FirResolvedTypeRef -> type
|
||||
is FirJavaTypeRef -> {
|
||||
val javaType = type
|
||||
javaType.toNotNullConeKotlinType(session, javaTypeParameterStack)
|
||||
type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
}
|
||||
else -> ConeKotlinErrorType("Unexpected type reference in JavaClassUseSiteMemberScope: ${this::class.java}")
|
||||
}
|
||||
|
||||
internal fun JavaType?.toNotNullConeKotlinType(
|
||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||
): ConeKotlinType {
|
||||
return toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NOT_NULL)
|
||||
}
|
||||
|
||||
internal fun JavaType.toFirJavaTypeRef(session: FirSession, javaTypeParameterStack: JavaTypeParameterStack): FirJavaTypeRef {
|
||||
val annotations = (this as? JavaClassifierType)?.annotations.orEmpty()
|
||||
return buildJavaTypeRef {
|
||||
@@ -95,25 +92,28 @@ internal fun JavaType.toFirJavaTypeRef(session: FirSession, javaTypeParameterSta
|
||||
internal fun JavaClassifierType.toFirResolvedTypeRef(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
nullability: ConeNullability = ConeNullability.NOT_NULL,
|
||||
typeParametersNullability: ConeNullability = ConeNullability.NOT_NULL
|
||||
isForSupertypes: Boolean,
|
||||
forTypeParameterBounds: Boolean
|
||||
): FirResolvedTypeRef {
|
||||
val coneType = this.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability, typeParametersNullability)
|
||||
val coneType =
|
||||
if (isForSupertypes)
|
||||
toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds)
|
||||
else
|
||||
toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forTypeParameterBounds)
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
type = coneType
|
||||
this@toFirResolvedTypeRef.annotations.mapTo(annotations) { it.toFirAnnotationCall(session, javaTypeParameterStack) }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun JavaType?.toConeKotlinTypeWithNullability(
|
||||
internal fun JavaType?.toConeKotlinTypeWithoutEnhancement(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
nullability: ConeNullability,
|
||||
typeParametersNullability: ConeNullability = ConeNullability.NOT_NULL
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
): ConeKotlinType {
|
||||
return when (this) {
|
||||
is JavaClassifierType -> {
|
||||
toConeKotlinTypeWithNullability(session, nullability, typeParametersNullability, javaTypeParameterStack)
|
||||
toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
}
|
||||
is JavaPrimitiveType -> {
|
||||
val primitiveType = type
|
||||
@@ -121,71 +121,213 @@ internal fun JavaType?.toConeKotlinTypeWithNullability(
|
||||
null -> "Unit"
|
||||
else -> javaName.capitalize()
|
||||
}
|
||||
|
||||
val classId = StandardClassIds.byName(kotlinPrimitiveName)
|
||||
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
|
||||
classId.toConeKotlinType(emptyArray(), isNullable = false)
|
||||
}
|
||||
is JavaArrayType -> {
|
||||
val componentType = componentType
|
||||
if (componentType !is JavaPrimitiveType) {
|
||||
val classId = StandardClassIds.Array
|
||||
val argumentType = ConeFlexibleType(
|
||||
componentType.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NOT_NULL),
|
||||
componentType.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NULLABLE)
|
||||
val argumentType = componentType.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
classId.toConeFlexibleType(
|
||||
arrayOf(argumentType),
|
||||
typeArgumentsForUpper = arrayOf(ConeKotlinTypeProjectionOut(argumentType))
|
||||
)
|
||||
classId.toConeKotlinType(arrayOf(argumentType), nullability.isNullable)
|
||||
} else {
|
||||
val javaComponentName = componentType.type?.typeName?.asString()?.capitalize() ?: error("Array of voids")
|
||||
val classId = StandardClassIds.byName(javaComponentName + "Array")
|
||||
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
|
||||
|
||||
classId.toConeFlexibleType(emptyArray())
|
||||
}
|
||||
}
|
||||
is JavaWildcardType -> bound?.toNotNullConeKotlinType(session, javaTypeParameterStack) ?: run {
|
||||
val classId = StandardClassIds.Any
|
||||
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
|
||||
is JavaWildcardType -> bound?.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) ?: run {
|
||||
StandardClassIds.Any.toConeFlexibleType(emptyArray())
|
||||
}
|
||||
null -> {
|
||||
val classId = StandardClassIds.Any
|
||||
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
|
||||
StandardClassIds.Any.toConeFlexibleType(emptyArray())
|
||||
}
|
||||
else -> error("Strange JavaType: ${this::class.java}")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun JavaClassifierType.toConeKotlinTypeWithNullability(
|
||||
private fun ClassId.toConeFlexibleType(
|
||||
typeArguments: Array<ConeTypeProjection>,
|
||||
typeArgumentsForUpper: Array<ConeTypeProjection> = typeArguments
|
||||
) = ConeFlexibleType(
|
||||
toConeKotlinType(typeArguments, isNullable = false),
|
||||
toConeKotlinType(typeArgumentsForUpper, isNullable = true)
|
||||
)
|
||||
|
||||
private fun JavaClassifierType.toConeKotlinTypeWithoutEnhancement(
|
||||
session: FirSession,
|
||||
nullability: ConeNullability,
|
||||
typeParametersNullability: ConeNullability,
|
||||
javaTypeParameterStack: JavaTypeParameterStack
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
forTypeParameterBounds: Boolean = false
|
||||
): ConeKotlinType {
|
||||
if (nullability == ConeNullability.UNKNOWN) {
|
||||
return ConeFlexibleType(
|
||||
toConeKotlinTypeWithNullability(session, ConeNullability.NOT_NULL, typeParametersNullability, javaTypeParameterStack),
|
||||
toConeKotlinTypeWithNullability(session, ConeNullability.NULLABLE, typeParametersNullability, javaTypeParameterStack)
|
||||
val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds)
|
||||
val upperBound =
|
||||
toConeKotlinTypeForFlexibleBound(
|
||||
session, javaTypeParameterStack, isLowerBound = false, forTypeParameterBounds, lowerBound
|
||||
)
|
||||
|
||||
return if (isRaw) ConeRawType(lowerBound, upperBound) else ConeFlexibleType(lowerBound, upperBound)
|
||||
}
|
||||
|
||||
private fun computeRawProjection(
|
||||
session: FirSession,
|
||||
parameter: FirTypeParameter,
|
||||
attr: TypeComponentPosition,
|
||||
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound()
|
||||
) = when (attr) {
|
||||
// Raw(List<T>) => (List<Any?>..List<*>)
|
||||
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
|
||||
// In the last case upper bound is equal to star projection `Enum<*>`,
|
||||
// but we want to keep matching tree structure of flexible bounds (at least they should have the same size)
|
||||
TypeComponentPosition.FLEXIBLE_LOWER -> {
|
||||
// T : String -> String
|
||||
// in T : String -> String
|
||||
// T : Enum<T> -> Enum<*>
|
||||
erasedUpperBound
|
||||
}
|
||||
TypeComponentPosition.FLEXIBLE_UPPER, TypeComponentPosition.INFLEXIBLE -> {
|
||||
if (!parameter.variance.allowsOutPosition)
|
||||
// in T -> Comparable<Nothing>
|
||||
session.builtinTypes.nothingType.type
|
||||
else if (erasedUpperBound is ConeClassLikeType &&
|
||||
erasedUpperBound.lookupTag.toSymbol(session)!!.firUnsafe<FirRegularClass>().typeParameters.isNotEmpty()
|
||||
)
|
||||
// T : Enum<E> -> out Enum<*>
|
||||
ConeKotlinTypeProjectionOut(erasedUpperBound)
|
||||
else
|
||||
// T : String -> *
|
||||
ConeStarProjection
|
||||
}
|
||||
}
|
||||
|
||||
// Definition:
|
||||
// ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
|
||||
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
|
||||
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
|
||||
private fun FirTypeParameter.getErasedUpperBound(
|
||||
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
|
||||
// E.g. `class A<T extends A, F extends A>`
|
||||
// To prevent recursive calls return defaultValue() instead
|
||||
potentiallyRecursiveTypeParameter: FirTypeParameter? = null,
|
||||
defaultValue: (() -> ConeKotlinType) = { ConeKotlinErrorType("Can't compute erased upper bound of type parameter `$this`") }
|
||||
): ConeKotlinType {
|
||||
if (this === potentiallyRecursiveTypeParameter) return defaultValue()
|
||||
|
||||
val firstUpperBound = this.bounds.first().coneTypeUnsafe<ConeKotlinType>()
|
||||
|
||||
return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
|
||||
}
|
||||
|
||||
private fun getErasedVersionOfFirstUpperBound(
|
||||
firstUpperBound: ConeKotlinType,
|
||||
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
|
||||
defaultValue: () -> ConeKotlinType
|
||||
): ConeKotlinType =
|
||||
when (firstUpperBound) {
|
||||
is ConeClassLikeType ->
|
||||
firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
|
||||
|
||||
is ConeFlexibleType -> {
|
||||
val lowerBound =
|
||||
getErasedVersionOfFirstUpperBound(firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
|
||||
.lowerBoundIfFlexible()
|
||||
if (firstUpperBound.upperBound is ConeTypeParameterType) {
|
||||
// Avoid exponential complexity
|
||||
ConeFlexibleType(
|
||||
lowerBound,
|
||||
lowerBound.withNullability(ConeNullability.NULLABLE)
|
||||
)
|
||||
} else {
|
||||
ConeFlexibleType(
|
||||
lowerBound,
|
||||
getErasedVersionOfFirstUpperBound(firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
|
||||
)
|
||||
}
|
||||
}
|
||||
is ConeTypeParameterType -> {
|
||||
val current = firstUpperBound.lookupTag.typeParameterSymbol.fir
|
||||
|
||||
if (alreadyVisitedParameters.add(current)) {
|
||||
val nextUpperBound = current.bounds.first().coneTypeUnsafe<ConeKotlinType>()
|
||||
getErasedVersionOfFirstUpperBound(nextUpperBound, alreadyVisitedParameters, defaultValue)
|
||||
} else {
|
||||
defaultValue()
|
||||
}
|
||||
}
|
||||
else -> error("Unexpected kind of firstUpperBound: $firstUpperBound [${firstUpperBound::class}]")
|
||||
}
|
||||
|
||||
private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
isLowerBound: Boolean,
|
||||
forTypeParameterBounds: Boolean,
|
||||
lowerBound: ConeLookupTagBasedType? = null
|
||||
): ConeLookupTagBasedType {
|
||||
return when (val classifier = classifier) {
|
||||
is JavaClass -> {
|
||||
//val classId = classifier.classId!!
|
||||
var classId = JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) ?: classifier.classId!!
|
||||
classId = classId.readOnlyToMutable() ?: classId
|
||||
|
||||
if (isLowerBound) {
|
||||
classId = classId.readOnlyToMutable() ?: classId
|
||||
}
|
||||
|
||||
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||
lookupTag.constructClassType(
|
||||
if (!isLowerBound && !isRaw && lookupTag == lowerBound?.lookupTag) {
|
||||
return lookupTag.constructClassType(
|
||||
lowerBound.typeArguments, isNullable = true
|
||||
)
|
||||
}
|
||||
|
||||
val mappedTypeArguments = if (isRaw) {
|
||||
|
||||
val defaultArgs = (1..classifier.typeParameters.size).map { ConeStarProjection }
|
||||
|
||||
if (forTypeParameterBounds) {
|
||||
// This is not fully correct, but it's a simple fix for some time to avoid recursive definition:
|
||||
// to create a proper raw type arguments, we should take class parameters some time
|
||||
defaultArgs
|
||||
} else {
|
||||
val classSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
|
||||
val position = if (isLowerBound) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER
|
||||
|
||||
classSymbol?.fir?.createRawArguments(defaultArgs, position) ?: defaultArgs
|
||||
}
|
||||
} else {
|
||||
typeArguments.map { argument ->
|
||||
argument.toConeProjection(
|
||||
session, javaTypeParameterStack, boundTypeParameter = null, nullability = typeParametersNullability
|
||||
argument.toConeProjectionWithoutEnhancement(
|
||||
session, javaTypeParameterStack, boundTypeParameter = null
|
||||
)
|
||||
}.toTypedArray(), nullability.isNullable
|
||||
}
|
||||
}
|
||||
|
||||
lookupTag.constructClassType(
|
||||
mappedTypeArguments.toTypedArray(), isNullable = !isLowerBound
|
||||
)
|
||||
}
|
||||
is JavaTypeParameter -> {
|
||||
val symbol = javaTypeParameterStack[classifier]
|
||||
ConeTypeParameterTypeImpl(symbol.toLookupTag(), nullability.isNullable)
|
||||
ConeTypeParameterTypeImpl(symbol.toLookupTag(), isNullable = !isLowerBound)
|
||||
}
|
||||
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
|
||||
else -> ConeKotlinErrorType("Unexpected classifier: $classifier")
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirRegularClass.createRawArguments(
|
||||
defaultArgs: List<ConeStarProjection>,
|
||||
position: TypeComponentPosition
|
||||
) = typeParameters.map { typeParameter ->
|
||||
val erasedUpperBound = typeParameter.getErasedUpperBound {
|
||||
defaultType().withArguments(defaultArgs.toTypedArray())
|
||||
}
|
||||
computeRawProjection(session, typeParameter, position, erasedUpperBound)
|
||||
}
|
||||
|
||||
internal fun JavaAnnotation.toFirAnnotationCall(
|
||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||
): FirAnnotationCall {
|
||||
@@ -221,12 +363,11 @@ internal fun JavaValueParameter.toFirValueParameter(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun JavaType?.toConeProjection(
|
||||
private fun JavaType?.toConeProjectionWithoutEnhancement(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
boundTypeParameter: FirTypeParameter?,
|
||||
nullability: ConeNullability = ConeNullability.NOT_NULL
|
||||
): ConeKotlinTypeProjection {
|
||||
boundTypeParameter: FirTypeParameter?
|
||||
): ConeTypeProjection {
|
||||
return when (this) {
|
||||
null -> ConeStarProjection
|
||||
is JavaWildcardType -> {
|
||||
@@ -236,7 +377,7 @@ internal fun JavaType?.toConeProjection(
|
||||
if (bound == null || parameterVariance != INVARIANT && parameterVariance != argumentVariance) {
|
||||
ConeStarProjection
|
||||
} else {
|
||||
val boundType = bound.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability)
|
||||
val boundType = bound.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
if (argumentVariance == OUT_VARIANCE) {
|
||||
ConeKotlinTypeProjectionOut(boundType)
|
||||
} else {
|
||||
@@ -244,7 +385,7 @@ internal fun JavaType?.toConeProjection(
|
||||
}
|
||||
}
|
||||
}
|
||||
is JavaClassifierType -> toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability)
|
||||
is JavaClassifierType -> toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
else -> ConeClassErrorType("Unexpected type argument: $this")
|
||||
}
|
||||
}
|
||||
@@ -337,7 +478,12 @@ internal fun Any?.createConstant(session: FirSession): FirExpression {
|
||||
private fun JavaType.toFirResolvedTypeRef(
|
||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||
): FirResolvedTypeRef {
|
||||
if (this is JavaClassifierType) return toFirResolvedTypeRef(session, javaTypeParameterStack)
|
||||
if (this is JavaClassifierType) return toFirResolvedTypeRef(
|
||||
session,
|
||||
javaTypeParameterStack,
|
||||
isForSupertypes = false,
|
||||
forTypeParameterBounds = false
|
||||
)
|
||||
return buildResolvedTypeRef {
|
||||
type = ConeClassErrorType("Unexpected JavaType: $this")
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||
import org.jetbrains.kotlin.fir.FirPureAbstractElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||
@@ -119,7 +118,6 @@ internal class FirJavaClassBuilder : AbstractFirRegularClassBuilder, FirAnnotati
|
||||
isCompanion = false
|
||||
isData = false
|
||||
isInline = false
|
||||
isNotSAM = this@FirJavaClassBuilder.isNotSam
|
||||
}
|
||||
|
||||
return FirJavaClass(
|
||||
|
||||
@@ -116,6 +116,10 @@ class FirJavaField @FirImplementationDetail constructor(
|
||||
}
|
||||
|
||||
override fun replaceReceiverTypeRef(newReceiverTypeRef: FirTypeRef?) {}
|
||||
|
||||
override fun <D> transformDelegate(transformer: FirTransformer<D>, data: D): FirField {
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
@FirBuilderDsl
|
||||
|
||||
@@ -22,6 +22,20 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.ASSIGNMENT_OPERATIONS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COMPARE_TO
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.CONTAINS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.DELEGATED_PROPERTY_OPERATORS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.GET
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.HAS_NEXT
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.INVOKE
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.ITERATOR
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.NEXT
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.SET
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_OPERATION_NAMES
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@UseExperimental(FirImplementationDetail::class)
|
||||
@@ -55,6 +69,10 @@ class FirJavaMethod @FirImplementationDetail constructor(
|
||||
annotations,
|
||||
)
|
||||
|
||||
private val ALL_JAVA_OPERATION_NAMES =
|
||||
UNARY_OPERATION_NAMES + BINARY_OPERATION_NAMES + ASSIGNMENT_OPERATIONS + DELEGATED_PROPERTY_OPERATORS +
|
||||
EQUALS + COMPARE_TO + CONTAINS + INVOKE + ITERATOR + GET + SET + NEXT + HAS_NEXT
|
||||
|
||||
@FirBuilderDsl
|
||||
class FirJavaMethodBuilder : FirSimpleFunctionBuilder() {
|
||||
lateinit var visibility: Visibility
|
||||
@@ -69,7 +87,9 @@ class FirJavaMethodBuilder : FirSimpleFunctionBuilder() {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
isOperator = true // All Java methods with name that allows to use it in operator form are considered operators
|
||||
// Approximation: all Java methods with name that allows to use it in operator form are considered operators
|
||||
// We need here more detailed checks (see modifierChecks.kt)
|
||||
isOperator = name in ALL_JAVA_OPERATION_NAMES || OperatorNameConventions.COMPONENT_REGEX.matches(name.asString())
|
||||
isInfix = false
|
||||
isInline = false
|
||||
isTailRec = false
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.java.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||
|
||||
object ConstantValueFactory {
|
||||
fun createArrayValue(value: List<FirExpression>): FirArrayOfCall {
|
||||
return buildArrayOfCall {
|
||||
arguments += value
|
||||
}
|
||||
}
|
||||
|
||||
fun createConstantValue(value: Any?): FirExpression? {
|
||||
return when (value) {
|
||||
is Byte -> buildConstExpression(null, FirConstKind.Byte, value)
|
||||
is Short -> buildConstExpression(null, FirConstKind.Short, value)
|
||||
is Int -> buildConstExpression(null, FirConstKind.Int, value)
|
||||
is Long -> buildConstExpression(null, FirConstKind.Long, value)
|
||||
is Char -> buildConstExpression(null, FirConstKind.Char, value)
|
||||
is Float -> buildConstExpression(null, FirConstKind.Float, value)
|
||||
is Double -> buildConstExpression(null, FirConstKind.Double, value)
|
||||
is Boolean -> buildConstExpression(null, FirConstKind.Boolean, value)
|
||||
is String -> buildConstExpression(null, FirConstKind.String, value)
|
||||
is ByteArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is ShortArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is IntArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is LongArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is CharArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is FloatArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is DoubleArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
is BooleanArray -> createArrayValue(value.map { createConstantValue(it)!! })
|
||||
null -> buildConstExpression(null, FirConstKind.Null, value)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,18 +5,349 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.java.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.deserialization.ProtoContainer
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.MemberSignature
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
|
||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import java.util.*
|
||||
|
||||
class JvmBinaryAnnotationDeserializer(
|
||||
session: FirSession
|
||||
) : AbstractAnnotationDeserializer(session) {
|
||||
override fun loadTypeAnnotations(typeProto: ProtoBuf.Type, nameResolver: NameResolver): List<FirAnnotationCall> {
|
||||
private val cache: MutableMap<KotlinJvmBinaryClass, Storage> = mutableMapOf()
|
||||
|
||||
private class Storage(
|
||||
val memberAnnotations: Map<MemberSignature, List<FirAnnotationCall>>,
|
||||
val propertyConstants: Map<MemberSignature, FirExpression>
|
||||
)
|
||||
|
||||
private val ProtoContainer.kotlinJvmBinaryClass: KotlinJvmBinaryClass?
|
||||
get() = (sourceElement as? JvmPackagePartSource)?.knownJvmBinaryClass
|
||||
|
||||
override fun loadTypeAnnotations(
|
||||
containingDeclaration: ProtoContainer,
|
||||
typeProto: ProtoBuf.Type,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable
|
||||
): List<FirAnnotationCall> {
|
||||
val annotations = typeProto.getExtension(JvmProtoBuf.typeAnnotation).orEmpty()
|
||||
return annotations.map { deserializeAnnotation(it, nameResolver) }
|
||||
}
|
||||
|
||||
override fun loadFunctionAnnotations(
|
||||
containingDeclaration: ProtoContainer,
|
||||
functionProto: ProtoBuf.Function,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable
|
||||
): List<FirAnnotationCall> {
|
||||
val kotlinClass = containingDeclaration.kotlinJvmBinaryClass ?: return emptyList()
|
||||
val signature = getCallableSignature(functionProto, nameResolver, typeTable, AnnotatedCallableKind.FUNCTION) ?: return emptyList()
|
||||
val storage = loadClassFileContent(kotlinClass)
|
||||
return storage.memberAnnotations[signature] ?: emptyList()
|
||||
}
|
||||
|
||||
override fun loadPropertyAnnotations(
|
||||
containingDeclaration: ProtoContainer,
|
||||
propertyProto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable
|
||||
): List<FirAnnotationCall> {
|
||||
val kotlinClass = containingDeclaration.kotlinJvmBinaryClass ?: return emptyList()
|
||||
val signature = getPropertySignature(propertyProto, nameResolver, typeTable) ?: return emptyList()
|
||||
val storage = loadClassFileContent(kotlinClass)
|
||||
return storage.memberAnnotations[signature] ?: emptyList()
|
||||
}
|
||||
|
||||
override fun loadConstructorAnnotations(
|
||||
containingDeclaration: ProtoContainer,
|
||||
constructorProto: ProtoBuf.Constructor,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable
|
||||
): List<FirAnnotationCall> {
|
||||
val kotlinClass = containingDeclaration.kotlinJvmBinaryClass ?: return emptyList()
|
||||
val signature = getCallableSignature(constructorProto, nameResolver, typeTable, AnnotatedCallableKind.FUNCTION) ?: return emptyList()
|
||||
val storage = loadClassFileContent(kotlinClass)
|
||||
return storage.memberAnnotations[signature] ?: emptyList()
|
||||
}
|
||||
|
||||
private fun getCallableSignature(
|
||||
proto: MessageLite,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable,
|
||||
kind: AnnotatedCallableKind,
|
||||
requireHasFieldFlagForField: Boolean = false
|
||||
): MemberSignature? {
|
||||
return when (proto) {
|
||||
is ProtoBuf.Constructor -> {
|
||||
MemberSignature.fromJvmMemberSignature(
|
||||
JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable) ?: return null
|
||||
)
|
||||
}
|
||||
is ProtoBuf.Function -> {
|
||||
MemberSignature.fromJvmMemberSignature(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null)
|
||||
}
|
||||
is ProtoBuf.Property -> {
|
||||
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
|
||||
when (kind) {
|
||||
AnnotatedCallableKind.PROPERTY_GETTER ->
|
||||
if (signature.hasGetter()) MemberSignature.fromMethod(nameResolver, signature.getter) else null
|
||||
AnnotatedCallableKind.PROPERTY_SETTER ->
|
||||
if (signature.hasSetter()) MemberSignature.fromMethod(nameResolver, signature.setter) else null
|
||||
AnnotatedCallableKind.PROPERTY ->
|
||||
getPropertySignature(proto, nameResolver, typeTable, true, true, requireHasFieldFlagForField)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPropertySignature(
|
||||
proto: ProtoBuf.Property,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable,
|
||||
field: Boolean = false,
|
||||
synthetic: Boolean = false,
|
||||
requireHasFieldFlagForField: Boolean = true
|
||||
): MemberSignature? {
|
||||
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
|
||||
|
||||
if (field) {
|
||||
val fieldSignature =
|
||||
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable, requireHasFieldFlagForField) ?: return null
|
||||
return MemberSignature.fromJvmMemberSignature(fieldSignature)
|
||||
} else if (synthetic && signature.hasSyntheticMethod()) {
|
||||
return MemberSignature.fromMethod(nameResolver, signature.syntheticMethod)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
private fun loadClassFileContent(kotlinClass: KotlinJvmBinaryClass): Storage {
|
||||
cache[kotlinClass]?.let { return it }
|
||||
|
||||
val memberAnnotations = HashMap<MemberSignature, MutableList<FirAnnotationCall>>()
|
||||
val propertyConstants = HashMap<MemberSignature, FirExpression>()
|
||||
|
||||
kotlinClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
||||
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? {
|
||||
return AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString(), desc))
|
||||
}
|
||||
|
||||
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
|
||||
val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc)
|
||||
|
||||
if (initializer != null) {
|
||||
val constant = loadConstant(desc, initializer)
|
||||
if (constant != null) {
|
||||
propertyConstants[signature] = constant
|
||||
}
|
||||
}
|
||||
return MemberAnnotationVisitor(signature)
|
||||
}
|
||||
|
||||
inner class AnnotationVisitorForMethod(signature: MemberSignature) : MemberAnnotationVisitor(signature),
|
||||
KotlinJvmBinaryClass.MethodAnnotationVisitor {
|
||||
|
||||
override fun visitParameterAnnotation(
|
||||
index: Int, classId: ClassId, source: SourceElement
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index)
|
||||
var result = memberAnnotations[paramSignature]
|
||||
if (result == null) {
|
||||
result = ArrayList()
|
||||
memberAnnotations[paramSignature] = result
|
||||
}
|
||||
return loadAnnotationIfNotSpecial(classId, source, result)
|
||||
}
|
||||
}
|
||||
|
||||
open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor {
|
||||
private val result = ArrayList<FirAnnotationCall>()
|
||||
|
||||
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
return loadAnnotationIfNotSpecial(classId, source, result)
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
if (result.isNotEmpty()) {
|
||||
memberAnnotations[signature] = result
|
||||
}
|
||||
}
|
||||
}
|
||||
}, getCachedFileContent(kotlinClass))
|
||||
|
||||
return Storage(memberAnnotations, propertyConstants).also {
|
||||
cache[kotlinClass] = it
|
||||
}
|
||||
}
|
||||
|
||||
fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? = null
|
||||
|
||||
private fun loadConstant(desc: String, initializer: Any): FirExpression? {
|
||||
val normalizedValue: Any = if (desc in "ZBCS") {
|
||||
val intValue = initializer as Int
|
||||
when (desc) {
|
||||
"Z" -> intValue != 0
|
||||
"B" -> intValue.toByte()
|
||||
"C" -> intValue.toChar()
|
||||
"S" -> intValue.toShort()
|
||||
else -> throw AssertionError(desc)
|
||||
}
|
||||
} else {
|
||||
initializer
|
||||
}
|
||||
|
||||
return ConstantValueFactory.createConstantValue(normalizedValue)
|
||||
}
|
||||
|
||||
private fun loadAnnotationIfNotSpecial(
|
||||
annotationClassId: ClassId,
|
||||
source: SourceElement,
|
||||
result: MutableList<FirAnnotationCall>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
if (annotationClassId in AbstractBinaryClassAnnotationAndConstantLoader.SPECIAL_ANNOTATIONS) return null
|
||||
|
||||
return loadAnnotation(annotationClassId, result)
|
||||
}
|
||||
|
||||
fun loadClass(classId: ClassId): FirClassSymbol<*>? {
|
||||
return session.firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirClassSymbol<*>
|
||||
}
|
||||
|
||||
private fun ClassId.toConeKotlinType(): ConeKotlinType = ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(this), emptyArray(), isNullable = false)
|
||||
|
||||
fun loadAnnotation(
|
||||
annotationClassId: ClassId,
|
||||
result: MutableList<FirAnnotationCall>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
val annotationClass = loadClass(annotationClassId) ?: return null
|
||||
val annotationConstructor = annotationClass.fir.declarations.firstIsInstanceOrNull<FirConstructor>() ?: return null
|
||||
|
||||
val builder = FirAnnotationCallBuilder().apply {
|
||||
annotationTypeRef = buildResolvedTypeRef {
|
||||
type = annotationClassId.toConeKotlinType()
|
||||
}
|
||||
}
|
||||
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
private val arguments = HashMap<Name, FirExpression>()
|
||||
|
||||
override fun visit(name: Name?, value: Any?) {
|
||||
if (name != null) {
|
||||
arguments[name] = createConstant(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClassLiteral(name: Name, value: ClassLiteralValue) {
|
||||
arguments[name] = buildClassLiteral(value)
|
||||
}
|
||||
|
||||
override fun visitEnum(name: Name, enumClassId: ClassId, enumEntryName: Name) {
|
||||
arguments[name] = buildEnum(enumClassId, enumEntryName)
|
||||
}
|
||||
|
||||
private fun buildClassLiteral(value: ClassLiteralValue): FirExpression {
|
||||
return buildGetClassCall {
|
||||
arguments += buildResolvedQualifier {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildEnum(
|
||||
enumClassId: ClassId,
|
||||
enumEntryName: Name
|
||||
): FirExpression {
|
||||
return buildQualifiedAccessExpression {
|
||||
typeRef = buildResolvedTypeRef {
|
||||
type = enumClassId.toConeKotlinType()
|
||||
}
|
||||
calleeReference = buildResolvedNamedReference {
|
||||
name = enumEntryName
|
||||
resolvedSymbol = loadClass(enumClassId)!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitArray(name: Name): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? {
|
||||
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
|
||||
private val elements = ArrayList<FirExpression>()
|
||||
|
||||
override fun visit(value: Any?) {
|
||||
elements.add(createConstant(name, value))
|
||||
}
|
||||
|
||||
override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) {
|
||||
elements.add(buildEnum(enumClassId, enumEntryName))
|
||||
}
|
||||
|
||||
override fun visitClassLiteral(value: ClassLiteralValue) {
|
||||
elements.add(buildClassLiteral(value))
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
val parameter = annotationConstructor.valueParameters.firstOrNull { it.name == name }
|
||||
if (parameter != null) {
|
||||
arguments[name] = ConstantValueFactory.createArrayValue(elements.compact())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnnotation(name: Name, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
val list = ArrayList<FirAnnotationCall>()
|
||||
val visitor = loadAnnotation(classId, list)!!
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
|
||||
override fun visitEnd() {
|
||||
visitor.visitEnd()
|
||||
arguments[name] = list.single()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
result += builder.build()
|
||||
}
|
||||
|
||||
private fun createConstant(name: Name?, value: Any?): FirExpression {
|
||||
return ConstantValueFactory.createConstantValue(value)
|
||||
?: buildErrorExpression {
|
||||
diagnostic = FirSimpleDiagnostic("Unsupported annotation argument: $name")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -122,6 +122,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
FirDeserializationContext.createForPackage(
|
||||
packageFqName, packageProto, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session),
|
||||
source
|
||||
),
|
||||
source,
|
||||
)
|
||||
|
||||
@@ -12,9 +12,8 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.classId
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithNullability
|
||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithoutEnhancement
|
||||
import org.jetbrains.kotlin.fir.java.toFirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
@@ -58,7 +57,8 @@ internal class EnhancementSignatureParts(
|
||||
}
|
||||
}
|
||||
|
||||
val containsFunctionN = current.toNotNullConeKotlinType(session, javaTypeParameterStack).contains {
|
||||
val typeWithoutEnhancement = current.type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
val containsFunctionN = typeWithoutEnhancement.contains {
|
||||
if (it is ConeClassErrorType) false
|
||||
else {
|
||||
val classId = it.lookupTag.classId
|
||||
@@ -67,7 +67,10 @@ internal class EnhancementSignatureParts(
|
||||
}
|
||||
}
|
||||
|
||||
val enhancedCurrent = current.enhance(session, javaTypeParameterStack, qualifiersWithPredefined ?: qualifiers)
|
||||
val enhancedCurrent = current.enhance(
|
||||
session, qualifiersWithPredefined ?: qualifiers,
|
||||
typeWithoutEnhancement
|
||||
)
|
||||
return PartEnhancementResult(
|
||||
enhancedCurrent, wereChanges = true, containsFunctionN = containsFunctionN
|
||||
)
|
||||
@@ -150,10 +153,10 @@ internal class EnhancementSignatureParts(
|
||||
}
|
||||
}
|
||||
is FirJavaTypeRef -> {
|
||||
val convertedType = type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||
Pair(
|
||||
// TODO: optimize
|
||||
type.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability = ConeNullability.NOT_NULL),
|
||||
type.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability = ConeNullability.NULLABLE)
|
||||
convertedType.lowerBoundIfFlexible(),
|
||||
convertedType.upperBoundIfFlexible()
|
||||
)
|
||||
}
|
||||
else -> return JavaTypeQualifiers.NONE
|
||||
|
||||
@@ -16,15 +16,11 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildQualifiedAccessExpressi
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.toConeProjection
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
@@ -36,13 +32,14 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.RawType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.extractRadix
|
||||
|
||||
@@ -56,60 +53,23 @@ internal class IndexedJavaTypeQualifiers(private val data: Array<JavaTypeQualifi
|
||||
|
||||
internal fun FirJavaTypeRef.enhance(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
qualifiers: IndexedJavaTypeQualifiers
|
||||
qualifiers: IndexedJavaTypeQualifiers,
|
||||
typeWithoutEnhancement: ConeKotlinType,
|
||||
): FirResolvedTypeRef {
|
||||
return type.enhancePossiblyFlexible(session, javaTypeParameterStack, annotations, qualifiers, 0)
|
||||
return typeWithoutEnhancement.enhancePossiblyFlexible(session, annotations, qualifiers, 0)
|
||||
}
|
||||
|
||||
// The index in the lambda is the position of the type component:
|
||||
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
|
||||
// which corresponds to the left-to-right breadth-first walk of the tree representation of the type.
|
||||
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
|
||||
private fun JavaType?.enhancePossiblyFlexible(
|
||||
private fun ConeKotlinType.enhancePossiblyFlexible(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
annotations: List<FirAnnotationCall>,
|
||||
qualifiers: IndexedJavaTypeQualifiers,
|
||||
index: Int
|
||||
): FirResolvedTypeRef {
|
||||
val type = this
|
||||
val arguments = this?.typeArguments().orEmpty()
|
||||
val enhanced = when (type) {
|
||||
is JavaClassifierType -> {
|
||||
val lowerResult = type.enhanceInflexibleType(
|
||||
session, javaTypeParameterStack, annotations, arguments, TypeComponentPosition.FLEXIBLE_LOWER, qualifiers, index
|
||||
)
|
||||
val upperResult = type.enhanceInflexibleType(
|
||||
session, javaTypeParameterStack, annotations, arguments, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index
|
||||
)
|
||||
|
||||
when {
|
||||
type.isRaw -> ConeRawType(lowerResult, upperResult)
|
||||
else -> coneFlexibleOrSimpleType(
|
||||
session, lowerResult, upperResult, isNotNullTypeParameter = qualifiers(index).isNotNullTypeParameter
|
||||
)
|
||||
}
|
||||
}
|
||||
is JavaArrayType -> {
|
||||
val baseEnhanced = type.toNotNullConeKotlinType(session, javaTypeParameterStack)
|
||||
|
||||
val upperBound = if (baseEnhanced.typeArguments.isNotEmpty()) {
|
||||
val typeArgument = baseEnhanced.typeArguments.first() as ConeKotlinType
|
||||
baseEnhanced.withArguments(arrayOf(ConeKotlinTypeProjectionOut(typeArgument)))
|
||||
} else {
|
||||
baseEnhanced
|
||||
}
|
||||
coneFlexibleOrSimpleType(
|
||||
session, baseEnhanced,
|
||||
upperBound.withNullability(ConeNullability.NULLABLE),
|
||||
isNotNullTypeParameter = false
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
type.toNotNullConeKotlinType(session, javaTypeParameterStack)
|
||||
}
|
||||
}
|
||||
val enhanced = enhanceConeKotlinType(session, qualifiers, index)
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
this.type = enhanced
|
||||
@@ -117,9 +77,35 @@ private fun JavaType?.enhancePossiblyFlexible(
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaType?.subtreeSize(): Int {
|
||||
if (this !is JavaClassifierType) return 1
|
||||
return 1 + typeArguments.sumBy { it?.subtreeSize() ?: 0 }
|
||||
private fun ConeKotlinType.enhanceConeKotlinType(
|
||||
session: FirSession,
|
||||
qualifiers: IndexedJavaTypeQualifiers,
|
||||
index: Int
|
||||
): ConeKotlinType {
|
||||
return when (this) {
|
||||
is ConeFlexibleType -> {
|
||||
val lowerResult = lowerBound.enhanceInflexibleType(
|
||||
session, TypeComponentPosition.FLEXIBLE_LOWER, qualifiers, index
|
||||
)
|
||||
val upperResult = upperBound.enhanceInflexibleType(
|
||||
session, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index
|
||||
)
|
||||
|
||||
when {
|
||||
lowerResult === lowerBound && upperResult === upperBound -> this
|
||||
this is ConeRawType -> ConeRawType(lowerResult, upperResult)
|
||||
else -> coneFlexibleOrSimpleType(
|
||||
session, lowerResult, upperResult, isNotNullTypeParameter = qualifiers(index).isNotNullTypeParameter
|
||||
)
|
||||
}
|
||||
}
|
||||
is ConeSimpleKotlinType -> enhanceInflexibleType(session, TypeComponentPosition.INFLEXIBLE, qualifiers, index)
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.subtreeSize(): Int {
|
||||
return 1 + typeArguments.sumBy { ((it as? ConeKotlinType)?.subtreeSize() ?: 0) + 1 }
|
||||
}
|
||||
|
||||
private fun coneFlexibleOrSimpleType(
|
||||
@@ -164,134 +150,51 @@ private fun ClassId.mutableToReadOnly(): ClassId? {
|
||||
}
|
||||
}
|
||||
|
||||
// Definition:
|
||||
// ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
|
||||
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
|
||||
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
|
||||
private fun FirTypeParameter.getErasedUpperBound(
|
||||
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
|
||||
// E.g. `class A<T extends A, F extends A>`
|
||||
// To prevent recursive calls return defaultValue() instead
|
||||
potentiallyRecursiveTypeParameter: FirTypeParameter? = null,
|
||||
defaultValue: (() -> ConeKotlinType) = { ConeKotlinErrorType("Can't compute erased upper bound of type parameter `$this`") }
|
||||
): ConeKotlinType {
|
||||
if (this === potentiallyRecursiveTypeParameter) return defaultValue()
|
||||
|
||||
val firstUpperBound = this.bounds.first().coneTypeUnsafe<ConeKotlinType>()
|
||||
|
||||
if (firstUpperBound is ConeClassLikeType) {
|
||||
return firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
|
||||
}
|
||||
|
||||
val alreadyVisited = mutableSetOf(potentiallyRecursiveTypeParameter, this)
|
||||
var current = (firstUpperBound as ConeTypeParameterType).lookupTag.typeParameterSymbol.fir
|
||||
|
||||
while (current !in alreadyVisited) {
|
||||
alreadyVisited += current
|
||||
|
||||
val nextUpperBound = current.bounds.first().coneTypeUnsafe<ConeKotlinType>()
|
||||
if (nextUpperBound is ConeClassLikeType) {
|
||||
return nextUpperBound.withArguments(nextUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
|
||||
}
|
||||
|
||||
current = (nextUpperBound as ConeTypeParameterType).lookupTag.typeParameterSymbol.fir
|
||||
}
|
||||
|
||||
return defaultValue()
|
||||
}
|
||||
|
||||
|
||||
fun computeProjection(
|
||||
private fun ConeKotlinType.enhanceInflexibleType(
|
||||
session: FirSession,
|
||||
parameter: FirTypeParameter,
|
||||
attr: TypeComponentPosition,
|
||||
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound()
|
||||
) = when (attr) {
|
||||
// Raw(List<T>) => (List<Any?>..List<*>)
|
||||
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
|
||||
// In the last case upper bound is equal to star projection `Enum<*>`,
|
||||
// but we want to keep matching tree structure of flexible bounds (at least they should have the same size)
|
||||
TypeComponentPosition.FLEXIBLE_LOWER -> {
|
||||
// T : String -> String
|
||||
// in T : String -> String
|
||||
// T : Enum<T> -> Enum<*>
|
||||
erasedUpperBound
|
||||
}
|
||||
TypeComponentPosition.FLEXIBLE_UPPER, TypeComponentPosition.INFLEXIBLE -> {
|
||||
if (!parameter.variance.allowsOutPosition)
|
||||
// in T -> Comparable<Nothing>
|
||||
session.builtinTypes.nothingType.type
|
||||
else if (erasedUpperBound is ConeClassLikeType &&
|
||||
erasedUpperBound.lookupTag.toSymbol(session)!!.firUnsafe<FirRegularClass>().typeParameters.isNotEmpty()
|
||||
)
|
||||
// T : Enum<E> -> out Enum<*>
|
||||
ConeKotlinTypeProjectionOut(erasedUpperBound)
|
||||
else
|
||||
// T : String -> *
|
||||
ConeStarProjection
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaClassifierType.enhanceInflexibleType(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
annotations: List<FirAnnotationCall>,
|
||||
arguments: List<JavaType?>,
|
||||
position: TypeComponentPosition,
|
||||
qualifiers: IndexedJavaTypeQualifiers,
|
||||
index: Int
|
||||
): ConeKotlinType {
|
||||
val originalTag = when (val classifier = classifier) {
|
||||
is JavaClass -> {
|
||||
val classId = classifier.classId!!
|
||||
var mappedId = JavaToKotlinClassMap.mapJavaToKotlin(classId.asSingleFqName())
|
||||
if (mappedId != null) {
|
||||
if (position == TypeComponentPosition.FLEXIBLE_LOWER) {
|
||||
mappedId = mappedId.readOnlyToMutable() ?: mappedId
|
||||
}
|
||||
}
|
||||
val kotlinClassId = mappedId ?: classId
|
||||
ConeClassLikeLookupTagImpl(kotlinClassId)
|
||||
}
|
||||
is JavaTypeParameter -> javaTypeParameterStack[classifier].toLookupTag()
|
||||
else -> return toNotNullConeKotlinType(session, javaTypeParameterStack)
|
||||
require(this !is ConeFlexibleType) {
|
||||
"$this should not be flexible"
|
||||
}
|
||||
if (this !is ConeLookupTagBasedType) return this
|
||||
|
||||
val originalTag = lookupTag
|
||||
|
||||
val effectiveQualifiers = qualifiers(index)
|
||||
val enhancedTag = originalTag.enhanceMutability(effectiveQualifiers, position)
|
||||
|
||||
val enhancedArguments = if (isRaw) {
|
||||
val firClassifier = originalTag.toSymbol(session)!!.firUnsafe<FirRegularClass>()
|
||||
firClassifier.typeParameters.map {
|
||||
val fir = it
|
||||
val erasedUpperBound = fir.getErasedUpperBound {
|
||||
firClassifier.defaultType().withArguments(firClassifier.typeParameters.map { ConeStarProjection }.toTypedArray())
|
||||
}
|
||||
computeProjection(session, fir, position, erasedUpperBound)
|
||||
}
|
||||
var wereChangesInArgs = false
|
||||
|
||||
val enhancedArguments = if (this is RawType) {
|
||||
// TODO: Support enhancing for raw types
|
||||
typeArguments
|
||||
} else {
|
||||
var globalArgIndex = index + 1
|
||||
arguments.mapIndexed { localArgIndex, arg ->
|
||||
if (arg is JavaWildcardType) {
|
||||
typeArguments.mapIndexed { localArgIndex, arg ->
|
||||
if (arg.kind != ProjectionKind.INVARIANT) {
|
||||
globalArgIndex++
|
||||
arg.toConeProjection(
|
||||
session,
|
||||
javaTypeParameterStack,
|
||||
((originalTag as? FirBasedSymbol<*>)?.fir as? FirCallableMemberDeclaration<*>)?.typeParameters?.getOrNull(localArgIndex)
|
||||
)
|
||||
arg
|
||||
} else {
|
||||
val argEnhancedTypeRef =
|
||||
arg.enhancePossiblyFlexible(session, javaTypeParameterStack, annotations, qualifiers, globalArgIndex)
|
||||
require(arg is ConeKotlinType) { "Should be invariant type: $arg" }
|
||||
globalArgIndex += arg.subtreeSize()
|
||||
|
||||
argEnhancedTypeRef.type.type.toTypeProjection(Variance.INVARIANT)
|
||||
arg.enhanceConeKotlinType(session, qualifiers, globalArgIndex).also {
|
||||
if (it !== arg) {
|
||||
wereChangesInArgs = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
|
||||
val enhancedNullability = getEnhancedNullability(effectiveQualifiers, position)
|
||||
|
||||
val enhancedType = enhancedTag.constructType(enhancedArguments.toTypedArray(), enhancedNullability)
|
||||
if (!wereChangesInArgs && originalTag == enhancedTag && enhancedNullability == isNullable) return this
|
||||
|
||||
val enhancedType = enhancedTag.constructType(enhancedArguments, enhancedNullability)
|
||||
|
||||
// TODO: why all of these is needed
|
||||
// val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
|
||||
|
||||
@@ -13,7 +13,9 @@ import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirPrimaryConstructorBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||
@@ -55,11 +57,11 @@ class JavaClassEnhancementScope(
|
||||
|
||||
private val enhancements = mutableMapOf<FirCallableSymbol<*>, FirCallableSymbol<*>>()
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> Unit) {
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
useSiteMemberScope.processPropertiesByName(name) process@{ original ->
|
||||
|
||||
val field = enhancements.getOrPut(original) { enhance(original, name) }
|
||||
processor(field)
|
||||
processor(field as FirVariableSymbol<*>)
|
||||
}
|
||||
|
||||
return super.processPropertiesByName(name, processor)
|
||||
@@ -104,11 +106,17 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
return symbol
|
||||
}
|
||||
is FirJavaMethod -> {
|
||||
original as FirAccessorSymbol
|
||||
return enhanceMethod(
|
||||
firElement, original.accessorId, original.accessorId.callableName, isAccessor = true, propertyId = original.callableId
|
||||
) as FirAccessorSymbol
|
||||
is FirSyntheticProperty -> {
|
||||
val accessorSymbol = firElement.symbol
|
||||
val enhancedFunctionSymbol = enhanceMethod(
|
||||
firElement.getter.delegate, accessorSymbol.accessorId, accessorSymbol.accessorId.callableName
|
||||
)
|
||||
return buildSyntheticProperty {
|
||||
session = this@JavaClassEnhancementScope.session
|
||||
this.name = name
|
||||
symbol = FirAccessorSymbol(accessorSymbol.callableId, accessorSymbol.accessorId)
|
||||
delegateGetter = enhancedFunctionSymbol.fir as FirSimpleFunction
|
||||
}.symbol
|
||||
}
|
||||
else -> {
|
||||
if (original is FirPropertySymbol || original is FirAccessorSymbol) return original
|
||||
@@ -132,9 +140,7 @@ class JavaClassEnhancementScope(
|
||||
private fun enhanceMethod(
|
||||
firMethod: FirFunction<*>,
|
||||
methodId: CallableId,
|
||||
name: Name,
|
||||
isAccessor: Boolean = false,
|
||||
propertyId: CallableId? = null
|
||||
name: Name
|
||||
): FirFunctionSymbol<*> {
|
||||
val memberContext = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, firMethod.annotations)
|
||||
|
||||
@@ -225,8 +231,7 @@ class JavaClassEnhancementScope(
|
||||
receiverTypeRef = newReceiverTypeRef
|
||||
this.name = name
|
||||
status = firMethod.status
|
||||
symbol = if (!isAccessor) FirNamedFunctionSymbol(methodId)
|
||||
else FirAccessorSymbol(callableId = propertyId!!, accessorId = methodId)
|
||||
symbol = FirNamedFunctionSymbol(methodId)
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
valueParameters += newValueParameters
|
||||
typeParameters += firMethod.typeParameters
|
||||
|
||||
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
@@ -16,10 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -52,37 +51,39 @@ class JavaClassUseSiteMemberScope(
|
||||
overrideCandidates: MutableSet<FirCallableSymbol<*>>,
|
||||
isGetter: Boolean
|
||||
): FirAccessorSymbol? {
|
||||
if (functionSymbol is FirNamedFunctionSymbol) {
|
||||
val fir = functionSymbol.fir
|
||||
if (fir.isStatic) {
|
||||
if (functionSymbol !is FirNamedFunctionSymbol) {
|
||||
return null
|
||||
}
|
||||
val fir = functionSymbol.fir
|
||||
if (fir.isStatic) {
|
||||
return null
|
||||
}
|
||||
when (isGetter) {
|
||||
true -> if (fir.valueParameters.isNotEmpty()) {
|
||||
return null
|
||||
}
|
||||
when (isGetter) {
|
||||
true -> if (fir.valueParameters.isNotEmpty()) {
|
||||
return null
|
||||
}
|
||||
false -> if (fir.valueParameters.size != 1) {
|
||||
return null
|
||||
}
|
||||
false -> if (fir.valueParameters.size != 1) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
overrideCandidates += functionSymbol
|
||||
val accessorSymbol = FirAccessorSymbol(
|
||||
accessorId = functionSymbol.callableId,
|
||||
callableId = CallableId(functionSymbol.callableId.packageName, functionSymbol.callableId.className, syntheticPropertyName)
|
||||
)
|
||||
if (functionSymbol is FirNamedFunctionSymbol) {
|
||||
functionSymbol.fir.let { callableMember -> accessorSymbol.bind(callableMember) }
|
||||
}
|
||||
return accessorSymbol
|
||||
return buildSyntheticProperty {
|
||||
session = this@JavaClassUseSiteMemberScope.session
|
||||
name = syntheticPropertyName
|
||||
symbol = FirAccessorSymbol(
|
||||
accessorId = functionSymbol.callableId,
|
||||
callableId = CallableId(functionSymbol.callableId.packageName, functionSymbol.callableId.className, syntheticPropertyName)
|
||||
)
|
||||
delegateGetter = fir
|
||||
}.symbol
|
||||
}
|
||||
|
||||
private fun processAccessorFunctionsAndPropertiesByName(
|
||||
propertyName: Name,
|
||||
getterNames: List<Name>,
|
||||
setterName: Name?,
|
||||
processor: (FirCallableSymbol<*>) -> Unit
|
||||
): Unit {
|
||||
processor: (FirVariableSymbol<*>) -> Unit
|
||||
) {
|
||||
val overrideCandidates = mutableSetOf<FirCallableSymbol<*>>()
|
||||
val klass = symbol.fir
|
||||
declaredMemberScope.processPropertiesByName(propertyName) { variableSymbol ->
|
||||
@@ -142,7 +143,7 @@ class JavaClassUseSiteMemberScope(
|
||||
}
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> Unit) {
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
// Do not generate accessors at all?
|
||||
if (name.isSpecial) {
|
||||
return processAccessorFunctionsAndPropertiesByName(name, emptyList(), null, processor)
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.modality
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
@@ -28,22 +28,29 @@ class JavaOverrideChecker internal constructor(
|
||||
private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean {
|
||||
if (candidateType is ConeFlexibleType) return isEqualTypes(candidateType.lowerBound, baseType, substitutor)
|
||||
if (baseType is ConeFlexibleType) return isEqualTypes(candidateType, baseType.lowerBound, substitutor)
|
||||
return if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) {
|
||||
candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it }
|
||||
} else {
|
||||
with(context) {
|
||||
isEqualTypeConstructors(
|
||||
substitutor.substituteOrSelf(candidateType).typeConstructor(),
|
||||
substitutor.substituteOrSelf(baseType).typeConstructor()
|
||||
)
|
||||
if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) {
|
||||
return candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it }
|
||||
}
|
||||
if (candidateType is ConeClassLikeType && baseType is ConeTypeParameterType) {
|
||||
val boundType = baseType.lookupTag.typeParameterSymbol.fir.bounds.singleOrNull()?.toConeKotlinTypeProbablyFlexible(
|
||||
session, javaTypeParameterStack
|
||||
)
|
||||
if (boundType != null) {
|
||||
return isEqualTypes(candidateType, boundType, substitutor)
|
||||
}
|
||||
}
|
||||
return with(context) {
|
||||
isEqualTypeConstructors(
|
||||
substitutor.substituteOrSelf(candidateType).typeConstructor(),
|
||||
substitutor.substituteOrSelf(baseType).typeConstructor()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) =
|
||||
isEqualTypes(
|
||||
candidateTypeRef.toNotNullConeKotlinType(session, javaTypeParameterStack),
|
||||
baseTypeRef.toNotNullConeKotlinType(session, javaTypeParameterStack),
|
||||
candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
|
||||
baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
|
||||
substitutor
|
||||
)
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls.jvm
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.AbstractConeCallConflictResolver
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.InferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user