mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-15 15:51:07 +00:00
Compare commits
352 Commits
rr/mitropo
...
1.1.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cb194c03f | ||
|
|
9191d38393 | ||
|
|
0dfe1a13a3 | ||
|
|
f9d74c858b | ||
|
|
d2f8942dda | ||
|
|
c656a7e244 | ||
|
|
393966d868 | ||
|
|
2aa6f5ab36 | ||
|
|
5ced60cf27 | ||
|
|
c46d3f4e99 | ||
|
|
bd2b0e576c | ||
|
|
87c3444ac7 | ||
|
|
1aebf44995 | ||
|
|
fab5f95420 | ||
|
|
56c06786e4 | ||
|
|
46d31b14ba | ||
|
|
a872b84785 | ||
|
|
6930a7cb46 | ||
|
|
9c288a65e7 | ||
|
|
5c9876f65e | ||
|
|
444604b589 | ||
|
|
758a79e8d1 | ||
|
|
ff4b8604da | ||
|
|
8092fe0ef6 | ||
|
|
1b688a3100 | ||
|
|
ba340aa3fe | ||
|
|
f82810b3ad | ||
|
|
72ca1338a2 | ||
|
|
438d35547a | ||
|
|
7a947ff026 | ||
|
|
f437cc4832 | ||
|
|
e98040ce76 | ||
|
|
ca259d7ddd | ||
|
|
ec92cb8733 | ||
|
|
c7d6ca0238 | ||
|
|
1ad2c716a5 | ||
|
|
df27f9d5d4 | ||
|
|
5bb98c5685 | ||
|
|
698b781726 | ||
|
|
0640fd43db | ||
|
|
23592cd549 | ||
|
|
9794ec70ae | ||
|
|
96e9545294 | ||
|
|
3ca24659a2 | ||
|
|
061741aab9 | ||
|
|
c77ac2da37 | ||
|
|
6089b9e459 | ||
|
|
94780418e7 | ||
|
|
a7685779f2 | ||
|
|
5131bb58a3 | ||
|
|
6e43210160 | ||
|
|
20e492e886 | ||
|
|
11889bda0b | ||
|
|
44a84889c0 | ||
|
|
df8ff29b07 | ||
|
|
d49767bbc6 | ||
|
|
9f950a2648 | ||
|
|
129b1c9521 | ||
|
|
b153b4c84e | ||
|
|
6bbe95d5bc | ||
|
|
9ee8c283ea | ||
|
|
34787901ed | ||
|
|
0b0d3db726 | ||
|
|
e8aadd25c0 | ||
|
|
21d9fc6782 | ||
|
|
2da7b7d3b6 | ||
|
|
743d662b80 | ||
|
|
89c4cae585 | ||
|
|
e32943571d | ||
|
|
7777f0b245 | ||
|
|
317e0948fa | ||
|
|
fbba4610e9 | ||
|
|
a5c684a969 | ||
|
|
8235c607dc | ||
|
|
af5c9efbd5 | ||
|
|
a4f5a0c918 | ||
|
|
2e6173e833 | ||
|
|
0a0a1c6fcd | ||
|
|
d70dfd457c | ||
|
|
9a80c0c7ab | ||
|
|
1cd723a552 | ||
|
|
5ca11db512 | ||
|
|
8b62b3ae55 | ||
|
|
3b42f4fff6 | ||
|
|
a8fdc88ac7 | ||
|
|
b15a441fc2 | ||
|
|
3a2fb489cb | ||
|
|
a208adf522 | ||
|
|
838a74d9de | ||
|
|
8e590d5913 | ||
|
|
aac8c19cf1 | ||
|
|
c49b55721b | ||
|
|
0f38b4636b | ||
|
|
93d9627054 | ||
|
|
2a4b6152a4 | ||
|
|
60e2e4911c | ||
|
|
92aa22aa9a | ||
|
|
674e0404d0 | ||
|
|
60f6754e0c | ||
|
|
cab7560089 | ||
|
|
7a1acaafad | ||
|
|
421962ab0f | ||
|
|
f43aa241da | ||
|
|
5d96a185bc | ||
|
|
166e81bd6d | ||
|
|
9fd7d949a4 | ||
|
|
b7a21e6cd8 | ||
|
|
62ba625247 | ||
|
|
c8fd0468f1 | ||
|
|
ba57d31391 | ||
|
|
878403bba4 | ||
|
|
d62e95f2d6 | ||
|
|
b8fbe1d808 | ||
|
|
d41fbcd285 | ||
|
|
12ed6c5ed2 | ||
|
|
b17ddb679c | ||
|
|
b24f272b99 | ||
|
|
008ff26687 | ||
|
|
f72bbfb527 | ||
|
|
22391b8737 | ||
|
|
28169a8a51 | ||
|
|
0396e5a9eb | ||
|
|
9c173bdd06 | ||
|
|
017bd3d9e0 | ||
|
|
336b3402a8 | ||
|
|
754733f514 | ||
|
|
85fbf3478d | ||
|
|
341eab5536 | ||
|
|
e1c12f3847 | ||
|
|
b08f36eabc | ||
|
|
114ea51232 | ||
|
|
7e3ea63586 | ||
|
|
91b05f6648 | ||
|
|
b2f0004a8b | ||
|
|
5b158f6d5a | ||
|
|
79212bbf2b | ||
|
|
f77bbf18d0 | ||
|
|
680462393f | ||
|
|
9cd56e691f | ||
|
|
54c74041b6 | ||
|
|
079f0ced7f | ||
|
|
eee5c1e836 | ||
|
|
fd411bdae1 | ||
|
|
95264f818d | ||
|
|
a1fd1726ce | ||
|
|
3b4b9c15d5 | ||
|
|
fabb150abc | ||
|
|
ce8943975e | ||
|
|
103c23250a | ||
|
|
cd380e6407 | ||
|
|
0f82e76e9b | ||
|
|
8b95973f6a | ||
|
|
92a49239b4 | ||
|
|
ed23880d60 | ||
|
|
756872a878 | ||
|
|
d245ff328c | ||
|
|
3f35fd3dcd | ||
|
|
4b3ead85d9 | ||
|
|
457fad7146 | ||
|
|
3f71b1af4f | ||
|
|
0203243fe0 | ||
|
|
f0a5fab759 | ||
|
|
444f14371d | ||
|
|
9d2d0c61d5 | ||
|
|
51f85aa8a5 | ||
|
|
22ea5a0679 | ||
|
|
b7f4a583cf | ||
|
|
fcb81c8c06 | ||
|
|
cf39aed382 | ||
|
|
39c3733786 | ||
|
|
cbbf796be2 | ||
|
|
b577a087ff | ||
|
|
d2192447ff | ||
|
|
0d55ab0750 | ||
|
|
6612f57767 | ||
|
|
f6777e8af9 | ||
|
|
0383370588 | ||
|
|
01779f10c3 | ||
|
|
aebc35a8f7 | ||
|
|
ae6973b8e4 | ||
|
|
6325fb1455 | ||
|
|
1efeec513f | ||
|
|
6c43e3f46b | ||
|
|
1558f81e1f | ||
|
|
70a0ca5b24 | ||
|
|
517e226ceb | ||
|
|
dee73deb28 | ||
|
|
e8bb5f7a47 | ||
|
|
0e0d429810 | ||
|
|
cee07c769e | ||
|
|
7823bee0a2 | ||
|
|
ea26411f86 | ||
|
|
94b51d8be0 | ||
|
|
935cf4d352 | ||
|
|
369d03d3f4 | ||
|
|
fae73c5b6e | ||
|
|
7faebbaadf | ||
|
|
6fe94b33fe | ||
|
|
e0b200a2fc | ||
|
|
83890dea47 | ||
|
|
a05abc0f1b | ||
|
|
9fa065142b | ||
|
|
aac8c847f7 | ||
|
|
fa9086e994 | ||
|
|
91cc4df61a | ||
|
|
ef3fb6e744 | ||
|
|
2a67ad5957 | ||
|
|
84547b535a | ||
|
|
cf3a2a6072 | ||
|
|
61f8931080 | ||
|
|
0f6b8d6d24 | ||
|
|
c2398cfc79 | ||
|
|
8f6e990b34 | ||
|
|
68ec640421 | ||
|
|
00ed7d37e0 | ||
|
|
22945c8adf | ||
|
|
9a44ad14b7 | ||
|
|
b874c92ea4 | ||
|
|
89484720a9 | ||
|
|
9afad21355 | ||
|
|
2ef1c2638d | ||
|
|
4aea15253b | ||
|
|
092f498c87 | ||
|
|
0052a60102 | ||
|
|
271b03e709 | ||
|
|
5085082882 | ||
|
|
e8c55ff562 | ||
|
|
3ac20bb452 | ||
|
|
c5b9c208b4 | ||
|
|
8e046c937a | ||
|
|
f4f6c1f9a8 | ||
|
|
bc17f4a037 | ||
|
|
3525d7b114 | ||
|
|
154939a2b0 | ||
|
|
a15ad448fa | ||
|
|
728db429df | ||
|
|
96a650085c | ||
|
|
09ecacabae | ||
|
|
8887728cae | ||
|
|
246d958b7a | ||
|
|
8a0f296e4f | ||
|
|
4cc8cdd603 | ||
|
|
7d8a66bd7e | ||
|
|
7366f6f885 | ||
|
|
c61453dfe4 | ||
|
|
1c2d598ad8 | ||
|
|
d25c2b321f | ||
|
|
9bae9ef919 | ||
|
|
f27ab21489 | ||
|
|
fff44b9a86 | ||
|
|
6af24876f9 | ||
|
|
9cff205755 | ||
|
|
e24becab2a | ||
|
|
989fe6197d | ||
|
|
dafc0d3eef | ||
|
|
f0327ca99d | ||
|
|
1f928ded2d | ||
|
|
cf00d29b0d | ||
|
|
cb2b038f26 | ||
|
|
9047547f8d | ||
|
|
aa8713953b | ||
|
|
51cfd9cda8 | ||
|
|
9f8557d782 | ||
|
|
22710fdd72 | ||
|
|
1a450eaad0 | ||
|
|
deb5fe104c | ||
|
|
04f707f8f8 | ||
|
|
fb9f0e8b3f | ||
|
|
f94d8145e2 | ||
|
|
e6e5f14c12 | ||
|
|
fca0f9da29 | ||
|
|
11004ed7a0 | ||
|
|
7f16ac6155 | ||
|
|
420747ef79 | ||
|
|
0f7e48aeef | ||
|
|
bab228a111 | ||
|
|
e8ea1968ec | ||
|
|
ecf69556d6 | ||
|
|
5ac69ed138 | ||
|
|
8238785405 | ||
|
|
2ec1e5aff9 | ||
|
|
9e27416df4 | ||
|
|
4c0f1e1dd8 | ||
|
|
fa52e816e8 | ||
|
|
110314c0c1 | ||
|
|
4b50020acc | ||
|
|
bc8fc980e1 | ||
|
|
5a0b269f91 | ||
|
|
3e875d017f | ||
|
|
b4683315f6 | ||
|
|
c42299a37f | ||
|
|
432f0ba0f4 | ||
|
|
fbf9bc7a07 | ||
|
|
8d9adfda7c | ||
|
|
b62cb188f7 | ||
|
|
51bac281f5 | ||
|
|
9cb7cba8ed | ||
|
|
a3e439c51b | ||
|
|
04984e5d1a | ||
|
|
af86bc314d | ||
|
|
c316a9922b | ||
|
|
b785d38f06 | ||
|
|
f489311884 | ||
|
|
522bd3abe8 | ||
|
|
cc2a6fc683 | ||
|
|
dcc7e94493 | ||
|
|
6a924c57cd | ||
|
|
e6403e8e97 | ||
|
|
06887e4f90 | ||
|
|
dbf2a0cb88 | ||
|
|
ab7a945eee | ||
|
|
a06ae76487 | ||
|
|
702eb3d921 | ||
|
|
952c276c01 | ||
|
|
9f1bd71780 | ||
|
|
2dbb6f8f2a | ||
|
|
9855b9a268 | ||
|
|
967d16547d | ||
|
|
30a976f75a | ||
|
|
e356c460b0 | ||
|
|
ec8295e674 | ||
|
|
83c8a92f6b | ||
|
|
42abb2ccf8 | ||
|
|
67e4833b11 | ||
|
|
976afd2f77 | ||
|
|
0cd618103f | ||
|
|
424fd67f9e | ||
|
|
021d7c17e4 | ||
|
|
119124a79c | ||
|
|
c2972a53e7 | ||
|
|
60e34ca808 | ||
|
|
e5a5d72e00 | ||
|
|
d11ee91d03 | ||
|
|
48cf1f05a7 | ||
|
|
26f3174d09 | ||
|
|
06d60b53b2 | ||
|
|
c3aeabed8c | ||
|
|
18b374ccba | ||
|
|
668e882db2 | ||
|
|
7f135ce137 | ||
|
|
1605475cc4 | ||
|
|
0eb102f332 | ||
|
|
59b9d0a5ad | ||
|
|
f54dcb3b3f | ||
|
|
453cd2e615 | ||
|
|
4e43cc6bb6 | ||
|
|
5cdb2d80bd | ||
|
|
4f618353ad | ||
|
|
1dcb888d6d | ||
|
|
f28d21bc6d | ||
|
|
91417cc4e5 | ||
|
|
132b588af7 |
3
.idea/artifacts/KotlinPlugin.xml
generated
3
.idea/artifacts/KotlinPlugin.xml
generated
@@ -61,6 +61,7 @@
|
||||
<element id="module-output" name="ir.psi2ir" />
|
||||
<element id="module-output" name="annotation-based-compiler-plugins-ide-support" />
|
||||
<element id="module-output" name="frontend.script" />
|
||||
<element id="extracted-dir" path="$PROJECT_DIR$/dependencies/json-org.jar" path-in-jar="/" />
|
||||
</element>
|
||||
<element id="library" level="project" name="javax.inject" />
|
||||
<element id="directory" name="jps">
|
||||
@@ -72,6 +73,7 @@
|
||||
</element>
|
||||
<element id="archive" name="android-extensions-compiler.jar">
|
||||
<element id="module-output" name="android-extensions-compiler" />
|
||||
<element id="module-output" name="android-extensions-runtime" />
|
||||
</element>
|
||||
<element id="archive" name="android-lint.jar">
|
||||
<element id="module-output" name="uast-kotlin" />
|
||||
@@ -105,6 +107,7 @@
|
||||
<element id="library" level="project" name="uast-java" />
|
||||
<element id="library" level="project" name="kotlinx-coroutines-core" />
|
||||
<element id="library" level="project" name="javaslang" />
|
||||
<element id="library" level="project" name="kotlinx-coroutines-jdk8" />
|
||||
</element>
|
||||
<element id="directory" name="kotlinc">
|
||||
<element id="dir-copy" path="$PROJECT_DIR$/dist/kotlinc" />
|
||||
|
||||
2
.idea/dictionaries/yan.xml
generated
2
.idea/dictionaries/yan.xml
generated
@@ -1,8 +1,10 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="yan">
|
||||
<words>
|
||||
<w>deserializes</w>
|
||||
<w>impls</w>
|
||||
<w>kapt</w>
|
||||
<w>parceler</w>
|
||||
<w>uast</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
||||
9
.idea/libraries/android_layoutlib.xml
generated
Normal file
9
.idea/libraries/android_layoutlib.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="android-layoutlib">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/layoutlib.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
11
.idea/libraries/kotlinx_coroutines_jdk8.xml
generated
Normal file
11
.idea/libraries/kotlinx_coroutines_jdk8.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlinx-coroutines-jdk8">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/kotlinx-coroutines-jdk8.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/kotlinx-coroutines-jdk8-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
59
.idea/libraries/robolectric.xml
generated
Normal file
59
.idea/libraries/robolectric.xml
generated
Normal file
@@ -0,0 +1,59 @@
|
||||
<component name="libraryTable">
|
||||
<library name="robolectric">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/accessibility-test-framework-2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/ant-1.8.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/ant-launcher-1.8.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-commons-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/asm-tree-5.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/assertj-core-2.6.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/backport-util-concurrent-3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/bcprov-jdk16-1.46.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/classworlds-1.1-alpha-2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/guava-20.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/hamcrest-core-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/hamcrest-library-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/icu4j-53.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-ant-tasks-2.1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-artifact-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-artifact-manager-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-error-diagnostics-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-model-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-plugin-registry-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-profile-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-project-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-repository-metadata-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/maven-settings-2.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/nekohtml-1.9.6.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-container-default-1.0-alpha-9-stable-1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-interpolation-1.11.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/plexus-utils-1.5.15.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/protobuf-java-2.6.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-annotations-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-junit-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-resources-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-sandbox-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-utils-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadow-api-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/shadows-core-3.3.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/sqlite4java-0.282.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-file-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-http-lightweight-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-http-shared-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/wagon-provider-api-1.0-beta-6.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xercesMinimal-1.9.6.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xmlpull-1.1.3.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xpp3_min-1.1.4c.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/xstream-1.4.8.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-sources-source.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/robolectric/robolectric-3.3.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
13
.idea/modules.xml
generated
13
.idea/modules.xml
generated
@@ -9,11 +9,11 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-compiler/android-extensions-compiler.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-compiler/android-extensions-compiler.iml" group="plugins/android-extensions" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml" group="plugins/android-extensions" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-jps/android-extensions-jps.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-jps/android-extensions-jps.iml" group="plugins/android-extensions" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-runtime/android-extensions-runtime.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-runtime/android-extensions-runtime.iml" group="plugins/android-extensions" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android-studio/android-studio.iml" filepath="$PROJECT_DIR$/android-studio/android-studio.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/android-tests/android-tests.iml" filepath="$PROJECT_DIR$/compiler/android-tests/android-tests.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-based-compiler-plugins-ide-support/annotation-based-compiler-plugins-ide-support.iml" filepath="$PROJECT_DIR$/plugins/annotation-based-compiler-plugins-ide-support/annotation-based-compiler-plugins-ide-support.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-collector/annotation-collector.iml" filepath="$PROJECT_DIR$/plugins/annotation-collector/annotation-collector.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-processing/annotation-processing.iml" filepath="$PROJECT_DIR$/plugins/annotation-processing/annotation-processing.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/ant/ant.iml" filepath="$PROJECT_DIR$/ant/ant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/compiler/backend/backend.iml" group="compiler/java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/backend-common/backend-common.iml" filepath="$PROJECT_DIR$/compiler/backend-common/backend-common.iml" group="compiler" />
|
||||
@@ -63,7 +63,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/ir/ir.psi2ir/ir.psi2ir.iml" filepath="$PROJECT_DIR$/compiler/ir/ir.psi2ir/ir.psi2ir.iml" group="compiler/ir" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/ir/ir.tree/ir.tree.iml" filepath="$PROJECT_DIR$/compiler/ir/ir.tree/ir.tree.iml" group="compiler/ir" />
|
||||
<module fileurl="file://$PROJECT_DIR$/j2k/j2k.iml" filepath="$PROJECT_DIR$/j2k/j2k.iml" group="j2k" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/java-model-wrappers/java-model-wrappers.iml" filepath="$PROJECT_DIR$/plugins/java-model-wrappers/java-model-wrappers.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/javac-wrapper/javac-wrapper.iml" filepath="$PROJECT_DIR$/compiler/javac-wrapper/javac-wrapper.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-plugin.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-plugin.iml" group="ide/jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-tests/jps-tests.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-tests/jps-tests.iml" group="ide/jps" />
|
||||
@@ -76,14 +75,14 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/js/js.tests/js.tests.iml" filepath="$PROJECT_DIR$/js/js.tests/js.tests.iml" group="compiler/js" />
|
||||
<module fileurl="file://$PROJECT_DIR$/js/js.translator/js.translator.iml" filepath="$PROJECT_DIR$/js/js.translator/js.translator.iml" group="compiler/js" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" filepath="$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" group="ide/jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kapt3/kapt3.iml" filepath="$PROJECT_DIR$/plugins/kapt3/kapt3.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kapt3/kapt3.iml" filepath="$PROJECT_DIR$/plugins/kapt3/kapt3.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml" filepath="$PROJECT_DIR$/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/light-classes/light-classes.iml" filepath="$PROJECT_DIR$/compiler/light-classes/light-classes.iml" group="compiler/java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" group="plugins/lint" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" group="plugins/lint" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-idea/lint-idea.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-idea/lint-idea.iml" group="plugins/lint" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" group="plugins/noarg" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" group="plugins/noarg" />
|
||||
<module fileurl="file://$PROJECT_DIR$/non-compiler-tests/non-compiler-tests.iml" filepath="$PROJECT_DIR$/non-compiler-tests/non-compiler-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" filepath="$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/plugins-tests/plugins-tests.iml" filepath="$PROJECT_DIR$/plugins/plugins-tests/plugins-tests.iml" group="plugins" />
|
||||
@@ -91,8 +90,8 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" filepath="$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/resolution/resolution.iml" filepath="$PROJECT_DIR$/compiler/resolution/resolution.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" filepath="$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" group="plugins/sam-with-receiver" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" group="plugins/sam-with-receiver" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/script.runtime/script.runtime.iml" filepath="$PROJECT_DIR$/core/script.runtime/script.runtime.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/serialization/serialization.iml" filepath="$PROJECT_DIR$/compiler/serialization/serialization.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/source-sections/source-sections-compiler/source-sections-compiler.iml" filepath="$PROJECT_DIR$/plugins/source-sections/source-sections-compiler/source-sections-compiler.iml" group="plugins" />
|
||||
|
||||
3415
ChangeLog.md
3415
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,8 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/kotlin-jsr223-local-example/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/common/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/js/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/js/it/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/js/it/node_modules" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/junit/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/jvm/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/libraries/stdlib/build" />
|
||||
@@ -81,4 +83,4 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
</module>
|
||||
|
||||
@@ -197,7 +197,7 @@ open class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
|
||||
}
|
||||
|
||||
class LookupTrackerImpl(private val delegate: LookupTracker) : LookupTracker {
|
||||
val lookups = MultiMap<LookupSymbol, String>()
|
||||
val lookups = MultiMap.createSet<LookupSymbol, String>()
|
||||
val pathInterner = StringInterner()
|
||||
private val interner = StringInterner()
|
||||
|
||||
|
||||
@@ -56,6 +56,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) return false
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
enum class ProtoBufPackageKind {
|
||||
@@ -64,7 +70,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
TYPE_ALIAS_LIST,
|
||||
TYPE_TABLE,
|
||||
SINCE_KOTLIN_INFO_TABLE,
|
||||
PACKAGE_MODULE_NAME
|
||||
PACKAGE_MODULE_NAME,
|
||||
PACKAGE_LOCAL_VARIABLE_LIST
|
||||
}
|
||||
|
||||
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
|
||||
@@ -91,6 +98,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -147,6 +160,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) return false
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
enum class ProtoBufClassKind {
|
||||
@@ -166,7 +185,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
TYPE_TABLE,
|
||||
SINCE_KOTLIN_INFO,
|
||||
SINCE_KOTLIN_INFO_TABLE,
|
||||
CLASS_MODULE_NAME
|
||||
CLASS_MODULE_NAME,
|
||||
CLASS_LOCAL_VARIABLE_LIST
|
||||
}
|
||||
|
||||
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
|
||||
@@ -224,6 +244,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
|
||||
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
|
||||
}
|
||||
|
||||
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
|
||||
|
||||
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -1053,6 +1079,10 @@ fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
|
||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.packageLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
@@ -1125,6 +1155,10 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
|
||||
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
|
||||
}
|
||||
|
||||
for(i in 0..getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
|
||||
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.classLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
|
||||
}
|
||||
|
||||
return hashCode
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,8 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
}
|
||||
|
||||
for (kind in diff) {
|
||||
when (kind!!) {
|
||||
@Suppress("UNUSED_VARIABLE") // To make this 'when' exhaustive
|
||||
val unused: Any = when (kind!!) {
|
||||
ProtoBufClassKind.COMPANION_OBJECT_NAME -> {
|
||||
if (oldProto.hasCompanionObjectName()) oldProto.companionObjectName.oldToNames()
|
||||
if (newProto.hasCompanionObjectName()) newProto.companionObjectName.newToNames()
|
||||
@@ -203,10 +204,7 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
}
|
||||
ProtoBufClassKind.CONSTRUCTOR_LIST -> {
|
||||
val differentNonPrivateConstructors = calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList)
|
||||
|
||||
if (differentNonPrivateConstructors.isNotEmpty()) {
|
||||
isClassAffected = true
|
||||
}
|
||||
isClassAffected = isClassAffected || differentNonPrivateConstructors.isNotEmpty()
|
||||
}
|
||||
ProtoBufClassKind.FUNCTION_LIST ->
|
||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getFunctionList))
|
||||
@@ -238,6 +236,9 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
||||
ProtoBufClassKind.CLASS_MODULE_NAME -> {
|
||||
// TODO
|
||||
}
|
||||
ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST -> {
|
||||
// Not affected, local variables are not accessible outside of a file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +268,8 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
|
||||
}
|
||||
|
||||
for (kind in diff) {
|
||||
when (kind!!) {
|
||||
@Suppress("UNUSED_VARIABLE") // To make this 'when' exhaustive
|
||||
val unused: Any = when (kind!!) {
|
||||
ProtoBufPackageKind.FUNCTION_LIST ->
|
||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getFunctionList))
|
||||
ProtoBufPackageKind.PROPERTY_LIST ->
|
||||
@@ -279,7 +281,9 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
|
||||
ProtoBufPackageKind.PACKAGE_MODULE_NAME -> {
|
||||
// TODO
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unsupported kind: $kind")
|
||||
ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST -> {
|
||||
// Not affected, local variables are not accessible outside of a file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ public final class DebugJvmProtoBuf {
|
||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.isRaw);
|
||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.typeParameterAnnotation);
|
||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classModuleName);
|
||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classLocalVariable);
|
||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageModuleName);
|
||||
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageLocalVariable);
|
||||
}
|
||||
public interface StringTableTypesOrBuilder extends
|
||||
// @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.jvm.StringTableTypes)
|
||||
@@ -4586,6 +4588,17 @@ public final class DebugJvmProtoBuf {
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Integer.class,
|
||||
null);
|
||||
public static final int CLASS_LOCAL_VARIABLE_FIELD_NUMBER = 102;
|
||||
/**
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Property>> classLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.getDefaultInstance());
|
||||
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
|
||||
/**
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||
@@ -4597,6 +4610,17 @@ public final class DebugJvmProtoBuf {
|
||||
.newFileScopedGeneratedExtension(
|
||||
java.lang.Integer.class,
|
||||
null);
|
||||
public static final int PACKAGE_LOCAL_VARIABLE_FIELD_NUMBER = 102;
|
||||
/**
|
||||
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
|
||||
*/
|
||||
public static final
|
||||
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package,
|
||||
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Property>> packageLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessage
|
||||
.newFileScopedGeneratedExtension(
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.class,
|
||||
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.getDefaultInstance());
|
||||
private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
|
||||
internal_static_org_jetbrains_kotlin_serialization_jvm_StringTableTypes_descriptor;
|
||||
private static
|
||||
@@ -4678,9 +4702,15 @@ public final class DebugJvmProtoBuf {
|
||||
"g.jetbrains.kotlin.serialization.Annotat" +
|
||||
"ion:J\n\021class_module_name\022).org.jetbrains" +
|
||||
".kotlin.serialization.Class\030e \001(\005B\004\230\265\030\001:" +
|
||||
"N\n\023package_module_name\022+.org.jetbrains.k" +
|
||||
"otlin.serialization.Package\030e \001(\005B\004\230\265\030\001B" +
|
||||
"\022B\020DebugJvmProtoBuf"
|
||||
"u\n\024class_local_variable\022).org.jetbrains." +
|
||||
"kotlin.serialization.Class\030f \003(\0132,.org.j" +
|
||||
"etbrains.kotlin.serialization.Property:N",
|
||||
"\n\023package_module_name\022+.org.jetbrains.ko" +
|
||||
"tlin.serialization.Package\030e \001(\005B\004\230\265\030\001:y" +
|
||||
"\n\026package_local_variable\022+.org.jetbrains" +
|
||||
".kotlin.serialization.Package\030f \003(\0132,.or" +
|
||||
"g.jetbrains.kotlin.serialization.Propert" +
|
||||
"yB\022B\020DebugJvmProtoBuf"
|
||||
};
|
||||
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
|
||||
@@ -4733,7 +4763,9 @@ public final class DebugJvmProtoBuf {
|
||||
isRaw.internalInit(descriptor.getExtensions().get(4));
|
||||
typeParameterAnnotation.internalInit(descriptor.getExtensions().get(5));
|
||||
classModuleName.internalInit(descriptor.getExtensions().get(6));
|
||||
packageModuleName.internalInit(descriptor.getExtensions().get(7));
|
||||
classLocalVariable.internalInit(descriptor.getExtensions().get(7));
|
||||
packageModuleName.internalInit(descriptor.getExtensions().get(8));
|
||||
packageLocalVariable.internalInit(descriptor.getExtensions().get(9));
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry =
|
||||
org.jetbrains.kotlin.protobuf.ExtensionRegistry.newInstance();
|
||||
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.stringIdInTable);
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
<fileset dir="${dependencies}" includes="jline.jar"/>
|
||||
<fileset dir="${dependencies}" includes="javaslang-2.0.6.jar"/>
|
||||
<fileset dir="${dependencies}" includes="json-org.jar"/>
|
||||
<fileset dir="${dependencies}" includes="kotlinx-coroutines-core.jar"/>
|
||||
<fileset dir="${basedir}/ideaSDK/jps" includes="jps-model.jar"/>
|
||||
</path>
|
||||
|
||||
@@ -403,6 +404,7 @@
|
||||
<zipfileset src="${dependencies}/javaslang-2.0.6.jar"/>
|
||||
<zipfileset src="${dependencies}/json-org.jar"/>
|
||||
<zipfileset src="${protobuf.jar}"/>
|
||||
<zipfileset src="${dependencies}/kotlinx-coroutines-core.jar"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
@@ -653,9 +655,11 @@
|
||||
<skip pattern="kotlin/Metadata"/>
|
||||
<src>
|
||||
<pathelement path="plugins/android-extensions/android-extensions-compiler/src"/>
|
||||
<pathelement path="plugins/android-extensions/android-extensions-runtime/src"/>
|
||||
</src>
|
||||
<classpath>
|
||||
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
|
||||
<pathelement path="${idea.sdk}/plugins/android/lib/layoutlib.jar"/>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
</javac2>
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
@@ -869,6 +870,11 @@ public class AsmUtil {
|
||||
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeByClassId(@NotNull ClassId classId) {
|
||||
return Type.getObjectType(classId.asString().replace('.', '$'));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String internalNameByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
|
||||
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();
|
||||
|
||||
@@ -192,6 +192,6 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
@Nullable
|
||||
@Override
|
||||
protected ClassDescriptor classForInnerClassRecord() {
|
||||
return DescriptorUtils.isTopLevelDeclaration(descriptor) ? null : descriptor;
|
||||
return InnerClassConsumer.Companion.classForInnerClassRecord(descriptor, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.ClosureContext;
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
@@ -229,9 +231,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
@Override
|
||||
protected void generateKotlinMetadataAnnotation() {
|
||||
FunctionDescriptor frontendFunDescriptor = CodegenUtilKt.unwrapFrontendVersion(funDescriptor);
|
||||
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(frontendFunDescriptor);
|
||||
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
|
||||
assert method != null : "No method for " + frontendFunDescriptor;
|
||||
|
||||
FunctionDescriptor freeLambdaDescriptor = FakeDescriptorsForReferencesKt.createFreeFakeLambdaDescriptor(frontendFunDescriptor);
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
@@ -245,30 +248,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
|
||||
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
||||
*/
|
||||
@NotNull
|
||||
public static FunctionDescriptor createFreeLambdaDescriptor(@NotNull FunctionDescriptor descriptor) {
|
||||
FunctionDescriptor.CopyBuilder<? extends FunctionDescriptor> builder = descriptor.newCopyBuilder();
|
||||
List<TypeParameterDescriptor> typeParameters = new ArrayList<>(0);
|
||||
builder.setTypeParameters(typeParameters);
|
||||
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
while (container != null) {
|
||||
if (container instanceof ClassDescriptor) {
|
||||
typeParameters.addAll(((ClassDescriptor) container).getDeclaredTypeParameters());
|
||||
}
|
||||
else if (container instanceof CallableDescriptor && !(container instanceof ConstructorDescriptor)) {
|
||||
typeParameters.addAll(((CallableDescriptor) container).getTypeParameters());
|
||||
}
|
||||
container = container.getContainingDeclaration();
|
||||
}
|
||||
|
||||
return typeParameters.isEmpty() ? descriptor : builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
writeOuterClassAndEnclosingMethod();
|
||||
@@ -381,13 +360,30 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
|
||||
if (container instanceof ClassDescriptor) {
|
||||
// TODO: getDefaultType() here is wrong and won't work for arrays
|
||||
putJavaLangClassInstance(iv, state.getTypeMapper().mapType(((ClassDescriptor) container).getDefaultType()));
|
||||
wrapJavaClassIntoKClass(iv);
|
||||
}
|
||||
else if (container instanceof PackageFragmentDescriptor) {
|
||||
iv.aconst(state.getTypeMapper().mapOwner(descriptor));
|
||||
}
|
||||
else if (descriptor instanceof VariableDescriptorWithAccessors) {
|
||||
iv.aconst(state.getBindingContext().get(
|
||||
CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, ((VariableDescriptorWithAccessors) descriptor)
|
||||
));
|
||||
}
|
||||
else {
|
||||
iv.aconst(null);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isContainerPackage =
|
||||
descriptor instanceof LocalVariableDescriptor
|
||||
? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) == null
|
||||
: container instanceof PackageFragmentDescriptor;
|
||||
|
||||
if (isContainerPackage) {
|
||||
// Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead,
|
||||
// but there's no nice API to obtain that name here yet
|
||||
// TODO: write the referenced declaration's module name and use it in reflection
|
||||
@@ -396,7 +392,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
Type.getMethodDescriptor(K_DECLARATION_CONTAINER_TYPE, getType(Class.class), getType(String.class)), false);
|
||||
}
|
||||
else {
|
||||
iv.aconst(null);
|
||||
wrapJavaClassIntoKClass(iv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -827,24 +827,29 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
public StackValue visitStringTemplateExpression(@NotNull KtStringTemplateExpression expression, StackValue receiver) {
|
||||
List<StringTemplateEntry> entries = preprocessStringTemplate(expression);
|
||||
|
||||
if (entries.size() == 1) {
|
||||
Type type = expressionType(expression);
|
||||
|
||||
if (entries.size() == 0) {
|
||||
return StackValue.constant("", type);
|
||||
}
|
||||
else if (entries.size() == 1) {
|
||||
StringTemplateEntry entry = entries.get(0);
|
||||
if (entry instanceof StringTemplateEntry.Expression) {
|
||||
KtExpression expr = ((StringTemplateEntry.Expression) entry).expression;
|
||||
return genToString(gen(expr), expressionType(expr));
|
||||
return genToString(gen(expr), type);
|
||||
}
|
||||
else {
|
||||
Type type = expressionType(expression);
|
||||
return StackValue.constant(((StringTemplateEntry.Constant) entry).value, type);
|
||||
}
|
||||
}
|
||||
|
||||
return StackValue.operation(JAVA_STRING_TYPE, v -> {
|
||||
genStringBuilderConstructor(v);
|
||||
invokeAppendForEntries(v, entries);
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
else {
|
||||
return StackValue.operation(type, v -> {
|
||||
genStringBuilderConstructor(v);
|
||||
invokeAppendForEntries(v, entries);
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeAppendForEntries(InstructionAdapter v, List<StringTemplateEntry> entries) {
|
||||
@@ -1604,11 +1609,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
// If it does not end with return we should return something
|
||||
// because if we don't there can be VerifyError (specific cases with Nothing-typed expressions)
|
||||
if (!endsWithReturn(expr)) {
|
||||
markLineNumber(expr, true);
|
||||
|
||||
if (isLambdaVoidBody(expr, typeForExpression)) {
|
||||
markLineNumber((KtFunctionLiteral) expr.getParent(), true);
|
||||
}
|
||||
else {
|
||||
markLineNumber(expr, true);
|
||||
}
|
||||
|
||||
if (typeForExpression.getSort() == Type.VOID) {
|
||||
StackValue.none().put(returnType, v);
|
||||
@@ -1772,31 +1778,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return lookupCapturedValueInConstructorParameters(descriptor);
|
||||
}
|
||||
|
||||
return lookupValuaAndLocalVariableMetadata(descriptor, StackValue.LOCAL_0, state, false, context, this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static StackValue lookupValuaAndLocalVariableMetadata(
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull StackValue prefix,
|
||||
@NotNull GenerationState state,
|
||||
boolean ignoreNoOuter,
|
||||
@NotNull CodegenContext context,
|
||||
@Nullable ExpressionCodegen codegen
|
||||
) {
|
||||
StackValue value = context.lookupInContext(descriptor, prefix, state, ignoreNoOuter);
|
||||
if(!isDelegatedLocalVariable(descriptor) || value == null) {
|
||||
return value;
|
||||
StackValue value = context.lookupInContext(descriptor, StackValue.LOCAL_0, state, false);
|
||||
if (isDelegatedLocalVariable(descriptor) && value != null) {
|
||||
VariableDescriptor metadata = getDelegatedLocalVariableMetadata((VariableDescriptor) descriptor, bindingContext);
|
||||
StackValue metadataValue = context.lookupInContext(metadata, StackValue.LOCAL_0, state, false);
|
||||
assert metadataValue != null : "Metadata stack value should be non-null for local delegated property: " + descriptor;
|
||||
return delegatedVariableValue(value, metadataValue, (VariableDescriptorWithAccessors) descriptor, typeMapper);
|
||||
}
|
||||
|
||||
|
||||
VariableDescriptor metadata = getDelegatedLocalVariableMetadata((VariableDescriptor) descriptor, state.getBindingContext());
|
||||
StackValue metadataValue = context.lookupInContext(metadata, prefix, state, ignoreNoOuter);
|
||||
assert metadataValue != null : "Metadata stack value should be non-null for local delegated property";
|
||||
//required for ImplementationBodyCodegen.lookupConstructorExpressionsInClosureIfPresent
|
||||
if (codegen == null) return null;
|
||||
return codegen.delegatedVariableValue(value, metadataValue, (VariableDescriptorWithAccessors) descriptor,
|
||||
state.getTypeMapper());
|
||||
return value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1807,7 +1797,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
int parameterOffsetInConstructor = context.closure.getCapturedParameterOffsetInConstructor(descriptor);
|
||||
// when captured parameter is singleton
|
||||
// see compiler/testData/codegen/box/objects/objectInLocalAnonymousObject.kt (fun local() captured in A)
|
||||
if (parameterOffsetInConstructor == -1) return adjustVariableValue(parentResult , descriptor);
|
||||
if (parameterOffsetInConstructor == -1) return adjustVariableValue(parentResult, descriptor);
|
||||
|
||||
assert parentResult instanceof StackValue.Field || parentResult instanceof StackValue.FieldForSharedVar
|
||||
: "Part of closure should be either Field or FieldForSharedVar";
|
||||
@@ -2044,32 +2034,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return genClosure((KtNamedFunction) expression, samType);
|
||||
}
|
||||
|
||||
Type asmType =
|
||||
state.getSamWrapperClasses().getSamWrapperClass(samType, expression.getContainingKtFile(), this);
|
||||
Type asmType = state.getSamWrapperClasses().getSamWrapperClass(samType, expression.getContainingKtFile(), this);
|
||||
|
||||
return StackValue.operation(asmType, v -> {
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
Label afterAll = new Label();
|
||||
|
||||
Type functionType = typeMapper.mapType(samType.getKotlinFunctionType());
|
||||
expression.accept(visitor, StackValue.none()).put(functionType, v);
|
||||
|
||||
Label ifNonNull = new Label();
|
||||
Label afterAll = new Label();
|
||||
|
||||
v.dup();
|
||||
v.ifnonnull(ifNonNull);
|
||||
v.ifnull(afterAll);
|
||||
|
||||
// if null: pop function value and wrapper objects, put null
|
||||
v.pop();
|
||||
v.pop2();
|
||||
v.aconst(null);
|
||||
v.goTo(afterAll);
|
||||
|
||||
v.mark(ifNonNull);
|
||||
int tmp = myFrameMap.enterTemp(functionType);
|
||||
v.store(tmp, functionType);
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
v.load(tmp, functionType);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, functionType), false);
|
||||
myFrameMap.leaveTemp(functionType);
|
||||
|
||||
v.mark(afterAll);
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -2966,10 +2951,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return genCmpWithZero(left, opToken);
|
||||
}
|
||||
|
||||
if (left instanceof KtSafeQualifiedExpression && isPrimitive(rightType)) {
|
||||
if (left instanceof KtSafeQualifiedExpression
|
||||
&& isSelectorPureNonNullType((KtSafeQualifiedExpression) left) && isPrimitive(rightType)) {
|
||||
return genCmpSafeCallToPrimitive((KtSafeQualifiedExpression) left, right, rightType, opToken);
|
||||
}
|
||||
if (isPrimitive(leftType) && right instanceof KtSafeQualifiedExpression) {
|
||||
if (isPrimitive(leftType) && right instanceof KtSafeQualifiedExpression && isSelectorPureNonNullType(((KtSafeQualifiedExpression) right))) {
|
||||
return genCmpPrimitiveToSafeCall(left, leftType, (KtSafeQualifiedExpression) right, opToken);
|
||||
}
|
||||
|
||||
@@ -2987,6 +2973,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return genEqualsForExpressionsPreferIEEE754Arithmetic(left, right, opToken, leftType, rightType, null);
|
||||
}
|
||||
|
||||
private boolean isSelectorPureNonNullType(@NotNull KtSafeQualifiedExpression safeExpression) {
|
||||
KtExpression expression = safeExpression.getSelectorExpression();
|
||||
if (expression == null) return false;
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(expression, bindingContext);
|
||||
if (resolvedCall == null) return false;
|
||||
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
return returnType != null && !TypeUtils.isNullableType(returnType);
|
||||
}
|
||||
|
||||
private StackValue genCmpPrimitiveToSafeCall(
|
||||
@NotNull KtExpression left,
|
||||
@NotNull Type leftType,
|
||||
@@ -3564,7 +3559,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue getVariableMetadataValue(VariableDescriptor variableDescriptor) {
|
||||
private StackValue getVariableMetadataValue(@NotNull VariableDescriptorWithAccessors variableDescriptor) {
|
||||
StackValue value = findLocalOrCapturedValue(getDelegatedLocalVariableMetadata(variableDescriptor, bindingContext));
|
||||
assert value != null : "Can't find stack value for local delegated variable metadata: " + variableDescriptor;
|
||||
return value;
|
||||
@@ -3610,14 +3605,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
StackValue metadataValue = getVariableMetadataValue(variableDescriptor);
|
||||
initializePropertyMetadata((KtProperty) variableDeclaration, variableDescriptor, metadataValue);
|
||||
|
||||
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall = bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor);
|
||||
if (provideDelegateResolvedCall != null) {
|
||||
resultType = generateProvideDelegateCallForLocalVariable(initializer, metadataValue, provideDelegateResolvedCall);
|
||||
ResolvedCall<FunctionDescriptor> provideDelegateCall = bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor);
|
||||
if (provideDelegateCall != null) {
|
||||
resultType = generateProvideDelegateCallForLocalVariable(initializer, metadataValue, provideDelegateCall);
|
||||
}
|
||||
}
|
||||
|
||||
storeTo.storeSelector(resultType, v);
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -3664,10 +3658,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull LocalVariableDescriptor variableDescriptor,
|
||||
@NotNull StackValue metadataVar
|
||||
) {
|
||||
// TODO: do not generate anonymous classes for local delegated properties in inline functions
|
||||
// We can use the $$delegatedProperties array as in non-inline functions and upon inlining, detect elements at what indices
|
||||
// of that array are used in the inline function body, load the corresponding initializing bytecode from <clinit> of the
|
||||
// container class (where the PropertyReferenceNImpl instance is created), copy and adapt it at the call site
|
||||
//noinspection ConstantConditions
|
||||
StackValue value = generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null, null);
|
||||
value.put(K_PROPERTY0_TYPE, v);
|
||||
metadataVar.storeSelector(K_PROPERTY0_TYPE, v);
|
||||
StackValue value = context.getFunctionDescriptor().isInline()
|
||||
? generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null, null)
|
||||
: PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
|
||||
value.put(K_PROPERTY_TYPE, v);
|
||||
metadataVar.storeSelector(K_PROPERTY_TYPE, v);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -595,8 +595,31 @@ public class FunctionCodegen {
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
int shiftForDestructuringVariables
|
||||
) {
|
||||
generateLocalVariablesForParameters(mv, jvmMethodSignature, thisType, methodBegin, methodEnd,
|
||||
functionDescriptor.getValueParameters(),
|
||||
if (functionDescriptor.isSuspend()) {
|
||||
FunctionDescriptor unwrapped = CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(
|
||||
functionDescriptor
|
||||
);
|
||||
|
||||
if (unwrapped != functionDescriptor) {
|
||||
generateLocalVariableTable(
|
||||
mv,
|
||||
new JvmMethodSignature(
|
||||
jvmMethodSignature.getAsmMethod(),
|
||||
jvmMethodSignature.getValueParameters().subList(
|
||||
0,
|
||||
jvmMethodSignature.getValueParameters().size() - 1
|
||||
)
|
||||
),
|
||||
unwrapped,
|
||||
thisType, methodBegin, methodEnd, ownerKind, typeMapper, shiftForDestructuringVariables
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
generateLocalVariablesForParameters(mv,
|
||||
jvmMethodSignature,
|
||||
thisType, methodBegin, methodEnd, functionDescriptor.getValueParameters(),
|
||||
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), typeMapper, shiftForDestructuringVariables
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1234,9 +1234,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void lookupInContext(@NotNull DeclarationDescriptor toLookup) {
|
||||
ExpressionCodegen.lookupValuaAndLocalVariableMetadata(toLookup, StackValue.LOCAL_0, state, true, context, null);
|
||||
context.lookupInContext(toLookup, StackValue.LOCAL_0, state, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,35 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import java.util.*
|
||||
|
||||
interface InnerClassConsumer {
|
||||
fun addInnerClassInfoFromAnnotation(classDescriptor: ClassDescriptor)
|
||||
|
||||
companion object {
|
||||
|
||||
fun classForInnerClassRecord(descriptor: ClassDescriptor, defaultImpls: Boolean): ClassDescriptor? {
|
||||
if (defaultImpls) {
|
||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||
val classDescriptorImpl = ClassDescriptorImpl(
|
||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE,
|
||||
/* isExternal = */ false)
|
||||
|
||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||
return classDescriptorImpl
|
||||
}
|
||||
else {
|
||||
return if (DescriptorUtils.isTopLevelDeclaration(descriptor)) null else descriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,20 +22,14 @@ import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import java.util.*
|
||||
|
||||
class InterfaceImplBodyCodegen(
|
||||
aClass: KtPureClassOrObject,
|
||||
@@ -47,12 +41,14 @@ class InterfaceImplBodyCodegen(
|
||||
private var isAnythingGenerated: Boolean = false
|
||||
get() = (v as InterfaceImplClassBuilder).isAnythingGenerated
|
||||
|
||||
private val defaultImplType = typeMapper.mapDefaultImpls(descriptor)
|
||||
|
||||
override fun generateDeclaration() {
|
||||
val codegenFlags = ACC_PUBLIC or ACC_FINAL or ACC_SUPER
|
||||
val flags = if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) codegenFlags or ACC_STATIC else codegenFlags
|
||||
v.defineClass(
|
||||
myClass.psiOrParent, state.classFileVersion, flags,
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
defaultImplType.internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
v.visitSource(myClass.containingKtFile.name, null)
|
||||
@@ -60,14 +56,7 @@ class InterfaceImplBodyCodegen(
|
||||
|
||||
override fun classForInnerClassRecord(): ClassDescriptor? {
|
||||
if (!isAnythingGenerated) return null
|
||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||
val classDescriptorImpl = ClassDescriptorImpl(
|
||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE,
|
||||
/* isExternal = */ false)
|
||||
|
||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||
return classDescriptorImpl
|
||||
return InnerClassConsumer.classForInnerClassRecord(descriptor, true)
|
||||
}
|
||||
|
||||
override fun generateSyntheticParts() {
|
||||
@@ -161,7 +150,7 @@ class InterfaceImplBodyCodegen(
|
||||
override fun done() {
|
||||
super.done()
|
||||
if (!isAnythingGenerated) {
|
||||
state.factory.removeClasses(setOf(typeMapper.mapDefaultImpls(descriptor).internalName))
|
||||
state.factory.removeClasses(setOf(defaultImplType.internalName))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,4 +179,8 @@ class InterfaceImplBodyCodegen(
|
||||
return super.newMethod(origin, access, name, desc, signature, exceptions)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateSyntheticPartsBeforeBody() {
|
||||
generatePropertyMetadataArrayFieldIfNeeded(defaultImplType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper;
|
||||
import org.jetbrains.kotlin.codegen.inline.NameGenerator;
|
||||
@@ -47,7 +48,6 @@ import org.jetbrains.kotlin.name.SpecialNames;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
@@ -69,7 +69,10 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember;
|
||||
@@ -131,10 +134,17 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public void generate() {
|
||||
generateDeclaration();
|
||||
|
||||
boolean shouldGenerateSyntheticParts =
|
||||
!(element instanceof KtClassOrObject) ||
|
||||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element);
|
||||
|
||||
if (shouldGenerateSyntheticParts) {
|
||||
generateSyntheticPartsBeforeBody();
|
||||
}
|
||||
|
||||
generateBody();
|
||||
|
||||
if (!(element instanceof KtClassOrObject) ||
|
||||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element)) {
|
||||
if (shouldGenerateSyntheticParts) {
|
||||
generateSyntheticParts();
|
||||
}
|
||||
|
||||
@@ -145,6 +155,9 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
done();
|
||||
}
|
||||
|
||||
protected void generateSyntheticPartsBeforeBody() {
|
||||
}
|
||||
|
||||
protected abstract void generateDeclaration();
|
||||
|
||||
protected abstract void generateBody();
|
||||
@@ -329,12 +342,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
parentCodegen.innerClasses.add(classDescriptor);
|
||||
}
|
||||
|
||||
for (MemberCodegen<?> codegen = this; codegen != null; codegen = codegen.getParentCodegen()) {
|
||||
ClassDescriptor outerClass = codegen.classForInnerClassRecord();
|
||||
if (outerClass != null) {
|
||||
innerClasses.add(outerClass);
|
||||
}
|
||||
}
|
||||
addParentsToInnerClassesIfNeeded(innerClasses);
|
||||
}
|
||||
|
||||
for (ClassDescriptor innerClass : innerClasses) {
|
||||
@@ -342,6 +350,18 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
}
|
||||
}
|
||||
|
||||
protected void addParentsToInnerClassesIfNeeded(@NotNull Collection<ClassDescriptor> innerClasses) {
|
||||
ClassDescriptor outerClass = classForInnerClassRecord();
|
||||
if (outerClass != null) {
|
||||
innerClasses.add(outerClass);
|
||||
}
|
||||
|
||||
MemberCodegen<?> parentCodegen = getParentCodegen();
|
||||
if (parentCodegen != null) {
|
||||
parentCodegen.addParentsToInnerClassesIfNeeded(innerClasses);
|
||||
}
|
||||
}
|
||||
|
||||
// It's necessary for proper recovering of classId by plain string JVM descriptor when loading annotations
|
||||
// See FileBasedKotlinClass.convertAnnotationVisitor
|
||||
@Override
|
||||
@@ -514,11 +534,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
|
||||
StackValue provideDelegateReceiver = codegen.gen(initializer);
|
||||
|
||||
int indexOfDelegatedProperty = PropertyCodegen.indexOfDelegatedProperty(property);
|
||||
|
||||
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethodWithReceiver(
|
||||
codegen, typeMapper, provideDelegateResolvedCall, indexOfDelegatedProperty, 1,
|
||||
provideDelegateReceiver, propertyDescriptor
|
||||
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethod(
|
||||
codegen, provideDelegateResolvedCall, provideDelegateReceiver, propertyDescriptor
|
||||
);
|
||||
|
||||
propValue.store(delegateValue, codegen.v);
|
||||
@@ -598,16 +615,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
}
|
||||
|
||||
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
|
||||
List<KtProperty> delegatedProperties = new ArrayList<>();
|
||||
for (KtDeclaration declaration : ((KtDeclarationContainer) element).getDeclarations()) {
|
||||
if (declaration instanceof KtProperty) {
|
||||
KtProperty property = (KtProperty) declaration;
|
||||
if (property.hasDelegate()) {
|
||||
delegatedProperties.add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (delegatedProperties.isEmpty()) return;
|
||||
List<VariableDescriptorWithAccessors> delegatedProperties = bindingContext.get(CodegenBinding.DELEGATED_PROPERTIES, thisAsmType);
|
||||
if (delegatedProperties == null || delegatedProperties.isEmpty()) return;
|
||||
|
||||
v.newField(NO_ORIGIN, ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME,
|
||||
"[" + K_PROPERTY_TYPE, null, null);
|
||||
@@ -619,8 +628,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
iv.newarray(K_PROPERTY_TYPE);
|
||||
|
||||
for (int i = 0, size = delegatedProperties.size(); i < size; i++) {
|
||||
PropertyDescriptor property =
|
||||
(PropertyDescriptor) BindingContextUtils.getNotNull(bindingContext, VARIABLE, delegatedProperties.get(i));
|
||||
VariableDescriptorWithAccessors property = delegatedProperties.get(i);
|
||||
|
||||
iv.dup();
|
||||
iv.iconst(i);
|
||||
@@ -630,10 +638,12 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
||||
iv.anew(implType);
|
||||
iv.dup();
|
||||
|
||||
// TODO: generate the container once and save to a local field instead (KT-10495)
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||
iv.aconst(property.getName().asString());
|
||||
PropertyReferenceCodegen.generateCallableReferenceSignature(iv, property, state);
|
||||
|
||||
iv.invokespecial(
|
||||
implType.getInternalName(), "<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
|
||||
|
||||
@@ -205,11 +205,8 @@ class MultifileClassCodegenImpl(
|
||||
val packageFragment = this.packageFragment
|
||||
?: throw AssertionError("File part $file of $facadeFqName: no package fragment")
|
||||
|
||||
val partClassFqName = file.getFileClassFqName()
|
||||
val partInitializerClassFqName = FqName(partClassFqName.asString() + "__Init")
|
||||
val partType = partClassFqName.toAsmType()
|
||||
val partInitializerType = partInitializerClassFqName.toAsmType()
|
||||
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, partInitializerType, file)
|
||||
val partType = file.getFileClassFqName().toAsmType()
|
||||
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, file)
|
||||
|
||||
generateNonPartClassDeclarations(file, partContext)
|
||||
|
||||
|
||||
@@ -175,8 +175,11 @@ class MultifileClassPartCodegen(
|
||||
}
|
||||
}
|
||||
|
||||
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(v.serializationBindings, state))
|
||||
val packageProto = serializer.packagePartProto(packageFragment.fqName, members).build()
|
||||
val extension = JvmSerializerExtension(v.serializationBindings, state)
|
||||
val serializer = DescriptorSerializer.createTopLevel(extension)
|
||||
val builder = serializer.packagePartProto(packageFragment.fqName, members)
|
||||
extension.serializeJvmPackage(builder, partType)
|
||||
val packageProto = builder.build()
|
||||
|
||||
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
||||
|
||||
|
||||
@@ -119,9 +119,11 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
|
||||
ProtoBuf.Package packageProto = serializer.packagePartProto(element.getPackageFqName(), members).build();
|
||||
JvmSerializerExtension extension = new JvmSerializerExtension(v.getSerializationBindings(), state);
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension);
|
||||
ProtoBuf.Package.Builder builder = serializer.packagePartProto(element.getPackageFqName(), members);
|
||||
extension.serializeJvmPackage(builder, packagePartType);
|
||||
ProtoBuf.Package packageProto = builder.build();
|
||||
|
||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
|
||||
writeAnnotationData(av, serializer, packageProto);
|
||||
|
||||
@@ -21,7 +21,10 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -32,7 +35,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtilKt;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
@@ -60,6 +62,8 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
@@ -478,7 +482,7 @@ public class PropertyCodegen {
|
||||
FunctionGenerationStrategy strategy;
|
||||
if (accessor == null || !accessor.hasBody()) {
|
||||
if (p instanceof KtProperty && ((KtProperty) p).hasDelegate()) {
|
||||
strategy = new DelegatedPropertyAccessorStrategy(state, accessorDescriptor, indexOfDelegatedProperty((KtProperty) p));
|
||||
strategy = new DelegatedPropertyAccessorStrategy(state, accessorDescriptor);
|
||||
}
|
||||
else {
|
||||
strategy = new DefaultPropertyAccessorStrategy(state, accessorDescriptor);
|
||||
@@ -491,39 +495,9 @@ public class PropertyCodegen {
|
||||
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(accessor != null ? accessor : p, accessorDescriptor), accessorDescriptor, strategy);
|
||||
}
|
||||
|
||||
public static int indexOfDelegatedProperty(@NotNull KtProperty property) {
|
||||
PsiElement parent = property.getParent();
|
||||
KtDeclarationContainer container;
|
||||
if (parent instanceof KtClassBody) {
|
||||
container = ((KtClassOrObject) parent.getParent());
|
||||
}
|
||||
else if (parent instanceof KtFile) {
|
||||
container = (KtFile) parent;
|
||||
}
|
||||
else if (KtPsiUtil.isScriptDeclaration(property)) {
|
||||
container = KtPsiUtil.getScript(property);
|
||||
assert container != null : "Script declaration for property '" + property.getText() + "' should be not null!";
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown delegated property container: " + parent);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (KtDeclaration declaration : container.getDeclarations()) {
|
||||
if (declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate()) {
|
||||
if (declaration == property) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Delegated property not found in its parent: " + PsiUtilsKt.getElementTextWithContext(property));
|
||||
}
|
||||
|
||||
|
||||
private static class DefaultPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
|
||||
private final PropertyAccessorDescriptor propertyAccessorDescriptor;
|
||||
|
||||
public DefaultPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||
super(state);
|
||||
propertyAccessorDescriptor = descriptor;
|
||||
@@ -561,75 +535,45 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public static StackValue invokeDelegatedPropertyConventionMethod(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
|
||||
int indexInPropertyMetadataArray,
|
||||
int propertyMetadataArgumentIndex
|
||||
) {
|
||||
StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
|
||||
return invokeDelegatedPropertyConventionMethodWithReceiver(
|
||||
codegen, typeMapper, resolvedCall, indexInPropertyMetadataArray, propertyMetadataArgumentIndex,
|
||||
receiver, propertyDescriptor
|
||||
);
|
||||
}
|
||||
|
||||
public static StackValue invokeDelegatedPropertyConventionMethodWithReceiver(
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
|
||||
int indexInPropertyMetadataArray,
|
||||
int propertyMetadataArgumentIndex,
|
||||
@Nullable StackValue receiver,
|
||||
@NotNull PropertyDescriptor propertyDescriptor
|
||||
) {
|
||||
Type owner = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ?
|
||||
codegen.getState().getTypeMapper().mapOwner(propertyDescriptor) :
|
||||
getDelegatedPropertyMetadataOwner(codegen, typeMapper);
|
||||
|
||||
codegen.tempVariables.put(
|
||||
resolvedCall.getCall().getValueArguments().get(propertyMetadataArgumentIndex).asElement(),
|
||||
new StackValue(K_PROPERTY_TYPE) {
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
Field array = StackValue.field(
|
||||
Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none()
|
||||
);
|
||||
StackValue.arrayElement(
|
||||
K_PROPERTY_TYPE, array, StackValue.constant(indexInPropertyMetadataArray, Type.INT_TYPE)
|
||||
).put(type, v);
|
||||
}
|
||||
}
|
||||
resolvedCall.getCall().getValueArguments().get(1).asElement(),
|
||||
getDelegatedPropertyMetadata(propertyDescriptor, codegen.getBindingContext())
|
||||
);
|
||||
|
||||
return codegen.invokeFunction(resolvedCall, receiver);
|
||||
}
|
||||
|
||||
private static Type getDelegatedPropertyMetadataOwner(@NotNull ExpressionCodegen codegen, @NotNull KotlinTypeMapper typeMapper) {
|
||||
CodegenContext<? extends ClassOrPackageFragmentDescriptor> ownerContext = codegen.getContext().getClassOrPackageParentContext();
|
||||
if (ownerContext instanceof ClassContext) {
|
||||
return typeMapper.mapClass(((ClassContext) ownerContext).getContextDescriptor());
|
||||
}
|
||||
else if (ownerContext instanceof PackageContext) {
|
||||
return ((PackageContext) ownerContext).getPackagePartType();
|
||||
}
|
||||
else if (ownerContext instanceof MultifileClassContextBase) {
|
||||
return ((MultifileClassContextBase) ownerContext).getFilePartType();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown context: " + ownerContext);
|
||||
@NotNull
|
||||
public static StackValue getDelegatedPropertyMetadata(
|
||||
@NotNull VariableDescriptorWithAccessors descriptor,
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
Type owner = bindingContext.get(DELEGATED_PROPERTY_METADATA_OWNER, descriptor);
|
||||
assert owner != null : "Delegated property owner not found: " + descriptor;
|
||||
|
||||
List<VariableDescriptorWithAccessors> allDelegatedProperties = bindingContext.get(DELEGATED_PROPERTIES, owner);
|
||||
int index = allDelegatedProperties == null ? -1 : allDelegatedProperties.indexOf(descriptor);
|
||||
if (index < 0) {
|
||||
throw new AssertionError("Delegated property not found in " + owner + ": " + descriptor);
|
||||
}
|
||||
|
||||
StackValue.Field array = StackValue.field(
|
||||
Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none()
|
||||
);
|
||||
return StackValue.arrayElement(K_PROPERTY_TYPE, array, StackValue.constant(index, Type.INT_TYPE));
|
||||
}
|
||||
|
||||
private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
|
||||
private final int index;
|
||||
private final PropertyAccessorDescriptor propertyAccessorDescriptor;
|
||||
|
||||
public DelegatedPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor, int index) {
|
||||
public DelegatedPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||
super(state);
|
||||
this.index = index;
|
||||
propertyAccessorDescriptor = descriptor;
|
||||
this.propertyAccessorDescriptor = descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -641,8 +585,9 @@ public class PropertyCodegen {
|
||||
bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, propertyAccessorDescriptor);
|
||||
assert resolvedCall != null : "Resolve call should be recorded for delegate call " + signature.toString();
|
||||
|
||||
StackValue lastValue = invokeDelegatedPropertyConventionMethod(propertyAccessorDescriptor.getCorrespondingProperty(),
|
||||
codegen, state.getTypeMapper(), resolvedCall, index, 1);
|
||||
PropertyDescriptor propertyDescriptor = propertyAccessorDescriptor.getCorrespondingProperty();
|
||||
StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
|
||||
StackValue lastValue = invokeDelegatedPropertyConventionMethod(codegen, resolvedCall, receiver, propertyDescriptor);
|
||||
Type asmType = signature.getReturnType();
|
||||
lastValue.put(asmType, v);
|
||||
v.areturn(asmType);
|
||||
|
||||
@@ -116,10 +116,11 @@ class PropertyReferenceCodegen(
|
||||
generateCallableReferenceSignature(this, target, state)
|
||||
}
|
||||
|
||||
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, state)
|
||||
}
|
||||
|
||||
if (!isLocalDelegatedProperty) {
|
||||
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, state)
|
||||
}
|
||||
generateAccessors()
|
||||
}
|
||||
}
|
||||
@@ -194,6 +195,17 @@ class PropertyReferenceCodegen(
|
||||
|
||||
@JvmStatic
|
||||
fun generateCallableReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) {
|
||||
if (callable is LocalVariableDescriptor) {
|
||||
val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable)
|
||||
val allDelegatedProperties = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTIES, asmType)
|
||||
val index = allDelegatedProperties?.indexOf(callable) ?: -1
|
||||
if (index < 0) {
|
||||
throw AssertionError("Local delegated property is not found in $asmType: $callable")
|
||||
}
|
||||
iv.aconst("<v#$index>") // v = "variable"
|
||||
return
|
||||
}
|
||||
|
||||
val accessor = when (callable) {
|
||||
is FunctionDescriptor -> callable
|
||||
is VariableDescriptorWithAccessors ->
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SamType {
|
||||
@NotNull
|
||||
public KotlinType getKotlinFunctionType() {
|
||||
//noinspection ConstantConditions
|
||||
return getJavaClassDescriptor().getFunctionTypeForSamInterface();
|
||||
return getJavaClassDescriptor().getDefaultFunctionTypeForSamInterface();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -38,8 +38,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClasses;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -370,26 +372,13 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
@NotNull
|
||||
private MutableClosure recordClosure(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
|
||||
return CodegenBinding.recordClosure(
|
||||
bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name), fileClassesProvider
|
||||
);
|
||||
return CodegenBinding.recordClosure(bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name));
|
||||
}
|
||||
|
||||
private void recordLocalVariablePropertyMetadata(LocalVariableDescriptor variableDescriptor) {
|
||||
KotlinType delegateType = JvmCodegenUtil.getPropertyDelegateType(variableDescriptor, bindingContext);
|
||||
if (delegateType == null) return;
|
||||
|
||||
LocalVariableDescriptor delegateVariableDescriptor = new LocalVariableDescriptor(
|
||||
variableDescriptor.getContainingDeclaration(),
|
||||
Annotations.Companion.getEMPTY(),
|
||||
variableDescriptor.getName(),
|
||||
delegateType,
|
||||
false,
|
||||
false,
|
||||
SourceElement.NO_SOURCE
|
||||
);
|
||||
bindingTrace.record(LOCAL_VARIABLE_DELEGATE, variableDescriptor, delegateVariableDescriptor);
|
||||
|
||||
LocalVariableDescriptor metadataVariableDescriptor = new LocalVariableDescriptor(
|
||||
variableDescriptor.getContainingDeclaration(),
|
||||
Annotations.Companion.getEMPTY(),
|
||||
@@ -428,12 +417,44 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
runtimeTypes.getSupertypeForPropertyReference(variableDescriptor, variableDescriptor.isVar(), /* bound = */ false);
|
||||
ClassDescriptor classDescriptor = recordClassForCallable(delegate, variableDescriptor, Collections.singleton(supertype), name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
Type containerType = getMetadataOwner(property);
|
||||
List<VariableDescriptorWithAccessors> descriptors = bindingTrace.get(DELEGATED_PROPERTIES, containerType);
|
||||
if (descriptors == null) {
|
||||
descriptors = new ArrayList<>(1);
|
||||
bindingTrace.record(DELEGATED_PROPERTIES, containerType, descriptors);
|
||||
}
|
||||
descriptors.add(variableDescriptor);
|
||||
|
||||
bindingTrace.record(DELEGATED_PROPERTY_METADATA_OWNER, variableDescriptor, containerType);
|
||||
}
|
||||
|
||||
super.visitProperty(property);
|
||||
nameStack.pop();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Type getMetadataOwner(@NotNull KtProperty property) {
|
||||
for (int i = classStack.size() - 1; i >= 0; i--) {
|
||||
ClassDescriptor descriptor = classStack.get(i);
|
||||
// The first "real" containing class (not a synthetic class for lambda) is the owner of the delegated property metadata
|
||||
if (!(descriptor instanceof SyntheticClassDescriptorForLambda)) {
|
||||
ClassId classId = DescriptorUtilsKt.getClassId(descriptor);
|
||||
if (classId == null) {
|
||||
return CodegenBinding.getAsmType(bindingContext, descriptor);
|
||||
}
|
||||
|
||||
return AsmUtil.asmTypeByClassId(
|
||||
DescriptorUtils.isInterface(descriptor)
|
||||
? classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME))
|
||||
: classId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Type.getObjectType(FileClasses.getFileClassInternalName(fileClassesProvider, property.getContainingKtFile()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNamedFunction(@NotNull KtNamedFunction function) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.codegen.SamType;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
@@ -49,7 +48,7 @@ public class CodegenBinding {
|
||||
|
||||
public static final WritableSlice<ClassDescriptor, Boolean> ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice();
|
||||
|
||||
public static final WritableSlice<ClassDescriptor, Collection<ClassDescriptor>> INNER_CLASSES = Slices.createSimpleSlice();
|
||||
private static final WritableSlice<ClassDescriptor, Collection<ClassDescriptor>> INNER_CLASSES = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<KtExpression, SamType> SAM_VALUE = Slices.createSimpleSlice();
|
||||
|
||||
@@ -60,18 +59,19 @@ public class CodegenBinding {
|
||||
public static final WritableSlice<String, List<WhenByEnumsMapping>> MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE =
|
||||
Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_DELEGATE =
|
||||
Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_PROPERTY_METADATA =
|
||||
Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<FunctionDescriptor, FunctionDescriptor> SUSPEND_FUNCTION_TO_JVM_VIEW =
|
||||
Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<ValueParameterDescriptor, ValueParameterDescriptor> PARAMETER_SYNONYM =
|
||||
Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<Type, List<VariableDescriptorWithAccessors>> DELEGATED_PROPERTIES =
|
||||
Slices.createSimpleSlice();
|
||||
public static final WritableSlice<VariableDescriptorWithAccessors, Type> DELEGATED_PROPERTY_METADATA_OWNER =
|
||||
Slices.createSimpleSlice();
|
||||
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_PROPERTY_METADATA =
|
||||
Slices.createSimpleSlice();
|
||||
|
||||
static {
|
||||
BasicWritableSlice.initSliceDebugNames(CodegenBinding.class);
|
||||
}
|
||||
@@ -150,8 +150,7 @@ public class CodegenBinding {
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@Nullable ClassDescriptor enclosing,
|
||||
@NotNull Type asmType,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
@NotNull Type asmType
|
||||
) {
|
||||
KtElement element = (KtElement) DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor);
|
||||
assert element != null : "No source element for " + classDescriptor;
|
||||
@@ -227,32 +226,6 @@ public class CodegenBinding {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<ClassDescriptor> getAllInnerClasses(
|
||||
@NotNull BindingContext bindingContext, @NotNull ClassDescriptor outermostClass
|
||||
) {
|
||||
Collection<ClassDescriptor> innerClasses = bindingContext.get(INNER_CLASSES, outermostClass);
|
||||
if (innerClasses == null || innerClasses.isEmpty()) return Collections.emptySet();
|
||||
|
||||
Set<ClassDescriptor> allInnerClasses = new HashSet<>();
|
||||
|
||||
Deque<ClassDescriptor> stack = new ArrayDeque<>(innerClasses);
|
||||
do {
|
||||
ClassDescriptor currentClass = stack.pop();
|
||||
if (allInnerClasses.add(currentClass)) {
|
||||
Collection<ClassDescriptor> nextClasses = bindingContext.get(INNER_CLASSES, currentClass);
|
||||
if (nextClasses != null) {
|
||||
for (ClassDescriptor nextClass : nextClasses) {
|
||||
stack.push(nextClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!stack.isEmpty());
|
||||
|
||||
return allInnerClasses;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static VariableDescriptor getDelegatedLocalVariableMetadata(
|
||||
@NotNull VariableDescriptor variableDescriptor,
|
||||
|
||||
@@ -248,10 +248,9 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
@NotNull PackageFragmentDescriptor descriptor,
|
||||
@NotNull Type multifileClassType,
|
||||
@NotNull Type filePartType,
|
||||
@NotNull Type filePartInitializerType,
|
||||
@NotNull KtFile sourceFile
|
||||
) {
|
||||
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType, filePartInitializerType, sourceFile);
|
||||
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType, sourceFile);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -55,9 +55,12 @@ public interface LocalLookup {
|
||||
boolean idx = localLookup != null && localLookup.lookupLocal(vd);
|
||||
if (!idx) return null;
|
||||
|
||||
VariableDescriptor delegateVariableDescriptor = state.getBindingContext().get(LOCAL_VARIABLE_DELEGATE, vd);
|
||||
KotlinType delegateType =
|
||||
vd instanceof VariableDescriptorWithAccessors
|
||||
? JvmCodegenUtil.getPropertyDelegateType((VariableDescriptorWithAccessors) vd, state.getBindingContext())
|
||||
: null;
|
||||
Type sharedVarType = state.getTypeMapper().getSharedVarType(vd);
|
||||
Type localType = state.getTypeMapper().mapType(delegateVariableDescriptor != null ? delegateVariableDescriptor : vd);
|
||||
Type localType = state.getTypeMapper().mapType(delegateType != null ? delegateType : vd.getType());
|
||||
Type type = sharedVarType != null ? sharedVarType : localType;
|
||||
|
||||
String fieldName = "$" + vd.getName();
|
||||
|
||||
@@ -24,19 +24,16 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class MultifileClassPartContext extends MultifileClassContextBase implements DelegatingToPartContext, FacadePartWithSourceFile {
|
||||
private final KtFile sourceFile;
|
||||
private final Type partInitializerType;
|
||||
|
||||
public MultifileClassPartContext(
|
||||
PackageFragmentDescriptor descriptor,
|
||||
CodegenContext parent,
|
||||
Type multifileClassType,
|
||||
Type filePartType,
|
||||
Type partInitializerType,
|
||||
@NotNull KtFile sourceFile
|
||||
) {
|
||||
super(descriptor, parent, multifileClassType, filePartType);
|
||||
this.sourceFile = sourceFile;
|
||||
this.partInitializerType = partInitializerType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -45,11 +42,6 @@ public class MultifileClassPartContext extends MultifileClassContextBase impleme
|
||||
return getFilePartType();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getPartInitializerType() {
|
||||
return partInitializerType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KtFile getSourceFile() {
|
||||
|
||||
@@ -43,11 +43,6 @@ public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor>
|
||||
return "Package: " + getContextDescriptor().getName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Type getPackagePartType() {
|
||||
return packagePartType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Type getImplementationOwnerClassType() {
|
||||
|
||||
@@ -479,7 +479,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
override fun generateKotlinMetadataAnnotation() {
|
||||
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { av ->
|
||||
val serializer = DescriptorSerializer.createForLambda(JvmSerializerExtension(v.serializationBindings, state))
|
||||
val functionProto = serializer.functionProto(createFreeLambdaDescriptor(suspendFunctionJvmView)).build()
|
||||
val functionProto = serializer.functionProto(createFreeFakeLambdaDescriptor(suspendFunctionJvmView)).build()
|
||||
AsmUtil.writeAnnotationData(av, serializer, functionProto)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
|
||||
|
||||
private val continuationIndex = if (isForNamedFunction) getLastParameterIndex(desc, access) else 0
|
||||
private var continuationIndex = if (isForNamedFunction) -1 else 0
|
||||
private var dataIndex = if (isForNamedFunction) -1 else 1
|
||||
private var exceptionIndex = if (isForNamedFunction) -1 else 2
|
||||
|
||||
@@ -83,6 +83,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
dataIndex = methodNode.maxLocals++
|
||||
exceptionIndex = methodNode.maxLocals++
|
||||
continuationIndex = methodNode.maxLocals++
|
||||
|
||||
prepareMethodNodePreludeForNamedFunction(methodNode)
|
||||
}
|
||||
@@ -195,6 +196,13 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
private fun prepareMethodNodePreludeForNamedFunction(methodNode: MethodNode) {
|
||||
val objectTypeForState = Type.getObjectType(classBuilderForCoroutineState.thisName)
|
||||
val continuationArgumentIndex = getLastParameterIndex(methodNode.desc, methodNode.access)
|
||||
methodNode.instructions.asSequence().filterIsInstance<VarInsnNode>().forEach {
|
||||
if (it.`var` != continuationArgumentIndex) return@forEach
|
||||
assert(it.opcode == Opcodes.ALOAD) { "Only ALOADs are allowed for continuation arguments" }
|
||||
it.`var` = continuationIndex
|
||||
}
|
||||
|
||||
methodNode.instructions.insert(withInstructionAdapter {
|
||||
val createStateInstance = Label()
|
||||
val afterCoroutineStateCreated = Label()
|
||||
@@ -213,11 +221,12 @@ class CoroutineTransformerMethodVisitor(
|
||||
// - Otherwise it's still can be a recursive call. To check it's not the case we set the last bit in the label in
|
||||
// `doResume` just before calling the suspend function (see kotlin.coroutines.experimental.jvm.internal.CoroutineImplForNamedFunction).
|
||||
// So, if it's set we're in continuation.
|
||||
visitVarInsn(Opcodes.ALOAD, continuationIndex)
|
||||
|
||||
visitVarInsn(Opcodes.ALOAD, continuationArgumentIndex)
|
||||
instanceOf(objectTypeForState)
|
||||
ifeq(createStateInstance)
|
||||
|
||||
visitVarInsn(Opcodes.ALOAD, continuationIndex)
|
||||
visitVarInsn(Opcodes.ALOAD, continuationArgumentIndex)
|
||||
checkcast(objectTypeForState)
|
||||
visitVarInsn(Opcodes.ASTORE, continuationIndex)
|
||||
|
||||
@@ -757,4 +766,4 @@ private fun AbstractInsnNode?.isInvisibleInDebugVarInsn(methodNode: MethodNode):
|
||||
}
|
||||
|
||||
private val SAFE_OPCODES =
|
||||
((Opcodes.DUP..Opcodes.DUP2_X2) + Opcodes.POP + Opcodes.POP2 + (Opcodes.IFEQ..Opcodes.GOTO)).toSet()
|
||||
((Opcodes.DUP..Opcodes.DUP2_X2) + Opcodes.NOP + Opcodes.POP + Opcodes.POP2 + (Opcodes.IFEQ..Opcodes.GOTO)).toSet()
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
|
||||
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
|
||||
*/
|
||||
fun createFreeFakeLambdaDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
return createFreeDescriptor(descriptor)
|
||||
}
|
||||
|
||||
private fun <D : CallableMemberDescriptor> createFreeDescriptor(descriptor: D): D {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val builder = descriptor.newCopyBuilder() as CallableMemberDescriptor.CopyBuilder<D>
|
||||
|
||||
val typeParameters = ArrayList<TypeParameterDescriptor>(0)
|
||||
builder.setTypeParameters(typeParameters)
|
||||
|
||||
var container: DeclarationDescriptor? = descriptor.containingDeclaration
|
||||
while (container != null) {
|
||||
if (container is ClassDescriptor) {
|
||||
typeParameters.addAll(container.declaredTypeParameters)
|
||||
}
|
||||
else if (container is CallableDescriptor && container !is ConstructorDescriptor) {
|
||||
typeParameters.addAll(container.typeParameters)
|
||||
}
|
||||
container = container.containingDeclaration
|
||||
}
|
||||
|
||||
return if (typeParameters.isEmpty()) descriptor else builder.build()!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a local delegated variable descriptor, creates a descriptor of a property that should be observed
|
||||
* when using reflection on that local variable at runtime.
|
||||
* Only members used by [DescriptorSerializer.propertyProto] are implemented correctly in this property descriptor.
|
||||
*/
|
||||
fun createFreeFakeLocalPropertyDescriptor(descriptor: LocalVariableDescriptor): PropertyDescriptor {
|
||||
val property = PropertyDescriptorImpl.create(
|
||||
descriptor.containingDeclaration, descriptor.annotations, Modality.FINAL, descriptor.visibility, descriptor.isVar,
|
||||
descriptor.name, CallableMemberDescriptor.Kind.DECLARATION, descriptor.source, false, descriptor.isConst,
|
||||
false, false, false, @Suppress("DEPRECATION") descriptor.isDelegated
|
||||
)
|
||||
property.setType(descriptor.type, descriptor.typeParameters, descriptor.dispatchReceiverParameter, descriptor.extensionReceiverParameter)
|
||||
|
||||
property.initialize(
|
||||
descriptor.getter?.run {
|
||||
PropertyGetterDescriptorImpl(property, annotations, modality, visibility, true, isExternal, isInline, kind, null, source).apply {
|
||||
initialize(this@run.returnType)
|
||||
}
|
||||
},
|
||||
descriptor.setter?.run {
|
||||
PropertySetterDescriptorImpl(property, annotations, modality, visibility, true, isExternal, isInline, kind, null, source).apply {
|
||||
initialize(this@run.valueParameters.single())
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return createFreeDescriptor(property)
|
||||
}
|
||||
@@ -460,7 +460,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
if (isBuiltInArrayIntrinsic(callableDescriptor)) {
|
||||
val classId = classId
|
||||
val bytes = state.inlineCache.classBytes.getOrPut(classId) { bytecode }
|
||||
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString())
|
||||
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(classId))
|
||||
}
|
||||
|
||||
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
|
||||
@@ -474,9 +474,16 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
throw IllegalStateException("Couldn't find declaration file for " + containerId)
|
||||
}
|
||||
|
||||
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString())
|
||||
}
|
||||
val methodNode = getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, AsmUtil.asmTypeByClassId(containerId)) ?: return null
|
||||
|
||||
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
|
||||
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
|
||||
if (isLegacySuspendInlineFunction(callableDescriptor)) {
|
||||
insertLegacySuspendInlineMarks(methodNode.node)
|
||||
}
|
||||
|
||||
return methodNode
|
||||
}
|
||||
|
||||
private fun isBuiltInArrayIntrinsic(callableDescriptor: CallableMemberDescriptor): Boolean {
|
||||
if (callableDescriptor is FictitiousArrayConstructor) return true
|
||||
@@ -523,7 +530,7 @@ abstract class InlineCodegen<out T: BaseExpressionCodegen>(
|
||||
val varDescriptor = field.descriptor
|
||||
//check that variable is inline function parameter
|
||||
return !(varDescriptor is ParameterDescriptor &&
|
||||
InlineUtil.isInlineLambdaParameter(varDescriptor) &&
|
||||
InlineUtil.isInlineParameter(varDescriptor) &&
|
||||
InlineUtil.isInline(varDescriptor.containingDeclaration))
|
||||
}
|
||||
|
||||
@@ -638,7 +645,7 @@ class PsiInlineCodegen(
|
||||
//TODO deparenthisise typed
|
||||
val deparenthesized = KtPsiUtil.deparenthesize(expression)
|
||||
|
||||
return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized)
|
||||
return InlineUtil.isInlineParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized)
|
||||
}
|
||||
|
||||
override fun genValueAndPut(
|
||||
|
||||
@@ -135,7 +135,7 @@ class DefaultLambda(
|
||||
classReader.b,
|
||||
"<init>",
|
||||
descriptor,
|
||||
lambdaClassType.internalName)?.node
|
||||
lambdaClassType)?.node
|
||||
|
||||
assert(constructor != null || capturedArgs.isEmpty()) {
|
||||
"Can't find non-default constructor <init>$descriptor for default lambda $lambdaClassType"
|
||||
@@ -164,7 +164,7 @@ class DefaultLambda(
|
||||
classReader.b,
|
||||
invokeMethod.name,
|
||||
invokeMethod.descriptor,
|
||||
lambdaClassType.internalName)!!
|
||||
lambdaClassType)!!
|
||||
|
||||
if (needReification) {
|
||||
//nested classes could also require reification
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import jdk.internal.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.getContainingKotlinJvmBinaryClass
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
|
||||
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
|
||||
|
||||
fun insertLegacySuspendInlineMarks(node: MethodNode) {
|
||||
with (node.instructions) {
|
||||
// look for return instruction before the end and insert "afterSuspendMarker" there
|
||||
insertBefore(findLastReturn(last) ?: return, produceSuspendMarker(false).instructions)
|
||||
// insert "beforeSuspendMarker" at the beginning
|
||||
insertBefore(first, produceSuspendMarker(true).instructions)
|
||||
}
|
||||
node.maxStack = node.maxStack.coerceAtLeast(2) // min stack need for suspend marker before return
|
||||
}
|
||||
|
||||
fun findLastReturn(node: AbstractInsnNode?): AbstractInsnNode? {
|
||||
var cur = node
|
||||
while (cur != null && cur.opcode != Opcodes.ARETURN) cur = cur.previous
|
||||
return cur
|
||||
}
|
||||
|
||||
private fun produceSuspendMarker(isStartNotEnd: Boolean): MethodNode =
|
||||
MethodNode().also { addSuspendMarker(InstructionAdapter(it), isStartNotEnd) }
|
||||
|
||||
fun isLegacySuspendInlineFunction(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (descriptor !is FunctionDescriptor) return false
|
||||
if (!descriptor.isSuspend || !descriptor.isInline) return false
|
||||
val jvmBytecodeVersion = descriptor.getContainingKotlinJvmBinaryClass()?.classHeader?.bytecodeVersion ?: return false
|
||||
return !jvmBytecodeVersion.isAtLeast(1, 0, 2)
|
||||
}
|
||||
@@ -846,9 +846,13 @@ class MethodInliner(
|
||||
}
|
||||
|
||||
if (isLocalReturn && endLabel != null) {
|
||||
val nop = InsnNode(Opcodes.NOP)
|
||||
instructions.insert(insnNode, nop)
|
||||
|
||||
val labelNode = endLabel.info as LabelNode
|
||||
val jumpInsnNode = JumpInsnNode(Opcodes.GOTO, labelNode)
|
||||
instructions.insert(insnNode, jumpInsnNode)
|
||||
instructions.insert(nop, jumpInsnNode)
|
||||
|
||||
instructions.remove(insnNode)
|
||||
insnNode = jumpInsnNode
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
@@ -94,6 +95,8 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
|
||||
private var context by Delegates.notNull<CodegenContext<*>>()
|
||||
|
||||
private var additionalInnerClasses = mutableListOf<ClassDescriptor>()
|
||||
|
||||
override val lookupLocation = KotlinLookupLocation(callElement)
|
||||
|
||||
|
||||
@@ -164,7 +167,9 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
if (isLambda)
|
||||
codegen.parentCodegen.className
|
||||
else
|
||||
state.typeMapper.mapImplementationOwner(descriptor).internalName
|
||||
state.typeMapper.mapImplementationOwner(descriptor).internalName,
|
||||
if (isLambda) emptyList() else additionalInnerClasses,
|
||||
isLambda
|
||||
)
|
||||
|
||||
val strategy = when (expression) {
|
||||
@@ -223,7 +228,9 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
internal val delegate: MemberCodegen<*>,
|
||||
declaration: KtElement,
|
||||
codegenContext: FieldOwnerContext<*>,
|
||||
private val className: String
|
||||
private val className: String,
|
||||
private val parentAsInnerClasses: List<ClassDescriptor>,
|
||||
private val isInlineLambdaCodegen: Boolean
|
||||
) : MemberCodegen<KtPureElement>(delegate as MemberCodegen<KtPureElement>, declaration, codegenContext) {
|
||||
|
||||
override fun generateDeclaration() {
|
||||
@@ -247,6 +254,14 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
return className
|
||||
}
|
||||
|
||||
override fun addParentsToInnerClassesIfNeeded(innerClasses: MutableCollection<ClassDescriptor>) {
|
||||
if (isInlineLambdaCodegen) {
|
||||
super.addParentsToInnerClassesIfNeeded(innerClasses)
|
||||
}
|
||||
else {
|
||||
innerClasses.addAll(parentAsInnerClasses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun doCreateMethodNodeFromSource(
|
||||
@@ -279,7 +294,9 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
val implementationOwner = state.typeMapper.mapImplementationOwner(callableDescriptor)
|
||||
val parentCodegen = FakeMemberCodegen(
|
||||
codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>,
|
||||
implementationOwner.internalName
|
||||
implementationOwner.internalName,
|
||||
additionalInnerClasses,
|
||||
false
|
||||
)
|
||||
if (element !is KtNamedFunction) {
|
||||
throw IllegalStateException("Property accessors with default parameters not supported " + callableDescriptor)
|
||||
@@ -390,22 +407,25 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
}
|
||||
|
||||
override fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
|
||||
context = getContext(functionDescriptor, state, DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile)
|
||||
context = getContext(functionDescriptor, functionDescriptor, state, DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile, additionalInnerClasses)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getContext(
|
||||
descriptor: DeclarationDescriptor, state: GenerationState, sourceFile: KtFile?
|
||||
descriptor: DeclarationDescriptor, innerDescriptor: DeclarationDescriptor, state: GenerationState, sourceFile: KtFile?, additionalInners: MutableList<ClassDescriptor>
|
||||
): CodegenContext<*> {
|
||||
if (descriptor is PackageFragmentDescriptor) {
|
||||
//no inners
|
||||
return PackageContext(descriptor, state.rootContext, null, sourceFile)
|
||||
}
|
||||
|
||||
val container = descriptor.containingDeclaration ?: error("No container for descriptor: " + descriptor)
|
||||
val parent = getContext(
|
||||
container,
|
||||
descriptor,
|
||||
state,
|
||||
sourceFile
|
||||
sourceFile,
|
||||
additionalInners
|
||||
)
|
||||
|
||||
return when (descriptor) {
|
||||
@@ -418,7 +438,14 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
)
|
||||
}
|
||||
is ClassDescriptor -> {
|
||||
val kind = if (DescriptorUtils.isInterface(descriptor)) OwnerKind.DEFAULT_IMPLS else OwnerKind.IMPLEMENTATION
|
||||
val kind =
|
||||
if (DescriptorUtils.isInterface(descriptor) && innerDescriptor !is ClassDescriptor)
|
||||
OwnerKind.DEFAULT_IMPLS
|
||||
else OwnerKind.IMPLEMENTATION
|
||||
|
||||
additionalInners.addIfNotNull(
|
||||
InnerClassConsumer.classForInnerClassRecord(descriptor, kind == OwnerKind.DEFAULT_IMPLS)
|
||||
)
|
||||
parent.intoClass(descriptor, kind, state)
|
||||
}
|
||||
is FunctionDescriptor -> {
|
||||
|
||||
@@ -51,7 +51,7 @@ fun extractDefaultLambdaOffsetAndDescriptor(jvmSignature: JvmMethodSignature, fu
|
||||
val valueParameterOffset = valueParameters.takeWhile { it.kind != JvmMethodParameterKind.VALUE }.size
|
||||
|
||||
return functionDescriptor.valueParameters.filter {
|
||||
InlineUtil.isInlineLambdaParameter(it) && it.declaresDefaultValue()
|
||||
InlineUtil.isInlineParameter(it) && it.declaresDefaultValue()
|
||||
}.associateBy {
|
||||
parameterOffsets[valueParameterOffset + it.index]
|
||||
}
|
||||
|
||||
@@ -89,12 +89,13 @@ private const val INLINE_MARKER_FINALLY_START = "finallyStart"
|
||||
private const val INLINE_MARKER_FINALLY_END = "finallyEnd"
|
||||
private const val INLINE_MARKER_BEFORE_SUSPEND_ID = 0
|
||||
private const val INLINE_MARKER_AFTER_SUSPEND_ID = 1
|
||||
private val INTRINSIC_ARRAY_CONSTRUCTOR_TYPE = AsmUtil.asmTypeByClassId(classId)
|
||||
|
||||
internal fun getMethodNode(
|
||||
classData: ByteArray,
|
||||
methodName: String,
|
||||
methodDescriptor: String,
|
||||
classInternalName: String
|
||||
classType: Type
|
||||
): SMAPAndMethodNode? {
|
||||
val cr = ClassReader(classData)
|
||||
var node: MethodNode? = null
|
||||
@@ -136,12 +137,12 @@ internal fun getMethodNode(
|
||||
return null
|
||||
}
|
||||
|
||||
if (classId.asString() == classInternalName) {
|
||||
if (INTRINSIC_ARRAY_CONSTRUCTOR_TYPE == classType) {
|
||||
// Don't load source map for intrinsic array constructors
|
||||
debugInfo[0] = null
|
||||
}
|
||||
|
||||
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classInternalName, lines[0], lines[1])
|
||||
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classType.internalName, lines[0], lines[1])
|
||||
return SMAPAndMethodNode(node!!, smap)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
|
||||
|
||||
other as StrictBasicValue
|
||||
|
||||
if (this === NULL_VALUE) return other === NULL_VALUE
|
||||
if (other === NULL_VALUE) return this === NULL_VALUE
|
||||
|
||||
if (type != other.type) return false
|
||||
|
||||
return true
|
||||
|
||||
@@ -44,13 +44,14 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
private var changes = false
|
||||
|
||||
fun run(): Boolean {
|
||||
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode()
|
||||
eliminateRedundantChecks(checkedReferenceTypes)
|
||||
val stackOnThrowExceptions = hashMapOf<AbstractInsnNode, Int>()
|
||||
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode(stackOnThrowExceptions)
|
||||
eliminateRedundantChecks(checkedReferenceTypes, stackOnThrowExceptions)
|
||||
|
||||
return changes
|
||||
}
|
||||
|
||||
private fun analyzeTypesAndRemoveDeadCode(): Map<AbstractInsnNode, Type> {
|
||||
private fun analyzeTypesAndRemoveDeadCode(stackOnThrowExceptionsHolder: MutableMap<AbstractInsnNode, Int>): Map<AbstractInsnNode, Type> {
|
||||
val insns = methodNode.instructions.toArray()
|
||||
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
|
||||
|
||||
@@ -64,6 +65,9 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
else if (insn.isCheckParameterIsNotNull() || insn.isCheckExpressionValueIsNotNull()) {
|
||||
checkedReferenceTypes[insn] = frame?.peek(1)?.type ?: continue
|
||||
}
|
||||
else if (insn.isThrowNpeIntrinsic()) {
|
||||
stackOnThrowExceptionsHolder[insn] = frame?.maxStackSize ?: continue
|
||||
}
|
||||
}
|
||||
|
||||
val dceResult = DeadCodeEliminationMethodTransformer().removeDeadCodeByFrames(methodNode, frames)
|
||||
@@ -74,8 +78,11 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
return checkedReferenceTypes
|
||||
}
|
||||
|
||||
private fun eliminateRedundantChecks(checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
|
||||
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes)
|
||||
private fun eliminateRedundantChecks(
|
||||
checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||
stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||
) {
|
||||
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes, stackOnThrowExceptions)
|
||||
|
||||
val nullabilityMap = analyzeNullabilities()
|
||||
|
||||
@@ -84,8 +91,10 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
transformTrivialChecks(nullabilityMap)
|
||||
}
|
||||
|
||||
private fun injectNullabilityAssumptions(checkedReferenceTypes: Map<AbstractInsnNode, Type>) =
|
||||
NullabilityAssumptionsBuilder(checkedReferenceTypes).injectNullabilityAssumptions()
|
||||
private fun injectNullabilityAssumptions(
|
||||
checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||
stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||
) = NullabilityAssumptionsBuilder(checkedReferenceTypes, stackOnThrowExceptions).injectNullabilityAssumptions()
|
||||
|
||||
private fun analyzeNullabilities(): Map<AbstractInsnNode, StrictBasicValue> {
|
||||
val frames = analyze(internalClassName, methodNode, NullabilityInterpreter())
|
||||
@@ -168,7 +177,10 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
}
|
||||
}
|
||||
|
||||
private inner class NullabilityAssumptionsBuilder(val checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
|
||||
private inner class NullabilityAssumptionsBuilder(
|
||||
val checkedReferenceTypes: Map<AbstractInsnNode, Type>,
|
||||
val stackOnThrowExceptions: MutableMap<AbstractInsnNode, Int>
|
||||
) {
|
||||
|
||||
private val checksDependingOnVariable = HashMap<Int, MutableList<AbstractInsnNode>>()
|
||||
|
||||
@@ -362,6 +374,8 @@ class RedundantNullCheckMethodTransformer : MethodTransformer() {
|
||||
athrow()
|
||||
})
|
||||
}
|
||||
|
||||
methodNode.maxStack = Math.max(methodNode.maxStack, (stackOnThrowExceptions[insn] ?: -1) + 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.util.slicedMap.*;
|
||||
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
|
||||
import org.jetbrains.kotlin.util.slicedMap.MutableSlicedMap;
|
||||
import org.jetbrains.kotlin.util.slicedMap.SlicedMapImpl;
|
||||
import org.jetbrains.kotlin.util.slicedMap.Slices;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
@@ -44,17 +47,6 @@ public final class JvmSerializationBindings {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SerializationMappingSetSlice<K> extends SetSlice<K> {
|
||||
public SerializationMappingSetSlice() {
|
||||
super(Slices.ONLY_REWRITE_TO_EQUAL, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <K> SerializationMappingSetSlice<K> create() {
|
||||
return new SerializationMappingSetSlice<>();
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
BasicWritableSlice.initSliceDebugNames(JvmSerializationBindings.class);
|
||||
}
|
||||
@@ -65,16 +57,8 @@ public final class JvmSerializationBindings {
|
||||
map.put(slice, key, value);
|
||||
}
|
||||
|
||||
public <K> void put(@NotNull SerializationMappingSetSlice<K> slice, @NotNull K key) {
|
||||
map.put(slice, key, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <K, V> V get(@NotNull SerializationMappingSlice<K, V> slice, @NotNull K key) {
|
||||
return map.get(slice, key);
|
||||
}
|
||||
|
||||
public <K> boolean get(@NotNull SerializationMappingSetSlice<K> slice, @NotNull K key) {
|
||||
return Boolean.TRUE.equals(map.get(slice, key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,19 +20,23 @@ import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode;
|
||||
import org.jetbrains.kotlin.codegen.FakeDescriptorsForReferencesKt;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl;
|
||||
import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeDeserializer;
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.serialization.AnnotationSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.serialization.SerializerExtension;
|
||||
import org.jetbrains.kotlin.serialization.StringTable;
|
||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.serialization.*;
|
||||
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
||||
import org.jetbrains.kotlin.types.FlexibleType;
|
||||
@@ -40,10 +44,14 @@ import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
|
||||
public class JvmSerializerExtension extends SerializerExtension {
|
||||
private final JvmSerializationBindings bindings;
|
||||
private final BindingContext codegenBinding;
|
||||
private final KotlinTypeMapper typeMapper;
|
||||
private final StringTable stringTable;
|
||||
private final AnnotationSerializer annotationSerializer;
|
||||
private final boolean useTypeTable;
|
||||
@@ -52,7 +60,9 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
|
||||
public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull GenerationState state) {
|
||||
this.bindings = bindings;
|
||||
this.stringTable = new JvmStringTable(state.getTypeMapper());
|
||||
this.codegenBinding = state.getBindingContext();
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.stringTable = new JvmStringTable(typeMapper);
|
||||
this.annotationSerializer = new AnnotationSerializer(stringTable);
|
||||
this.useTypeTable = state.getUseTypeTableInSerializer();
|
||||
this.moduleName = state.getModuleName();
|
||||
@@ -75,6 +85,10 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
if (!moduleName.equals(JvmAbi.DEFAULT_MODULE_NAME)) {
|
||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
|
||||
}
|
||||
|
||||
Type containerAsmType =
|
||||
DescriptorUtils.isInterface(descriptor) ? typeMapper.mapDefaultImpls(descriptor) : typeMapper.mapClass(descriptor);
|
||||
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,6 +98,29 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
}
|
||||
}
|
||||
|
||||
public void serializeJvmPackage(@NotNull ProtoBuf.Package.Builder proto, @NotNull Type partAsmType) {
|
||||
writeLocalProperties(proto, partAsmType, JvmProtoBuf.packageLocalVariable);
|
||||
}
|
||||
|
||||
private <MessageType extends GeneratedMessageLite.ExtendableMessage<MessageType>,
|
||||
BuilderType extends GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>> void writeLocalProperties(
|
||||
@NotNull BuilderType proto,
|
||||
@NotNull Type classAsmType,
|
||||
@NotNull GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Property>> extension
|
||||
) {
|
||||
List<VariableDescriptorWithAccessors> localVariables = codegenBinding.get(CodegenBinding.DELEGATED_PROPERTIES, classAsmType);
|
||||
if (localVariables == null) return;
|
||||
|
||||
for (VariableDescriptorWithAccessors localVariable : localVariables) {
|
||||
if (localVariable instanceof LocalVariableDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
FakeDescriptorsForReferencesKt.createFreeFakeLocalPropertyDescriptor((LocalVariableDescriptor) localVariable);
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createForLambda(this);
|
||||
proto.addExtension(extension, serializer.propertyProto(propertyDescriptor).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeFlexibleType(
|
||||
@NotNull FlexibleType flexibleType,
|
||||
|
||||
@@ -99,20 +99,6 @@ public class KotlinTypeMapper {
|
||||
private final boolean isJvm8TargetWithDefaults;
|
||||
|
||||
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
|
||||
private final Function2<String, String, String> defaultClassNameFactory
|
||||
= TypeMappingConfiguration.Companion.getDEFAULT_INNER_CLASS_NAME_FACTORY();
|
||||
|
||||
private final Function2<String, String, String> innerClassNameFactory = new Function2<String, String, String>() {
|
||||
@Override
|
||||
public String invoke(String outer, String inner) {
|
||||
if (classBuilderMode == ClassBuilderMode.KAPT3) {
|
||||
return outer + '/' + inner;
|
||||
}
|
||||
|
||||
return defaultClassNameFactory.invoke(outer, inner);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
|
||||
@@ -122,7 +108,7 @@ public class KotlinTypeMapper {
|
||||
@NotNull
|
||||
@Override
|
||||
public Function2<String, String, String> getInnerClassNameFactory() {
|
||||
return innerClassNameFactory;
|
||||
return TypeMappingConfiguration.DefaultImpls.getInnerClassNameFactory(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1392,11 +1378,11 @@ public class KotlinTypeMapper {
|
||||
Type sharedVarType = getSharedVarType(variableDescriptor);
|
||||
if (sharedVarType == null) {
|
||||
if (isDelegatedLocalVariable(variableDescriptor)) {
|
||||
VariableDescriptor delegateVariableDescriptor = bindingContext.get(LOCAL_VARIABLE_DELEGATE,
|
||||
(VariableDescriptor) variableDescriptor);
|
||||
assert delegateVariableDescriptor != null :
|
||||
"Local delegated property " + variableDescriptor + " delegate descriptor should be not null";
|
||||
sharedVarType = mapType(delegateVariableDescriptor.getType());
|
||||
//noinspection CastConflictsWithInstanceof
|
||||
KotlinType delegateType =
|
||||
JvmCodegenUtil.getPropertyDelegateType((LocalVariableDescriptor) variableDescriptor, bindingContext);
|
||||
assert delegateType != null : "Local delegated property type should not be null: " + variableDescriptor;
|
||||
sharedVarType = mapType(delegateType);
|
||||
}
|
||||
else {
|
||||
sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType());
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.state;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface Progress {
|
||||
Progress DEAF = (sourceFiles, outputFile) -> {
|
||||
};
|
||||
|
||||
/**
|
||||
* @param sourceFiles a (possibly empty) collection of source files {@code outputFile} was generated from
|
||||
* @param outputFile an output file
|
||||
*/
|
||||
void reportOutput(@NotNull Collection<File> sourceFiles, @Nullable File outputFile);
|
||||
}
|
||||
@@ -16,6 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class CommonCompilerArguments extends CommonToolArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
|
||||
@@ -89,6 +96,14 @@ public abstract class CommonCompilerArguments extends CommonToolArguments {
|
||||
public static final String ERROR = "error";
|
||||
public static final String ENABLE = "enable";
|
||||
|
||||
@NotNull
|
||||
public Map<AnalysisFlag<?>, Object> configureAnalysisFlags() {
|
||||
Map<AnalysisFlag<?>, Object> result = new HashMap<>();
|
||||
result.put(AnalysisFlag.getSkipMetadataVersionCheck(), skipMetadataVersionCheck);
|
||||
result.put(AnalysisFlag.getMultiPlatformDoNotCheckImpl(), noCheckImpl);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Used only for serialize and deserialize settings. Don't use in other places!
|
||||
public static final class DummyImpl extends CommonCompilerArguments {}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag;
|
||||
import org.jetbrains.kotlin.config.Jsr305State;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
|
||||
@@ -157,9 +163,26 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
description = "Java compiler arguments")
|
||||
public String[] javacArguments;
|
||||
|
||||
@Argument(value = "-Xload-jsr305-annotations", description = "Load JSR-305 nullability annotations")
|
||||
public boolean loadJsr305annotations;
|
||||
@Argument(
|
||||
value = "-Xjsr305-annotations",
|
||||
valueDescription = "{ignore|enable}",
|
||||
description = "Specify global behavior for JSR-305 nullability annotations: ignore, or treat as other supported nullability annotations"
|
||||
)
|
||||
public String jsr305GlobalReportLevel = Jsr305State.DEFAULT.getDescription();
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
public String[] friendPaths;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<AnalysisFlag<?>, Object> configureAnalysisFlags() {
|
||||
Map<AnalysisFlag<?>, Object> result = super.configureAnalysisFlags();
|
||||
for (Jsr305State state : Jsr305State.values()) {
|
||||
if (state.getDescription().equals(jsr305GlobalReportLevel)) {
|
||||
result.put(AnalysisFlag.getLoadJsr305Annotations(), state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import java.lang.reflect.Field
|
||||
import java.util.*
|
||||
|
||||
annotation class Argument(
|
||||
val value: String,
|
||||
@@ -54,7 +53,7 @@ data class ArgumentParseErrors(
|
||||
)
|
||||
|
||||
// Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors].
|
||||
fun <A : CommonToolArguments> parseCommandLineArguments(args: Array<out String>, result: A) {
|
||||
fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, result: A) {
|
||||
data class ArgumentField(val field: Field, val argument: Argument)
|
||||
|
||||
val fields = result::class.java.fields.mapNotNull { field ->
|
||||
|
||||
@@ -189,15 +189,12 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
extraLanguageFeatures.put(LanguageFeature.Coroutines, coroutinesState);
|
||||
}
|
||||
|
||||
LanguageVersionSettingsImpl settings =
|
||||
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures);
|
||||
settings.switchFlag(AnalysisFlags.getSkipMetadataVersionCheck(), arguments.skipMetadataVersionCheck);
|
||||
settings.switchFlag(AnalysisFlags.getMultiPlatformDoNotCheckImpl(), arguments.noCheckImpl);
|
||||
configureAnalysisFlags(settings, arguments);
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, settings);
|
||||
}
|
||||
|
||||
protected void configureAnalysisFlags(@NotNull LanguageVersionSettingsImpl settings, @NotNull A arguments) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, new LanguageVersionSettingsImpl(
|
||||
languageVersion,
|
||||
ApiVersion.createByLanguageVersion(apiVersion),
|
||||
arguments.configureAnalysisFlags(),
|
||||
extraLanguageFeatures
|
||||
));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
K2JVMCompiler.resetInitStartTime()
|
||||
|
||||
val arguments = createArguments()
|
||||
parseCommandLineArguments(args, arguments)
|
||||
parseCommandLineArguments(args.asList(), arguments)
|
||||
val collector = PrintingMessageCollector(errStream, messageRenderer, arguments.verbose)
|
||||
|
||||
try {
|
||||
@@ -99,7 +99,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
|
||||
// Used in kotlin-maven-plugin (KotlinCompileMojoBase) and in kotlin-gradle-plugin (KotlinJvmOptionsImpl, KotlinJsOptionsImpl)
|
||||
fun parseArguments(args: Array<out String>, arguments: A) {
|
||||
parseCommandLineArguments(args, arguments)
|
||||
parseCommandLineArguments(args.asList(), arguments)
|
||||
val message = validateArguments(arguments.errors)
|
||||
if (message != null) {
|
||||
throw IllegalArgumentException(message)
|
||||
@@ -142,6 +142,9 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
if (System.getProperty("java.awt.headless") == null) {
|
||||
System.setProperty("java.awt.headless", "true")
|
||||
}
|
||||
if (System.getProperty(PlainTextMessageRenderer.KOTLIN_COLORS_ENABLED_PROPERTY) == null) {
|
||||
System.setProperty(PlainTextMessageRenderer.KOTLIN_COLORS_ENABLED_PROPERTY, "true")
|
||||
}
|
||||
val exitCode = doMainNoExit(compiler, args)
|
||||
if (exitCode != ExitCode.OK) {
|
||||
System.exit(exitCode.code)
|
||||
|
||||
@@ -92,19 +92,9 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
|
||||
return messageCollector.hasErrors()
|
||||
}
|
||||
|
||||
interface Analyzer {
|
||||
fun analyze(): AnalysisResult
|
||||
|
||||
fun reportEnvironmentErrors() {
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeAndReport(files: Collection<KtFile>, analyzer: Analyzer) {
|
||||
analysisResult = analyzer.analyze()
|
||||
fun analyzeAndReport(files: Collection<KtFile>, analyze: () -> AnalysisResult) {
|
||||
analysisResult = analyze()
|
||||
reportSyntaxErrors(files)
|
||||
if (analysisResult.bindingContext.diagnostics.any { it.isValid && it.severity == Severity.ERROR }) {
|
||||
analyzer.reportEnvironmentErrors()
|
||||
}
|
||||
reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector)
|
||||
reportIncompleteHierarchies()
|
||||
reportAlternativeSignatureErrors()
|
||||
|
||||
@@ -30,12 +30,13 @@ import java.util.Set;
|
||||
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*;
|
||||
|
||||
public abstract class PlainTextMessageRenderer implements MessageRenderer {
|
||||
public static final String KOTLIN_COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled";
|
||||
public static final boolean COLOR_ENABLED;
|
||||
|
||||
static {
|
||||
boolean colorEnabled = false;
|
||||
// TODO: investigate why ANSI escape codes on Windows only work in REPL for some reason
|
||||
if (!SystemInfo.isWindows && !"false".equals(System.getProperty("kotlin.colors.enabled"))) {
|
||||
if (!SystemInfo.isWindows && "true".equals(System.getProperty(KOTLIN_COLORS_ENABLED_PROPERTY))) {
|
||||
try {
|
||||
// AnsiConsole doesn't check isatty() for stderr (see https://github.com/fusesource/jansi/pull/35).
|
||||
colorEnabled = CLibrary.isatty(CLibrary.STDERR_FILENO) != 0;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.script
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.script.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.script.ScriptContentLoader
|
||||
import java.io.File
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||
|
||||
class CliScriptDependenciesProvider(
|
||||
project: Project,
|
||||
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider
|
||||
) : ScriptDependenciesProvider {
|
||||
|
||||
private val cacheLock = ReentrantReadWriteLock()
|
||||
private val cache = hashMapOf<String, ScriptDependencies?>()
|
||||
private val scriptContentLoader = ScriptContentLoader(project)
|
||||
|
||||
override fun getScriptDependencies(file: VirtualFile): ScriptDependencies? = cacheLock.read {
|
||||
calculateExternalDependencies(file)
|
||||
}
|
||||
|
||||
private fun calculateExternalDependencies(file: VirtualFile): ScriptDependencies? {
|
||||
val path = file.path
|
||||
val cached = cache[path]
|
||||
return if (cached != null) cached
|
||||
else {
|
||||
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file)
|
||||
if (scriptDef != null) {
|
||||
val deps = scriptContentLoader.loadContentsAndResolveDependencies(scriptDef, file)
|
||||
|
||||
if (deps != null) {
|
||||
log.info("[kts] new cached deps for $path: ${deps.classpath.joinToString(File.pathSeparator)}")
|
||||
}
|
||||
cacheLock.write {
|
||||
cache.put(path, deps)
|
||||
}
|
||||
deps
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val log = Logger.getInstance(ScriptDependenciesProvider::class.java)
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.script
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.script.ScriptReportSink
|
||||
import kotlin.script.experimental.dependencies.ScriptReport
|
||||
|
||||
class CliScriptReportSink(private val messageCollector: MessageCollector) : ScriptReportSink {
|
||||
override fun attachReports(scriptFile: VirtualFile, reports: List<ScriptReport>) {
|
||||
reports.forEach {
|
||||
messageCollector.report(it.severity.convertSeverity(), it.message, location(scriptFile, it.position))
|
||||
}
|
||||
}
|
||||
|
||||
private fun location(scriptFile: VirtualFile, position: ScriptReport.Position?): CompilerMessageLocation? {
|
||||
if (position == null) return CompilerMessageLocation.create(scriptFile.path)
|
||||
|
||||
return CompilerMessageLocation.create(scriptFile.path, position.startLine, position.startColumn, null)
|
||||
}
|
||||
|
||||
private fun ScriptReport.Severity.convertSeverity(): CompilerMessageSeverity = when(this) {
|
||||
ScriptReport.Severity.ERROR -> CompilerMessageSeverity.ERROR
|
||||
ScriptReport.Severity.WARNING -> CompilerMessageSeverity.WARNING
|
||||
ScriptReport.Severity.INFO -> CompilerMessageSeverity.INFO
|
||||
ScriptReport.Severity.DEBUG -> CompilerMessageSeverity.LOGGING
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,8 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
return COMPILATION_ERROR;
|
||||
}
|
||||
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = analyzeAndReportErrors(messageCollector, sourcesFiles, config);
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector);
|
||||
analyzerWithCompilerReport.analyzeAndReport(sourcesFiles, () -> TopDownAnalyzerFacadeForJS.analyzeFiles(sourcesFiles, config));
|
||||
if (analyzerWithCompilerReport.hasErrors()) {
|
||||
return COMPILATION_ERROR;
|
||||
}
|
||||
@@ -280,24 +281,6 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
messageCollector.report(LOGGING, "Compiling source files: " + StringsKt.join(fileNames, ", "), null);
|
||||
}
|
||||
|
||||
private static AnalyzerWithCompilerReport analyzeAndReportErrors(
|
||||
@NotNull MessageCollector messageCollector, @NotNull List<KtFile> sources, @NotNull JsConfig config
|
||||
) {
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(messageCollector);
|
||||
analyzerWithCompilerReport.analyzeAndReport(sources, new AnalyzerWithCompilerReport.Analyzer() {
|
||||
@NotNull
|
||||
@Override
|
||||
public AnalysisResult analyze() {
|
||||
return TopDownAnalyzerFacadeForJS.analyzeFiles(sources, config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportEnvironmentErrors() {
|
||||
}
|
||||
});
|
||||
return analyzerWithCompilerReport;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupPlatformSpecificArgumentsAndServices(
|
||||
@NotNull CompilerConfiguration configuration, @NotNull K2JSCompilerArguments arguments,
|
||||
|
||||
@@ -30,10 +30,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
|
||||
@@ -106,11 +103,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
val classpath = getClasspath(paths, arguments)
|
||||
configuration.addJvmClasspathRoots(classpath)
|
||||
for (modularRoot in arguments.javaModulePath?.split(File.pathSeparatorChar).orEmpty()) {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, JvmModulePathRoot(File(modularRoot)))
|
||||
}
|
||||
configureContentRoots(paths, arguments, configuration)
|
||||
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, arguments.moduleName ?: JvmAbi.DEFAULT_MODULE_NAME)
|
||||
|
||||
@@ -187,7 +180,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
val scriptDefinitionProvider = KotlinScriptDefinitionProvider.getInstance(environment.project)!!
|
||||
val scriptFile = File(sourcePath)
|
||||
if (scriptFile.isDirectory || !scriptDefinitionProvider.isScript(scriptFile)) {
|
||||
if (scriptFile.isDirectory || !scriptDefinitionProvider.isScript(scriptFile.name)) {
|
||||
val extensionHint =
|
||||
if (configuration.get(JVMConfigurationKeys.SCRIPT_DEFINITIONS) == listOf(StandardScriptDefinition)) " (.kts)"
|
||||
else ""
|
||||
@@ -197,7 +190,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size)
|
||||
|
||||
return KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, paths, scriptArgs)
|
||||
return KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, scriptArgs)
|
||||
}
|
||||
else {
|
||||
if (destination != null) {
|
||||
@@ -310,10 +303,6 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureAnalysisFlags(settings: LanguageVersionSettingsImpl, arguments: K2JVMCompilerArguments) {
|
||||
settings.switchFlag(AnalysisFlags.loadJsr305Annotations, arguments.loadJsr305annotations)
|
||||
}
|
||||
|
||||
override fun createArguments(): K2JVMCompilerArguments = K2JVMCompilerArguments().apply {
|
||||
if (System.getenv("KOTLIN_REPORT_PERF") != null) {
|
||||
reportPerf = true
|
||||
@@ -383,21 +372,35 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
arguments.declarationsOutputPath?.let { configuration.put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||
}
|
||||
|
||||
private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> {
|
||||
val classpath = arrayListOf<File>()
|
||||
if (arguments.classpath != null) {
|
||||
classpath.addAll(arguments.classpath.split(File.pathSeparatorChar).map(::File))
|
||||
private fun configureContentRoots(paths: KotlinPaths, arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration) {
|
||||
for (path in arguments.classpath?.split(File.pathSeparatorChar).orEmpty()) {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(File(path)))
|
||||
}
|
||||
|
||||
for (modularRoot in arguments.javaModulePath?.split(File.pathSeparatorChar).orEmpty()) {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, JvmModulePathRoot(File(modularRoot)))
|
||||
}
|
||||
|
||||
val isModularJava = configuration.get(JVMConfigurationKeys.JDK_HOME).let { it != null && CoreJrtFileSystem.isModularJdk(it) }
|
||||
fun addRoot(moduleName: String, file: File) {
|
||||
if (isModularJava) {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, JvmModulePathRoot(file))
|
||||
configuration.add(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, moduleName)
|
||||
}
|
||||
else {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(file))
|
||||
}
|
||||
}
|
||||
|
||||
if (!arguments.noStdlib) {
|
||||
classpath.add(paths.runtimePath)
|
||||
classpath.add(paths.scriptRuntimePath)
|
||||
addRoot("kotlin.stdlib", paths.stdlibPath)
|
||||
addRoot("kotlin.script.runtime", paths.scriptRuntimePath)
|
||||
}
|
||||
// "-no-stdlib" implies "-no-reflect": otherwise we would be able to transitively read stdlib classes through kotlin-reflect,
|
||||
// which is likely not what user wants since s/he manually provided "-no-stdlib"
|
||||
if (!arguments.noReflect && !arguments.noStdlib) {
|
||||
classpath.add(paths.reflectPath)
|
||||
addRoot("kotlin.reflect", paths.reflectPath)
|
||||
}
|
||||
return classpath
|
||||
}
|
||||
|
||||
private fun setupJdkClasspathRoots(arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration, messageCollector: MessageCollector): ExitCode {
|
||||
@@ -456,7 +459,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
messageCollector.report(
|
||||
INFO,
|
||||
"Added script definition $template to configuration: files pattern = \"${def.scriptFilePattern}\", " +
|
||||
"resolver = ${def.resolver?.javaClass?.name}"
|
||||
"resolver = ${def.dependencyResolver.javaClass.name}"
|
||||
)
|
||||
}
|
||||
catch (ex: ClassNotFoundException) {
|
||||
|
||||
@@ -34,11 +34,11 @@ import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
||||
import org.jetbrains.kotlin.config.ContentRoot
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.isValidJavaFqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleGraph
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
@@ -52,7 +52,7 @@ internal class ClasspathRootsResolver(
|
||||
private val additionalModules: List<String>,
|
||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?
|
||||
) {
|
||||
private val javaModuleFinder = CliJavaModuleFinder(VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL))
|
||||
val javaModuleFinder = CliJavaModuleFinder(VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL))
|
||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||
|
||||
data class RootsAndModules(val roots: List<JavaRoot>, val modules: List<JavaModule>)
|
||||
|
||||
@@ -73,6 +73,9 @@ import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PRO
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.script.CliScriptReportSink
|
||||
import org.jetbrains.kotlin.cli.common.script.CliScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
|
||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||
@@ -103,8 +106,8 @@ import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.script.KotlinScriptExternalImportsProvider
|
||||
import org.jetbrains.kotlin.script.KotlinScriptExternalImportsProviderImpl
|
||||
import org.jetbrains.kotlin.script.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.script.ScriptReportSink
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
|
||||
@@ -173,7 +176,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES))
|
||||
|
||||
registerProjectServicesForCLI(projectEnvironment)
|
||||
registerProjectServices(projectEnvironment)
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
registerProjectServices(projectEnvironment, messageCollector)
|
||||
|
||||
sourceFiles += CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration, {
|
||||
message ->
|
||||
@@ -185,15 +189,14 @@ class KotlinCoreEnvironment private constructor(
|
||||
scriptDefinitionProvider.setScriptDefinitions(
|
||||
configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS))
|
||||
|
||||
KotlinScriptExternalImportsProvider.getInstance(project)?.run {
|
||||
ScriptDependenciesProvider.getInstance(project).let { importsProvider ->
|
||||
configuration.addJvmClasspathRoots(
|
||||
getCombinedClasspathFor(sourceFiles)
|
||||
sourceFiles.mapNotNull(importsProvider::getScriptDependencies)
|
||||
.flatMap { it.classpath }
|
||||
.distinctBy { it.absolutePath })
|
||||
}
|
||||
}
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
classpathRootsResolver = ClasspathRootsResolver(
|
||||
PsiManager.getInstance(project), messageCollector,
|
||||
configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES),
|
||||
@@ -229,7 +232,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
project.registerService(
|
||||
JavaModuleResolver::class.java,
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules)
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules,
|
||||
classpathRootsResolver.javaModuleFinder.systemModules.toList())
|
||||
)
|
||||
|
||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||
@@ -515,13 +519,16 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
// made public for Upsource
|
||||
@JvmStatic
|
||||
fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment) {
|
||||
fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment, messageCollector: MessageCollector?) {
|
||||
with (projectEnvironment.project) {
|
||||
val kotlinScriptDefinitionProvider = KotlinScriptDefinitionProvider()
|
||||
registerService(KotlinScriptDefinitionProvider::class.java, kotlinScriptDefinitionProvider)
|
||||
registerService(KotlinScriptExternalImportsProvider::class.java, KotlinScriptExternalImportsProviderImpl(projectEnvironment.project, kotlinScriptDefinitionProvider))
|
||||
registerService(ScriptDependenciesProvider::class.java, CliScriptDependenciesProvider(projectEnvironment.project, kotlinScriptDefinitionProvider))
|
||||
registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this))
|
||||
registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this))
|
||||
if (messageCollector != null) {
|
||||
registerService(ScriptReportSink::class.java, CliScriptReportSink(messageCollector))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.io.JarUtil
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||
@@ -34,7 +34,8 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
|
||||
@@ -58,15 +59,11 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.script.tryConstructClassFromStringArgs
|
||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.net.URLClassLoader
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.jar.Attributes
|
||||
|
||||
object KotlinToJVMBytecodeCompiler {
|
||||
|
||||
@@ -190,14 +187,26 @@ object KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
|
||||
for (module in chunk) {
|
||||
for (javaRootPath in module.getJavaSourceRoots()) {
|
||||
configuration.addJavaSourceRoot(File(javaRootPath.path), javaRootPath.packagePrefix)
|
||||
for ((path, packagePrefix) in module.getJavaSourceRoots()) {
|
||||
configuration.addJavaSourceRoot(File(path), packagePrefix)
|
||||
}
|
||||
}
|
||||
|
||||
val isJava9Module = chunk.any { module ->
|
||||
module.getJavaSourceRoots().any { (path, packagePrefix) ->
|
||||
val file = File(path)
|
||||
packagePrefix == null &&
|
||||
(file.name == PsiJavaModule.MODULE_INFO_FILE ||
|
||||
(file.isDirectory && file.listFiles().any { it.name == PsiJavaModule.MODULE_INFO_FILE }))
|
||||
}
|
||||
}
|
||||
|
||||
for (module in chunk) {
|
||||
for (classpathRoot in module.getClasspathRoots()) {
|
||||
configuration.addJvmClasspathRoot(File(classpathRoot))
|
||||
configuration.add(
|
||||
JVMConfigurationKeys.CONTENT_ROOTS,
|
||||
if (isJava9Module) JvmModulePathRoot(File(classpathRoot)) else JvmClasspathRoot(File(classpathRoot))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,12 +258,8 @@ object KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
fun compileAndExecuteScript(
|
||||
environment: KotlinCoreEnvironment,
|
||||
paths: KotlinPaths,
|
||||
scriptArgs: List<String>): ExitCode
|
||||
{
|
||||
val scriptClass = compileScript(environment, paths) ?: return ExitCode.COMPILATION_ERROR
|
||||
internal fun compileAndExecuteScript(environment: KotlinCoreEnvironment, scriptArgs: List<String>): ExitCode {
|
||||
val scriptClass = compileScript(environment) ?: return ExitCode.COMPILATION_ERROR
|
||||
|
||||
try {
|
||||
try {
|
||||
@@ -317,29 +322,24 @@ object KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
stream.println(cause)
|
||||
val fullTrace = cause.stackTrace
|
||||
val relevantEntries = fullTrace.size - exception.stackTrace.size
|
||||
for (i in 0..relevantEntries - 1) {
|
||||
for (i in 0 until fullTrace.size - exception.stackTrace.size) {
|
||||
stream.println("\tat " + fullTrace[i])
|
||||
}
|
||||
}
|
||||
|
||||
fun compileScript(environment: KotlinCoreEnvironment, paths: KotlinPaths): Class<*>? =
|
||||
compileScript(environment,
|
||||
{
|
||||
val classPaths = arrayListOf(paths.runtimePath.toURI().toURL())
|
||||
environment.configuration.jvmClasspathRoots.mapTo(classPaths) { it.toURI().toURL() }
|
||||
URLClassLoader(classPaths.toTypedArray())
|
||||
})
|
||||
|
||||
fun compileScript(environment: KotlinCoreEnvironment, parentClassLoader: ClassLoader): Class<*>? = compileScript(environment, { parentClassLoader })
|
||||
|
||||
private inline fun compileScript(
|
||||
environment: KotlinCoreEnvironment,
|
||||
makeParentClassLoader: () -> ClassLoader): Class<*>? {
|
||||
fun compileScript(environment: KotlinCoreEnvironment, parentClassLoader: ClassLoader? = null): Class<*>? {
|
||||
val state = analyzeAndGenerate(environment) ?: return null
|
||||
|
||||
try {
|
||||
val classLoader = GeneratedClassLoader(state.factory, makeParentClassLoader())
|
||||
val urls = environment.configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS).mapNotNull { root ->
|
||||
when (root) {
|
||||
is JvmModulePathRoot -> root.file // TODO: only add required modules
|
||||
is JvmClasspathRoot -> root.file
|
||||
else -> null
|
||||
}
|
||||
}.map { it.toURI().toURL() }
|
||||
|
||||
val classLoader = GeneratedClassLoader(state.factory, parentClassLoader ?: URLClassLoader(urls.toTypedArray(), null))
|
||||
|
||||
val script = environment.getSourceFiles()[0].script ?: error("Script must be parsed")
|
||||
return classLoader.loadClass(script.fqName.asString())
|
||||
@@ -365,30 +365,24 @@ object KotlinToJVMBytecodeCompiler {
|
||||
|
||||
val analysisStart = PerformanceCounter.currentTime()
|
||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector)
|
||||
analyzerWithCompilerReport.analyzeAndReport(sourceFiles, object : AnalyzerWithCompilerReport.Analyzer {
|
||||
override fun analyze(): AnalysisResult {
|
||||
val project = environment.project
|
||||
val moduleOutputs = environment.configuration.get(JVMConfigurationKeys.MODULES)?.mapNotNull { module ->
|
||||
environment.findLocalFile(module.getOutputDirectory())
|
||||
}.orEmpty()
|
||||
val sourcesOnly = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
|
||||
// To support partial and incremental compilation, we add the scope which contains binaries from output directories
|
||||
// of the compiled modules (.class) to the list of scopes of the source module
|
||||
val scope = if (moduleOutputs.isEmpty()) sourcesOnly else sourcesOnly.uniteWith(DirectoriesScope(project, moduleOutputs))
|
||||
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
project,
|
||||
sourceFiles,
|
||||
CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
environment.configuration,
|
||||
environment::createPackagePartProvider,
|
||||
sourceModuleSearchScope = scope
|
||||
)
|
||||
}
|
||||
|
||||
override fun reportEnvironmentErrors() {
|
||||
reportRuntimeConflicts(collector, environment.configuration.jvmClasspathRoots)
|
||||
}
|
||||
})
|
||||
analyzerWithCompilerReport.analyzeAndReport(sourceFiles) {
|
||||
val project = environment.project
|
||||
val moduleOutputs = environment.configuration.get(JVMConfigurationKeys.MODULES)?.mapNotNull { module ->
|
||||
environment.findLocalFile(module.getOutputDirectory())
|
||||
}.orEmpty()
|
||||
val sourcesOnly = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, sourceFiles)
|
||||
// To support partial and incremental compilation, we add the scope which contains binaries from output directories
|
||||
// of the compiled modules (.class) to the list of scopes of the source module
|
||||
val scope = if (moduleOutputs.isEmpty()) sourcesOnly else sourcesOnly.uniteWith(DirectoriesScope(project, moduleOutputs))
|
||||
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
project,
|
||||
sourceFiles,
|
||||
CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
environment.configuration,
|
||||
environment::createPackagePartProvider,
|
||||
sourceModuleSearchScope = scope
|
||||
)
|
||||
}
|
||||
|
||||
val analysisNanos = PerformanceCounter.currentTime() - analysisStart
|
||||
|
||||
@@ -476,28 +470,4 @@ object KotlinToJVMBytecodeCompiler {
|
||||
|
||||
private val KotlinCoreEnvironment.messageCollector: MessageCollector
|
||||
get() = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
private fun reportRuntimeConflicts(messageCollector: MessageCollector, jvmClasspathRoots: List<File>) {
|
||||
fun String.removeIdeaVersionSuffix(): String {
|
||||
val versionIndex = indexOfAny(arrayListOf("-IJ", "-Idea"))
|
||||
return if (versionIndex >= 0) substring(0, versionIndex) else this
|
||||
}
|
||||
|
||||
val runtimes = jvmClasspathRoots.map {
|
||||
try {
|
||||
it.canonicalFile
|
||||
}
|
||||
catch (e: IOException) {
|
||||
it
|
||||
}
|
||||
}.filter { it.name == PathUtil.KOTLIN_JAVA_RUNTIME_JAR && it.exists() }
|
||||
|
||||
val runtimeVersions = runtimes.map {
|
||||
JarUtil.getJarAttribute(it, Attributes.Name.IMPLEMENTATION_VERSION).orEmpty().removeIdeaVersionSuffix()
|
||||
}
|
||||
|
||||
if (runtimeVersions.toSet().size > 1) {
|
||||
messageCollector.report(ERROR, "Conflicting versions of Kotlin runtime on classpath: " + runtimes.joinToString { it.path })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
||||
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
@@ -173,8 +174,6 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder
|
||||
)
|
||||
|
||||
StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(dependenciesContainer, null) }
|
||||
|
||||
moduleClassResolver.compiledCodeResolver = dependenciesContainer.get<JavaDescriptorResolver>()
|
||||
|
||||
dependenciesContext.setDependencies(listOfNotNull(dependenciesContext.module, optionalBuiltInsModule))
|
||||
@@ -201,8 +200,6 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
).apply {
|
||||
initJvmBuiltInsForTopDownAnalysis()
|
||||
(partProvider as? IncrementalPackagePartProvider)?.deserializationConfiguration = get<DeserializationConfiguration>()
|
||||
|
||||
StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(this, null) }
|
||||
}
|
||||
|
||||
moduleClassResolver.sourceCodeResolver = container.get<JavaDescriptorResolver>()
|
||||
@@ -212,7 +209,8 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
targetIds?.mapTo(additionalProviders) { targetId ->
|
||||
IncrementalPackageFragmentProvider(
|
||||
files, module, storageManager, container.get<DeserializationComponentsForJava>().components,
|
||||
incrementalComponents.getIncrementalCache(targetId), targetId
|
||||
incrementalComponents.getIncrementalCache(targetId), targetId,
|
||||
container.get<KotlinClassFinder>()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,31 +18,63 @@ package org.jetbrains.kotlin.cli.jvm.modules
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleGraph
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
|
||||
class CliJavaModuleResolver(
|
||||
override val moduleGraph: JavaModuleGraph,
|
||||
private val javaModules: List<JavaModule>
|
||||
private val moduleGraph: JavaModuleGraph,
|
||||
private val userModules: List<JavaModule>,
|
||||
private val systemModules: List<JavaModule.Explicit>
|
||||
) : JavaModuleResolver {
|
||||
init {
|
||||
assert(javaModules.count { !it.isBinary } <= 1) {
|
||||
"Modules computed by ClasspathRootsResolver cannot have more than one source module: $javaModules"
|
||||
assert(userModules.count { !it.isBinary } <= 1) {
|
||||
"Modules computed by ClasspathRootsResolver cannot have more than one source module: $userModules"
|
||||
}
|
||||
}
|
||||
|
||||
private val sourceModule = javaModules.firstOrNull { !it.isBinary }
|
||||
private val sourceModule: JavaModule? = userModules.firstOrNull { !it.isBinary }
|
||||
|
||||
override fun findJavaModule(file: VirtualFile): JavaModule? =
|
||||
when (file.fileType) {
|
||||
KotlinFileType.INSTANCE, JavaFileType.INSTANCE -> sourceModule
|
||||
JavaClassFileType.INSTANCE -> javaModules.firstOrNull { module ->
|
||||
module.isBinary && VfsUtilCore.isAncestor(module.moduleRoot, file, false)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
private fun findJavaModule(file: VirtualFile): JavaModule? {
|
||||
if (file.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL) {
|
||||
return systemModules.firstOrNull { module -> file in module }
|
||||
}
|
||||
|
||||
return when (file.fileType) {
|
||||
KotlinFileType.INSTANCE, JavaFileType.INSTANCE -> sourceModule
|
||||
JavaClassFileType.INSTANCE -> userModules.firstOrNull { module -> module.isBinary && file in module }
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private operator fun JavaModule.contains(file: VirtualFile): Boolean =
|
||||
VfsUtilCore.isAncestor(moduleRoot, file, false)
|
||||
|
||||
override fun checkAccessibility(
|
||||
fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?
|
||||
): JavaModuleResolver.AccessError? {
|
||||
val ourModule = fileFromOurModule?.let(this::findJavaModule)
|
||||
val theirModule = this.findJavaModule(referencedFile)
|
||||
|
||||
if (ourModule?.name == theirModule?.name) return null
|
||||
|
||||
if (theirModule == null) {
|
||||
return JavaModuleResolver.AccessError.ModuleDoesNotReadUnnamedModule
|
||||
}
|
||||
|
||||
if (ourModule != null && !moduleGraph.reads(ourModule.name, theirModule.name)) {
|
||||
return JavaModuleResolver.AccessError.ModuleDoesNotReadModule(theirModule.name)
|
||||
}
|
||||
|
||||
val fqName = referencedPackage ?: return null
|
||||
if (!theirModule.exports(fqName) && (ourModule == null || !theirModule.exportsTo(fqName, ourModule.name))) {
|
||||
return JavaModuleResolver.AccessError.ModuleDoesNotExportPackage(theirModule.name)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.modules
|
||||
package org.jetbrains.kotlin.cli.jvm.modules
|
||||
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleFinder
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
|
||||
class JavaModuleGraph(finder: JavaModuleFinder) {
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
|
||||
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.script.dependencies.KotlinScriptExternalDependencies
|
||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||
|
||||
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
|
||||
|
||||
@@ -70,5 +70,5 @@ class GenericReplCompilerState(environment: KotlinCoreEnvironment, override val
|
||||
|
||||
val analyzerEngine = ReplCodeAnalyzer(environment)
|
||||
|
||||
var lastDependencies: KotlinScriptExternalDependencies? = null
|
||||
var lastDependencies: ScriptDependencies? = null
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.repl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
|
||||
// TODO: remove if unused after switching old repl to the new infrastruct
|
||||
open class GenericRepl protected constructor(
|
||||
disposable: Disposable,
|
||||
scriptDefinition: KotlinScriptDefinition,
|
||||
compilerConfiguration: CompilerConfiguration,
|
||||
messageCollector: MessageCollector,
|
||||
baseClassloader: ClassLoader?,
|
||||
protected val fallbackScriptArgs: ScriptArgsWithTypes? = null,
|
||||
protected val repeatingMode: ReplRepeatingMode = ReplRepeatingMode.NONE
|
||||
) : ReplCompiler, ReplEvaluator, ReplAtomicEvaluator {
|
||||
|
||||
protected val compiler: ReplCompiler by lazy { GenericReplCompiler(disposable, scriptDefinition, compilerConfiguration, messageCollector) }
|
||||
protected val evaluator: ReplFullEvaluator by lazy { GenericReplCompilingEvaluator(compiler, compilerConfiguration.jvmClasspathRoots, baseClassloader, fallbackScriptArgs, repeatingMode) }
|
||||
|
||||
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = evaluator.createState(lock)
|
||||
|
||||
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = compiler.check(state, codeLine)
|
||||
|
||||
override fun compile(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCompileResult = compiler.compile(state, codeLine)
|
||||
|
||||
override fun eval(state: IReplStageState<*>, compileResult: ReplCompileResult.CompiledClasses, scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
|
||||
evaluator.eval(state, compileResult, scriptArgs, invokeWrapper)
|
||||
|
||||
override fun compileAndEval(state: IReplStageState<*>, codeLine: ReplCodeLine, scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
|
||||
evaluator.compileAndEval(state, codeLine, scriptArgs, invokeWrapper)
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.KtScriptInitializer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.script.ScriptDependenciesProvider
|
||||
import java.io.File
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.write
|
||||
@@ -67,7 +68,7 @@ open class GenericReplCompiler(disposable: Disposable,
|
||||
Pair(compilerState.lastLineState!!.psiFile, compilerState.lastLineState!!.errorHolder)
|
||||
}
|
||||
|
||||
val newDependencies = scriptDefinition.getDependenciesFor(psiFile, checker.environment.project, compilerState.lastDependencies)
|
||||
val newDependencies = ScriptDependenciesProvider.getInstance(checker.environment.project).getScriptDependencies(psiFile)
|
||||
var classpathAddendum: List<File>? = null
|
||||
if (compilerState.lastDependencies != newDependencies) {
|
||||
compilerState.lastDependencies = newDependencies
|
||||
|
||||
@@ -22,8 +22,10 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import java.io.PrintWriter
|
||||
import java.net.URLClassLoader
|
||||
@@ -38,10 +40,15 @@ class ReplInterpreter(
|
||||
private val lineNumber = AtomicInteger()
|
||||
|
||||
private val previousIncompleteLines = arrayListOf<String>()
|
||||
private val classLoader: ReplClassLoader = run {
|
||||
val classpath = configuration.jvmClasspathRoots.map { it.toURI().toURL() }
|
||||
ReplClassLoader(URLClassLoader(classpath.toTypedArray(), null))
|
||||
|
||||
private val classpathRoots = configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS).mapNotNull { root ->
|
||||
when (root) {
|
||||
is JvmModulePathRoot -> root.file // TODO: only add required modules
|
||||
is JvmClasspathRoot -> root.file
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
private val classLoader = ReplClassLoader(URLClassLoader(classpathRoots.map { it.toURI().toURL() }.toTypedArray(), null))
|
||||
|
||||
private val messageCollector = object : MessageCollector {
|
||||
private var hasErrors = false
|
||||
@@ -69,8 +76,12 @@ class ReplInterpreter(
|
||||
}
|
||||
|
||||
// TODO: add script definition with project-based resolving for IDEA repl
|
||||
private val scriptCompiler: ReplCompiler by lazy { GenericReplCompiler(disposable, REPL_LINE_AS_SCRIPT_DEFINITION, configuration, messageCollector) }
|
||||
private val scriptEvaluator: ReplFullEvaluator by lazy { GenericReplCompilingEvaluator(scriptCompiler, configuration.jvmClasspathRoots, classLoader, null, ReplRepeatingMode.REPEAT_ANY_PREVIOUS) }
|
||||
private val scriptCompiler: ReplCompiler by lazy {
|
||||
GenericReplCompiler(disposable, REPL_LINE_AS_SCRIPT_DEFINITION, configuration, messageCollector)
|
||||
}
|
||||
private val scriptEvaluator: ReplFullEvaluator by lazy {
|
||||
GenericReplCompilingEvaluator(scriptCompiler, classpathRoots, classLoader, null, ReplRepeatingMode.REPEAT_ANY_PREVIOUS)
|
||||
}
|
||||
|
||||
private val evalState by lazy { scriptEvaluator.createState() }
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.metadata
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.common.DefaultAnalyzerFacade
|
||||
import org.jetbrains.kotlin.builtins.BuiltInsBinaryVersion
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
@@ -63,11 +62,11 @@ open class MetadataSerializer(private val dependOnOldBuiltIns: Boolean) {
|
||||
}
|
||||
|
||||
val analyzer = AnalyzerWithCompilerReport(messageCollector)
|
||||
analyzer.analyzeAndReport(files, object : AnalyzerWithCompilerReport.Analyzer {
|
||||
override fun analyze(): AnalysisResult = DefaultAnalyzerFacade.analyzeFiles(files, moduleName, dependOnOldBuiltIns) {
|
||||
_, content -> environment.createPackagePartProvider(content.moduleContentScope)
|
||||
analyzer.analyzeAndReport(files) {
|
||||
DefaultAnalyzerFacade.analyzeFiles(files, moduleName, dependOnOldBuiltIns) { _, content ->
|
||||
environment.createPackagePartProvider(content.moduleContentScope)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (analyzer.hasErrors()) return
|
||||
|
||||
|
||||
@@ -184,9 +184,8 @@ messages/**)
|
||||
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureReader { *; }
|
||||
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
|
||||
|
||||
-keepclassmembers class org.jetbrains.org.objectweb.asm.Type {
|
||||
*** ARRAY;
|
||||
*** OBJECT;
|
||||
-keep class org.jetbrains.org.objectweb.asm.Type {
|
||||
public protected *;
|
||||
}
|
||||
|
||||
-keepclassmembers class org.jetbrains.org.objectweb.asm.ClassReader {
|
||||
@@ -203,4 +202,7 @@ messages/**)
|
||||
|
||||
# for tools.jar
|
||||
-keep class com.sun.tools.javac.** { *; }
|
||||
-keep class com.sun.source.** { *; }
|
||||
-keep class com.sun.source.** { *; }
|
||||
|
||||
# for coroutines
|
||||
-keep class kotlinx.coroutines.** { *; }
|
||||
|
||||
@@ -33,9 +33,8 @@ open class BasicCompilerServicesWithResultsFacadeServer(
|
||||
) : CompilerServicesFacadeBase,
|
||||
UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory)
|
||||
{
|
||||
override fun report(category: Int, severity: Int, message: String?, attachment: Serializable?): Void? {
|
||||
override fun report(category: Int, severity: Int, message: String?, attachment: Serializable?) {
|
||||
messageCollector.reportFromDaemon(outputsCollector, category, severity, message, attachment)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,27 +56,24 @@ open class CompilerCallbackServicesFacadeServer(
|
||||
|
||||
override fun incrementalCache_getModuleMappingData(target: TargetId): ByteArray? = incrementalCompilationComponents!!.getIncrementalCache(target).getModuleMappingData()
|
||||
|
||||
override fun incrementalCache_registerInline(target: TargetId, fromPath: String, jvmSignature: String, toPath: String): Void? {
|
||||
override fun incrementalCache_registerInline(target: TargetId, fromPath: String, jvmSignature: String, toPath: String) {
|
||||
incrementalCompilationComponents!!.getIncrementalCache(target).registerInline(fromPath, jvmSignature, toPath)
|
||||
return null
|
||||
}
|
||||
|
||||
override fun incrementalCache_getClassFilePath(target: TargetId, internalClassName: String): String = incrementalCompilationComponents!!.getIncrementalCache(target).getClassFilePath(internalClassName)
|
||||
|
||||
override fun incrementalCache_close(target: TargetId): Void? {
|
||||
override fun incrementalCache_close(target: TargetId) {
|
||||
incrementalCompilationComponents!!.getIncrementalCache(target).close()
|
||||
return null
|
||||
}
|
||||
|
||||
override fun lookupTracker_requiresPosition() = incrementalCompilationComponents!!.getLookupTracker().requiresPosition
|
||||
|
||||
override fun lookupTracker_record(lookups: Collection<LookupInfo>): Void? {
|
||||
override fun lookupTracker_record(lookups: Collection<LookupInfo>) {
|
||||
val lookupTracker = incrementalCompilationComponents!!.getLookupTracker()
|
||||
|
||||
for (it in lookups) {
|
||||
lookupTracker.record(it.filePath, it.position, it.scopeFqName, it.scopeKind, it.name)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private val lookupTracker_isDoNothing: Boolean = incrementalCompilationComponents?.getLookupTracker() === LookupTracker.DO_NOTHING
|
||||
|
||||
@@ -444,7 +444,7 @@ class DaemonReportingTargets(val out: PrintStream? = null,
|
||||
val messageCollector: MessageCollector? = null,
|
||||
val compilerServices: CompilerServicesFacadeBase? = null)
|
||||
|
||||
internal fun DaemonReportingTargets.report(category: DaemonReportCategory, message: String, source: String? = null): Unit {
|
||||
internal fun DaemonReportingTargets.report(category: DaemonReportCategory, message: String, source: String? = null) {
|
||||
val sourceMessage: String by lazy { source?.let { "[$it] $message" } ?: message }
|
||||
out?.println("${category.name}: $sourceMessage")
|
||||
messages?.add(DaemonReportMessage(category, sourceMessage))
|
||||
|
||||
@@ -27,9 +27,8 @@ class RemoteInputStreamServer(val `in`: InputStream, port: Int = SOCKET_ANY_FREE
|
||||
: RemoteInputStream,
|
||||
UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory)
|
||||
{
|
||||
override fun close(): Void? {
|
||||
override fun close() {
|
||||
`in`.close()
|
||||
return null
|
||||
}
|
||||
|
||||
override fun read(length: Int): ByteArray {
|
||||
|
||||
@@ -28,18 +28,15 @@ class RemoteOutputStreamServer(val out: OutputStream, port: Int = SOCKET_ANY_FRE
|
||||
: RemoteOutputStream,
|
||||
UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory)
|
||||
{
|
||||
override fun close(): Void? {
|
||||
override fun close() {
|
||||
out.close()
|
||||
return null
|
||||
}
|
||||
|
||||
override fun write(data: ByteArray, offset: Int, length: Int): Void? {
|
||||
override fun write(data: ByteArray, offset: Int, length: Int) {
|
||||
out.write(data, offset, length)
|
||||
return null
|
||||
}
|
||||
|
||||
override fun write(dataByte: Int): Void? {
|
||||
override fun write(dataByte: Int) {
|
||||
out.write(dataByte)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.rmi.RemoteException
|
||||
|
||||
interface CompilationResults : Remote {
|
||||
@Throws(RemoteException::class)
|
||||
fun add(compilationResultCategory: Int, value: Serializable): Void?
|
||||
fun add(compilationResultCategory: Int, value: Serializable)
|
||||
}
|
||||
|
||||
enum class CompilationResultCategory(val code: Int) {
|
||||
|
||||
@@ -56,13 +56,13 @@ interface CompilerCallbackServicesFacade : Remote {
|
||||
fun incrementalCache_getModuleMappingData(target: TargetId): ByteArray?
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalCache_registerInline(target: TargetId, fromPath: String, jvmSignature: String, toPath: String): Void?
|
||||
fun incrementalCache_registerInline(target: TargetId, fromPath: String, jvmSignature: String, toPath: String)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalCache_getClassFilePath(target: TargetId, internalClassName: String): String
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalCache_close(target: TargetId): Void?
|
||||
fun incrementalCache_close(target: TargetId)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalCache_getMultifileFacadeParts(target: TargetId, internalName: String): Collection<String>?
|
||||
@@ -73,7 +73,7 @@ interface CompilerCallbackServicesFacade : Remote {
|
||||
fun lookupTracker_requiresPosition(): Boolean
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun lookupTracker_record(lookups: Collection<LookupInfo>): Void?
|
||||
fun lookupTracker_record(lookups: Collection<LookupInfo>)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun lookupTracker_isDoNothing(): Boolean
|
||||
|
||||
@@ -25,7 +25,7 @@ interface CompilerServicesFacadeBase : Remote {
|
||||
* Reports different kind of diagnostic messages from compile daemon to compile daemon clients (jps, gradle, ...)
|
||||
*/
|
||||
@Throws(RemoteException::class)
|
||||
fun report(category: Int, severity: Int, message: String?, attachment: Serializable?): Void?
|
||||
fun report(category: Int, severity: Int, message: String?, attachment: Serializable?)
|
||||
}
|
||||
|
||||
enum class ReportCategory(val code: Int) {
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.rmi.RemoteException
|
||||
interface RemoteInputStream : Remote {
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun close(): Void?
|
||||
fun close()
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun read(length: Int): ByteArray
|
||||
|
||||
@@ -22,8 +22,8 @@ import java.rmi.RemoteException
|
||||
interface RemoteOperationsTracer : Remote {
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun before(id: String): Void?
|
||||
fun before(id: String)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun after(id: String): Void?
|
||||
fun after(id: String)
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ import java.rmi.RemoteException
|
||||
interface RemoteOutputStream : Remote {
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun close(): Void?
|
||||
fun close()
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun write(data: ByteArray, offset: Int, length: Int): Void?
|
||||
fun write(data: ByteArray, offset: Int, length: Int)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun write(dataByte: Int): Void?
|
||||
fun write(dataByte: Int)
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ class CompileServiceImpl(
|
||||
port = port.toString()))
|
||||
try {
|
||||
if (!runFile.createNewFile()) throw Exception("createNewFile returned false")
|
||||
} catch (e: Exception) {
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalStateException("Unable to create run file '${runFile.absolutePath}'", e)
|
||||
}
|
||||
runFile.deleteOnExit()
|
||||
@@ -366,7 +366,7 @@ class CompileServiceImpl(
|
||||
} as CLICompiler<CommonCompilerArguments>
|
||||
|
||||
val k2PlatformArgs = compiler.createArguments()
|
||||
parseCommandLineArguments(compilerArguments, k2PlatformArgs)
|
||||
parseCommandLineArguments(compilerArguments.asList(), k2PlatformArgs)
|
||||
val argumentParseError = validateArguments(k2PlatformArgs.errors)
|
||||
if (argumentParseError != null) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, argumentParseError)
|
||||
@@ -598,7 +598,7 @@ class CompileServiceImpl(
|
||||
try {
|
||||
body()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
catch (e: Throwable) {
|
||||
System.err.println("Exception in timer thread: " + e.message)
|
||||
e.printStackTrace(System.err)
|
||||
log.log(Level.SEVERE, "Exception in timer thread", e)
|
||||
@@ -609,7 +609,7 @@ class CompileServiceImpl(
|
||||
|
||||
if (state.delayedShutdownQueued.get()) return
|
||||
|
||||
val anyDead = state.sessions.cleanDead() && state.cleanDeadClients()
|
||||
val anyDead = state.sessions.cleanDead() || state.cleanDeadClients()
|
||||
|
||||
ifAliveUnit(minAliveness = Aliveness.LastSession) {
|
||||
when {
|
||||
@@ -619,7 +619,7 @@ class CompileServiceImpl(
|
||||
shutdownWithDelay()
|
||||
return
|
||||
}
|
||||
state.aliveClientsCount == 0 && compilationsCounter.get() > 0 -> {
|
||||
state.aliveClientsCount == 0 -> {
|
||||
log.info("No more clients left")
|
||||
shutdownWithDelay()
|
||||
return
|
||||
@@ -667,6 +667,7 @@ class CompileServiceImpl(
|
||||
|
||||
ifAliveUnit {
|
||||
|
||||
log.info("initiate elections")
|
||||
val aliveWithOpts = walkDaemons(File(daemonOptions.runFilesPathOrDefault), compilerId, runFile, filter = { _, p -> p != port }, report = { _, msg -> log.info(msg) }).toList()
|
||||
val comparator = compareByDescending<DaemonWithMetadata, DaemonJVMOptions>(DaemonJVMOptionsMemoryComparator(), { it.jvmOptions })
|
||||
.thenBy(FileAgeComparator()) { it.runFile }
|
||||
@@ -682,7 +683,7 @@ class CompileServiceImpl(
|
||||
}
|
||||
daemon.scheduleShutdown(true)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
catch (e: Throwable) {
|
||||
log.info("Cannot connect to a daemon, assuming dying ('${runFile.canonicalPath}'): ${e.message}")
|
||||
}
|
||||
}
|
||||
@@ -883,7 +884,7 @@ class CompileServiceImpl(
|
||||
return res
|
||||
}
|
||||
// TODO: consider possibilities to handle OutOfMemory
|
||||
catch (e: Exception) {
|
||||
catch (e: Throwable) {
|
||||
log.info("Error: $e")
|
||||
throw e
|
||||
}
|
||||
@@ -927,7 +928,7 @@ class CompileServiceImpl(
|
||||
try {
|
||||
body()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
catch (e: Throwable) {
|
||||
log.log(Level.SEVERE, "Exception", e)
|
||||
CompileService.CallResult.Error(e.message ?: "unknown")
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ open class KotlinJvmReplService(
|
||||
addJvmClasspathRoots(PathUtil.getKotlinPathsForCompiler().let { listOf(it.stdlibPath, it.reflectPath, it.scriptRuntimePath) })
|
||||
addJvmClasspathRoots(templateClasspath)
|
||||
put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script")
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE).apply {
|
||||
switchFlag(AnalysisFlags.skipMetadataVersionCheck, true)
|
||||
}
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlag.skipMetadataVersionCheck to true)
|
||||
)
|
||||
}
|
||||
|
||||
protected fun makeScriptDefinition(templateClasspath: List<File>, templateClassName: String): KotlinScriptDefinition? {
|
||||
@@ -66,7 +66,7 @@ open class KotlinJvmReplService(
|
||||
val cls = classloader.loadClass(templateClassName)
|
||||
val def = KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, null, null, emptyMap())
|
||||
messageCollector.report(INFO, "New script definition $templateClassName: files pattern = \"${def.scriptFilePattern}\", " +
|
||||
"resolver = ${def.resolver?.javaClass?.name}")
|
||||
"resolver = ${def.dependencyResolver.javaClass.name}")
|
||||
return def
|
||||
}
|
||||
catch (ex: ClassNotFoundException) {
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.frontend.java.di
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.builtins.JvmBuiltInsPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
@@ -32,8 +32,6 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.java.*
|
||||
import org.jetbrains.kotlin.load.java.components.*
|
||||
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
|
||||
import org.jetbrains.kotlin.load.java.sam.SamConversionResolverImpl
|
||||
import org.jetbrains.kotlin.load.java.sam.SamWithReceiverResolver
|
||||
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||
@@ -64,8 +62,6 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis(
|
||||
useImpl<SignaturePropagatorImpl>()
|
||||
useImpl<TraceBasedErrorReporter>()
|
||||
useImpl<PsiBasedExternalAnnotationResolver>()
|
||||
useInstance(SamWithReceiverResolver())
|
||||
useImpl<SamConversionResolverImpl>()
|
||||
useInstance(InternalFlexibleTypeTransformer)
|
||||
|
||||
useImpl<CompilerDeserializationConfiguration>()
|
||||
@@ -103,7 +99,7 @@ fun createContainerForLazyResolveWithJava(
|
||||
|
||||
useInstance(languageVersionSettings)
|
||||
|
||||
if (languageVersionSettings.isFlagEnabled(AnalysisFlags.loadJsr305Annotations)) {
|
||||
if (languageVersionSettings.getFlag(AnalysisFlag.loadJsr305Annotations).shouldReportError) {
|
||||
useImpl<AnnotationTypeQualifierResolverImpl>()
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -21,13 +21,16 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
|
||||
class SamConversionResolverImpl(val storageManager: StorageManager, val samWithReceiverResolver: SamWithReceiverResolver): SamConversionResolver {
|
||||
class SamConversionResolverImpl(
|
||||
storageManager: StorageManager,
|
||||
private val samWithReceiverResolvers: Iterable<SamWithReceiverResolver>
|
||||
): SamConversionResolver {
|
||||
private val functionTypesForSamInterfaces = storageManager.createCacheWithNullableValues<JavaClassDescriptor, SimpleType>()
|
||||
|
||||
override fun resolveFunctionTypeIfSamInterface(classDescriptor: JavaClassDescriptor): SimpleType? {
|
||||
return functionTypesForSamInterfaces.computeIfAbsent(classDescriptor) {
|
||||
val abstractMethod = SingleAbstractMethodUtils.getSingleAbstractMethodOrNull(classDescriptor) ?: return@computeIfAbsent null
|
||||
val shouldConvertFirstParameterToDescriptor = samWithReceiverResolver.shouldConvertFirstSamParameterToReceiver(abstractMethod)
|
||||
val shouldConvertFirstParameterToDescriptor = samWithReceiverResolvers.any { it.shouldConvertFirstSamParameterToReceiver(abstractMethod) }
|
||||
SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod, shouldConvertFirstParameterToDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,18 +18,6 @@ package org.jetbrains.kotlin.load.java.sam
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
|
||||
class SamWithReceiverResolver {
|
||||
private val extensions = mutableListOf<Extension>()
|
||||
|
||||
fun registerExtension(extension: Extension) {
|
||||
extensions += extension
|
||||
}
|
||||
|
||||
fun shouldConvertFirstSamParameterToReceiver(function: FunctionDescriptor): Boolean {
|
||||
return extensions.any { it.shouldConvertFirstSamParameterToReceiver(function) }
|
||||
}
|
||||
|
||||
interface Extension {
|
||||
fun shouldConvertFirstSamParameterToReceiver(function: FunctionDescriptor): Boolean
|
||||
}
|
||||
interface SamWithReceiverResolver {
|
||||
fun shouldConvertFirstSamParameterToReceiver(function: FunctionDescriptor): Boolean
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.load.java.components.SamConversionResolver;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
|
||||
@@ -57,29 +58,41 @@ public class SingleAbstractMethodUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static KotlinType getFunctionTypeForSamType(@NotNull KotlinType samType) {
|
||||
public static SimpleType getFunctionTypeForSamInterface(
|
||||
@NotNull JavaClassDescriptor clazz,
|
||||
@Nullable SamConversionResolver samResolver
|
||||
) {
|
||||
if (samResolver == null) {
|
||||
return clazz.getDefaultFunctionTypeForSamInterface();
|
||||
}
|
||||
|
||||
return samResolver.resolveFunctionTypeIfSamInterface(clazz);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static KotlinType getFunctionTypeForSamType(@NotNull KotlinType samType, @Nullable SamConversionResolver samResolver) {
|
||||
UnwrappedType unwrappedType = samType.unwrap();
|
||||
if (unwrappedType instanceof FlexibleType) {
|
||||
SimpleType lower = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getLowerBound());
|
||||
SimpleType upper = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getUpperBound());
|
||||
SimpleType lower = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getLowerBound(), samResolver);
|
||||
SimpleType upper = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getUpperBound(), samResolver);
|
||||
assert (lower == null) == (upper == null) : "Illegal flexible type: " + unwrappedType;
|
||||
|
||||
if (upper == null) return null;
|
||||
return KotlinTypeFactory.flexibleType(lower, upper);
|
||||
}
|
||||
else {
|
||||
return getFunctionTypeForSamType((SimpleType) unwrappedType);
|
||||
return getFunctionTypeForSamType((SimpleType) unwrappedType, samResolver);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static SimpleType getFunctionTypeForSamType(@NotNull SimpleType samType) {
|
||||
private static SimpleType getFunctionTypeForSamType(@NotNull SimpleType samType, @Nullable SamConversionResolver samResolver) {
|
||||
// e.g. samType == Comparator<String>?
|
||||
|
||||
ClassifierDescriptor classifier = samType.getConstructor().getDeclarationDescriptor();
|
||||
if (classifier instanceof JavaClassDescriptor) {
|
||||
// Function2<T, T, Int>
|
||||
SimpleType functionTypeDefault = ((JavaClassDescriptor) classifier).getFunctionTypeForSamInterface();
|
||||
SimpleType functionTypeDefault = getFunctionTypeForSamInterface((JavaClassDescriptor) classifier, samResolver);
|
||||
|
||||
if (functionTypeDefault != null) {
|
||||
SimpleType noProjectionsSamType = SingleAbstractMethodUtilsKt.nonProjectionParametrization(samType);
|
||||
@@ -157,7 +170,8 @@ public class SingleAbstractMethodUtils {
|
||||
@NotNull
|
||||
public static SamConstructorDescriptor createSamConstructorFunction(
|
||||
@NotNull DeclarationDescriptor owner,
|
||||
@NotNull JavaClassDescriptor samInterface
|
||||
@NotNull JavaClassDescriptor samInterface,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
assert getSingleAbstractMethodOrNull(samInterface) != null : samInterface;
|
||||
|
||||
@@ -165,7 +179,7 @@ public class SingleAbstractMethodUtils {
|
||||
|
||||
List<TypeParameterDescriptor> samTypeParameters = samInterface.getTypeConstructor().getParameters();
|
||||
SimpleType unsubstitutedSamType = samInterface.getDefaultType();
|
||||
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType);
|
||||
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType, samResolver);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -174,11 +188,12 @@ public class SingleAbstractMethodUtils {
|
||||
@NotNull JavaClassDescriptor samInterface,
|
||||
@NotNull SimpleFunctionDescriptorImpl samConstructor,
|
||||
@NotNull List<TypeParameterDescriptor> samTypeParameters,
|
||||
@NotNull KotlinType unsubstitutedSamType
|
||||
@NotNull KotlinType unsubstitutedSamType,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
TypeParameters typeParameters = recreateAndInitializeTypeParameters(samTypeParameters, samConstructor);
|
||||
|
||||
KotlinType parameterTypeUnsubstituted = getFunctionTypeForSamType(unsubstitutedSamType);
|
||||
KotlinType parameterTypeUnsubstituted = getFunctionTypeForSamType(unsubstitutedSamType, samResolver);
|
||||
assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + unsubstitutedSamType;
|
||||
KotlinType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
|
||||
assert parameterType != null : "couldn't substitute type: " + parameterTypeUnsubstituted +
|
||||
@@ -207,20 +222,21 @@ public class SingleAbstractMethodUtils {
|
||||
|
||||
public static SamConstructorDescriptor createTypeAliasSamConstructorFunction(
|
||||
@NotNull TypeAliasDescriptor typeAliasDescriptor,
|
||||
@NotNull SamConstructorDescriptor underlyingSamConstructor
|
||||
@NotNull SamConstructorDescriptor underlyingSamConstructor,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
SamTypeAliasConstructorDescriptorImpl result = new SamTypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingSamConstructor);
|
||||
|
||||
JavaClassDescriptor samInterface = underlyingSamConstructor.getBaseDescriptorForSynthetic();
|
||||
List<TypeParameterDescriptor> samTypeParameters = typeAliasDescriptor.getTypeConstructor().getParameters();
|
||||
SimpleType unsubstitutedSamType = typeAliasDescriptor.getExpandedType();
|
||||
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType);
|
||||
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType, samResolver);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isSamType(@NotNull KotlinType type) {
|
||||
return getFunctionTypeForSamType(type) != null;
|
||||
return getFunctionTypeForSamType(type, null) != null;
|
||||
}
|
||||
|
||||
public static boolean isSamAdapterNecessary(@NotNull FunctionDescriptor fun) {
|
||||
@@ -233,7 +249,10 @@ public class SingleAbstractMethodUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SamAdapterDescriptor<JavaMethodDescriptor> createSamAdapterFunction(@NotNull JavaMethodDescriptor original) {
|
||||
public static SamAdapterDescriptor<JavaMethodDescriptor> createSamAdapterFunction(
|
||||
@NotNull JavaMethodDescriptor original,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
SamAdapterFunctionDescriptor result = new SamAdapterFunctionDescriptor(original);
|
||||
return initSamAdapter(original, result, new FunctionInitializer() {
|
||||
@Override
|
||||
@@ -252,11 +271,14 @@ public class SingleAbstractMethodUtils {
|
||||
original.getVisibility()
|
||||
);
|
||||
}
|
||||
});
|
||||
}, samResolver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SamAdapterDescriptor<JavaClassConstructorDescriptor> createSamAdapterConstructor(@NotNull JavaClassConstructorDescriptor original) {
|
||||
public static SamAdapterDescriptor<JavaClassConstructorDescriptor> createSamAdapterConstructor(
|
||||
@NotNull JavaClassConstructorDescriptor original,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
SamAdapterClassConstructorDescriptor result = new SamAdapterClassConstructorDescriptor(original);
|
||||
return initSamAdapter(original, result, new FunctionInitializer() {
|
||||
@Override
|
||||
@@ -268,14 +290,15 @@ public class SingleAbstractMethodUtils {
|
||||
result.initialize(valueParameters, original.getVisibility());
|
||||
result.setReturnType(returnType);
|
||||
}
|
||||
});
|
||||
}, samResolver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static <F extends FunctionDescriptor> SamAdapterDescriptor<F> initSamAdapter(
|
||||
@NotNull F original,
|
||||
@NotNull SamAdapterDescriptor<F> adapter,
|
||||
@NotNull FunctionInitializer initializer
|
||||
@NotNull FunctionInitializer initializer,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), adapter);
|
||||
|
||||
@@ -288,7 +311,7 @@ public class SingleAbstractMethodUtils {
|
||||
", substitutor = " + substitutor;
|
||||
|
||||
|
||||
List<ValueParameterDescriptor> valueParameters = createValueParametersForSamAdapter(original, adapter, substitutor);
|
||||
List<ValueParameterDescriptor> valueParameters = createValueParametersForSamAdapter(original, adapter, substitutor, samResolver);
|
||||
|
||||
initializer.initialize(typeParameters.descriptors, valueParameters, returnType);
|
||||
|
||||
@@ -298,13 +321,14 @@ public class SingleAbstractMethodUtils {
|
||||
public static List<ValueParameterDescriptor> createValueParametersForSamAdapter(
|
||||
@NotNull FunctionDescriptor original,
|
||||
@NotNull FunctionDescriptor samAdapter,
|
||||
@NotNull TypeSubstitutor substitutor
|
||||
@NotNull TypeSubstitutor substitutor,
|
||||
@NotNull SamConversionResolver samResolver
|
||||
) {
|
||||
List<ValueParameterDescriptor> originalValueParameters = original.getValueParameters();
|
||||
List<ValueParameterDescriptor> valueParameters = new ArrayList<>(originalValueParameters.size());
|
||||
for (ValueParameterDescriptor originalParam : originalValueParameters) {
|
||||
KotlinType originalType = originalParam.getType();
|
||||
KotlinType functionType = getFunctionTypeForSamType(originalType);
|
||||
KotlinType functionType = getFunctionTypeForSamType(originalType, samResolver);
|
||||
KotlinType newTypeUnsubstituted = functionType != null ? functionType : originalType;
|
||||
KotlinType newType = substitutor.substitute(newTypeUnsubstituted, Variance.IN_VARIANCE);
|
||||
assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + substitutor;
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.text.CharacterIterator
|
||||
import java.text.StringCharacterIterator
|
||||
@@ -51,7 +53,7 @@ class BinaryClassSignatureParser(globalContext: ClassifierResolutionContext) {
|
||||
typeParameters.add(parseTypeParameter(signature, context))
|
||||
}
|
||||
signature.next()
|
||||
return typeParameters
|
||||
return typeParameters.compact()
|
||||
}
|
||||
|
||||
private fun parseTypeParameter(signature: CharacterIterator, context: ClassifierResolutionContext): JavaTypeParameter {
|
||||
@@ -148,7 +150,10 @@ class BinaryClassSignatureParser(globalContext: ClassifierResolutionContext) {
|
||||
|
||||
if (canonicalName.toString() == "java/lang/Object") return JAVA_LANG_OBJECT_CLASSIFIER_TYPE
|
||||
|
||||
return PlainJavaClassifierType({ context.resolveByInternalName(canonicalName.toString()) }, argumentGroups.reversed().flatten())
|
||||
return PlainJavaClassifierType(
|
||||
{ context.resolveByInternalName(canonicalName.toString()) },
|
||||
argumentGroups.reversed().flattenTo(arrayListOf()).compact()
|
||||
)
|
||||
}
|
||||
|
||||
private fun parseClassOrTypeVariableElement(signature: CharacterIterator, context: ClassifierResolutionContext): JavaType {
|
||||
|
||||
@@ -41,7 +41,7 @@ class BinaryJavaClass(
|
||||
) : ClassVisitor(ASM_API_VERSION_FOR_CLASS_READING), VirtualFileBoundJavaClass, BinaryJavaModifierListOwner, MapBasedJavaAnnotationOwner {
|
||||
lateinit var myInternalName: String
|
||||
|
||||
override val annotations: MutableCollection<JavaAnnotation> = mutableListOf()
|
||||
override val annotations: MutableCollection<JavaAnnotation> = ContainerUtil.newSmartList()
|
||||
override lateinit var typeParameters: List<JavaTypeParameter>
|
||||
override lateinit var supertypes: Collection<JavaClassifierType>
|
||||
override val methods = arrayListOf<JavaMethod>()
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -36,7 +37,7 @@ abstract class BinaryJavaMethodBase(
|
||||
) : JavaMember, MapBasedJavaAnnotationOwner, BinaryJavaModifierListOwner {
|
||||
override val annotationsByFqName by buildLazyValueForMap()
|
||||
|
||||
override val annotations: Collection<JavaAnnotation> = mutableListOf()
|
||||
override val annotations: Collection<JavaAnnotation> = ContainerUtil.newSmartList()
|
||||
|
||||
companion object {
|
||||
private class MethodInfo(
|
||||
@@ -79,7 +80,7 @@ abstract class BinaryJavaMethodBase(
|
||||
}
|
||||
|
||||
val parameterTypes = info.valueParameterTypes
|
||||
val parameterList = ContainerUtil.newSmartList<JavaValueParameter>()
|
||||
val parameterList = ContainerUtil.newArrayList<JavaValueParameter>()
|
||||
val paramCount = parameterTypes.size
|
||||
for (i in 0..paramCount - 1) {
|
||||
val type = parameterTypes[i]
|
||||
@@ -93,7 +94,10 @@ abstract class BinaryJavaMethodBase(
|
||||
BinaryJavaConstructor(access, containingClass, parameterList, info.typeParameters)
|
||||
else
|
||||
BinaryJavaMethod(
|
||||
access, containingClass, parameterList, info.typeParameters, Name.identifier(name), info.returnType
|
||||
access, containingClass,
|
||||
parameterList.compact(),
|
||||
info.typeParameters,
|
||||
Name.identifier(name), info.returnType
|
||||
)
|
||||
|
||||
val paramIgnoreCount = when {
|
||||
@@ -126,16 +130,18 @@ abstract class BinaryJavaMethodBase(
|
||||
|
||||
if (iterator.current() != '(') throw ClsFormatException()
|
||||
iterator.next()
|
||||
val paramTypes: List<JavaType>
|
||||
var paramTypes: List<JavaType>
|
||||
if (iterator.current() == ')') {
|
||||
paramTypes = emptyList()
|
||||
}
|
||||
else {
|
||||
paramTypes = ContainerUtil.newSmartList()
|
||||
paramTypes = ContainerUtil.newArrayList()
|
||||
while (iterator.current() != ')' && iterator.current() != CharacterIterator.DONE) {
|
||||
paramTypes.add(signatureParser.parseTypeString(iterator, context))
|
||||
}
|
||||
if (iterator.current() != ')') throw ClsFormatException()
|
||||
|
||||
paramTypes = (paramTypes as ArrayList).compact()
|
||||
}
|
||||
iterator.next()
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -42,7 +44,8 @@ class IncrementalPackageFragmentProvider(
|
||||
val storageManager: StorageManager,
|
||||
val deserializationComponents: DeserializationComponents,
|
||||
val incrementalCache: IncrementalCache,
|
||||
val target: TargetId
|
||||
val target: TargetId,
|
||||
private val kotlinClassFinder: KotlinClassFinder
|
||||
) : PackageFragmentProvider {
|
||||
val fqNameToPackageFragment =
|
||||
PackagePartClassUtils.getFilesWithCallables(sourceFiles)
|
||||
@@ -79,11 +82,17 @@ class IncrementalPackageFragmentProvider(
|
||||
partsInternalNames.mapNotNull { internalName ->
|
||||
incrementalCache.getPackagePartData(internalName)?.let { (data, strings) ->
|
||||
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(data, strings)
|
||||
|
||||
val jvmBinaryClass = kotlinClassFinder.findKotlinClass(
|
||||
ClassId.topLevel(FqName(internalName.replace('/', '.')))
|
||||
)
|
||||
|
||||
DeserializedPackageMemberScope(
|
||||
this, packageProto, nameResolver,
|
||||
JvmPackagePartSource(
|
||||
JvmClassName.byInternalName(internalName),
|
||||
JvmClassName.byFqNameWithoutInnerClasses(multifileClassFqName.asString())
|
||||
JvmClassName.byFqNameWithoutInnerClasses(multifileClassFqName.asString()),
|
||||
knownJvmBinaryClass = jvmBinaryClass
|
||||
),
|
||||
deserializationComponents, classNames = { emptyList() }
|
||||
)
|
||||
|
||||
@@ -100,8 +100,6 @@ object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
||||
useBuiltInsProvider = false // TODO: load built-ins from module dependencies in IDE
|
||||
)
|
||||
|
||||
StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(container, moduleInfo) }
|
||||
|
||||
val resolveSession = container.get<ResolveSession>()
|
||||
val javaDescriptorResolver = container.get<JavaDescriptorResolver>()
|
||||
|
||||
|
||||
@@ -34,8 +34,9 @@ import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.checkers.ClassifierUsageChecker
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver.AccessError.*
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||
|
||||
@@ -61,33 +62,19 @@ class JvmModuleAccessibilityChecker(project: Project) : CallChecker {
|
||||
): Diagnostic? {
|
||||
val referencedFile = findVirtualFile(targetClassOrPackage, originalDescriptor) ?: return null
|
||||
|
||||
// TODO: do not resolve our JavaModule every time, invent a way to obtain it from ModuleDescriptor and do it once in constructor
|
||||
val ourModule = fileFromOurModule?.let(moduleResolver::findJavaModule)
|
||||
val theirModule = moduleResolver.findJavaModule(referencedFile)
|
||||
val referencedPackageFqName =
|
||||
DescriptorUtils.getParentOfType(targetClassOrPackage, PackageFragmentDescriptor::class.java, false)?.fqName
|
||||
val diagnostic = moduleResolver.checkAccessibility(fileFromOurModule, referencedFile, referencedPackageFqName)
|
||||
|
||||
// If we're both in the unnamed module, it's OK, no error should be reported
|
||||
if (ourModule == null && theirModule == null) return null
|
||||
|
||||
if (theirModule == null) {
|
||||
// We should probably prohibit this usage according to JPMS (named module cannot use types from unnamed module),
|
||||
// but we cannot be sure that a module without module-info.java is going to be actually used as an unnamed module.
|
||||
// It could also be an automatic module, in which case it would be read by every module.
|
||||
return null
|
||||
return when (diagnostic) {
|
||||
is ModuleDoesNotReadUnnamedModule ->
|
||||
JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE.on(reportOn)
|
||||
is ModuleDoesNotReadModule ->
|
||||
JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE.on(reportOn, diagnostic.dependencyModuleName)
|
||||
is ModuleDoesNotExportPackage ->
|
||||
JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE.on(reportOn, diagnostic.dependencyModuleName, referencedPackageFqName!!.asString())
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (ourModule?.name == theirModule.name) return null
|
||||
|
||||
if (ourModule != null && !moduleResolver.moduleGraph.reads(ourModule.name, theirModule.name)) {
|
||||
return ErrorsJvm.JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE.on(reportOn, theirModule.name)
|
||||
}
|
||||
|
||||
val containingPackage = DescriptorUtils.getParentOfType(targetClassOrPackage, PackageFragmentDescriptor::class.java, false)
|
||||
val fqName = containingPackage?.fqName ?: return null
|
||||
if (!theirModule.exports(fqName) && (ourModule == null || !theirModule.exportsTo(fqName, ourModule.name))) {
|
||||
return ErrorsJvm.JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE.on(reportOn, theirModule.name, fqName.asString())
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun findVirtualFile(
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.getContainingKotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
|
||||
object ObsoleteABIForInlineSuspendFunctionCallChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
val candidateDescriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
|
||||
if (!candidateDescriptor.isSuspend || !candidateDescriptor.isInline) return
|
||||
|
||||
val jvmBytecodeVersion = candidateDescriptor.getContainingKotlinJvmBinaryClass()?.classHeader?.bytecodeVersion ?: return
|
||||
|
||||
if (!jvmBytecodeVersion.isAtLeast(1, 0, 2)) {
|
||||
context.trace.report(ErrorsJvm.OBSOLETE_SUSPEND_INLINE_FUNCTIONS_ABI.on(reportOn))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,9 +112,9 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(INTERFACE_STATIC_METHOD_CALL_FROM_JAVA6_TARGET, "Calls to static methods in Java interfaces are deprecated in JVM target 1.6. Recompile with '-jvm-target 1.8'");
|
||||
|
||||
MAP.put(INLINE_FROM_HIGHER_PLATFORM, "Cannot inline bytecode built with {0} into bytecode that is being built with {1}. Please specify proper ''-jvm-target'' option", STRING, STRING);
|
||||
MAP.put(OBSOLETE_SUSPEND_INLINE_FUNCTIONS_ABI, "Cannot inline suspend function built with compiler version less than 1.1.4/1.2-M1");
|
||||
|
||||
MAP.put(JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE, "Symbol is declared in module ''{0}'' which current module does not depend on", STRING);
|
||||
MAP.put(JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE, "Symbol is declared in unnamed module which is not read by current module");
|
||||
MAP.put(JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE, "Symbol is declared in module ''{0}'' which does not export package ''{1}''", STRING, STRING);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,9 +93,9 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<PsiElement> INTERFACE_STATIC_METHOD_CALL_FROM_JAVA6_TARGET = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory2<PsiElement, String, String> INLINE_FROM_HIGHER_PLATFORM = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> OBSOLETE_SUSPEND_INLINE_FUNCTIONS_ABI = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, String> JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> JAVA_MODULE_DOES_NOT_READ_UNNAMED_MODULE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, String, String> JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.PsiModifier
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.utils.compactIfPossible
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.ModuleVisitor
|
||||
@@ -74,14 +74,15 @@ class JavaModuleInfo(
|
||||
}
|
||||
|
||||
override fun visitExport(packageFqName: String, access: Int, modules: Array<String>?) {
|
||||
exports.add(Exports(FqName(packageFqName), modules?.toList().orEmpty()))
|
||||
// For some reason, '/' is the delimiter in packageFqName here
|
||||
exports.add(Exports(FqName(packageFqName.replace('/', '.')), modules?.toList().orEmpty()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ClassReader.SKIP_DEBUG or ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
|
||||
|
||||
return if (moduleName != null)
|
||||
JavaModuleInfo(moduleName!!, requires.compactIfPossible(), exports.compactIfPossible())
|
||||
JavaModuleInfo(moduleName!!, requires.compact(), exports.compact())
|
||||
else null
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user