mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-11 00:21:31 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d84f225ab |
2
.idea/artifacts/KotlinAndroidExtensions.xml
generated
2
.idea/artifacts/KotlinAndroidExtensions.xml
generated
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="ArtifactManager">
|
||||
<artifact name="KotlinAndroidExtensions">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensions</output-path>
|
||||
@@ -15,7 +14,6 @@
|
||||
<element id="archive" name="android-compiler-plugin.jar">
|
||||
<element id="module-output" name="android-compiler-plugin" />
|
||||
</element>
|
||||
<element id="file-copy" path="$PROJECT_DIR$/dist/kotlinc/lib/kotlin-runtime.jar" />
|
||||
</element>
|
||||
</root>
|
||||
</artifact>
|
||||
|
||||
3
.idea/artifacts/KotlinJpsPlugin.xml
generated
3
.idea/artifacts/KotlinJpsPlugin.xml
generated
@@ -19,9 +19,6 @@
|
||||
<element id="module-output" name="util" />
|
||||
<element id="module-output" name="util.runtime" />
|
||||
<element id="file-copy" path="$PROJECT_DIR$/resources/kotlinManifest.properties" />
|
||||
<element id="module-output" name="kotlinr" />
|
||||
<element id="module-output" name="rmi-interface" />
|
||||
<element id="module-output" name="deserialization" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
3
.idea/artifacts/KotlinPlugin.xml
generated
3
.idea/artifacts/KotlinPlugin.xml
generated
@@ -44,9 +44,6 @@
|
||||
<element id="module-output" name="idea-core" />
|
||||
<element id="module-output" name="idea-js" />
|
||||
<element id="module-output" name="container" />
|
||||
<element id="module-output" name="rmi-interface" />
|
||||
<element id="module-output" name="kotlinr" />
|
||||
<element id="module-output" name="idea-repl" />
|
||||
</element>
|
||||
<element id="library" level="project" name="javax.inject" />
|
||||
<element id="directory" name="jps">
|
||||
|
||||
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -26,4 +26,4 @@
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="-target 1.6" />
|
||||
</component>
|
||||
</project>
|
||||
</project>
|
||||
2
.idea/dictionaries/abreslav.xml
generated
2
.idea/dictionaries/abreslav.xml
generated
@@ -2,14 +2,12 @@
|
||||
<dictionary name="abreslav">
|
||||
<words>
|
||||
<w>accessor</w>
|
||||
<w>covariantly</w>
|
||||
<w>deserialized</w>
|
||||
<w>dominator</w>
|
||||
<w>inferrer</w>
|
||||
<w>iterable</w>
|
||||
<w>nondeterministic</w>
|
||||
<w>nullable</w>
|
||||
<w>overridable</w>
|
||||
<w>pseudocode</w>
|
||||
<w>substitutor</w>
|
||||
<w>subtyping</w>
|
||||
|
||||
2
.idea/dictionaries/bashor.xml
generated
2
.idea/dictionaries/bashor.xml
generated
@@ -2,8 +2,6 @@
|
||||
<dictionary name="bashor">
|
||||
<words>
|
||||
<w>ctor</w>
|
||||
<w>lookups</w>
|
||||
<w>unescape</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
|
||||
3
.idea/dictionaries/valentin.xml
generated
3
.idea/dictionaries/valentin.xml
generated
@@ -4,14 +4,11 @@
|
||||
<w>decapitalize</w>
|
||||
<w>delegator</w>
|
||||
<w>funs</w>
|
||||
<w>immediates</w>
|
||||
<w>initializers</w>
|
||||
<w>inserter</w>
|
||||
<w>negatable</w>
|
||||
<w>pparent</w>
|
||||
<w>prioritizer</w>
|
||||
<w>processings</w>
|
||||
<w>rbrace</w>
|
||||
<w>rbracket</w>
|
||||
<w>renderers</w>
|
||||
<w>rparenth</w>
|
||||
|
||||
7
.idea/encodings.xml
generated
7
.idea/encodings.xml
generated
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false">
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
||||
|
||||
2
.idea/libraries/android_plugin.xml
generated
2
.idea/libraries/android_plugin.xml
generated
@@ -9,7 +9,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib" recursive="false" />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib/jps" recursive="false" />
|
||||
|
||||
2
.idea/libraries/copyright_plugin.xml
generated
2
.idea/libraries/copyright_plugin.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/coverage_plugin.xml
generated
2
.idea/libraries/coverage_plugin.xml
generated
@@ -7,7 +7,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/gradle_and_groovy_plugin.xml
generated
2
.idea/libraries/gradle_and_groovy_plugin.xml
generated
@@ -10,7 +10,7 @@
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/plugins/gradle/lib" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/plugins/gradle/lib" recursive="false" />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/plugins/Groovy/lib" recursive="false" />
|
||||
|
||||
4
.idea/libraries/idea_full.xml
generated
4
.idea/libraries/idea_full.xml
generated
@@ -2,7 +2,7 @@
|
||||
<library name="idea-full">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/lib" />
|
||||
@@ -12,7 +12,7 @@
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/cli-parser-1.1.1-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/lib" recursive="false" />
|
||||
</library>
|
||||
|
||||
4
.idea/libraries/intellij_core.xml
generated
4
.idea/libraries/intellij_core.xml
generated
@@ -2,7 +2,7 @@
|
||||
<library name="intellij-core">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/ideaSDK/core" />
|
||||
@@ -11,7 +11,7 @@
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/core" recursive="false" />
|
||||
</library>
|
||||
|
||||
4
.idea/libraries/intellij_core_analysis.xml
generated
4
.idea/libraries/intellij_core_analysis.xml
generated
@@ -2,7 +2,7 @@
|
||||
<library name="intellij-core-analysis">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/core-analysis/intellij-core-analysis.jar!/" />
|
||||
@@ -11,7 +11,7 @@
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/intellilang_plugin.xml
generated
2
.idea/libraries/intellilang_plugin.xml
generated
@@ -5,7 +5,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/java_i18n.xml
generated
2
.idea/libraries/java_i18n.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/jps.xml
generated
2
.idea/libraries/jps.xml
generated
@@ -9,7 +9,7 @@
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/protobuf-java-2.5.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/jps" recursive="false" />
|
||||
</library>
|
||||
|
||||
2
.idea/libraries/jps_model.xml
generated
2
.idea/libraries/jps_model.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/jps_test.xml
generated
2
.idea/libraries/jps_test.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/jps/test" recursive="false" />
|
||||
</library>
|
||||
|
||||
2
.idea/libraries/junit_plugin.xml
generated
2
.idea/libraries/junit_plugin.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/maven.xml
generated
2
.idea/libraries/maven.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/plugins/maven/lib" recursive="false" />
|
||||
</library>
|
||||
|
||||
2
.idea/libraries/properties.xml
generated
2
.idea/libraries/properties.xml
generated
@@ -8,7 +8,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/libraries/testng_plugin.xml
generated
2
.idea/libraries/testng_plugin.xml
generated
@@ -9,7 +9,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
8
.idea/libraries/trove4j.xml
generated
8
.idea/libraries/trove4j.xml
generated
@@ -8,10 +8,10 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/core/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/generated/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/test/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/util/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/trove4j_src.jar!/core/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/trove4j_src.jar!/test/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/trove4j_src.jar!/util/src" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/trove4j_src.jar!/generated/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
11
.idea/misc.xml
generated
11
.idea/misc.xml
generated
@@ -7,9 +7,6 @@
|
||||
</component>
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="javax.inject.Inject" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="FacetAutodetectingManager">
|
||||
<autodetection-disabled>
|
||||
@@ -45,6 +42,11 @@
|
||||
<option value="$PROJECT_DIR$/confluence/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="ignoredFiles">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/confluence/pom.xml" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectResources">
|
||||
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
|
||||
@@ -52,9 +54,6 @@
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="SuppressABINotification">
|
||||
<option name="isSuppressed" value="true" />
|
||||
</component>
|
||||
<component name="WebServicesPlugin" addRequiredLibraries="true" />
|
||||
<component name="com.sixrr.metrics.MetricsReloaded">
|
||||
<option name="selectedProfile" value="" />
|
||||
|
||||
6
.idea/modules.xml
generated
6
.idea/modules.xml
generated
@@ -17,9 +17,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/builtins-serializer/builtins-serializer.iml" filepath="$PROJECT_DIR$/compiler/builtins-serializer/builtins-serializer.iml" group="compiler/cli" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/cli/cli.iml" filepath="$PROJECT_DIR$/compiler/cli/cli.iml" group="compiler/cli" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/cli/cli-common/cli-common.iml" filepath="$PROJECT_DIR$/compiler/cli/cli-common/cli-common.iml" group="compiler/cli" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/cli/cli-runner/cli-runner.iml" filepath="$PROJECT_DIR$/compiler/cli/cli-runner/cli-runner.iml" group="compiler/cli" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/tests/compiler-tests.iml" filepath="$PROJECT_DIR$/compiler/tests/compiler-tests.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/conditional-preprocessor/conditional-preprocessor.iml" filepath="$PROJECT_DIR$/compiler/conditional-preprocessor/conditional-preprocessor.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/container/container.iml" filepath="$PROJECT_DIR$/compiler/container/container.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/descriptor.loader.java/descriptor.loader.java.iml" filepath="$PROJECT_DIR$/core/descriptor.loader.java/descriptor.loader.java.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/descriptors/descriptors.iml" filepath="$PROJECT_DIR$/core/descriptors/descriptors.iml" group="core" />
|
||||
@@ -37,7 +35,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-js/idea-js.iml" filepath="$PROJECT_DIR$/idea/idea-js/idea-js.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea-runner/idea-runner.iml" filepath="$PROJECT_DIR$/idea-runner/idea-runner.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" filepath="$PROJECT_DIR$/idea/idea-test-framework/idea-test-framework.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" filepath="$PROJECT_DIR$/compiler/preloader/instrumentation/instrumentation.iml" group="compiler/cli" />
|
||||
@@ -53,13 +50,10 @@
|
||||
<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$/idea/kotlin-android-plugin/kotlin-android-plugin.iml" filepath="$PROJECT_DIR$/idea/kotlin-android-plugin/kotlin-android-plugin.iml" group="ide" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/rmi/kotlinr/kotlinr.iml" filepath="$PROJECT_DIR$/compiler/rmi/kotlinr/kotlinr.iml" group="rmi" />
|
||||
<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$/compiler/plugin-api/plugin-api.iml" filepath="$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/preloader.iml" filepath="$PROJECT_DIR$/compiler/preloader/preloader.iml" group="compiler/cli" />
|
||||
<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/rmi/rmi-interface/rmi-interface.iml" filepath="$PROJECT_DIR$/compiler/rmi/rmi-interface/rmi-interface.iml" group="rmi" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/rmi/rmi-server/rmi-server.iml" filepath="$PROJECT_DIR$/compiler/rmi/rmi-server/rmi-server.iml" group="rmi" />
|
||||
<module fileurl="file://$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" filepath="$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" group="core" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/serialization/serialization.iml" filepath="$PROJECT_DIR$/compiler/serialization/serialization.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/util/util.iml" filepath="$PROJECT_DIR$/compiler/util/util.iml" />
|
||||
|
||||
7
.idea/runConfigurations/All_Tests.xml
generated
7
.idea/runConfigurations/All_Tests.xml
generated
@@ -13,7 +13,7 @@
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="package" />
|
||||
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx900m -XX:MaxPermSize=400m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m" />
|
||||
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx900m -XX:MaxPermSize=320m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=64m" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
@@ -34,6 +34,9 @@
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Debug" />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method />
|
||||
<method>
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="compiler-quick" />
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="runtime" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
3
.idea/runConfigurations/IDEA.xml
generated
3
.idea/runConfigurations/IDEA.xml
generated
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="IDEA" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin,$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensions -Dkotlin.internal.mode.enabled=true" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="IDEA (No ProcessCanceledException)" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=250m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=250m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin,$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensions -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
26
.idea/runConfigurations/IDEA__win_.xml
generated
26
.idea/runConfigurations/IDEA__win_.xml
generated
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="IDEA (win)" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=${JAVA_HOME}\lib\tools.jar,../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="1.7" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="idea-runner" />
|
||||
<envs />
|
||||
<method>
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="KotlinPlugin" />
|
||||
</option>
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="KotlinAndroidExtensions" />
|
||||
</option>
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/idea-runner/runner.xml" target="force-enable-kotlin-plugin" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
31
.idea/runConfigurations/Update_Dist_Run.xml
generated
31
.idea/runConfigurations/Update_Dist_Run.xml
generated
@@ -1,31 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Update-Dist-Run" type="Application" factoryName="Application" singleton="true">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="idea-runner" />
|
||||
<envs />
|
||||
<method>
|
||||
<option name="Make" enabled="false" />
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="clean_idea_output" />
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/update_dependencies.xml" target="update" />
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/build.xml" target="dist" />
|
||||
<option name="MakeProject" enabled="true" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Generate Tests" run_configuration_type="Application" />
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="KotlinPlugin" />
|
||||
</option>
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="KotlinAndroidExtensions" />
|
||||
</option>
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/idea_runner/runner.xml" target="force_enable_kotlin_plugin" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -47,4 +47,4 @@
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
</module>
|
||||
|
||||
18
ReadMe.md
18
ReadMe.md
@@ -8,12 +8,12 @@ Welcome to [Kotlin](http://kotlinlang.org/)! Some handy links:
|
||||
|
||||
* [Kotlin Site](http://kotlinlang.org/)
|
||||
* [Getting Started Guide](http://kotlinlang.org/docs/tutorials/getting-started.html)
|
||||
* [Try Kotlin](http://try.kotlinlang.org/)
|
||||
* [Web Demo](http://kotlin-demo.jetbrains.com/)
|
||||
* [API](http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/index.html)
|
||||
* [Issue Tracker](http://youtrack.jetbrains.com/issues/KT)
|
||||
* [Forum](http://devnet.jetbrains.net/community/kotlin?view=discussions)
|
||||
* [Kotlin Blog](http://blog.jetbrains.com/kotlin/)
|
||||
* [Follow Kotlin on Twitter](https://twitter.com/kotlin)
|
||||
* [Follow Kotlin on Twitter](http://twitter.com/#!/project_kotlin)
|
||||
* [TeamCity CI build](https://teamcity.jetbrains.com/project.html?tab=projectOverview&projectId=Kotlin)
|
||||
|
||||
## Editing Kotlin
|
||||
@@ -35,7 +35,7 @@ which will setup the dependencies on
|
||||
Then, you need to run
|
||||
|
||||
ant -f build.xml
|
||||
|
||||
|
||||
which will build the binaries of the compiler and put them into the 'dist' directory. You may need to increase the **heap size** for Ant using
|
||||
[ANT_OPTS](http://www.liferay.com/community/wiki/-/wiki/Main/Ant+opts).
|
||||
|
||||
@@ -87,7 +87,7 @@ You can now open any Kotlin based projects.
|
||||
**Note for contributors**: If you are planning to contribute to Kotlin project you probably want to have locally the same version of plugin that build server is using for building.
|
||||
As this version is constantly moving, the best way to always be updated is to let IntelliJ IDEA notify you when it is time to renew your plugin.
|
||||
|
||||
Open
|
||||
Open
|
||||
|
||||
Preferences -> Plugins -> Browse Repositories -> Manage Repositories...
|
||||
|
||||
@@ -116,7 +116,7 @@ Also the [JavaScript translation](https://github.com/JetBrains/kotlin/blob/maste
|
||||
|
||||
The Kotlin compiler is written in Java and Kotlin (we gradually migrate more and more of it to pure Kotlin). So the easiest way to work on the compiler or IntelliJ IDEA plugin is
|
||||
|
||||
* download a clean [IDEA 15 EAP build](https://confluence.jetbrains.com/display/IDEADEV/IDEA+15+EAP)
|
||||
* download a clean [IDEA 14 EAP build](http://confluence.jetbrains.com/display/IDEADEV/IDEA+14+EAP)
|
||||
* [install the Kotlin plugin](#pre-built-plugin)
|
||||
* open the [root kotlin project](https://github.com/JetBrains/kotlin) in IDEA (opening the kotlin directory)
|
||||
|
||||
@@ -129,7 +129,7 @@ You can now run the various Run/Debug Configurations such as
|
||||
|
||||
## If you want to work on the Kotlin libraries
|
||||
|
||||
* download a clean [IDEA 15 EAP build](https://confluence.jetbrains.com/display/IDEADEV/IDEA+15+EAP)
|
||||
* download a clean [IDEA 14 EAP build](http://confluence.jetbrains.com/display/IDEADEV/IDEA+14+EAP)
|
||||
* [install the Kotlin plugin](#pre-built-plugin)
|
||||
* open the [kotlin libraries project](https://github.com/JetBrains/kotlin/tree/master/libraries)
|
||||
|
||||
@@ -145,10 +145,8 @@ Some of the code in the standard library is created by generating code from temp
|
||||
The best way to submit a patch is to [fork the project on github](http://help.github.com/fork-a-repo/) then send us a
|
||||
[pull request](http://help.github.com/send-pull-requests/) via [github](http://github.com).
|
||||
|
||||
If you create your own fork, it might help to enable rebase by default
|
||||
when you pull by executing `git config --global pull.rebase
|
||||
true`. This will avoid your local repo having too many merge commits
|
||||
which will help keep your pull request simple and easy to apply.
|
||||
If you create your own fork, it might help to [enable rebase by default when you pull](http://d.strelau.net/post/47338904/git-pull-rebase-by-default)
|
||||
which will avoid your local repo having too many merge commits which will help keep your pull request simple and easy to apply.
|
||||
|
||||
## Commit comments
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<project name="Kotlin CI Steps" default="none">
|
||||
<project name="Jet CI Steps" default="none">
|
||||
<import file="build.xml" optional="false"/>
|
||||
<import file="replicate_versions.xml" optional="false"/>
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
<print-file-size-statistic path="${output}" file-name="stdlib.meta.js"/>
|
||||
</target>
|
||||
|
||||
<target name="post_build" depends="zipArtifacts, revertTemplateFiles, printStatistics, remove_internal_artifacts, dont_remove_internal_artifacts"/>
|
||||
<target name="post_build" depends="zipArtifacts, revertTemplateFiles, printStatistics, remove_internal_artifacts"/>
|
||||
|
||||
<target name="none">
|
||||
<fail message="Either specify pre_build or post_build"/>
|
||||
@@ -187,23 +187,27 @@
|
||||
</and>
|
||||
</condition>
|
||||
|
||||
<target name="remove_internal_artifacts" description="Remove internal artifacts for rr/* branches, but store them for rr/internal/*" if="need.remove.artifacts">
|
||||
<echo message="Remove internal artifacts" />
|
||||
<target name="remove_internal_artifacts" description="Remove internal artifacts for rr/* branches, but store them for rr/internal/*">
|
||||
<if>
|
||||
<istrue value="${need.remove.artifacts}"/>
|
||||
<then>
|
||||
<echo message="Remove internal artifacts" />
|
||||
|
||||
<delete failonerror="false" verbose="true">
|
||||
<fileset dir="dist">
|
||||
<include name="kotlin-compiler-before-shrink.jar"/>
|
||||
<include name="kotlin-for-upsource.jar"/>
|
||||
<include name="kotlin-for-upsource-sources.jar"/>
|
||||
<include name="kotlin-test-data.zip"/>
|
||||
</fileset>
|
||||
<fileset dir="out/artifacts/internal">
|
||||
<include name="kotlin-ide-common.jar"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="dont_remove_internal_artifacts" unless="need.remove.artifacts">
|
||||
<echo message="Internal artifacts left untouched"/>
|
||||
<delete failonerror="false" verbose="true">
|
||||
<fileset dir="dist">
|
||||
<include name="kotlin-compiler-before-shrink.jar"/>
|
||||
<include name="kotlin-for-upsource.jar"/>
|
||||
<include name="kotlin-for-upsource-sources.jar"/>
|
||||
<include name="kotlin-test-data.zip"/>
|
||||
</fileset>
|
||||
<fileset dir="out/artifacts/internal">
|
||||
<include name="kotlin-ide-common.jar"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
</then>
|
||||
<else>
|
||||
<echo message="Internal artifacts left untouched"/>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -25,7 +25,6 @@ public class Kotlin2JvmTask : KotlinCompilerBaseTask() {
|
||||
|
||||
public var externalAnnotations: Path? = null
|
||||
public var includeRuntime: Boolean = true
|
||||
public var moduleName: String? = null
|
||||
|
||||
private var compileClasspath: Path? = null
|
||||
|
||||
@@ -70,16 +69,6 @@ public class Kotlin2JvmTask : KotlinCompilerBaseTask() {
|
||||
args.add(it.list().join(pathSeparator))
|
||||
}
|
||||
|
||||
|
||||
if (moduleName == null) {
|
||||
moduleName = defaultModuleName
|
||||
}
|
||||
|
||||
moduleName?.let {
|
||||
args.add("-module-name")
|
||||
args.add(moduleName!!)
|
||||
}
|
||||
|
||||
if (noStdlib) args.add("-no-stdlib")
|
||||
if (includeRuntime) args.add("-include-runtime")
|
||||
}
|
||||
|
||||
@@ -17,17 +17,16 @@
|
||||
package org.jetbrains.kotlin.ant
|
||||
|
||||
import org.apache.tools.ant.AntClassLoader
|
||||
import org.apache.tools.ant.Task
|
||||
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
|
||||
import org.jetbrains.kotlin.preloading.Preloader
|
||||
import java.io.File
|
||||
import java.lang.ref.SoftReference
|
||||
import java.net.JarURLConnection
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
object KotlinAntTaskUtil {
|
||||
private var classLoaderRef = SoftReference<ClassLoader?>(null)
|
||||
|
||||
private val libPath: File by lazy {
|
||||
private val libPath: File by Delegates.lazy {
|
||||
// Find path of kotlin-ant.jar in the filesystem and find kotlin-compiler.jar in the same directory
|
||||
val resourcePath = "/" + javaClass.getName().replace('.', '/') + ".class"
|
||||
val jarConnection = javaClass.getResource(resourcePath).openConnection() as? JarURLConnection
|
||||
@@ -37,11 +36,11 @@ object KotlinAntTaskUtil {
|
||||
antTaskJarPath.getParentFile()
|
||||
}
|
||||
|
||||
val compilerJar: File by lazy {
|
||||
val compilerJar: File by Delegates.lazy {
|
||||
File(libPath, "kotlin-compiler.jar").assertExists()
|
||||
}
|
||||
|
||||
val runtimeJar: File by lazy {
|
||||
val runtimeJar: File by Delegates.lazy {
|
||||
File(libPath, "kotlin-runtime.jar").assertExists()
|
||||
}
|
||||
|
||||
@@ -52,21 +51,16 @@ object KotlinAntTaskUtil {
|
||||
return this
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getOrCreateClassLoader(): ClassLoader {
|
||||
synchronized fun getOrCreateClassLoader(): ClassLoader {
|
||||
val cached = classLoaderRef.get()
|
||||
if (cached != null) return cached
|
||||
|
||||
val myLoader = javaClass.classLoader
|
||||
val myLoader = javaClass.getClassLoader()
|
||||
if (myLoader !is AntClassLoader) return myLoader
|
||||
|
||||
val classLoader = ClassPreloadingUtils.preloadClasses(listOf(compilerJar), Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE, myLoader, null)
|
||||
val classLoader = ClassPreloadingUtils.preloadClasses(listOf(compilerJar), 4096, myLoader, null)
|
||||
classLoaderRef = SoftReference(classLoader)
|
||||
|
||||
return classLoader
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public val Task.defaultModuleName: String?
|
||||
get() = owningTarget?.name ?: project?.name
|
||||
@@ -38,19 +38,12 @@ public class KotlinCompilerAdapter extends Javac13 {
|
||||
private static final List<String> KOTLIN_EXTENSIONS = Arrays.asList("kt", "kts");
|
||||
|
||||
private Path externalAnnotations;
|
||||
|
||||
private String moduleName;
|
||||
|
||||
public List<Commandline.Argument> additionalArguments = new ArrayList<Commandline.Argument>(0);
|
||||
|
||||
public void setExternalAnnotations(Path externalAnnotations) {
|
||||
this.externalAnnotations = externalAnnotations;
|
||||
}
|
||||
|
||||
public void setModuleName(String moduleName) {
|
||||
this.moduleName = moduleName;
|
||||
}
|
||||
|
||||
public Path createExternalAnnotations() {
|
||||
if (externalAnnotations == null) {
|
||||
externalAnnotations = new Path(getProject());
|
||||
@@ -92,11 +85,6 @@ public class KotlinCompilerAdapter extends Javac13 {
|
||||
|
||||
kotlinc.setExternalAnnotations(externalAnnotations);
|
||||
|
||||
if (moduleName == null) {
|
||||
moduleName = AntPackage.getDefaultModuleName(javac);
|
||||
}
|
||||
kotlinc.setModuleName(moduleName);
|
||||
|
||||
kotlinc.getAdditionalArguments().addAll(additionalArguments);
|
||||
|
||||
// Javac13#execute passes everything in compileList to javac, which doesn't recognize .kt files
|
||||
|
||||
@@ -34,7 +34,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
|
||||
public var nowarn: Boolean = false
|
||||
public var verbose: Boolean = false
|
||||
public var printVersion: Boolean = false
|
||||
public var failOnError: Boolean = true
|
||||
public var failOnError: Boolean = false
|
||||
|
||||
public var noStdlib: Boolean = false
|
||||
|
||||
|
||||
266
build.xml
266
build.xml
@@ -1,4 +1,6 @@
|
||||
<project name="Kotlin" default="dist" xmlns:if="ant:if" xmlns:unless="ant:unless">
|
||||
<project name="Kotlin" default="dist">
|
||||
<include file="jslib_files.xml" />
|
||||
|
||||
<property file="resources/kotlinManifest.properties"/>
|
||||
|
||||
<!-- Set to false to disable proguard run on kotlin-compiler.jar. Speeds up the build -->
|
||||
@@ -14,7 +16,6 @@
|
||||
<property name="bootstrap.reflect" value="${bootstrap.compiler.home}/lib/kotlin-reflect.jar"/>
|
||||
|
||||
<property name="output" value="${basedir}/dist"/>
|
||||
<property name="intermediate-sources" value="out/src" />
|
||||
<property name="kotlin-home" value="${output}/kotlinc"/>
|
||||
<property name="build.number" value="snapshot"/>
|
||||
<property name="bootstrap.build.no.tests" value="false"/>
|
||||
@@ -38,8 +39,6 @@
|
||||
</or>
|
||||
</condition>
|
||||
|
||||
<include file="jslib_files.xml" />
|
||||
|
||||
<!--
|
||||
The compiler produced on the first step of the build (Bootstrap No Tests) is only guaranteed to work against the OLD runtime
|
||||
located in dependencies/bootstrap-compiler/.../kotlin-runtime.jar, because the newly built compiler is just a Kotlin application,
|
||||
@@ -69,6 +68,7 @@
|
||||
</path>
|
||||
|
||||
<typedef resource="org/jetbrains/kotlin/ant/antlib.xml" classpath="${bootstrap.compiler.home}/lib/kotlin-ant.jar"/>
|
||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpath="${dependencies.dir}/ant-contrib.jar"/>
|
||||
|
||||
<path id="javac2.classpath">
|
||||
<pathelement location="${idea.sdk}/lib/javac2.jar"/>
|
||||
@@ -87,9 +87,6 @@
|
||||
<include name="compiler/builtins-serializer/src"/>
|
||||
<include name="compiler/cli/src"/>
|
||||
<include name="compiler/cli/cli-common/src"/>
|
||||
<include name="compiler/conditional-preprocessor/src/"/>
|
||||
<include name="compiler/rmi/rmi-server/src"/>
|
||||
<include name="compiler/rmi/rmi-interface/src"/>
|
||||
<include name="compiler/container/src"/>
|
||||
<include name="compiler/frontend/src"/>
|
||||
<include name="compiler/frontend.java/src"/>
|
||||
@@ -119,8 +116,6 @@
|
||||
<include name="backend-common/**"/>
|
||||
<include name="cli/**"/>
|
||||
<include name="cli-common/**"/>
|
||||
<include name="rmi-server/**"/>
|
||||
<include name="rmi-interface/**"/>
|
||||
<include name="util/**"/>
|
||||
<include name="util.runtime/**"/>
|
||||
<include name="light-classes/**"/>
|
||||
@@ -139,6 +134,10 @@
|
||||
<dirset refid="compilerSources.dirset"/>
|
||||
</path>
|
||||
|
||||
<path id="preloaderSources.path">
|
||||
<dirset dir="compiler/preloader/src"/>
|
||||
</path>
|
||||
|
||||
<macrodef name="cleandir">
|
||||
<attribute name="dir"/>
|
||||
|
||||
@@ -153,10 +152,6 @@
|
||||
<delete dir="${output}"/>
|
||||
</target>
|
||||
|
||||
<target name="clean_idea_output">
|
||||
<delete dir="${basedir}/out"/>
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${kotlin-home}"/>
|
||||
<mkdir dir="${kotlin-home}/lib"/>
|
||||
@@ -176,20 +171,22 @@
|
||||
|
||||
<chmod dir="${kotlin-home}/bin" excludes="**/*.bat" perm="755"/>
|
||||
|
||||
<sequential if:true="${bootstrap.or.local.build}">
|
||||
<copy file="${bootstrap.runtime}" tofile="${kotlin-home}/lib/kotlin-runtime-internal-bootstrap.jar"/>
|
||||
<copy file="${bootstrap.reflect}" tofile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar"/>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar" update="true">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="kotlin-runtime-internal-bootstrap.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</sequential>
|
||||
|
||||
<sequential unless:true="${bootstrap.or.local.build}">
|
||||
<copy file="${bootstrap.runtime}" todir="${kotlin-home}/lib"/>
|
||||
<copy file="${bootstrap.reflect}" todir="${kotlin-home}/lib"/>
|
||||
</sequential>
|
||||
<if>
|
||||
<istrue value="${bootstrap.or.local.build}"/>
|
||||
<then>
|
||||
<copy file="${bootstrap.runtime}" tofile="${kotlin-home}/lib/kotlin-runtime-internal-bootstrap.jar"/>
|
||||
<copy file="${bootstrap.reflect}" tofile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar"/>
|
||||
<jar destfile="${kotlin-home}/lib/kotlin-reflect-internal-bootstrap.jar" update="true">
|
||||
<manifest>
|
||||
<attribute name="Class-Path" value="kotlin-runtime-internal-bootstrap.jar"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</then>
|
||||
<else>
|
||||
<copy file="${bootstrap.runtime}" todir="${kotlin-home}/lib"/>
|
||||
<copy file="${bootstrap.reflect}" todir="${kotlin-home}/lib"/>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<target name="compiler-sources">
|
||||
@@ -204,9 +201,6 @@
|
||||
<fileset dir="compiler/builtins-serializer/src"/>
|
||||
<fileset dir="compiler/cli/src"/>
|
||||
<fileset dir="compiler/cli/cli-common/src"/>
|
||||
<fileset dir="compiler/conditional-preprocessor/src"/>
|
||||
<fileset dir="compiler/rmi/rmi-server/src"/>
|
||||
<fileset dir="compiler/rmi/rmi-interface/src"/>
|
||||
<fileset dir="compiler/container/src"/>
|
||||
<fileset dir="compiler/frontend/src"/>
|
||||
<fileset dir="compiler/frontend.java/src"/>
|
||||
@@ -232,38 +226,42 @@
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
<sequential if:true="${generate.javadoc}">
|
||||
<delete dir="${output}/kotlin-compiler-javadoc" failonerror="false"/>
|
||||
<javadoc destdir="${output}/kotlin-compiler-javadoc"
|
||||
sourcepathref="compilerSources.path"
|
||||
classpathref="classpath"
|
||||
linksource="yes"
|
||||
windowtitle="${manifest.impl.title.kotlin.compiler}"/>
|
||||
<jar jarfile="${output}/kotlin-compiler-javadoc.jar">
|
||||
<fileset dir="${output}/kotlin-compiler-javadoc"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
<if>
|
||||
<istrue value="${generate.javadoc}"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
<then>
|
||||
<delete dir="${output}/kotlin-compiler-javadoc" failonerror="false"/>
|
||||
<javadoc destdir="${output}/kotlin-compiler-javadoc"
|
||||
sourcepathref="compilerSources.path"
|
||||
classpathref="classpath"
|
||||
linksource="yes"
|
||||
windowtitle="${manifest.impl.title.kotlin.compiler}"/>
|
||||
<jar jarfile="${output}/kotlin-compiler-javadoc.jar">
|
||||
<fileset dir="${output}/kotlin-compiler-javadoc"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.javadoc}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</sequential>
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<sequential unless:true="${generate.javadoc}">
|
||||
<jar jarfile="${output}/kotlin-compiler-javadoc.jar">
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.javadoc}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</then>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.javadoc}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</sequential>
|
||||
<else>
|
||||
<jar jarfile="${output}/kotlin-compiler-javadoc.jar">
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.javadoc}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</else>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<macrodef name="new-kotlin2js">
|
||||
@@ -287,9 +285,9 @@
|
||||
<assertions>
|
||||
<enable/>
|
||||
</assertions>
|
||||
<arg value="-cp"/>
|
||||
<arg value="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
<arg value="org.jetbrains.kotlin.cli.js.K2JSCompiler"/>
|
||||
<arg line="4096 notime"/>
|
||||
<arg line="${src.line}"/>
|
||||
<arg value="-output"/>
|
||||
<arg value="@{output}"/>
|
||||
@@ -307,8 +305,6 @@
|
||||
<property name="compiled.stdlib.meta.js" value="stdlib.meta.js"/>
|
||||
<property name="stdlib.js.dir" value="${basedir}/js/js.translator/testData"/>
|
||||
|
||||
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
|
||||
|
||||
<new-kotlin2js output="${output}/${compiled.builtins.js}">
|
||||
<src>
|
||||
<fileset refid="kotlin.builtin.files"/>
|
||||
@@ -397,8 +393,8 @@
|
||||
<target name="preloader">
|
||||
<cleandir dir="${output}/classes/preloader"/>
|
||||
<javac destdir="${output}/classes/preloader" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<src location="${basedir}/compiler/preloader/src"/>
|
||||
source="${java.target}" target="${java.target}">
|
||||
<src refid="preloaderSources.path"/>
|
||||
</javac>
|
||||
|
||||
<jar jarfile="${kotlin-home}/lib/kotlin-preloader.jar">
|
||||
@@ -406,39 +402,16 @@
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.preloader}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
|
||||
<attribute name="Main-Class" value="org.jetbrains.kotlin.preloading.Preloader"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="runner">
|
||||
<cleandir dir="${output}/classes/runner"/>
|
||||
<kotlinc output="${output}/classes/runner">
|
||||
<src location="${basedir}/compiler/cli/cli-runner/src"/>
|
||||
</kotlinc>
|
||||
|
||||
<local name="runtime.jar"/>
|
||||
<condition property="runtime.jar" value="kotlin-runtime-internal-bootstrap.jar" else="kotlin-runtime.jar">
|
||||
<istrue value="${bootstrap.or.local.build}"/>
|
||||
</condition>
|
||||
|
||||
<jar jarfile="${kotlin-home}/lib/kotlin-runner.jar">
|
||||
<fileset dir="${output}/classes/runner"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
|
||||
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.runner}"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
<attribute name="Main-Class" value="org.jetbrains.kotlin.runner.Main"/>
|
||||
<attribute name="Class-Path" value="${runtime.jar}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="serialize-builtins">
|
||||
<cleandir dir="${output}/builtins"/>
|
||||
<java classname="org.jetbrains.kotlin.preloading.Preloader"
|
||||
@@ -449,9 +422,10 @@
|
||||
<assertions>
|
||||
<enable/>
|
||||
</assertions>
|
||||
<arg value="-cp"/>
|
||||
<arg value="${bootstrap.compiler.home}/lib/kotlin-compiler.jar"/>
|
||||
<arg value="org.jetbrains.kotlin.serialization.builtins.BuiltinsPackage"/>
|
||||
<arg value="4096"/>
|
||||
<arg value="notime"/>
|
||||
<arg value="${output}/builtins"/>
|
||||
<arg value="core/builtins/native"/>
|
||||
<arg value="core/builtins/src"/>
|
||||
@@ -471,7 +445,6 @@
|
||||
</fileset>
|
||||
<fileset dir="${basedir}/compiler/frontend.java/src" includes="META-INF/services/**"/>
|
||||
<fileset dir="${basedir}/compiler/backend/src" includes="META-INF/services/**"/>
|
||||
<fileset dir="${basedir}/compiler/cli/src" includes="META-INF/services/**"/>
|
||||
<fileset dir="${basedir}/resources" includes="kotlinManifest.properties"/>
|
||||
|
||||
<fileset dir="idea/src">
|
||||
@@ -482,7 +455,7 @@
|
||||
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-platform.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-utils.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/oromatcher.jar"/>
|
||||
<zipfileset src="${idea.sdk}/jps/jps-model.jar"/>
|
||||
<zipfileset src="${dependencies.dir}/jline.jar"/>
|
||||
@@ -517,18 +490,13 @@
|
||||
</target>
|
||||
|
||||
<target name="compiler">
|
||||
<taskdef resource="proguard/ant/task.properties">
|
||||
<classpath>
|
||||
<pathelement path="${dependencies.dir}/proguard.jar"/>
|
||||
<pathelement path="${dependencies.dir}/proguard-anttask.jar"/>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
<taskdef resource="proguard/ant/task.properties" classpath="${dependencies.dir}/proguard.jar"/>
|
||||
|
||||
<cleandir dir="${output}/classes/compiler"/>
|
||||
|
||||
<javac2 destdir="${output}/classes/compiler" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin externalannotations="${external.annotations.path}" modulename="kotlin-compiler"/>
|
||||
<withKotlin externalannotations="${external.annotations.path}"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<src refid="compilerSources.path"/>
|
||||
<classpath refid="classpath"/>
|
||||
@@ -538,25 +506,30 @@
|
||||
|
||||
<delete file="${kotlin-home}/lib/kotlin-compiler.jar" failonerror="false"/>
|
||||
|
||||
<copy file="${output}/kotlin-compiler-before-shrink.jar"
|
||||
tofile="${kotlin-home}/lib/kotlin-compiler.jar"
|
||||
unless:true="${shrink}" />
|
||||
<if>
|
||||
<isfalse value="${shrink}"/>
|
||||
|
||||
<sequential if:true="${shrink}">
|
||||
<available property="rtjar" value="${java.home}/lib/rt.jar" file="${java.home}/lib/rt.jar"/>
|
||||
<available property="rtjar" value="${java.home}/../Classes/classes.jar" file="${java.home}/../Classes/classes.jar"/>
|
||||
<then>
|
||||
<copy file="${output}/kotlin-compiler-before-shrink.jar"
|
||||
tofile="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</then>
|
||||
|
||||
<available property="jssejar" value="${java.home}/lib/jsse.jar" file="${java.home}/lib/jsse.jar"/>
|
||||
<available property="jssejar" value="${java.home}/../Classes/jsse.jar" file="${java.home}/../Classes/jsse.jar"/>
|
||||
<else>
|
||||
<available property="rtjar" value="${java.home}/lib/rt.jar" file="${java.home}/lib/rt.jar"/>
|
||||
<available property="rtjar" value="${java.home}/../Classes/classes.jar" file="${java.home}/../Classes/classes.jar"/>
|
||||
|
||||
<proguard configuration="${basedir}/compiler/compiler.pro"/>
|
||||
</sequential>
|
||||
<available property="jssejar" value="${java.home}/lib/jsse.jar" file="${java.home}/lib/jsse.jar"/>
|
||||
<available property="jssejar" value="${java.home}/../Classes/jsse.jar" file="${java.home}/../Classes/jsse.jar"/>
|
||||
|
||||
<proguard configuration="${basedir}/compiler/compiler.pro"/>
|
||||
</else>
|
||||
</if>
|
||||
|
||||
<jar jarfile="${output}/kotlin-compiler-for-maven.jar">
|
||||
<!-- TODO: don't include both to the jar: it's impossible to test changes to core in the local maven build without bootstrap -->
|
||||
<zipfileset src="${kotlin-home}/lib/kotlin-compiler.jar" includes="**"/>
|
||||
<zipfileset src="${bootstrap.runtime}" includes="**" />
|
||||
<zipfileset src="${bootstrap.reflect}" includes="**" />
|
||||
<zipfileset src="${bootstrap.runtime}" includes="**" excludes="META-INF/**"/>
|
||||
<zipfileset src="${bootstrap.reflect}" includes="**" excludes="META-INF/**"/>
|
||||
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
|
||||
@@ -570,31 +543,10 @@
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="kotlinr">
|
||||
<cleandir dir="${output}/classes/kotlinr"/>
|
||||
|
||||
<kotlinc output="${output}/classes/kotlinr" modulename="kotlin-rmi">
|
||||
<src>
|
||||
<pathelement path="compiler/rmi/kotlinr/src"/>
|
||||
</src>
|
||||
<classpath>
|
||||
<pathelement path="${bootstrap.runtime}"/>
|
||||
<pathelement path="${bootstrap.reflect}"/>
|
||||
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
</classpath>
|
||||
</kotlinc>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/kotlinr.jar">
|
||||
<fileset dir="${output}/classes/kotlinr"/>
|
||||
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="android-compiler-plugin">
|
||||
<cleandir dir="${output}/classes/android-compiler-plugin"/>
|
||||
<javac2 destdir="${output}/classes/android-compiler-plugin" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
|
||||
<withKotlin modulename="kotlin-android-compiler-plugin"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
|
||||
<kotlinc output="${output}/classes/android-compiler-plugin">
|
||||
<src>
|
||||
<pathelement path="plugins/android-compiler-plugin/src"/>
|
||||
</src>
|
||||
@@ -604,7 +556,7 @@
|
||||
<pathelement path="${bootstrap.runtime}"/>
|
||||
<pathelement path="${bootstrap.reflect}"/>
|
||||
</classpath>
|
||||
</javac2>
|
||||
</kotlinc>
|
||||
|
||||
<jar destfile="${kotlin-home}/lib/android-compiler-plugin.jar">
|
||||
<fileset dir="${output}/classes/android-compiler-plugin"/>
|
||||
@@ -617,7 +569,7 @@
|
||||
<cleandir dir="${output}/classes/ant"/>
|
||||
<javac2 destdir="${output}/classes/ant" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin externalannotations="${external.annotations.path}" modulename="kotlin-ant-tools"/>
|
||||
<withKotlin externalannotations="${external.annotations.path}"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<src>
|
||||
<dirset dir="${basedir}/ant">
|
||||
@@ -676,8 +628,6 @@
|
||||
|
||||
<macrodef name="new-kotlinc">
|
||||
<attribute name="output"/>
|
||||
<attribute name="moduleName"/>
|
||||
<attribute name="additionalOptions" default=""/>
|
||||
<element name="src"/>
|
||||
<element name="class-path"/>
|
||||
|
||||
@@ -703,18 +653,15 @@
|
||||
<assertions>
|
||||
<enable/>
|
||||
</assertions>
|
||||
<arg value="-cp"/>
|
||||
<arg value="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
<arg value="org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"/>
|
||||
<arg line="4096 notime"/>
|
||||
<arg line="${src.line}"/>
|
||||
<arg value="-d"/>
|
||||
<arg value="@{output}"/>
|
||||
<arg value="-no-stdlib"/>
|
||||
<arg line="@{additionalOptions}"/>
|
||||
<arg value="-classpath"/>
|
||||
<arg value="${toString:classpath.path}"/>
|
||||
<arg value="-module-name"/>
|
||||
<arg value="@{moduleName}"/>
|
||||
</java>
|
||||
|
||||
<javac2 srcdir="${toString:src.dirset}" destdir="@{output}" debug="true" debuglevel="lines,vars,source"
|
||||
@@ -729,31 +676,8 @@
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<macrodef name="kotlin-pp">
|
||||
<attribute name="src"/>
|
||||
<attribute name="output"/>
|
||||
<attribute name="profile"/>
|
||||
|
||||
<sequential>
|
||||
<java classname="org.jetbrains.kotlin.preloading.Preloader" failonerror="true" fork="true" maxmemory="${max.heap.size.for.forked.jvm}">
|
||||
<classpath>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/>
|
||||
</classpath>
|
||||
<assertions>
|
||||
<enable/>
|
||||
</assertions>
|
||||
<arg value="-cp"/>
|
||||
<arg value="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
<arg value="org.jetbrains.kotlin.preprocessor.PreprocessorPackage"/>
|
||||
<arg value="@{src}"/>
|
||||
<arg value="@{output}"/>
|
||||
<arg value="@{profile}"/>
|
||||
</java>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<target name="builtins">
|
||||
<new-kotlinc output="${output}/classes/builtins" moduleName="kotlin-builtins">
|
||||
<new-kotlinc output="${output}/classes/builtins">
|
||||
<src>
|
||||
<include name="core/builtins/src"/>
|
||||
<include name="core/runtime.jvm/src"/>
|
||||
@@ -766,7 +690,7 @@
|
||||
</target>
|
||||
|
||||
<target name="stdlib">
|
||||
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib">
|
||||
<new-kotlinc output="${output}/classes/stdlib">
|
||||
<src>
|
||||
<include name="libraries/stdlib/src"/>
|
||||
</src>
|
||||
@@ -777,7 +701,7 @@
|
||||
</target>
|
||||
|
||||
<target name="core">
|
||||
<new-kotlinc output="${output}/classes/core" moduleName="kotlin-core">
|
||||
<new-kotlinc output="${output}/classes/core">
|
||||
<src>
|
||||
<include name="core/descriptor.loader.java/src"/>
|
||||
<include name="core/descriptors/src"/>
|
||||
@@ -795,7 +719,7 @@
|
||||
</target>
|
||||
|
||||
<target name="reflection">
|
||||
<new-kotlinc output="${output}/classes/reflection" moduleName="kotlin-reflection" additionalOptions="-Xmultifile-package-facades">
|
||||
<new-kotlinc output="${output}/classes/reflection">
|
||||
<src>
|
||||
<include name="core/reflection.jvm/src"/>
|
||||
</src>
|
||||
@@ -923,7 +847,7 @@
|
||||
depends="builtins,stdlib,core,reflection,pack-runtime,pack-runtime-sources"/>
|
||||
|
||||
<target name="dist"
|
||||
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin,kotlinr"
|
||||
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler,compiler-sources,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin"
|
||||
description="Builds redistributables from sources"/>
|
||||
|
||||
<target name="dist-quick"
|
||||
@@ -947,7 +871,7 @@
|
||||
|
||||
<javac2 destdir="${output}/classes/idea-analysis" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
|
||||
source="${java.target}" target="${java.target}">
|
||||
<withKotlin externalannotations="${external.annotations.path}" modulename="kotlin-for-upsource"/>
|
||||
<withKotlin externalannotations="${external.annotations.path}"/>
|
||||
<skip pattern="kotlin/jvm/internal/.*"/>
|
||||
<src>
|
||||
<dirset dir="${basedir}/idea/ide-common" includes="src"/>
|
||||
@@ -973,7 +897,6 @@
|
||||
</fileset>
|
||||
<fileset dir="${basedir}/compiler/frontend.java/src" includes="META-INF/services/**"/>
|
||||
<fileset dir="${basedir}/compiler/backend/src" includes="META-INF/services/**"/>
|
||||
<fileset dir="${basedir}/compiler/cli/src" includes="META-INF/services/**"/>
|
||||
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
<zipgroupfileset file="${kotlin-home}/lib/kotlin-runtime.jar"/>
|
||||
@@ -1014,7 +937,6 @@
|
||||
<zip destfile="${output}/kotlin-test-data.zip">
|
||||
<zipfileset dir="compiler/testData" prefix="compiler"/>
|
||||
<zipfileset dir="idea/testData" prefix="ide"/>
|
||||
<zipfileset dir="idea/idea-completion/testData" prefix="ide/completion"/>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -17,18 +17,19 @@
|
||||
package org.jetbrains.kotlin.backend.common;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.BridgesPackage;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
@@ -39,11 +40,19 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
|
||||
|
||||
/**
|
||||
* Backend-independent utility class.
|
||||
*/
|
||||
public class CodegenUtil {
|
||||
|
||||
private CodegenUtil() {
|
||||
}
|
||||
|
||||
// TODO: consider putting predefined method signatures here too.
|
||||
public static final String EQUALS_METHOD_NAME = "equals";
|
||||
public static final String TO_STRING_METHOD_NAME = "toString";
|
||||
public static final String HASH_CODE_METHOD_NAME = "hashCode";
|
||||
|
||||
@Nullable
|
||||
public static FunctionDescriptor getDeclaredFunctionByRawSignature(
|
||||
@NotNull ClassDescriptor owner,
|
||||
@@ -51,9 +60,9 @@ public class CodegenUtil {
|
||||
@NotNull ClassifierDescriptor returnedClassifier,
|
||||
@NotNull ClassifierDescriptor... valueParameterClassifiers
|
||||
) {
|
||||
Collection<FunctionDescriptor> functions = owner.getDefaultType().getMemberScope().getFunctions(name, NoLookupLocation.FROM_BACKEND);
|
||||
Collection<FunctionDescriptor> functions = owner.getDefaultType().getMemberScope().getFunctions(name);
|
||||
for (FunctionDescriptor function : functions) {
|
||||
if (!CallResolverUtilPackage.isOrOverridesSynthesized(function)
|
||||
if (!CallResolverUtil.isOrOverridesSynthesized(function)
|
||||
&& function.getTypeParameters().isEmpty()
|
||||
&& valueParameterClassesMatch(function.getValueParameters(), Arrays.asList(valueParameterClassifiers))
|
||||
&& rawTypeMatches(function.getReturnType(), returnedClassifier)) {
|
||||
@@ -63,6 +72,29 @@ public class CodegenUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FunctionDescriptor getAnyEqualsMethod(@NotNull KotlinBuiltIns builtIns) {
|
||||
ClassDescriptor anyClass = builtIns.getAny();
|
||||
FunctionDescriptor function = getDeclaredFunctionByRawSignature(
|
||||
anyClass, Name.identifier(EQUALS_METHOD_NAME), builtIns.getBoolean(), anyClass
|
||||
);
|
||||
assert function != null;
|
||||
return function;
|
||||
}
|
||||
|
||||
public static FunctionDescriptor getAnyToStringMethod(@NotNull KotlinBuiltIns builtIns) {
|
||||
ClassDescriptor anyClass = builtIns.getAny();
|
||||
FunctionDescriptor function = getDeclaredFunctionByRawSignature(anyClass, Name.identifier(TO_STRING_METHOD_NAME), builtIns.getString());
|
||||
assert function != null;
|
||||
return function;
|
||||
}
|
||||
|
||||
public static FunctionDescriptor getAnyHashCodeMethod(@NotNull KotlinBuiltIns builtIns) {
|
||||
ClassDescriptor anyClass = builtIns.getAny();
|
||||
FunctionDescriptor function = getDeclaredFunctionByRawSignature(anyClass, Name.identifier(HASH_CODE_METHOD_NAME), builtIns.getInt());
|
||||
assert function != null;
|
||||
return function;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PropertyDescriptor getDelegatePropertyIfAny(JetExpression expression, ClassDescriptor classDescriptor, BindingContext bindingContext) {
|
||||
PropertyDescriptor propertyDescriptor = null;
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import kotlin.platform.platformStatic
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
import java.util.Comparator
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
|
||||
public object CodegenUtilKt {
|
||||
|
||||
@@ -34,8 +34,7 @@ public object CodegenUtilKt {
|
||||
// toTrait = Bar
|
||||
// delegateExpressionType = typeof(baz)
|
||||
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||
@JvmStatic
|
||||
public fun getDelegates(
|
||||
public platformStatic fun getDelegates(
|
||||
descriptor: ClassDescriptor,
|
||||
toTrait: ClassDescriptor,
|
||||
delegateExpressionType: JetType? = null
|
||||
@@ -58,12 +57,12 @@ public object CodegenUtilKt {
|
||||
val name = overriddenDescriptor.getName()
|
||||
|
||||
// this is the actual member of delegateExpressionType that we are delegating to
|
||||
(scope.getFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getProperties(name, NoLookupLocation.FROM_BACKEND))
|
||||
(scope.getFunctions(name) + scope.getProperties(name))
|
||||
.first {
|
||||
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it)).map { it.getOriginal() }.contains(overriddenDescriptor.getOriginal())
|
||||
}
|
||||
}
|
||||
assert(actualDelegates.size() <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||
assert(actualDelegates.size() <= 1) { "Meny delegates found for $delegatingMember: $actualDelegates" }
|
||||
|
||||
actualDelegates.firstOrNull()
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.backend.common;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.JetClass;
|
||||
@@ -43,13 +41,11 @@ public abstract class DataClassMethodGenerator {
|
||||
private final JetClassOrObject declaration;
|
||||
private final BindingContext bindingContext;
|
||||
private final ClassDescriptor classDescriptor;
|
||||
private final KotlinBuiltIns builtIns;
|
||||
|
||||
public DataClassMethodGenerator(JetClassOrObject declaration, BindingContext bindingContext) {
|
||||
this.declaration = declaration;
|
||||
this.bindingContext = bindingContext;
|
||||
this.classDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration);
|
||||
this.builtIns = getBuiltIns(classDescriptor);
|
||||
}
|
||||
|
||||
public void generate() {
|
||||
@@ -65,17 +61,20 @@ public abstract class DataClassMethodGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter);
|
||||
// Backend-specific implementations.
|
||||
protected abstract void generateComponentFunction(
|
||||
@NotNull FunctionDescriptor function,
|
||||
@NotNull ValueParameterDescriptor parameter
|
||||
);
|
||||
|
||||
protected abstract void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<JetParameter> constructorParameters);
|
||||
|
||||
protected abstract void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
||||
protected abstract void generateToStringMethod(@NotNull List<PropertyDescriptor> properties);
|
||||
|
||||
protected abstract void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
||||
protected abstract void generateHashCodeMethod(@NotNull List<PropertyDescriptor> properties);
|
||||
|
||||
protected abstract void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
||||
protected abstract void generateEqualsMethod(@NotNull List<PropertyDescriptor> properties);
|
||||
|
||||
@NotNull
|
||||
protected ClassDescriptor getClassDescriptor() {
|
||||
return classDescriptor;
|
||||
}
|
||||
@@ -102,23 +101,24 @@ public abstract class DataClassMethodGenerator {
|
||||
}
|
||||
|
||||
private void generateDataClassToStringIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor function = getDeclaredMember("toString", builtIns.getString());
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateToStringMethod(function, properties);
|
||||
ClassDescriptor stringClass = getBuiltIns(classDescriptor).getString();
|
||||
if (!hasDeclaredNonTrivialMember(CodegenUtil.TO_STRING_METHOD_NAME, stringClass)) {
|
||||
generateToStringMethod(properties);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDataClassHashCodeIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor function = getDeclaredMember("hashCode", builtIns.getInt());
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateHashCodeMethod(function, properties);
|
||||
ClassDescriptor intClass = getBuiltIns(classDescriptor).getInt();
|
||||
if (!hasDeclaredNonTrivialMember(CodegenUtil.HASH_CODE_METHOD_NAME, intClass)) {
|
||||
generateHashCodeMethod(properties);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDataClassEqualsIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor function = getDeclaredMember("equals", builtIns.getBoolean(), builtIns.getAny());
|
||||
if (function != null && isTrivial(function)) {
|
||||
generateEqualsMethod(function, properties);
|
||||
ClassDescriptor booleanClass = getBuiltIns(classDescriptor).getBoolean();
|
||||
ClassDescriptor anyClass = getBuiltIns(classDescriptor).getAny();
|
||||
if (!hasDeclaredNonTrivialMember(CodegenUtil.EQUALS_METHOD_NAME, booleanClass, anyClass)) {
|
||||
generateEqualsMethod(properties);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,41 +132,42 @@ public abstract class DataClassMethodGenerator {
|
||||
return result;
|
||||
}
|
||||
|
||||
private
|
||||
@NotNull
|
||||
private List<JetParameter> getPrimaryConstructorParameters() {
|
||||
List<JetParameter> getPrimaryConstructorParameters() {
|
||||
if (declaration instanceof JetClass) {
|
||||
return declaration.getPrimaryConstructorParameters();
|
||||
return ((JetClass) declaration).getPrimaryConstructorParameters();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FunctionDescriptor getDeclaredMember(
|
||||
/**
|
||||
* @return true if the class has a declared member with the given name anywhere in its hierarchy besides Any
|
||||
*/
|
||||
private boolean hasDeclaredNonTrivialMember(
|
||||
@NotNull String name,
|
||||
@NotNull ClassDescriptor returnedClassifier,
|
||||
@NotNull ClassDescriptor... valueParameterClassifiers
|
||||
) {
|
||||
return CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||
classDescriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the member is an inherited implementation of a method from Any
|
||||
*/
|
||||
private boolean isTrivial(@NotNull FunctionDescriptor function) {
|
||||
if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
FunctionDescriptor function =
|
||||
CodegenUtil.getDeclaredFunctionByRawSignature(classDescriptor, Name.identifier(name), returnedClassifier,
|
||||
valueParameterClassifiers);
|
||||
if (function == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (CallableDescriptor overridden : OverrideResolver.getOverriddenDeclarations(function)) {
|
||||
if (overridden instanceof CallableMemberDescriptor
|
||||
&& ((CallableMemberDescriptor) overridden).getKind() == CallableMemberDescriptor.Kind.DECLARATION
|
||||
&& !overridden.getContainingDeclaration().equals(builtIns.getAny())) {
|
||||
return false;
|
||||
&& !overridden.getContainingDeclaration().equals(getBuiltIns(classDescriptor).getAny())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.backend.common.bridges
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import java.util.HashSet
|
||||
|
||||
public interface FunctionHandle {
|
||||
public trait FunctionHandle {
|
||||
public val isDeclaration: Boolean
|
||||
public val isAbstract: Boolean
|
||||
|
||||
@@ -56,7 +56,7 @@ public fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
// If it's a concrete fake override, some of the bridges may be inherited from the super-classes. Specifically, bridges for all
|
||||
// declarations that are reachable from all concrete immediate super-functions of the given function. Note that all such bridges are
|
||||
// guaranteed to delegate to the same implementation as bridges for the given function, that's why it's safe to inherit them
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@suppress("UNCHECKED_CAST")
|
||||
for (overridden in function.getOverridden() as Iterable<Function>) {
|
||||
if (!overridden.isAbstract) {
|
||||
bridgesToGenerate.removeAll(findAllReachableDeclarations(overridden).map(signature))
|
||||
@@ -77,7 +77,7 @@ private fun <Function : FunctionHandle> findAllReachableDeclarations(function: F
|
||||
}
|
||||
}
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@suppress("UNCHECKED_CAST")
|
||||
DFS.dfs(listOf(function), { it.getOverridden() as Iterable<Function> }, collector)
|
||||
return HashSet(collector.result())
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil
|
||||
|
||||
public fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
descriptor: FunctionDescriptor,
|
||||
@@ -69,7 +69,7 @@ private data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescrip
|
||||
*/
|
||||
public fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
if (descriptor.getKind().isReal()) return null
|
||||
if (isOrOverridesSynthesized(descriptor)) return null
|
||||
if (CallResolverUtil.isOrOverridesSynthesized(descriptor)) return null
|
||||
|
||||
val implementation = findImplementationFromInterface(descriptor) ?: return null
|
||||
val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.backend.common.output
|
||||
|
||||
import java.io.File
|
||||
|
||||
public interface OutputFileCollection {
|
||||
public trait OutputFileCollection {
|
||||
public fun get(relativePath: String): OutputFile?
|
||||
public fun asList(): List<OutputFile>
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class SimpleOutputFileCollection(private val outputFiles: List<OutputFile
|
||||
override fun asList(): List<OutputFile> = outputFiles
|
||||
}
|
||||
|
||||
public interface OutputFile {
|
||||
public trait OutputFile {
|
||||
public val relativePath: String
|
||||
public val sourceFiles: List<File>
|
||||
public fun asByteArray(): ByteArray
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" name="javax.inject" level="project" />
|
||||
<orderEntry type="module" module-name="serialization" />
|
||||
<orderEntry type="module" module-name="backend-common" exported="" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
|
||||
@@ -17,14 +17,9 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.psi.JetSuperExpression;
|
||||
|
||||
public interface AccessorForCallableDescriptor<T extends CallableMemberDescriptor> {
|
||||
@NotNull
|
||||
T getCalleeDescriptor();
|
||||
|
||||
@Nullable
|
||||
JetSuperExpression getSuperCallExpression();
|
||||
}
|
||||
|
||||
@@ -17,38 +17,36 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
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.name.Name
|
||||
import org.jetbrains.kotlin.psi.JetSuperExpression
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import java.util.*
|
||||
|
||||
public class AccessorForConstructorDescriptor(
|
||||
private val calleeDescriptor: ConstructorDescriptor,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
private val superCallExpression: JetSuperExpression?
|
||||
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.special("<init>")),
|
||||
ConstructorDescriptor,
|
||||
AccessorForCallableDescriptor<ConstructorDescriptor> {
|
||||
containingDeclaration: DeclarationDescriptor
|
||||
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.special("<init>"))
|
||||
, ConstructorDescriptor
|
||||
, AccessorForCallableDescriptor<ConstructorDescriptor> {
|
||||
|
||||
override fun getCalleeDescriptor(): ConstructorDescriptor = calleeDescriptor
|
||||
|
||||
override fun getContainingDeclaration(): ClassDescriptor = calleeDescriptor.containingDeclaration
|
||||
override fun getContainingDeclaration(): ClassDescriptor = calleeDescriptor.getContainingDeclaration()
|
||||
|
||||
override fun isPrimary(): Boolean = false
|
||||
|
||||
override fun getReturnType(): JetType = super.getReturnType()!!
|
||||
|
||||
override fun getSuperCallExpression(): JetSuperExpression? = superCallExpression
|
||||
|
||||
init {
|
||||
initialize(
|
||||
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
|
||||
calleeDescriptor.dispatchReceiverParameter,
|
||||
DescriptorUtils.getReceiverParameterType(getExtensionReceiverParameter()),
|
||||
calleeDescriptor.getDispatchReceiverParameter(),
|
||||
copyTypeParameters(calleeDescriptor),
|
||||
copyValueParameters(calleeDescriptor),
|
||||
calleeDescriptor.returnType,
|
||||
calleeDescriptor.getReturnType(),
|
||||
Modality.FINAL,
|
||||
Visibilities.INTERNAL,
|
||||
false
|
||||
Visibilities.INTERNAL
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,38 +17,35 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.JetSuperExpression;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
|
||||
import static org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||
|
||||
public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDescriptor implements AccessorForCallableDescriptor<FunctionDescriptor> {
|
||||
|
||||
private final FunctionDescriptor calleeDescriptor;
|
||||
private final JetSuperExpression superCallExpression;
|
||||
|
||||
public AccessorForFunctionDescriptor(
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
int index,
|
||||
@Nullable JetSuperExpression superCallExpression
|
||||
int index
|
||||
) {
|
||||
super(containingDeclaration,
|
||||
Name.identifier("access$" + (descriptor instanceof ConstructorDescriptor ? "init" : descriptor.getName()) + "$" + index));
|
||||
this.calleeDescriptor = descriptor;
|
||||
this.superCallExpression = superCallExpression;
|
||||
|
||||
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
|
||||
descriptor instanceof ConstructorDescriptor || AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)
|
||||
? null
|
||||
? NO_RECEIVER_PARAMETER
|
||||
: descriptor.getDispatchReceiverParameter(),
|
||||
copyTypeParameters(descriptor),
|
||||
copyValueParameters(descriptor),
|
||||
descriptor.getReturnType(),
|
||||
Modality.FINAL,
|
||||
Visibilities.INTERNAL,
|
||||
descriptor.isOperator());
|
||||
Visibilities.INTERNAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -56,9 +53,4 @@ public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDe
|
||||
public FunctionDescriptor getCalleeDescriptor() {
|
||||
return calleeDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSuperExpression getSuperCallExpression() {
|
||||
return superCallExpression;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,13 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
|
||||
public class AccessorForPropertyBackingFieldInOuterClass extends AccessorForPropertyDescriptor {
|
||||
|
||||
public AccessorForPropertyBackingFieldInOuterClass(
|
||||
@NotNull PropertyDescriptor property,
|
||||
@NotNull PropertyDescriptor pd,
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
int index,
|
||||
@Nullable JetType delegationType
|
||||
) {
|
||||
super(property, delegationType != null ? delegationType : property.getType(), null, null, containingDeclaration, index, null);
|
||||
super(pd, delegationType != null ? delegationType : pd.getType(), null, null, containingDeclaration, index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.JetSuperExpression;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
|
||||
@@ -34,16 +33,9 @@ import java.util.Collections;
|
||||
public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implements AccessorForCallableDescriptor<PropertyDescriptor> {
|
||||
private final PropertyDescriptor calleeDescriptor;
|
||||
private final int accessorIndex;
|
||||
private final JetSuperExpression superCallExpression;
|
||||
|
||||
public AccessorForPropertyDescriptor(
|
||||
@NotNull PropertyDescriptor property,
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
int index,
|
||||
@Nullable JetSuperExpression superCallExpression
|
||||
) {
|
||||
this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()),
|
||||
property.getDispatchReceiverParameter(), containingDeclaration, index, superCallExpression);
|
||||
public AccessorForPropertyDescriptor(@NotNull PropertyDescriptor pd, @NotNull DeclarationDescriptor containingDeclaration, int index) {
|
||||
this(pd, pd.getType(), DescriptorUtils.getReceiverParameterType(pd.getExtensionReceiverParameter()), pd.getDispatchReceiverParameter(), containingDeclaration, index);
|
||||
}
|
||||
|
||||
protected AccessorForPropertyDescriptor(
|
||||
@@ -52,16 +44,14 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
|
||||
@Nullable JetType receiverType,
|
||||
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
int index,
|
||||
@Nullable JetSuperExpression superCallExpression
|
||||
int index
|
||||
) {
|
||||
super(containingDeclaration, null, Annotations.EMPTY, Modality.FINAL, Visibilities.LOCAL,
|
||||
original.isVar(), Name.identifier("access$" + getIndexedAccessorSuffix(original, index)),
|
||||
Kind.DECLARATION, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false);
|
||||
Kind.DECLARATION, SourceElement.NO_SOURCE);
|
||||
|
||||
this.calleeDescriptor = original;
|
||||
this.accessorIndex = index;
|
||||
this.superCallExpression = superCallExpression;
|
||||
setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), dispatchReceiverParameter, receiverType);
|
||||
initialize(new Getter(this), new Setter(this));
|
||||
}
|
||||
@@ -79,12 +69,6 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
|
||||
//noinspection ConstantConditions
|
||||
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getGetter();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JetSuperExpression getSuperCallExpression() {
|
||||
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallExpression();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Setter extends PropertySetterDescriptorImpl implements AccessorForCallableDescriptor<PropertySetterDescriptor>{
|
||||
@@ -100,12 +84,6 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
|
||||
//noinspection ConstantConditions
|
||||
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getSetter();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JetSuperExpression getSuperCallExpression() {
|
||||
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallExpression();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -114,11 +92,6 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
|
||||
return calleeDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetSuperExpression getSuperCallExpression() {
|
||||
return superCallExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getIndexedAccessorSuffix() {
|
||||
return getIndexedAccessorSuffix(calleeDescriptor, accessorIndex);
|
||||
|
||||
@@ -18,24 +18,24 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.annotation.WrappedAnnotated;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||
import org.jetbrains.kotlin.types.Flexibility;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.TypesPackage;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getClassObjectType;
|
||||
@@ -52,7 +52,7 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(@NotNull Annotated annotated) {
|
||||
return Annotations.Companion.findAnyAnnotation(annotated.getAnnotations(), fqName) != null;
|
||||
return annotated.getAnnotations().findAnnotation(fqName) != null;
|
||||
}
|
||||
|
||||
public int getJvmFlag() {
|
||||
@@ -61,15 +61,14 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
public static final List<JvmFlagAnnotation> FIELD_FLAGS = Arrays.asList(
|
||||
new JvmFlagAnnotation("kotlin.jvm.Volatile", Opcodes.ACC_VOLATILE),
|
||||
new JvmFlagAnnotation("kotlin.jvm.Transient", Opcodes.ACC_TRANSIENT)
|
||||
new JvmFlagAnnotation("kotlin.jvm.volatile", Opcodes.ACC_VOLATILE),
|
||||
new JvmFlagAnnotation("kotlin.jvm.transient", Opcodes.ACC_TRANSIENT)
|
||||
);
|
||||
|
||||
public static final List<JvmFlagAnnotation> METHOD_FLAGS = Arrays.asList(
|
||||
new JvmFlagAnnotation("kotlin.jvm.Strictfp", Opcodes.ACC_STRICT),
|
||||
new JvmFlagAnnotation("kotlin.jvm.Synchronized", Opcodes.ACC_SYNCHRONIZED),
|
||||
new JvmFlagAnnotation("kotlin.jvm.native", Opcodes.ACC_NATIVE),
|
||||
new JvmFlagAnnotation("kotlin.external", Opcodes.ACC_NATIVE)
|
||||
new JvmFlagAnnotation("kotlin.jvm.strictfp", Opcodes.ACC_STRICT),
|
||||
new JvmFlagAnnotation("kotlin.jvm.synchronized", Opcodes.ACC_SYNCHRONIZED),
|
||||
new JvmFlagAnnotation("kotlin.jvm.native", Opcodes.ACC_NATIVE)
|
||||
);
|
||||
|
||||
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {};
|
||||
@@ -84,38 +83,17 @@ public abstract class AnnotationCodegen {
|
||||
* @param returnType can be null if not applicable (e.g. {@code annotated} is a class)
|
||||
*/
|
||||
public void genAnnotations(@Nullable Annotated annotated, @Nullable Type returnType) {
|
||||
genAnnotations(annotated, returnType, null);
|
||||
}
|
||||
|
||||
public void genAnnotations(@Nullable Annotated annotated, @Nullable Type returnType, @Nullable AnnotationUseSiteTarget allowedTarget) {
|
||||
if (annotated == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(annotated instanceof DeclarationDescriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> annotationDescriptorsAlreadyPresent = new HashSet<String>();
|
||||
|
||||
Annotations annotations = annotated.getAnnotations();
|
||||
|
||||
for (AnnotationWithTarget annotationWithTarget : annotations.getAllAnnotations()) {
|
||||
AnnotationDescriptor annotation = annotationWithTarget.getAnnotation();
|
||||
AnnotationUseSiteTarget annotationTarget = annotationWithTarget.getTarget();
|
||||
|
||||
// Skip targeted annotations by default
|
||||
if (allowedTarget == null && annotationTarget != null) continue;
|
||||
|
||||
// Skip if the target is not the same
|
||||
if (allowedTarget != null && annotationTarget != null && allowedTarget != annotationTarget) continue;
|
||||
|
||||
Set<KotlinTarget> applicableTargets = AnnotationChecker.applicableTargetSet(annotation);
|
||||
if (annotated instanceof AnonymousFunctionDescriptor
|
||||
&& !applicableTargets.contains(KotlinTarget.FUNCTION)
|
||||
&& !applicableTargets.contains(KotlinTarget.PROPERTY_GETTER)
|
||||
&& !applicableTargets.contains(KotlinTarget.PROPERTY_SETTER)) {
|
||||
assert (applicableTargets.contains(KotlinTarget.EXPRESSION)) :
|
||||
"Inconsistent target list for lambda annotation: " + applicableTargets + " on " + annotated;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (AnnotationDescriptor annotation : annotated.getAnnotations()) {
|
||||
String descriptor = genAnnotation(annotation);
|
||||
if (descriptor != null) {
|
||||
annotationDescriptorsAlreadyPresent.add(descriptor);
|
||||
@@ -130,13 +108,8 @@ public abstract class AnnotationCodegen {
|
||||
@Nullable Type returnType,
|
||||
@NotNull Set<String> annotationDescriptorsAlreadyPresent
|
||||
) {
|
||||
Annotated unwrapped = annotated;
|
||||
if (annotated instanceof WrappedAnnotated) {
|
||||
unwrapped = ((WrappedAnnotated) annotated).getOriginalAnnotated();
|
||||
}
|
||||
|
||||
if (unwrapped instanceof CallableDescriptor) {
|
||||
CallableDescriptor descriptor = (CallableDescriptor) unwrapped;
|
||||
if (annotated instanceof CallableDescriptor) {
|
||||
CallableDescriptor descriptor = (CallableDescriptor) annotated;
|
||||
|
||||
// No need to annotate privates, synthetic accessors and their parameters
|
||||
if (isInvisibleFromTheOutside(descriptor)) return;
|
||||
@@ -146,14 +119,6 @@ public abstract class AnnotationCodegen {
|
||||
generateNullabilityAnnotation(descriptor.getReturnType(), annotationDescriptorsAlreadyPresent);
|
||||
}
|
||||
}
|
||||
if (unwrapped instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) unwrapped;
|
||||
if (classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
|
||||
generateDocumentedAnnotation(classDescriptor, annotationDescriptorsAlreadyPresent);
|
||||
generateRetentionAnnotation(classDescriptor, annotationDescriptorsAlreadyPresent);
|
||||
generateTargetAnnotation(classDescriptor, annotationDescriptorsAlreadyPresent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInvisibleFromTheOutside(@Nullable DeclarationDescriptor descriptor) {
|
||||
@@ -195,64 +160,6 @@ public abstract class AnnotationCodegen {
|
||||
generateAnnotationIfNotPresent(annotationDescriptorsAlreadyPresent, annotationClass);
|
||||
}
|
||||
|
||||
private static final Map<KotlinTarget, ElementType> annotationTargetMap =
|
||||
new EnumMap<KotlinTarget, ElementType>(KotlinTarget.class);
|
||||
|
||||
static {
|
||||
annotationTargetMap.put(KotlinTarget.CLASS, ElementType.TYPE);
|
||||
annotationTargetMap.put(KotlinTarget.ANNOTATION_CLASS, ElementType.ANNOTATION_TYPE);
|
||||
annotationTargetMap.put(KotlinTarget.CONSTRUCTOR, ElementType.CONSTRUCTOR);
|
||||
annotationTargetMap.put(KotlinTarget.LOCAL_VARIABLE, ElementType.LOCAL_VARIABLE);
|
||||
annotationTargetMap.put(KotlinTarget.FUNCTION, ElementType.METHOD);
|
||||
annotationTargetMap.put(KotlinTarget.PROPERTY_GETTER, ElementType.METHOD);
|
||||
annotationTargetMap.put(KotlinTarget.PROPERTY_SETTER, ElementType.METHOD);
|
||||
annotationTargetMap.put(KotlinTarget.FIELD, ElementType.FIELD);
|
||||
annotationTargetMap.put(KotlinTarget.VALUE_PARAMETER, ElementType.PARAMETER);
|
||||
}
|
||||
|
||||
private void generateTargetAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
|
||||
String descriptor = Type.getType(Target.class).getDescriptor();
|
||||
if (!annotationDescriptorsAlreadyPresent.add(descriptor)) return;
|
||||
Set<KotlinTarget> targets = AnnotationChecker.Companion.applicableTargetSet(classDescriptor);
|
||||
Set<ElementType> javaTargets;
|
||||
if (targets == null) {
|
||||
javaTargets = getJavaTargetList(classDescriptor);
|
||||
if (javaTargets == null) return;
|
||||
}
|
||||
else {
|
||||
javaTargets = EnumSet.noneOf(ElementType.class);
|
||||
for (KotlinTarget target : targets) {
|
||||
if (annotationTargetMap.get(target) == null) continue;
|
||||
javaTargets.add(annotationTargetMap.get(target));
|
||||
}
|
||||
}
|
||||
AnnotationVisitor visitor = visitAnnotation(descriptor, true);
|
||||
AnnotationVisitor arrayVisitor = visitor.visitArray("value");
|
||||
for (ElementType javaTarget : javaTargets) {
|
||||
arrayVisitor.visitEnum(null, Type.getType(ElementType.class).getDescriptor(), javaTarget.name());
|
||||
}
|
||||
arrayVisitor.visitEnd();
|
||||
visitor.visitEnd();
|
||||
}
|
||||
|
||||
private void generateRetentionAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
|
||||
RetentionPolicy policy = getRetentionPolicy(classDescriptor);
|
||||
String descriptor = Type.getType(Retention.class).getDescriptor();
|
||||
if (!annotationDescriptorsAlreadyPresent.add(descriptor)) return;
|
||||
AnnotationVisitor visitor = visitAnnotation(descriptor, true);
|
||||
visitor.visitEnum("value", Type.getType(RetentionPolicy.class).getDescriptor(), policy.name());
|
||||
visitor.visitEnd();
|
||||
}
|
||||
|
||||
private void generateDocumentedAnnotation(@NotNull ClassDescriptor classDescriptor, @NotNull Set<String> annotationDescriptorsAlreadyPresent) {
|
||||
boolean documented = DescriptorUtilPackage.isDocumentedAnnotation(classDescriptor);
|
||||
if (!documented) return;
|
||||
String descriptor = Type.getType(Documented.class).getDescriptor();
|
||||
if (!annotationDescriptorsAlreadyPresent.add(descriptor)) return;
|
||||
AnnotationVisitor visitor = visitAnnotation(descriptor, true);
|
||||
visitor.visitEnd();
|
||||
}
|
||||
|
||||
private void generateAnnotationIfNotPresent(Set<String> annotationDescriptorsAlreadyPresent, Class<?> annotationClass) {
|
||||
String descriptor = Type.getType(annotationClass).getDescriptor();
|
||||
if (!annotationDescriptorsAlreadyPresent.contains(descriptor)) {
|
||||
@@ -265,9 +172,9 @@ public abstract class AnnotationCodegen {
|
||||
return !type.isMarkedNullable() && classifier instanceof TypeParameterDescriptor && TypeUtils.hasNullableSuperType(type);
|
||||
}
|
||||
|
||||
public void generateAnnotationDefaultValue(@NotNull ConstantValue<?> value, @NotNull JetType expectedType) {
|
||||
public void generateAnnotationDefaultValue(@NotNull CompileTimeConstant value, @NotNull JetType expectedType) {
|
||||
AnnotationVisitor visitor = visitAnnotation(null, false); // Parameters are unimportant
|
||||
genCompileTimeValue(null, value, visitor);
|
||||
genCompileTimeValue(null, value, expectedType, visitor);
|
||||
visitor.visitEnd();
|
||||
}
|
||||
|
||||
@@ -290,16 +197,17 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) {
|
||||
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
|
||||
for (Map.Entry<ValueParameterDescriptor, CompileTimeConstant<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
|
||||
ValueParameterDescriptor descriptor = entry.getKey();
|
||||
String name = descriptor.getName().asString();
|
||||
genCompileTimeValue(name, entry.getValue(), annotationVisitor);
|
||||
genCompileTimeValue(name, entry.getValue(), descriptor.getType(), annotationVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
private void genCompileTimeValue(
|
||||
@Nullable final String name,
|
||||
@NotNull ConstantValue<?> value,
|
||||
@NotNull CompileTimeConstant<?> value,
|
||||
@NotNull final JetType expectedType,
|
||||
@NotNull final AnnotationVisitor annotationVisitor
|
||||
) {
|
||||
AnnotationArgumentVisitor argumentVisitor = new AnnotationArgumentVisitor<Void, Void>() {
|
||||
@@ -351,15 +259,15 @@ public abstract class AnnotationCodegen {
|
||||
@Override
|
||||
public Void visitEnumValue(EnumValue value, Void data) {
|
||||
String propertyName = value.getValue().getName().asString();
|
||||
annotationVisitor.visitEnum(name, typeMapper.mapType(value.getType()).getDescriptor(), propertyName);
|
||||
annotationVisitor.visitEnum(name, typeMapper.mapType(value.getType(KotlinBuiltIns.getInstance())).getDescriptor(), propertyName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitArrayValue(ArrayValue value, Void data) {
|
||||
AnnotationVisitor visitor = annotationVisitor.visitArray(name);
|
||||
for (ConstantValue<?> argument : value.getValue()) {
|
||||
genCompileTimeValue(null, argument, visitor);
|
||||
for (CompileTimeConstant<?> argument : value.getValue()) {
|
||||
genCompileTimeValue(null, argument, value.getType(KotlinBuiltIns.getInstance()), visitor);
|
||||
}
|
||||
visitor.visitEnd();
|
||||
return null;
|
||||
@@ -380,7 +288,14 @@ public abstract class AnnotationCodegen {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void visitSimpleValue(ConstantValue<?> value) {
|
||||
@Override
|
||||
public Void visitNumberTypeValue(IntegerValueTypeConstant value, Void data) {
|
||||
Object numberType = value.getValue(expectedType);
|
||||
annotationVisitor.visit(name, numberType);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void visitSimpleValue(CompileTimeConstant value) {
|
||||
annotationVisitor.visit(name, value.getValue());
|
||||
return null;
|
||||
}
|
||||
@@ -395,7 +310,7 @@ public abstract class AnnotationCodegen {
|
||||
return visitUnsupportedValue(value);
|
||||
}
|
||||
|
||||
private Void visitUnsupportedValue(ConstantValue<?> value) {
|
||||
private Void visitUnsupportedValue(CompileTimeConstant value) {
|
||||
throw new IllegalStateException("Don't know how to compile annotation value " + value);
|
||||
}
|
||||
};
|
||||
@@ -403,54 +318,13 @@ public abstract class AnnotationCodegen {
|
||||
value.accept(argumentVisitor, null);
|
||||
}
|
||||
|
||||
private static final Map<KotlinRetention, RetentionPolicy> annotationRetentionMap =
|
||||
new EnumMap<KotlinRetention, RetentionPolicy>(KotlinRetention.class);
|
||||
|
||||
static {
|
||||
annotationRetentionMap.put(KotlinRetention.SOURCE, RetentionPolicy.SOURCE);
|
||||
annotationRetentionMap.put(KotlinRetention.BINARY, RetentionPolicy.CLASS);
|
||||
annotationRetentionMap.put(KotlinRetention.RUNTIME, RetentionPolicy.RUNTIME);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Set<ElementType> getJavaTargetList(ClassDescriptor descriptor) {
|
||||
AnnotationDescriptor targetAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Target.class.getName()));
|
||||
if (targetAnnotation != null) {
|
||||
Collection<ConstantValue<?>> valueArguments = targetAnnotation.getAllValueArguments().values();
|
||||
if (!valueArguments.isEmpty()) {
|
||||
ConstantValue<?> compileTimeConstant = valueArguments.iterator().next();
|
||||
if (compileTimeConstant instanceof ArrayValue) {
|
||||
List<? extends ConstantValue<?>> values = ((ArrayValue) compileTimeConstant).getValue();
|
||||
Set<ElementType> result = EnumSet.noneOf(ElementType.class);
|
||||
for (ConstantValue<?> value : values) {
|
||||
if (value instanceof EnumValue) {
|
||||
ClassDescriptor enumEntry = ((EnumValue) value).getValue();
|
||||
JetType classObjectType = getClassObjectType(enumEntry);
|
||||
if (classObjectType != null) {
|
||||
if ("java/lang/annotation/ElementType".equals(typeMapper.mapType(classObjectType).getInternalName())) {
|
||||
result.add(ElementType.valueOf(enumEntry.getName().asString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private RetentionPolicy getRetentionPolicy(@NotNull Annotated descriptor) {
|
||||
KotlinRetention retention = DescriptorUtilPackage.getAnnotationRetention(descriptor);
|
||||
if (retention != null) {
|
||||
return annotationRetentionMap.get(retention);
|
||||
}
|
||||
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
|
||||
if (retentionAnnotation != null) {
|
||||
Collection<ConstantValue<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
|
||||
Collection<CompileTimeConstant<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
|
||||
if (!valueArguments.isEmpty()) {
|
||||
ConstantValue<?> compileTimeConstant = valueArguments.iterator().next();
|
||||
CompileTimeConstant<?> compileTimeConstant = valueArguments.iterator().next();
|
||||
if (compileTimeConstant instanceof EnumValue) {
|
||||
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
|
||||
JetType classObjectType = getClassObjectType(enumEntry);
|
||||
@@ -463,7 +337,7 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
return RetentionPolicy.RUNTIME;
|
||||
return RetentionPolicy.CLASS;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -25,17 +25,16 @@ import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ArgumentGenerator {
|
||||
/**
|
||||
* @return a {@code List} of bit masks of default arguments that should be passed as last arguments to $default method, if there were
|
||||
* any default arguments, or an empty {@code List} if there were none
|
||||
* @see kotlin.reflect.jvm.internal.KCallableImpl#callBy(Map...)
|
||||
*/
|
||||
@NotNull
|
||||
public List<Integer> generate(@NotNull List<ResolvedValueArgument> valueArguments) {
|
||||
List<Integer> masks = new ArrayList<Integer>(1);
|
||||
boolean maskIsNeeded = false;
|
||||
int mask = 0;
|
||||
int n = valueArguments.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
@@ -48,6 +47,7 @@ public abstract class ArgumentGenerator {
|
||||
generateExpression(i, (ExpressionValueArgument) argument);
|
||||
}
|
||||
else if (argument instanceof DefaultValueArgument) {
|
||||
maskIsNeeded = true;
|
||||
mask |= 1 << (i % Integer.SIZE);
|
||||
generateDefault(i, (DefaultValueArgument) argument);
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public abstract class ArgumentGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (mask == 0 && masks.isEmpty()) {
|
||||
if (!maskIsNeeded) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,21 +32,20 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPackage;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.Approximation;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypesPackage;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
@@ -61,6 +60,7 @@ import java.util.Set;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isInterface;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.ABI_VERSION_FIELD_NAME;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
@@ -219,11 +219,6 @@ public class AsmUtil {
|
||||
int flags = getVisibilityAccessFlag(functionDescriptor);
|
||||
flags |= getVarargsFlag(functionDescriptor);
|
||||
flags |= getDeprecatedAccessFlag(functionDescriptor);
|
||||
if (DescriptorUtilPackage.isAnnotatedAsHidden(functionDescriptor)
|
||||
|| functionDescriptor instanceof PropertyAccessorDescriptor
|
||||
&& DescriptorUtilPackage.isAnnotatedAsHidden(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -288,9 +283,6 @@ public class AsmUtil {
|
||||
|
||||
public static int getDeprecatedAccessFlag(@NotNull MemberDescriptor descriptor) {
|
||||
if (descriptor instanceof PropertyAccessorDescriptor) {
|
||||
if (((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty().isConst()) {
|
||||
return ACC_DEPRECATED;
|
||||
}
|
||||
return KotlinBuiltIns.isDeprecated(descriptor)
|
||||
? ACC_DEPRECATED
|
||||
: getDeprecatedAccessFlag(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty());
|
||||
@@ -313,49 +305,22 @@ public class AsmUtil {
|
||||
@Nullable
|
||||
private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||
if (isInterface(containingDeclaration)) {
|
||||
return memberVisibility == Visibilities.PRIVATE ? NO_FLAG_PACKAGE_PRIVATE : ACC_PUBLIC;
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
Visibility memberVisibility = memberDescriptor.getVisibility();
|
||||
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
|
||||
if (isEnumEntry(memberDescriptor)) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof ConstructorDescriptor && isAnonymousObject(memberDescriptor.getContainingDeclaration())) {
|
||||
return NO_FLAG_PACKAGE_PRIVATE;
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof SyntheticJavaPropertyDescriptor) {
|
||||
return getVisibilityAccessFlag(((SyntheticJavaPropertyDescriptor) memberDescriptor).getGetMethod());
|
||||
}
|
||||
if (memberDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) memberDescriptor).getCorrespondingProperty();
|
||||
if (property instanceof SyntheticJavaPropertyDescriptor) {
|
||||
FunctionDescriptor method = memberDescriptor == property.getGetter()
|
||||
? ((SyntheticJavaPropertyDescriptor) property).getGetMethod()
|
||||
: ((SyntheticJavaPropertyDescriptor) property).getSetMethod();
|
||||
assert method != null : "No get/set method in SyntheticJavaPropertyDescriptor: " + property;
|
||||
return getVisibilityAccessFlag(method);
|
||||
}
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof CallableDescriptor && memberVisibility == Visibilities.PROTECTED) {
|
||||
for (CallableDescriptor overridden : DescriptorUtils.getAllOverriddenDescriptors((CallableDescriptor) memberDescriptor)) {
|
||||
if (isInterface(overridden.getContainingDeclaration())) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Visibilities.isPrivate(memberVisibility)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// the following code is only for PRIVATE visibility of member
|
||||
if (memberDescriptor instanceof ConstructorDescriptor) {
|
||||
if (isNonCompanionObject(containingDeclaration) || isEnumEntry(containingDeclaration)) {
|
||||
@@ -367,9 +332,6 @@ public class AsmUtil {
|
||||
return ACC_PROTECTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (memberDescriptor instanceof PropertyDescriptor && ((PropertyDescriptor) memberDescriptor).isConst()) return null;
|
||||
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
return ACC_PUBLIC;
|
||||
}
|
||||
@@ -637,29 +599,29 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean genNotNullAssertionForField(
|
||||
public static void genNotNullAssertionForField(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull PropertyDescriptor descriptor
|
||||
) {
|
||||
return genNotNullAssertion(v, state, descriptor, "checkFieldIsNotNull");
|
||||
genNotNullAssertion(v, state, descriptor, "checkFieldIsNotNull");
|
||||
}
|
||||
|
||||
private static boolean genNotNullAssertion(
|
||||
private static void genNotNullAssertion(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@NotNull String assertMethodToCall
|
||||
) {
|
||||
// Assertions are generated elsewhere for platform types
|
||||
if (JvmPackage.getPLATFORM_TYPES()) return false;
|
||||
if (JvmPackage.getPLATFORM_TYPES()) return;
|
||||
|
||||
if (!state.isCallAssertionsEnabled()) return false;
|
||||
if (!state.isCallAssertionsEnabled()) return;
|
||||
|
||||
if (!isDeclaredInJava(descriptor)) return false;
|
||||
if (!isDeclaredInJava(descriptor)) return;
|
||||
|
||||
JetType type = descriptor.getReturnType();
|
||||
if (type == null || isNullableType(TypesPackage.lowerIfFlexible(type))) return false;
|
||||
if (type == null || isNullableType(TypesPackage.lowerIfFlexible(type))) return;
|
||||
|
||||
Type asmType = state.getTypeMapper().mapReturnType(descriptor);
|
||||
if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) {
|
||||
@@ -668,20 +630,17 @@ public class AsmUtil {
|
||||
v.visitLdcInsn(descriptor.getName().asString());
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, assertMethodToCall,
|
||||
"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V", false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue genNotNullAssertions(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull final StackValue stackValue,
|
||||
@Nullable final RuntimeAssertionInfo runtimeAssertionInfo
|
||||
@Nullable final Approximation.Info approximationInfo
|
||||
) {
|
||||
if (!state.isCallAssertionsEnabled()) return stackValue;
|
||||
if (runtimeAssertionInfo == null || !runtimeAssertionInfo.getNeedNotNullAssertion()) return stackValue;
|
||||
if (approximationInfo == null || !TypesPackage.assertNotNull(approximationInfo)) return stackValue;
|
||||
|
||||
return new StackValue(stackValue.type) {
|
||||
|
||||
@@ -690,7 +649,7 @@ public class AsmUtil {
|
||||
stackValue.put(type, v);
|
||||
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
||||
v.dup();
|
||||
v.visitLdcInsn(runtimeAssertionInfo.getMessage());
|
||||
v.visitLdcInsn(approximationInfo.getMessage());
|
||||
v.invokestatic("kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull",
|
||||
"(Ljava/lang/Object;Ljava/lang/String;)V", false);
|
||||
}
|
||||
@@ -832,7 +791,7 @@ public class AsmUtil {
|
||||
|
||||
public static void writeKotlinSyntheticClassAnnotation(@NotNull ClassBuilder v, @NotNull KotlinSyntheticClass.Kind kind) {
|
||||
AnnotationVisitor av = v.newAnnotation(Type.getObjectType(KotlinSyntheticClass.CLASS_NAME.getInternalName()).getDescriptor(), true);
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
av.visit(ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||
av.visitEnum(
|
||||
JvmAnnotationNames.KIND_FIELD_NAME,
|
||||
Type.getObjectType(KotlinSyntheticClass.KIND_INTERNAL_NAME).getDescriptor(),
|
||||
|
||||
@@ -49,7 +49,7 @@ open class BranchedValue(
|
||||
open fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||
if (arg1 is CondJump) arg1.condJump(jumpLabel, v, jumpIfFalse) else arg1.put(operandType, v)
|
||||
arg2?.put(operandType, v)
|
||||
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel);
|
||||
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode], v), jumpLabel);
|
||||
}
|
||||
|
||||
open fun loopJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
public interface Callable {
|
||||
public trait Callable {
|
||||
public val owner: Type
|
||||
|
||||
public val dispatchReceiverType: Type?
|
||||
|
||||
@@ -21,7 +21,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.BridgesPackage;
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
@@ -77,7 +80,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<JetClassOrObject> {
|
||||
}
|
||||
}
|
||||
|
||||
generatePrimaryConstructorProperties();
|
||||
generatePrimaryConstructorProperties(propertyCodegen, myClass);
|
||||
}
|
||||
|
||||
private static boolean shouldProcessFirst(JetDeclaration declaration) {
|
||||
@@ -98,8 +101,8 @@ public abstract class ClassBodyCodegen extends MemberCodegen<JetClassOrObject> {
|
||||
}
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructorProperties() {
|
||||
boolean isAnnotation = descriptor.getKind() == ClassKind.ANNOTATION_CLASS;
|
||||
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, JetClassOrObject origin) {
|
||||
boolean isAnnotation = origin instanceof JetClass && ((JetClass) origin).isAnnotation();
|
||||
for (JetParameter p : getPrimaryConstructorParameters()) {
|
||||
if (p.hasValOrVar()) {
|
||||
PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
|
||||
|
||||
@@ -21,37 +21,25 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getMappingFileName;
|
||||
|
||||
public class ClassFileFactory implements OutputFileCollection {
|
||||
private final GenerationState state;
|
||||
private final ClassBuilderFactory builderFactory;
|
||||
private final Map<FqName, PackageCodegen> package2codegen = new HashMap<FqName, PackageCodegen>();
|
||||
private final Map<FqName, MultifileClassCodegen> multifileClass2codegen = new HashMap<FqName, MultifileClassCodegen>();
|
||||
private final Map<String, OutAndSourceFileList> generators = new LinkedHashMap<String, OutAndSourceFileList>();
|
||||
private final Map<String, ClassBuilderAndSourceFileList> generators = new LinkedHashMap<String, ClassBuilderAndSourceFileList>();
|
||||
|
||||
private boolean isDone = false;
|
||||
|
||||
@@ -84,106 +72,12 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
void done() {
|
||||
if (!isDone) {
|
||||
isDone = true;
|
||||
Collection<PackageCodegen> packageCodegens = package2codegen.values();
|
||||
for (PackageCodegen codegen : packageCodegens) {
|
||||
for (PackageCodegen codegen : package2codegen.values()) {
|
||||
codegen.done();
|
||||
}
|
||||
Collection<MultifileClassCodegen> multifileClassCodegens = multifileClass2codegen.values();
|
||||
for (MultifileClassCodegen codegen : multifileClassCodegens) {
|
||||
codegen.done();
|
||||
}
|
||||
writeModuleMappings(packageCodegens, multifileClassCodegens);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeModuleMappings(
|
||||
@NotNull Collection<PackageCodegen> packageCodegens,
|
||||
@NotNull Collection<MultifileClassCodegen> multifileClassCodegens
|
||||
) {
|
||||
final JvmPackageTable.PackageTable.Builder builder = JvmPackageTable.PackageTable.newBuilder();
|
||||
String outputFilePath = getMappingFileName(state.getModuleName());
|
||||
|
||||
List<PackageParts> parts = collectGeneratedPackageParts(packageCodegens, multifileClassCodegens);
|
||||
|
||||
Set<File> sourceFiles = new HashSet<File>();
|
||||
// TODO extract common logic
|
||||
for (PackageCodegen codegen : packageCodegens) {
|
||||
sourceFiles.addAll(toIoFilesIgnoringNonPhysical(PackagePartClassUtils.getFilesWithCallables(codegen.getFiles())));
|
||||
}
|
||||
for (MultifileClassCodegen codegen : multifileClassCodegens) {
|
||||
sourceFiles.addAll(toIoFilesIgnoringNonPhysical(PackagePartClassUtils.getFilesWithCallables(codegen.getFiles())));
|
||||
}
|
||||
|
||||
for (PackageParts part : CodegenPackage.addCompiledPartsAndSort(parts, state)) {
|
||||
PackageParts.Companion.serialize(part, builder);
|
||||
}
|
||||
|
||||
if (builder.getPackagePartsCount() != 0) {
|
||||
state.getProgress().reportOutput(sourceFiles, new File(outputFilePath));
|
||||
generators.put(outputFilePath, new OutAndSourceFileList(KotlinPackage.toList(sourceFiles)) {
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
try {
|
||||
ByteArrayOutputStream moduleMapping = new ByteArrayOutputStream(4096);
|
||||
DataOutputStream dataOutStream = new DataOutputStream(moduleMapping);
|
||||
int[] version = JvmAbi.VERSION.toArray();
|
||||
dataOutStream.writeInt(version.length);
|
||||
for (int number : version) {
|
||||
dataOutStream.writeInt(number);
|
||||
}
|
||||
builder.build().writeTo(dataOutStream);
|
||||
dataOutStream.flush();
|
||||
return moduleMapping.toByteArray();
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilderFactory factory) {
|
||||
try {
|
||||
return new String(asBytes(factory), "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static List<PackageParts> collectGeneratedPackageParts(
|
||||
@NotNull Collection<PackageCodegen> packageCodegens,
|
||||
@NotNull Collection<MultifileClassCodegen> multifileClassCodegens
|
||||
) {
|
||||
Map<String, PackageParts> mergedPartsByPackageName = new LinkedHashMap<String, PackageParts>();
|
||||
|
||||
for (PackageCodegen packageCodegen : packageCodegens) {
|
||||
PackageParts generatedParts = packageCodegen.getPackageParts();
|
||||
PackageParts premergedParts = new PackageParts(generatedParts.getPackageFqName());
|
||||
mergedPartsByPackageName.put(generatedParts.getPackageFqName(), premergedParts);
|
||||
premergedParts.getParts().addAll(generatedParts.getParts());
|
||||
}
|
||||
|
||||
for (MultifileClassCodegen multifileClassCodegen : multifileClassCodegens) {
|
||||
PackageParts multifileClassParts = multifileClassCodegen.getPackageParts();
|
||||
PackageParts premergedParts = mergedPartsByPackageName.get(multifileClassParts.getPackageFqName());
|
||||
if (premergedParts == null) {
|
||||
premergedParts = new PackageParts(multifileClassParts.getPackageFqName());
|
||||
mergedPartsByPackageName.put(multifileClassParts.getPackageFqName(), premergedParts);
|
||||
}
|
||||
premergedParts.getParts().addAll(multifileClassParts.getParts());
|
||||
}
|
||||
|
||||
List<PackageParts> result = new ArrayList<PackageParts>();
|
||||
result.addAll(mergedPartsByPackageName.values());
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<OutputFile> asList() {
|
||||
@@ -215,16 +109,6 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
return answer.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@TestOnly
|
||||
public Map<String, String> createTextForEachFile() {
|
||||
Map<String, String> answer = new LinkedHashMap<String, String>();
|
||||
for (OutputFile file : asList()) {
|
||||
answer.put(file.getRelativePath(), file.asText());
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PackageCodegen forPackage(@NotNull FqName fqName, @NotNull Collection<JetFile> files) {
|
||||
assert !isDone : "Already done!";
|
||||
@@ -237,17 +121,6 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
return codegen;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MultifileClassCodegen forMultifileClass(@NotNull FqName facadeFqName, @NotNull Collection<JetFile> files) {
|
||||
assert !isDone : "Already done!";
|
||||
MultifileClassCodegen codegen = multifileClass2codegen.get(facadeFqName);
|
||||
if (codegen == null) {
|
||||
codegen = new MultifileClassCodegen(state, files, facadeFqName);
|
||||
multifileClass2codegen.put(facadeFqName, codegen);
|
||||
}
|
||||
return codegen;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<File> toIoFilesIgnoringNonPhysical(@NotNull Collection<? extends PsiFile> psiFiles) {
|
||||
List<File> result = Lists.newArrayList();
|
||||
@@ -278,7 +151,7 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<File> getSourceFiles() {
|
||||
OutAndSourceFileList pair = generators.get(relativeClassFilePath);
|
||||
ClassBuilderAndSourceFileList pair = generators.get(relativeClassFilePath);
|
||||
if (pair == null) {
|
||||
throw new IllegalStateException("No record for binary file " + relativeClassFilePath);
|
||||
}
|
||||
@@ -289,13 +162,13 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
@NotNull
|
||||
@Override
|
||||
public byte[] asByteArray() {
|
||||
return generators.get(relativeClassFilePath).asBytes(builderFactory);
|
||||
return builderFactory.asBytes(generators.get(relativeClassFilePath).classBuilder);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String asText() {
|
||||
return generators.get(relativeClassFilePath).asText(builderFactory);
|
||||
return builderFactory.asText(generators.get(relativeClassFilePath).classBuilder);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -305,36 +178,14 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ClassBuilderAndSourceFileList extends OutAndSourceFileList {
|
||||
private static final class ClassBuilderAndSourceFileList {
|
||||
private final ClassBuilder classBuilder;
|
||||
private final List<File> sourceFiles;
|
||||
|
||||
private ClassBuilderAndSourceFileList(ClassBuilder classBuilder, List<File> sourceFiles) {
|
||||
super(sourceFiles);
|
||||
this.classBuilder = classBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] asBytes(ClassBuilderFactory factory) {
|
||||
return factory.asBytes(classBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asText(ClassBuilderFactory factory) {
|
||||
return factory.asText(classBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class OutAndSourceFileList {
|
||||
|
||||
protected final List<File> sourceFiles;
|
||||
|
||||
private OutAndSourceFileList(List<File> sourceFiles) {
|
||||
this.sourceFiles = sourceFiles;
|
||||
}
|
||||
|
||||
public abstract byte[] asBytes(ClassBuilderFactory factory);
|
||||
|
||||
public abstract String asText(ClassBuilderFactory factory);
|
||||
}
|
||||
|
||||
public void removeInlinedClasses(Set<String> classNamesToRemove) {
|
||||
|
||||
@@ -1,59 +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
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ConflictingJvmDeclarationsData
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MemberKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
public abstract class ClassNameCollectionClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
|
||||
protected abstract fun handleClashingNames(internalName: String, origin: JvmDeclarationOrigin)
|
||||
|
||||
override fun newClassBuilder(origin: JvmDeclarationOrigin): ClassNameCollectionClassBuilder {
|
||||
return ClassNameCollectionClassBuilder(origin, delegate.newClassBuilder(origin))
|
||||
}
|
||||
|
||||
private inner class ClassNameCollectionClassBuilder(
|
||||
private val classCreatedFor: JvmDeclarationOrigin,
|
||||
internal val _delegate: ClassBuilder
|
||||
) : DelegatingClassBuilder() {
|
||||
|
||||
override fun getDelegate() = _delegate
|
||||
|
||||
private var classInternalName: String? = null
|
||||
|
||||
override fun defineClass(origin: PsiElement?, version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<out String>) {
|
||||
classInternalName = name
|
||||
super.defineClass(origin, version, access, name, signature, superName, interfaces)
|
||||
}
|
||||
|
||||
override fun done() {
|
||||
if (classInternalName != null) {
|
||||
handleClashingNames(classInternalName!!, classCreatedFor)
|
||||
}
|
||||
super.done()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,21 +30,12 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.psi.JetElement;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.kotlin.utils.UtilsPackage;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -56,7 +46,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.ExpressionCodegen.generateClassLiteralReference;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
|
||||
@@ -64,7 +53,6 @@ import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticC
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
@@ -73,7 +61,6 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
private final SamType samType;
|
||||
private final JetType superClassType;
|
||||
private final List<JetType> superInterfaceTypes;
|
||||
private final FunctionDescriptor functionReferenceTarget;
|
||||
private final FunctionGenerationStrategy strategy;
|
||||
private final CalculatedClosure closure;
|
||||
private final Type asmType;
|
||||
@@ -89,7 +76,6 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
@Nullable SamType samType,
|
||||
@NotNull ClosureContext context,
|
||||
@NotNull KotlinSyntheticClass.Kind syntheticClassKind,
|
||||
@Nullable FunctionDescriptor functionReferenceTarget,
|
||||
@NotNull FunctionGenerationStrategy strategy,
|
||||
@NotNull MemberCodegen<?> parentCodegen,
|
||||
@NotNull ClassBuilder classBuilder
|
||||
@@ -100,7 +86,6 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
this.classDescriptor = context.getContextDescriptor();
|
||||
this.samType = samType;
|
||||
this.syntheticClassKind = syntheticClassKind;
|
||||
this.functionReferenceTarget = functionReferenceTarget;
|
||||
this.strategy = strategy;
|
||||
|
||||
if (samType == null) {
|
||||
@@ -197,21 +182,17 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
|
||||
descriptorForBridges
|
||||
.initialize(null, erasedInterfaceFunction.getDispatchReceiverParameter(), erasedInterfaceFunction.getTypeParameters(),
|
||||
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(),
|
||||
Modality.OPEN, erasedInterfaceFunction.getVisibility(), false);
|
||||
erasedInterfaceFunction.getValueParameters(), erasedInterfaceFunction.getReturnType(), Modality.OPEN,
|
||||
erasedInterfaceFunction.getVisibility());
|
||||
|
||||
descriptorForBridges.addOverriddenDescriptor(erasedInterfaceFunction);
|
||||
functionCodegen.generateBridges(descriptorForBridges);
|
||||
}
|
||||
|
||||
if (functionReferenceTarget != null) {
|
||||
generateFunctionReferenceMethods(functionReferenceTarget);
|
||||
}
|
||||
|
||||
this.constructor = generateConstructor();
|
||||
this.constructor = generateConstructor(superClassAsmType);
|
||||
|
||||
if (isConst(closure)) {
|
||||
generateConstInstance(asmType, asmType, UtilsPackage.<InstructionAdapter>doNothing());
|
||||
generateConstInstance();
|
||||
}
|
||||
|
||||
genClosureFields(closure, v, typeMapper);
|
||||
@@ -224,20 +205,6 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
@Override
|
||||
protected void generateKotlinAnnotation() {
|
||||
writeKotlinSyntheticClassAnnotation(v, syntheticClassKind);
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), typeMapper));
|
||||
|
||||
ProtoBuf.Callable callableProto = serializer.callableProto(funDescriptor).build();
|
||||
|
||||
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CALLABLE), true);
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
AnnotationVisitor array = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME);
|
||||
for (String string : BitEncoding.encodeBytes(serializer.serialize(callableProto))) {
|
||||
array.visit(null, string);
|
||||
}
|
||||
array.visitEnd();
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -247,39 +214,77 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue putInstanceOnStack(@NotNull final ExpressionCodegen codegen) {
|
||||
return StackValue.operation(
|
||||
functionReferenceTarget != null ? K_FUNCTION : asmType,
|
||||
new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
if (isConst(closure)) {
|
||||
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
|
||||
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
|
||||
}
|
||||
|
||||
if (functionReferenceTarget != null) {
|
||||
v.invokestatic(REFLECTION, "function", Type.getMethodDescriptor(K_FUNCTION, FUNCTION_REFERENCE), false);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
public StackValue putInstanceOnStack(
|
||||
@NotNull final ExpressionCodegen codegen,
|
||||
@Nullable final FunctionDescriptor functionReferenceTarget
|
||||
) {
|
||||
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
if (isConst(closure)) {
|
||||
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
|
||||
}
|
||||
);
|
||||
else {
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
|
||||
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
|
||||
}
|
||||
|
||||
if (functionReferenceTarget != null) {
|
||||
equipFunctionReferenceWithReflection(v, functionReferenceTarget);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void equipFunctionReferenceWithReflection(@NotNull InstructionAdapter v, @NotNull FunctionDescriptor target) {
|
||||
DeclarationDescriptor container = target.getContainingDeclaration();
|
||||
|
||||
Type type;
|
||||
if (container instanceof PackageFragmentDescriptor) {
|
||||
type = target.getExtensionReceiverParameter() != null
|
||||
? K_TOP_LEVEL_EXTENSION_FUNCTION
|
||||
: K_TOP_LEVEL_FUNCTION;
|
||||
}
|
||||
else if (container instanceof ClassDescriptor) {
|
||||
type = K_MEMBER_FUNCTION;
|
||||
}
|
||||
else {
|
||||
type = K_LOCAL_FUNCTION;
|
||||
}
|
||||
|
||||
Method method = method("function", K_FUNCTION, FUNCTION_REFERENCE);
|
||||
v.invokestatic(REFLECTION, method.getName(), method.getDescriptor(), false);
|
||||
StackValue.coerce(K_FUNCTION, type, v);
|
||||
}
|
||||
|
||||
|
||||
private void generateConstInstance() {
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_SYNTHETIC, "<clinit>", "()V", null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
v.newField(OtherOrigin(element, funDescriptor), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, asmType.getDescriptor(), null, null);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
mv.visitCode();
|
||||
iv.anew(asmType);
|
||||
iv.dup();
|
||||
iv.invokespecial(asmType.getInternalName(), "<init>", "()V", false);
|
||||
iv.putstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
|
||||
mv.visitInsn(RETURN);
|
||||
FunctionCodegen.endVisit(mv, "<clinit>", element);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateBridge(@NotNull Method bridge, @NotNull Method delegate) {
|
||||
if (bridge.equals(delegate)) return;
|
||||
|
||||
MethodVisitor mv =
|
||||
v.newMethod(OtherOrigin(element, funDescriptor), ACC_PUBLIC | ACC_BRIDGE,
|
||||
bridge.getName(), bridge.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
v.newMethod(OtherOrigin(element, funDescriptor), ACC_PUBLIC | ACC_BRIDGE, bridge.getName(), bridge.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||
|
||||
@@ -290,18 +295,17 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
|
||||
iv.load(0, asmType);
|
||||
|
||||
Type[] myParameterTypes = bridge.getArgumentTypes();
|
||||
ReceiverParameterDescriptor receiver = funDescriptor.getExtensionReceiverParameter();
|
||||
int count = 1;
|
||||
if (receiver != null) {
|
||||
StackValue.local(count, bridge.getArgumentTypes()[count - 1]).put(typeMapper.mapType(receiver.getType()), iv);
|
||||
count++;
|
||||
}
|
||||
|
||||
List<ParameterDescriptor> calleeParameters = KotlinPackage.plus(
|
||||
UtilsPackage.<ParameterDescriptor>singletonOrEmptyList(funDescriptor.getExtensionReceiverParameter()),
|
||||
funDescriptor.getValueParameters()
|
||||
);
|
||||
|
||||
int slot = 1;
|
||||
for (int i = 0; i < calleeParameters.size(); i++) {
|
||||
Type type = myParameterTypes[i];
|
||||
StackValue.local(slot, type).put(typeMapper.mapType(calleeParameters.get(i)), iv);
|
||||
slot += type.getSize();
|
||||
List<ValueParameterDescriptor> params = funDescriptor.getValueParameters();
|
||||
for (ValueParameterDescriptor param : params) {
|
||||
StackValue.local(count, bridge.getArgumentTypes()[count - 1]).put(typeMapper.mapType(param.getType()), iv);
|
||||
count++;
|
||||
}
|
||||
|
||||
iv.invokevirtual(asmType.getInternalName(), delegate.getName(), delegate.getDescriptor(), false);
|
||||
@@ -312,79 +316,8 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
FunctionCodegen.endVisit(mv, "bridge", element);
|
||||
}
|
||||
|
||||
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
|
||||
private void generateFunctionReferenceMethods(@NotNull FunctionDescriptor descriptor) {
|
||||
int flags = ACC_PUBLIC | ACC_FINAL;
|
||||
boolean generateBody = state.getClassBuilderMode() == ClassBuilderMode.FULL;
|
||||
|
||||
{
|
||||
MethodVisitor mv =
|
||||
v.newMethod(NO_ORIGIN, flags, "getOwner", Type.getMethodDescriptor(K_DECLARATION_CONTAINER_TYPE), null, null);
|
||||
if (generateBody) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
generateCallableReferenceDeclarationContainer(iv, descriptor, typeMapper);
|
||||
iv.areturn(K_DECLARATION_CONTAINER_TYPE);
|
||||
FunctionCodegen.endVisit(iv, "function reference getOwner", element);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MethodVisitor mv =
|
||||
v.newMethod(NO_ORIGIN, flags, "getName", Type.getMethodDescriptor(JAVA_STRING_TYPE), null, null);
|
||||
if (generateBody) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
iv.aconst(descriptor.getName().asString());
|
||||
iv.areturn(JAVA_STRING_TYPE);
|
||||
FunctionCodegen.endVisit(iv, "function reference getName", element);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MethodVisitor mv = v.newMethod(NO_ORIGIN, flags, "getSignature", Type.getMethodDescriptor(JAVA_STRING_TYPE), null, null);
|
||||
if (generateBody) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
Method method = typeMapper.mapSignature(descriptor.getOriginal()).getAsmMethod();
|
||||
iv.aconst(method.getName() + method.getDescriptor());
|
||||
iv.areturn(JAVA_STRING_TYPE);
|
||||
FunctionCodegen.endVisit(iv, "function reference getSignature", element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateCallableReferenceDeclarationContainer(
|
||||
@NotNull InstructionAdapter iv,
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@NotNull JetTypeMapper typeMapper
|
||||
) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container instanceof ClassDescriptor) {
|
||||
// TODO: getDefaultType() here is wrong and won't work for arrays
|
||||
StackValue value = generateClassLiteralReference(typeMapper, ((ClassDescriptor) container).getDefaultType());
|
||||
value.put(K_CLASS_TYPE, iv);
|
||||
}
|
||||
else if (container instanceof PackageFragmentDescriptor) {
|
||||
String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(
|
||||
((PackageFragmentDescriptor) container).getFqName()
|
||||
);
|
||||
iv.getstatic(packageClassInternalName, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, K_PACKAGE_TYPE.getDescriptor());
|
||||
}
|
||||
else if (container instanceof ScriptDescriptor) {
|
||||
// TODO: correct container for scripts (KScript?)
|
||||
StackValue value = generateClassLiteralReference(
|
||||
typeMapper, ((ScriptDescriptor) container).getClassDescriptor().getDefaultType()
|
||||
);
|
||||
value.put(K_CLASS_TYPE, iv);
|
||||
}
|
||||
else {
|
||||
iv.aconst(null);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Method generateConstructor() {
|
||||
private Method generateConstructor(@NotNull Type superClassAsmType) {
|
||||
List<FieldInfo> args = calculateConstructorParameters(typeMapper, closure, asmType);
|
||||
|
||||
Type[] argTypes = fieldListToTypeArray(args);
|
||||
@@ -473,7 +406,6 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
ClassDescriptor elementClass = elementDescriptor.getExtensionReceiverParameter() == null
|
||||
? getBuiltIns(elementDescriptor).getFunction(arity)
|
||||
: getBuiltIns(elementDescriptor).getExtensionFunction(arity);
|
||||
JetScope scope = elementClass.getDefaultType().getMemberScope();
|
||||
return scope.getFunctions(OperatorConventions.INVOKE, NoLookupLocation.FROM_BACKEND).iterator().next();
|
||||
return elementClass.getDefaultType().getMemberScope().getFunctions(OperatorConventions.INVOKE).iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
|
||||
public class CodegenFileClassesProvider(private val packageFacadesAsMultifileClasses: Boolean) : JvmFileClassesProvider {
|
||||
override public fun getFileClassInfo(file: JetFile): JvmFileClassInfo {
|
||||
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
||||
if (packageFacadesAsMultifileClasses && !fileClassInfo.isMultifileClass) {
|
||||
return JvmFileClassUtil.getMultifilePackageFacadePartInfo(file)
|
||||
}
|
||||
else {
|
||||
return fileClassInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,24 +18,23 @@ package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.codegen.MutableClassDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_ABSTRACT
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_PUBLIC
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_SYNTHETIC
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.ArrayList
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedHashSet
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||
import java.util.HashSet
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
|
||||
/**
|
||||
* Generates exception-throwing stubs for methods from mutable collection classes not implemented in Kotlin classes which inherit only from
|
||||
@@ -47,7 +46,7 @@ class CollectionStubMethodGenerator(
|
||||
private val functionCodegen: FunctionCodegen,
|
||||
private val v: ClassBuilder
|
||||
) {
|
||||
private val typeMapper = state.typeMapper
|
||||
private val typeMapper = state.getTypeMapper()
|
||||
|
||||
fun generate() {
|
||||
val superCollectionClasses = findRelevantSuperCollectionClasses()
|
||||
@@ -128,7 +127,7 @@ class CollectionStubMethodGenerator(
|
||||
private fun findRelevantSuperCollectionClasses(): Collection<CollectionClassPair> {
|
||||
fun pair(readOnlyClass: ClassDescriptor, mutableClass: ClassDescriptor) = CollectionClassPair(readOnlyClass, mutableClass)
|
||||
|
||||
val collectionClasses = with(descriptor.builtIns) {
|
||||
val collectionClasses = with(KotlinBuiltIns.getInstance()) {
|
||||
listOf(
|
||||
pair(getCollection(), getMutableCollection()),
|
||||
pair(getSet(), getMutableSet()),
|
||||
@@ -165,7 +164,7 @@ class CollectionStubMethodGenerator(
|
||||
val result = ArrayList<FunctionDescriptor>()
|
||||
|
||||
OverrideResolver.generateOverridesInAClass(klass, listOf(), object : OverridingUtil.DescriptorSink {
|
||||
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
|
||||
override fun addToScope(fakeOverride: CallableMemberDescriptor) {
|
||||
if (fakeOverride !is FunctionDescriptor) return
|
||||
if (fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionClass) != null) {
|
||||
result.add(fakeOverride)
|
||||
@@ -192,13 +191,13 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> {
|
||||
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), ClassKind.CLASS, false,
|
||||
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), JetScope.Empty, ClassKind.CLASS, false,
|
||||
Name.special("<synthetic inheritor of ${descriptor.getName()}>"), descriptor.getSource())
|
||||
child.setModality(Modality.FINAL)
|
||||
child.setVisibility(Visibilities.PUBLIC)
|
||||
val typeParameters = descriptor.getTypeConstructor().getParameters()
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitutor.EMPTY, child, newTypeParameters)
|
||||
child.setTypeParameterDescriptors(typeParameters)
|
||||
return Pair(child, newTypeParameters)
|
||||
}
|
||||
@@ -208,7 +207,8 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): JetType {
|
||||
return JetTypeImpl.create(Annotations.EMPTY, classDescriptor, false, typeArguments)
|
||||
return JetTypeImpl(Annotations.EMPTY, classDescriptor.getTypeConstructor(), false, typeArguments,
|
||||
classDescriptor.getMemberScope(typeArguments))
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.signature(): JvmMethodSignature = typeMapper.mapSignature(this)
|
||||
|
||||
@@ -17,14 +17,15 @@
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.JetClass
|
||||
import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||
import org.jetbrains.kotlin.psi.JetElement
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -38,13 +39,12 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
* If all of the parameters of the specified constructor declare default values,
|
||||
* generates a no-argument constructor that passes default values for all arguments.
|
||||
*/
|
||||
fun generateConstructorOverloadsIfNeeded(
|
||||
constructorDescriptor: ConstructorDescriptor,
|
||||
classBuilder: ClassBuilder,
|
||||
contextKind: OwnerKind,
|
||||
classOrObject: JetClassOrObject
|
||||
) {
|
||||
if (generateOverloadsIfNeeded(classOrObject, constructorDescriptor, constructorDescriptor, contextKind, classBuilder)) {
|
||||
fun generateConstructorOverloadsIfNeeded(constructorDescriptor: ConstructorDescriptor,
|
||||
classBuilder: ClassBuilder,
|
||||
context: CodegenContext<*>,
|
||||
classOrObject: JetClassOrObject) {
|
||||
if (generateOverloadsIfNeeded(classOrObject, constructorDescriptor, constructorDescriptor,
|
||||
context, classBuilder)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
return
|
||||
}
|
||||
|
||||
generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject, contextKind,
|
||||
generateOverloadWithSubstitutedParameters(constructorDescriptor, constructorDescriptor, classBuilder, classOrObject,
|
||||
context,
|
||||
constructorDescriptor.countDefaultParameters())
|
||||
}
|
||||
|
||||
@@ -69,30 +70,26 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
* implementation in the companion object class)
|
||||
* @return true if the overloads annotation was found on the element, false otherwise
|
||||
*/
|
||||
fun generateOverloadsIfNeeded(
|
||||
methodElement: JetElement?,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
delegateFunctionDescriptor: FunctionDescriptor,
|
||||
contextKind: OwnerKind,
|
||||
classBuilder: ClassBuilder
|
||||
): Boolean {
|
||||
if (!functionDescriptor.hasJvmOverloadsAnnotation()) {
|
||||
fun generateOverloadsIfNeeded(methodElement: JetElement?,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
delegateFunctionDescriptor: FunctionDescriptor,
|
||||
owner: CodegenContext<*>,
|
||||
classBuilder: ClassBuilder): Boolean {
|
||||
if (functionDescriptor.getAnnotations().findAnnotation(FqName("kotlin.jvm.jvmOverloads")) == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
val count = functionDescriptor.countDefaultParameters()
|
||||
val context = owner.intoFunction(functionDescriptor)
|
||||
|
||||
for (i in 1..count) {
|
||||
generateOverloadWithSubstitutedParameters(
|
||||
functionDescriptor, delegateFunctionDescriptor, classBuilder, methodElement, contextKind, i
|
||||
)
|
||||
generateOverloadWithSubstitutedParameters(functionDescriptor, delegateFunctionDescriptor, classBuilder, methodElement, context, i)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.countDefaultParameters() =
|
||||
valueParameters.count { it.hasDefaultValue() }
|
||||
getValueParameters().count { it.hasDefaultValue() }
|
||||
|
||||
/**
|
||||
* Generates an overload for [functionDescriptor] that substitutes default values for the last
|
||||
@@ -105,19 +102,18 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
* implementation in the companion object class)
|
||||
* @param methodElement the PSI element for the method implementation (used in diagnostic messages only)
|
||||
*/
|
||||
private fun generateOverloadWithSubstitutedParameters(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
delegateFunctionDescriptor: FunctionDescriptor,
|
||||
classBuilder: ClassBuilder,
|
||||
methodElement: JetElement?,
|
||||
contextKind: OwnerKind,
|
||||
substituteCount: Int
|
||||
) {
|
||||
val typeMapper = state.typeMapper
|
||||
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
|
||||
fun generateOverloadWithSubstitutedParameters(functionDescriptor: FunctionDescriptor,
|
||||
delegateFunctionDescriptor: FunctionDescriptor,
|
||||
classBuilder: ClassBuilder,
|
||||
methodElement: JetElement?,
|
||||
context: CodegenContext<*>,
|
||||
substituteCount: Int) {
|
||||
val typeMapper = state.getTypeMapper()
|
||||
|
||||
val isStatic = AsmUtil.isStaticMethod(context.getContextKind(), functionDescriptor)
|
||||
val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0)
|
||||
val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount)
|
||||
val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters)
|
||||
val signature = typeMapper.mapSignature(functionDescriptor, context.getContextKind(), remainingParameters)
|
||||
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
|
||||
signature.getAsmMethod().getName(),
|
||||
signature.getAsmMethod().getDescriptor(),
|
||||
@@ -131,7 +127,7 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
annotationCodegen.genAnnotations(it.value, signature.getValueParameters()[it.index].getAsmType())
|
||||
}
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) {
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) {
|
||||
mv.visitEnd()
|
||||
return
|
||||
}
|
||||
@@ -140,7 +136,7 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
val v = InstructionAdapter(mv)
|
||||
mv.visitCode()
|
||||
|
||||
val methodOwner = typeMapper.mapToCallableMethod(delegateFunctionDescriptor, false).owner
|
||||
val methodOwner = typeMapper.mapToCallableMethod(delegateFunctionDescriptor, false, context).owner
|
||||
if (!isStatic) {
|
||||
val thisIndex = frameMap.enterTemp(AsmTypes.OBJECT_TYPE)
|
||||
v.load(thisIndex, methodOwner) // Load this on stack
|
||||
@@ -191,7 +187,7 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
v.aconst(null)
|
||||
}
|
||||
|
||||
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
|
||||
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, context.getContextKind(), context)
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
v.invokespecial(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false)
|
||||
}
|
||||
@@ -210,11 +206,10 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
|
||||
private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: JetClassOrObject): Boolean {
|
||||
val classDescriptor = constructorDescriptor.getContainingDeclaration()
|
||||
if (classDescriptor.getKind() != ClassKind.CLASS) return false
|
||||
|
||||
if (classOrObject.isLocal()) return false
|
||||
|
||||
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
||||
if (CodegenBinding.canHaveOuter(state.getBindingContext(), classDescriptor)) return false
|
||||
|
||||
if (Visibilities.isPrivate(classDescriptor.getVisibility()) || Visibilities.isPrivate(constructorDescriptor.getVisibility()))
|
||||
return false
|
||||
|
||||
@@ -1,42 +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
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ConflictingJvmDeclarationsData
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MemberKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
public abstract class DelegatingClassBuilderFactory(
|
||||
protected val delegate: ClassBuilderFactory
|
||||
|
||||
) : ClassBuilderFactory by delegate {
|
||||
|
||||
abstract override fun newClassBuilder(origin: JvmDeclarationOrigin): DelegatingClassBuilder
|
||||
|
||||
public override fun asBytes(builder: ClassBuilder?): ByteArray? {
|
||||
return delegate.asBytes((builder as DelegatingClassBuilder).getDelegate())
|
||||
}
|
||||
|
||||
public override fun asText(builder: ClassBuilder?): String? {
|
||||
return delegate.asText((builder as DelegatingClassBuilder).getDelegate())
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
||||
import org.jetbrains.kotlin.codegen.inline.*;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsPackage;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -46,35 +45,37 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ScriptCodeDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesPackage;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.EvaluatePackage;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.Approximation;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypeProjection;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
@@ -84,6 +85,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -102,6 +104,7 @@ import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.TraitImpl;
|
||||
import static org.jetbrains.kotlin.serialization.deserialization.DeserializationPackage.findClassAcrossModuleDependencies;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implements LocalLookup {
|
||||
@@ -279,12 +282,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
StackValue stackValue = selector.accept(visitor, receiver);
|
||||
|
||||
RuntimeAssertionInfo runtimeAssertionInfo = null;
|
||||
Approximation.Info approximationInfo = null;
|
||||
if (selector instanceof JetExpression) {
|
||||
runtimeAssertionInfo = bindingContext.get(BindingContextSlicesPackage.getRUNTIME_ASSERTION_INFO(), (JetExpression) selector);
|
||||
approximationInfo = bindingContext.get(BindingContext.EXPRESSION_RESULT_APPROXIMATION, (JetExpression) selector);
|
||||
}
|
||||
|
||||
return genNotNullAssertions(state, stackValue, runtimeAssertionInfo);
|
||||
return genNotNullAssertions(state, stackValue, approximationInfo);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
@@ -354,15 +357,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@Override
|
||||
public StackValue visitSuperExpression(@NotNull JetSuperExpression expression, StackValue data) {
|
||||
return StackValue.thisOrOuter(this, getSuperCallLabelTarget(context, expression), true, true);
|
||||
return StackValue.thisOrOuter(this, getSuperCallLabelTarget(expression), true, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor getSuperCallLabelTarget(
|
||||
@NotNull CodegenContext<?> context,
|
||||
@NotNull JetSuperExpression expression
|
||||
) {
|
||||
BindingContext bindingContext = context.getState().getBindingContext();
|
||||
private ClassDescriptor getSuperCallLabelTarget(JetSuperExpression expression) {
|
||||
PsiElement labelPsi = bindingContext.get(LABEL_TARGET, expression.getTargetLabel());
|
||||
ClassDescriptor labelTarget = (ClassDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, labelPsi);
|
||||
DeclarationDescriptor descriptor = bindingContext.get(REFERENCE_TARGET, expression.getInstanceReference());
|
||||
@@ -1076,8 +1075,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
assert loopRangeType != null;
|
||||
Type asmLoopRangeType = asmType(loopRangeType);
|
||||
|
||||
Collection<VariableDescriptor> incrementProp =
|
||||
loopRangeType.getMemberScope().getProperties(Name.identifier("increment"), NoLookupLocation.FROM_BACKEND);
|
||||
Collection<VariableDescriptor> incrementProp = loopRangeType.getMemberScope().getProperties(Name.identifier("increment"));
|
||||
assert incrementProp.size() == 1 : loopRangeType + " " + incrementProp.size();
|
||||
incrementType = asmType(incrementProp.iterator().next().getType());
|
||||
|
||||
@@ -1295,19 +1293,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@Override
|
||||
public StackValue visitConstantExpression(@NotNull JetConstantExpression expression, StackValue receiver) {
|
||||
ConstantValue<?> compileTimeValue = getCompileTimeConstant(expression, bindingContext);
|
||||
CompileTimeConstant<?> compileTimeValue = getCompileTimeConstant(expression, bindingContext);
|
||||
assert compileTimeValue != null;
|
||||
return StackValue.constant(compileTimeValue.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(@NotNull JetExpression expression, @NotNull BindingContext bindingContext) {
|
||||
public static CompileTimeConstant getCompileTimeConstant(@NotNull JetExpression expression, @NotNull BindingContext bindingContext) {
|
||||
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, bindingContext);
|
||||
if (compileTimeValue == null) {
|
||||
return null;
|
||||
if (compileTimeValue instanceof IntegerValueTypeConstant) {
|
||||
JetType expectedType = bindingContext.getType(expression);
|
||||
assert expectedType != null : "Expression is not type checked: " + expression.getText();
|
||||
return EvaluatePackage.createCompileTimeConstantWithType((IntegerValueTypeConstant) compileTimeValue, expectedType);
|
||||
}
|
||||
JetType expectedType = bindingContext.getType(expression);
|
||||
return compileTimeValue.toConstantValue(expectedType);
|
||||
return compileTimeValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1430,8 +1429,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
);
|
||||
|
||||
ClosureCodegen closureCodegen = new ClosureCodegen(
|
||||
state, declaration, samType, context.intoClosure(descriptor, this, typeMapper), kind,
|
||||
functionReferenceTarget, strategy, parentCodegen, cv
|
||||
state, declaration, samType, context.intoClosure(descriptor, this, typeMapper), kind, strategy, parentCodegen, cv
|
||||
);
|
||||
|
||||
closureCodegen.generate();
|
||||
@@ -1441,7 +1439,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
propagateChildReifiedTypeParametersUsages(closureCodegen.getReifiedTypeParametersUsages());
|
||||
}
|
||||
|
||||
return closureCodegen.putInstanceOnStack(this);
|
||||
return closureCodegen.putInstanceOnStack(this, functionReferenceTarget);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1470,7 +1468,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
ConstructorDescriptor constructorToCall = SamCodegenUtil.resolveSamAdapter(superConstructor);
|
||||
List<ValueParameterDescriptor> superValueParameters = superConstructor.getValueParameters();
|
||||
int params = superValueParameters.size();
|
||||
List<Type> superMappedTypes = typeMapper.mapToCallableMethod(constructorToCall, false).getValueParameterTypes();
|
||||
List<Type> superMappedTypes = typeMapper.mapToCallableMethod(constructorToCall).getValueParameterTypes();
|
||||
assert superMappedTypes.size() >= params : String
|
||||
.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s",
|
||||
superMappedTypes.size(), params, classDescriptor);
|
||||
@@ -1660,7 +1658,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
int index = myFrameMap.enter(variableDescriptor, type);
|
||||
|
||||
if (isSharedVarType(type)) {
|
||||
markLineNumber(statement, false);
|
||||
v.anew(type);
|
||||
v.dup();
|
||||
v.invokespecial(type.getInternalName(), "<init>", "()V", false);
|
||||
@@ -1979,19 +1976,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
assert descriptor != null : "Couldn't find descriptor for '" + expression.getText() + "'";
|
||||
descriptor = descriptor.getOriginal();
|
||||
|
||||
boolean isSyntheticField = descriptor instanceof SyntheticFieldDescriptor;
|
||||
if (isSyntheticField) {
|
||||
descriptor = ((SyntheticFieldDescriptor) descriptor).getPropertyDescriptor();
|
||||
}
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor memberDescriptor = DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor);
|
||||
|
||||
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor);
|
||||
if (intrinsic instanceof IntrinsicPropertyGetter) {
|
||||
if (intrinsic instanceof JavaClassProperty) {
|
||||
//TODO: intrinsic properties (see intermediateValueForProperty)
|
||||
Type returnType = typeMapper.mapType(memberDescriptor);
|
||||
StackValue intrinsicResult = ((IntrinsicPropertyGetter) intrinsic).generate(resolvedCall, this, returnType, receiver);
|
||||
if (intrinsicResult != null) return intrinsicResult;
|
||||
return ((JavaClassProperty) intrinsic).generate(returnType, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2011,17 +2003,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
|
||||
boolean directToField =
|
||||
(expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER || isSyntheticField)
|
||||
&& contextKind() != OwnerKind.TRAIT_IMPL;
|
||||
JetSuperExpression superExpression =
|
||||
resolvedCall == null ? null : CallResolverUtilPackage.getSuperCallExpression(resolvedCall.getCall());
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superExpression);
|
||||
expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL;
|
||||
JetExpression r = getReceiverForSelector(expression);
|
||||
boolean isSuper = r instanceof JetSuperExpression;
|
||||
propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor);
|
||||
|
||||
if (directToField) {
|
||||
receiver = StackValue.receiverWithoutReceiverArgument(receiver);
|
||||
}
|
||||
|
||||
return intermediateValueForProperty(propertyDescriptor, directToField, superExpression, receiver);
|
||||
return intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null, receiver);
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
@@ -2047,14 +2038,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return localOrCaptured;
|
||||
}
|
||||
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (descriptor instanceof ValueParameterDescriptor && container instanceof ScriptCodeDescriptor) {
|
||||
ScriptCodeDescriptor scriptCodeDescriptor = (ScriptCodeDescriptor) container;
|
||||
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) scriptCodeDescriptor.getContainingDeclaration();
|
||||
if (descriptor instanceof ValueParameterDescriptor && descriptor.getContainingDeclaration() instanceof ScriptDescriptor) {
|
||||
ScriptDescriptor scriptDescriptor = (ScriptDescriptor) descriptor.getContainingDeclaration();
|
||||
Type scriptClassType = asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
|
||||
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
|
||||
ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
|
||||
//noinspection ConstantConditions
|
||||
StackValue script = StackValue.thisOrOuter(this, scriptClass, false, false);
|
||||
Type fieldType = typeMapper.mapType(valueParameterDescriptor);
|
||||
return StackValue.field(fieldType, scriptClassType, valueParameterDescriptor.getName().getIdentifier(), false, script,
|
||||
@@ -2145,20 +2133,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@Nullable JetSuperExpression superExpression,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, false, receiver);
|
||||
return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, MethodKind.GENERAL, receiver);
|
||||
}
|
||||
|
||||
public StackValue.Property intermediateValueForProperty(
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
boolean forceField,
|
||||
@Nullable JetSuperExpression superExpression,
|
||||
boolean skipAccessorsForPrivateFieldInOuterClass,
|
||||
@NotNull MethodKind methodKind,
|
||||
StackValue receiver
|
||||
) {
|
||||
if (propertyDescriptor instanceof SyntheticJavaPropertyDescriptor) {
|
||||
return intermediateValueForSyntheticExtensionProperty((SyntheticJavaPropertyDescriptor) propertyDescriptor, receiver);
|
||||
}
|
||||
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
@@ -2173,61 +2157,59 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
CallableMethod callableGetter = null;
|
||||
CallableMethod callableSetter = null;
|
||||
|
||||
CodegenContext backingFieldContext;
|
||||
boolean changeOwnerOnTypeMapping;
|
||||
boolean skipPropertyAccessors;
|
||||
boolean skipPropertyAccessors = forceField && !isBackingFieldInAnotherClass;
|
||||
|
||||
CodegenContext backingFieldContext = context.getParentContext();
|
||||
boolean changeOwnerOnTypeMapping = isBackingFieldInAnotherClass;
|
||||
|
||||
if (isBackingFieldInAnotherClass && forceField) {
|
||||
backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration());
|
||||
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
|
||||
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || methodKind == MethodKind.SYNTHETIC_ACCESSOR || methodKind == MethodKind.INITIALIZER;
|
||||
if (!skipPropertyAccessors) {
|
||||
//noinspection ConstantConditions
|
||||
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(
|
||||
propertyDescriptor, true, delegateType, superExpression
|
||||
);
|
||||
changeOwnerOnTypeMapping = !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass);
|
||||
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor, true, delegateType);
|
||||
changeOwnerOnTypeMapping = changeOwnerOnTypeMapping && !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass);
|
||||
}
|
||||
else {
|
||||
changeOwnerOnTypeMapping = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
backingFieldContext = context.getParentContext();
|
||||
changeOwnerOnTypeMapping = isBackingFieldInAnotherClass;
|
||||
skipPropertyAccessors = forceField;
|
||||
}
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
|
||||
if (couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
|
||||
callableGetter = null;
|
||||
}
|
||||
else {
|
||||
if (isSuper && !isInterface(containingDeclaration)) {
|
||||
ClassDescriptor owner = getSuperCallLabelTarget(context, superExpression);
|
||||
ClassDescriptor owner = getSuperCallLabelTarget(superExpression);
|
||||
CodegenContext c = context.findParentContextWithDescriptor(owner);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor;
|
||||
if (c != context.getParentContext()) {
|
||||
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor, superExpression);
|
||||
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superExpression);
|
||||
propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor);
|
||||
|
||||
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
|
||||
if (getter != null) {
|
||||
callableGetter = typeMapper.mapToCallableMethod(getter, isSuper);
|
||||
callableGetter = typeMapper.mapToCallableMethod(getter, isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, context);
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyDescriptor.isVar()) {
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (setter != null && !couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context)) {
|
||||
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
|
||||
if (setter != null) {
|
||||
if (couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context)) {
|
||||
callableSetter = null;
|
||||
}
|
||||
else {
|
||||
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||
Type backingFieldOwner =
|
||||
typeMapper.mapOwner(changeOwnerOnTypeMapping ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor);
|
||||
Type backingFieldOwner = typeMapper.mapOwner(changeOwnerOnTypeMapping ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor,
|
||||
isCallInsideSameModuleAsDeclared(propertyDescriptor, context, state.getOutDirectory()));
|
||||
|
||||
String fieldName;
|
||||
if (isExtensionProperty && !isDelegatedProperty) {
|
||||
@@ -2239,32 +2221,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
fieldName = ((FieldOwnerContext) backingFieldContext).getFieldName(propertyDescriptor, isDelegatedProperty);
|
||||
}
|
||||
else {
|
||||
Name name;
|
||||
if (propertyDescriptor instanceof AccessorForPropertyDescriptor) {
|
||||
name = ((AccessorForPropertyDescriptor) propertyDescriptor).getCalleeDescriptor().getName();
|
||||
}
|
||||
else {
|
||||
name = propertyDescriptor.getName();
|
||||
}
|
||||
fieldName = JvmAbi.getDefaultFieldNameForProperty(name, isDelegatedProperty);
|
||||
fieldName = JvmAbi.getDefaultFieldNameForProperty(propertyDescriptor.getName(), isDelegatedProperty);
|
||||
}
|
||||
|
||||
return StackValue.property(propertyDescriptor, backingFieldOwner,
|
||||
typeMapper.mapType(
|
||||
isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()),
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, state, receiver);
|
||||
}
|
||||
typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()),
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, state, receiver);
|
||||
|
||||
@NotNull
|
||||
private StackValue.Property intermediateValueForSyntheticExtensionProperty(
|
||||
@NotNull SyntheticJavaPropertyDescriptor propertyDescriptor,
|
||||
StackValue receiver
|
||||
) {
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getOriginal().getType());
|
||||
CallableMethod callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetMethod(), false);
|
||||
FunctionDescriptor setMethod = propertyDescriptor.getSetMethod();
|
||||
CallableMethod callableSetter = setMethod != null ? typeMapper.mapToCallableMethod(setMethod, false) : null;
|
||||
return StackValue.property(propertyDescriptor, null, type, false, null, callableGetter, callableSetter, state, receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2336,17 +2299,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PropertyDescriptor accessiblePropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||
return context.accessiblePropertyDescriptor(propertyDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FunctionDescriptor accessibleFunctionDescriptor(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||
FunctionDescriptor originalIfSamAdapter = SamCodegenUtil.getOriginalIfSamAdapter(descriptor);
|
||||
if (originalIfSamAdapter != null) {
|
||||
descriptor = originalIfSamAdapter;
|
||||
}
|
||||
// $default method is not private, so you need no accessor to call it
|
||||
return usesDefaultArguments(resolvedCall)
|
||||
? descriptor
|
||||
: context.accessibleDescriptor(descriptor, CallResolverUtilPackage.getSuperCallExpression(resolvedCall.getCall()));
|
||||
return usesDefaultArguments(resolvedCall) ? descriptor : context.accessibleFunctionDescriptor(descriptor);
|
||||
}
|
||||
|
||||
private static boolean usesDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
@@ -2368,15 +2330,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@NotNull
|
||||
public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
|
||||
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
|
||||
JetSuperExpression superCallExpression = CallResolverUtilPackage.getSuperCallExpression(call);
|
||||
JetSuperExpression superCallExpression = CallResolverUtil.getSuperCallExpression(call);
|
||||
boolean superCall = superCallExpression != null;
|
||||
|
||||
if (superCall && !isInterface(fd.getContainingDeclaration())) {
|
||||
ClassDescriptor owner = getSuperCallLabelTarget(context, superCallExpression);
|
||||
ClassDescriptor owner = getSuperCallLabelTarget(superCallExpression);
|
||||
CodegenContext c = context.findParentContextWithDescriptor(owner);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + fd;
|
||||
if (c != context.getParentContext()) {
|
||||
fd = (FunctionDescriptor) c.getAccessor(fd, superCallExpression);
|
||||
fd = (FunctionDescriptor) c.getAccessor(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2405,12 +2367,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return intrinsic.toCallable(fd, superCall, resolvedCall, this);
|
||||
}
|
||||
|
||||
return resolveToCallableMethod(fd, superCall);
|
||||
return resolveToCallableMethod(fd, superCall, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CallableMethod resolveToCallableMethod(@NotNull FunctionDescriptor fd, boolean superCall) {
|
||||
return typeMapper.mapToCallableMethod(SamCodegenUtil.resolveSamAdapter(fd), superCall);
|
||||
private CallableMethod resolveToCallableMethod(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull CodegenContext context) {
|
||||
return typeMapper.mapToCallableMethod(SamCodegenUtil.resolveSamAdapter(fd), superCall, context);
|
||||
}
|
||||
|
||||
public void invokeMethodWithArguments(
|
||||
@@ -2514,17 +2476,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
TypeParameterDescriptor key = entry.getKey();
|
||||
if (!key.isReified()) continue;
|
||||
|
||||
JetType type = entry.getValue();
|
||||
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
|
||||
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(entry.getValue());
|
||||
if (parameterDescriptor == null) {
|
||||
// type is not generic
|
||||
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
|
||||
Type asmType = typeMapper.mapTypeParameter(type, signatureWriter);
|
||||
Type type = typeMapper.mapTypeParameter(entry.getValue(), signatureWriter);
|
||||
|
||||
mappings.addParameterMappingToType(
|
||||
key.getName().getIdentifier(),
|
||||
type,
|
||||
asmType,
|
||||
signatureWriter.toString()
|
||||
);
|
||||
}
|
||||
@@ -2572,6 +2532,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JetExpression getReceiverForSelector(PsiElement expression) {
|
||||
if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) {
|
||||
JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
|
||||
return parent.getReceiverExpression();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generateReceiver(@NotNull CallableDescriptor descriptor) {
|
||||
return context.generateReceiver(descriptor, state, false);
|
||||
@@ -2671,6 +2640,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
|
||||
|
||||
private static boolean isReceiver(PsiElement expression) {
|
||||
PsiElement parent = expression.getParent();
|
||||
if (parent instanceof JetQualifiedExpression) {
|
||||
JetExpression receiverExpression = ((JetQualifiedExpression) parent).getReceiverExpression();
|
||||
return expression == receiverExpression;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void genVarargs(@NotNull VarargValueArgument valueArgument, @NotNull JetType outType) {
|
||||
Type type = asmType(outType);
|
||||
assert type.getSort() == Type.ARRAY;
|
||||
@@ -2755,13 +2733,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@Override
|
||||
public StackValue visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, StackValue data) {
|
||||
checkReflectionIsAvailable(expression);
|
||||
|
||||
JetType type = bindingContext.getType(expression);
|
||||
assert type != null;
|
||||
|
||||
assert state.getReflectionTypes().getkClass().getTypeConstructor().equals(type.getConstructor())
|
||||
: "::class expression should be type checked to a KClass: " + type;
|
||||
|
||||
return generateClassLiteralReference(typeMapper, KotlinPackage.single(type.getArguments()).getType());
|
||||
return generateClassLiteralReference(KotlinPackage.single(type.getArguments()).getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2775,63 +2755,104 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
|
||||
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
|
||||
if (variableDescriptor != null) {
|
||||
return generatePropertyReference(expression, variableDescriptor, resolvedCall);
|
||||
if (variableDescriptor == null) {
|
||||
throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
|
||||
// TODO: this diagnostic should also be reported on function references once they obtain reflection
|
||||
checkReflectionIsAvailable(expression);
|
||||
|
||||
VariableDescriptor descriptor = (VariableDescriptor) resolvedCall.getResultingDescriptor();
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
return generateTopLevelPropertyReference(descriptor);
|
||||
}
|
||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||
return generateMemberPropertyReference(descriptor, (ClassDescriptor) containingDeclaration);
|
||||
}
|
||||
else if (containingDeclaration instanceof ScriptDescriptor) {
|
||||
return generateMemberPropertyReference(descriptor, ((ScriptDescriptor) containingDeclaration).getClassDescriptor());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unsupported callable reference container: " + containingDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkReflectionIsAvailable(@NotNull JetExpression expression) {
|
||||
if (findClassAcrossModuleDependencies(state.getModule(), JvmAbi.REFLECTION_FACTORY_IMPL) == null) {
|
||||
state.getDiagnostics().report(ErrorsJvm.NO_REFLECTION_IN_CLASS_PATH.on(expression, expression));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generatePropertyReference(
|
||||
@NotNull JetCallableReferenceExpression expression,
|
||||
@NotNull VariableDescriptor variableDescriptor,
|
||||
@NotNull ResolvedCall<?> resolvedCall
|
||||
private StackValue generateTopLevelPropertyReference(@NotNull final VariableDescriptor descriptor) {
|
||||
PackageFragmentDescriptor containingPackage = (PackageFragmentDescriptor) descriptor.getContainingDeclaration();
|
||||
final String packageClassInternalName = PackageClassUtils.getPackageClassInternalName(containingPackage.getFqName());
|
||||
|
||||
final ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
final Method factoryMethod;
|
||||
if (receiverParameter != null) {
|
||||
Type[] parameterTypes = new Type[] {JAVA_STRING_TYPE, K_PACKAGE_TYPE, getType(Class.class)};
|
||||
factoryMethod = descriptor.isVar()
|
||||
? method("mutableTopLevelExtensionProperty", K_MUTABLE_TOP_LEVEL_EXTENSION_PROPERTY_TYPE, parameterTypes)
|
||||
: method("topLevelExtensionProperty", K_TOP_LEVEL_EXTENSION_PROPERTY_TYPE, parameterTypes);
|
||||
}
|
||||
else {
|
||||
Type[] parameterTypes = new Type[] {JAVA_STRING_TYPE, K_PACKAGE_TYPE};
|
||||
factoryMethod = descriptor.isVar()
|
||||
? method("mutableTopLevelVariable", K_MUTABLE_TOP_LEVEL_VARIABLE_TYPE, parameterTypes)
|
||||
: method("topLevelVariable", K_TOP_LEVEL_VARIABLE_TYPE, parameterTypes);
|
||||
}
|
||||
|
||||
return StackValue.operation(factoryMethod.getReturnType(), new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
v.visitLdcInsn(descriptor.getName().asString());
|
||||
v.getstatic(packageClassInternalName, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, K_PACKAGE_TYPE.getDescriptor());
|
||||
|
||||
if (receiverParameter != null) {
|
||||
putJavaLangClassInstance(v, typeMapper.mapType(receiverParameter));
|
||||
}
|
||||
|
||||
v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StackValue generateMemberPropertyReference(
|
||||
@NotNull final VariableDescriptor descriptor,
|
||||
@NotNull final ClassDescriptor containingClass
|
||||
) {
|
||||
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
|
||||
final Method factoryMethod = descriptor.isVar()
|
||||
? method("mutableMemberProperty", K_MUTABLE_MEMBER_PROPERTY_TYPE, JAVA_STRING_TYPE, K_CLASS_TYPE)
|
||||
: method("memberProperty", K_MEMBER_PROPERTY_TYPE, JAVA_STRING_TYPE, K_CLASS_TYPE);
|
||||
|
||||
ClassBuilder classBuilder = state.getFactory().newVisitor(
|
||||
OtherOrigin(expression),
|
||||
typeMapper.mapClass(classDescriptor),
|
||||
expression.getContainingFile()
|
||||
);
|
||||
return StackValue.operation(factoryMethod.getReturnType(), new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
v.visitLdcInsn(descriptor.getName().asString());
|
||||
StackValue receiverClass = generateClassLiteralReference(containingClass.getDefaultType());
|
||||
receiverClass.put(receiverClass.type, v);
|
||||
v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
|
||||
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
|
||||
expression, classBuilder, classDescriptor, (ResolvedCall<VariableDescriptor>) resolvedCall
|
||||
);
|
||||
codegen.generate();
|
||||
|
||||
return codegen.putInstanceOnStack();
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue generateClassLiteralReference(@NotNull final JetTypeMapper typeMapper, @NotNull final JetType type) {
|
||||
private StackValue generateClassLiteralReference(@NotNull final JetType type) {
|
||||
return StackValue.operation(K_CLASS_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
Type classAsmType = typeMapper.mapType(type);
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (descriptor instanceof TypeParameterDescriptor) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||
if (typeParameterDescriptor.isReified()) {
|
||||
// Emit reified type parameters as Kotlin classes.
|
||||
// ReifiedTypeInliner will rewrite the following GETSTATIC to proper bytecode instructions
|
||||
// if the class literal for actual type should be emitted with wrapped Java class.
|
||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.CLASS_LITERAL_MARKER_METHOD_NAME,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
|
||||
);
|
||||
v.getstatic(classAsmType.getInternalName(), JvmAbi.KOTLIN_CLASS_FIELD_NAME, K_CLASS_TYPE.getDescriptor());
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Non-reified type parameter under ::class should be rejected by type checker: " +
|
||||
typeParameterDescriptor.getName().asString());
|
||||
}
|
||||
}
|
||||
else if (shouldUseJavaClassForClassLiteral(descriptor)) {
|
||||
//noinspection ConstantConditions
|
||||
ModuleDescriptor module = DescriptorUtils.getContainingModule(descriptor);
|
||||
if (descriptor instanceof JavaClassDescriptor || module == module.getBuiltIns().getBuiltInsModule()) {
|
||||
putJavaLangClassInstance(v, classAsmType);
|
||||
wrapJavaClassIntoKClass(v);
|
||||
}
|
||||
@@ -3044,7 +3065,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
|
||||
private boolean isIntZero(JetExpression expr, Type exprType) {
|
||||
ConstantValue<?> exprValue = getCompileTimeConstant(expr, bindingContext);
|
||||
CompileTimeConstant<?> exprValue = getCompileTimeConstant(expr, bindingContext);
|
||||
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
|
||||
}
|
||||
|
||||
@@ -3424,7 +3445,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
pushClosureOnStack(constructor.getContainingDeclaration(), dispatchReceiver == null, defaultCallGenerator);
|
||||
|
||||
constructor = SamCodegenUtil.resolveSamAdapter(constructor);
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructor, false);
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructor);
|
||||
invokeMethodWithArguments(method, resolvedCall, StackValue.none());
|
||||
|
||||
return Unit.INSTANCE$;
|
||||
@@ -3495,7 +3516,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
boolean isGetter = "get".equals(operationDescriptor.getName().asString());
|
||||
|
||||
Callable callable = resolveToCallable(operationDescriptor, false, isGetter ? resolvedGetCall : resolvedSetCall);
|
||||
Callable callableMethod = resolveToCallableMethod(operationDescriptor, false);
|
||||
Callable callableMethod = resolveToCallableMethod(operationDescriptor, false, context);
|
||||
Type[] argumentTypes = callableMethod.getParameterTypes();
|
||||
|
||||
StackValue collectionElementReceiver = createCollectionElementReceiver(
|
||||
|
||||
@@ -26,17 +26,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.Bridge;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.BridgesPackage;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageFacadeContext;
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeDeclarationsPackage;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction;
|
||||
@@ -44,15 +42,17 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.types.Approximation;
|
||||
import org.jetbrains.kotlin.types.TypesPackage;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
@@ -72,7 +72,7 @@ import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.OLD_JET_VALUE_PARAMETER_ANNOTATION;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
@@ -122,9 +122,10 @@ public class FunctionCodegen {
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull FunctionDescriptor delegateFunctionDescriptor
|
||||
) {
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(
|
||||
function, functionDescriptor, delegateFunctionDescriptor, owner.getContextKind(), v
|
||||
);
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(function,
|
||||
functionDescriptor,
|
||||
delegateFunctionDescriptor,
|
||||
owner, v);
|
||||
}
|
||||
|
||||
public void generateMethod(
|
||||
@@ -142,20 +143,14 @@ public class FunctionCodegen {
|
||||
@NotNull FunctionGenerationStrategy strategy
|
||||
) {
|
||||
OwnerKind contextKind = methodContext.getContextKind();
|
||||
if (isTrait(functionDescriptor.getContainingDeclaration()) &&
|
||||
functionDescriptor.getVisibility() == Visibilities.PRIVATE &&
|
||||
contextKind != OwnerKind.TRAIT_IMPL) {
|
||||
return;
|
||||
}
|
||||
|
||||
JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, contextKind);
|
||||
Method asmMethod = jvmSignature.getAsmMethod();
|
||||
|
||||
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
|
||||
boolean isNative = NativeDeclarationsPackage.hasNativeAnnotation(functionDescriptor);
|
||||
|
||||
if (isNative && owner instanceof DelegatingFacadeContext) {
|
||||
// Native methods are only defined in facades and do not need package part implementations
|
||||
if (isNative && owner instanceof PackageContext && !(owner instanceof PackageFacadeContext)) {
|
||||
// Native methods are only defined in package facades and do not need package part implementations
|
||||
return;
|
||||
}
|
||||
MethodVisitor mv = v.newMethod(origin,
|
||||
@@ -165,18 +160,21 @@ public class FunctionCodegen {
|
||||
jvmSignature.getGenericsSignature(),
|
||||
getThrownExceptions(functionDescriptor, typeMapper));
|
||||
|
||||
String implClassName = CodegenContextUtil.getImplementationClassShortName(owner);
|
||||
if (implClassName != null) {
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, functionDescriptor, implClassName);
|
||||
if (owner instanceof PackageFacadeContext) {
|
||||
Type ownerType = ((PackageFacadeContext) owner).getDelegateToClassType();
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, functionDescriptor, shortNameByAsmType(ownerType));
|
||||
}
|
||||
if (CodegenContextUtil.isImplClassOwner(owner)) {
|
||||
else {
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
|
||||
}
|
||||
|
||||
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
|
||||
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, asmMethod.getReturnType());
|
||||
generateParameterAnnotations(functionDescriptor, mv, typeMapper.mapSignature(functionDescriptor));
|
||||
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
|
||||
generateJetValueParameterAnnotations(mv, functionDescriptor, jvmSignature);
|
||||
}
|
||||
|
||||
generateBridges(functionDescriptor);
|
||||
|
||||
boolean staticInCompanionObject = AnnotationsPackage.isPlatformStaticInCompanionObject(functionDescriptor);
|
||||
@@ -208,7 +206,7 @@ public class FunctionCodegen {
|
||||
mv.visitCode();
|
||||
FunctionDescriptor staticFunctionDescriptor = PlatformStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
|
||||
JvmMethodSignature jvmMethodSignature =
|
||||
typeMapper.mapSignature(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor, null));
|
||||
typeMapper.mapSignature(memberCodegen.getContext().accessibleFunctionDescriptor(staticFunctionDescriptor));
|
||||
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
|
||||
generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
|
||||
}
|
||||
@@ -218,38 +216,6 @@ public class FunctionCodegen {
|
||||
methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, bindingContext);
|
||||
}
|
||||
|
||||
private void generateMethodAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
Method asmMethod,
|
||||
MethodVisitor mv
|
||||
) {
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forMethod(mv, typeMapper);
|
||||
|
||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
AnnotationUseSiteTarget target = functionDescriptor instanceof PropertySetterDescriptor ? PROPERTY_SETTER : PROPERTY_GETTER;
|
||||
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType(), target);
|
||||
}
|
||||
else {
|
||||
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType());
|
||||
}
|
||||
|
||||
writePackageFacadeMethodAnnotationsIfNeeded(mv);
|
||||
}
|
||||
|
||||
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
|
||||
if (owner instanceof PackageFacadeContext) {
|
||||
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
|
||||
Type delegateToClassType = packageFacadeContext.getDelegateToClassType();
|
||||
if (delegateToClassType != null) {
|
||||
String className = delegateToClassType.getClassName();
|
||||
AnnotationVisitor
|
||||
av = mv.visitAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_DELEGATED_METHOD), true);
|
||||
av.visit(JvmAnnotationNames.IMPLEMENTATION_CLASS_NAME_FIELD_NAME, className);
|
||||
av.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateParameterAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull MethodVisitor mv,
|
||||
@@ -269,30 +235,57 @@ public class FunctionCodegen {
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
ValueParameterDescriptor parameter = iterator.next();
|
||||
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper);
|
||||
AnnotationCodegen.forParameter(i, mv, typeMapper).genAnnotations(parameter, parameterSignature.getAsmType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (functionDescriptor instanceof PropertySetterDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = ((PropertySetterDescriptor) functionDescriptor).getCorrespondingProperty();
|
||||
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(propertyDescriptor);
|
||||
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), SETTER_PARAMETER);
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void generateJetValueParameterAnnotations(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull JvmMethodSignature jvmSignature
|
||||
) {
|
||||
Iterator<ValueParameterDescriptor> descriptors = functionDescriptor.getValueParameters().iterator();
|
||||
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
|
||||
|
||||
if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||
annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType(), CONSTRUCTOR_PARAMETER);
|
||||
for (int i = 0; i < kotlinParameterTypes.size(); i++) {
|
||||
JvmMethodParameterKind kind = kotlinParameterTypes.get(i).getKind();
|
||||
if (kind.isSkippedInGenericSignature()) continue;
|
||||
|
||||
String name;
|
||||
boolean nullableType;
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
ValueParameterDescriptor descriptor = descriptors.next();
|
||||
name = descriptor.getName().asString();
|
||||
nullableType = descriptor.getType().isMarkedNullable();
|
||||
}
|
||||
else {
|
||||
String lowercaseKind = kind.name().toLowerCase();
|
||||
if (needIndexForVar(kind)) {
|
||||
name = "$" + lowercaseKind + "$" + i;
|
||||
}
|
||||
else {
|
||||
annotationCodegen.genAnnotations(parameter, parameterSignature.getAsmType());
|
||||
name = "$" + lowercaseKind;
|
||||
}
|
||||
|
||||
if (kind == JvmMethodParameterKind.RECEIVER) {
|
||||
ReceiverParameterDescriptor receiver = functionDescriptor.getExtensionReceiverParameter();
|
||||
nullableType = receiver == null || receiver.getType().isMarkedNullable();
|
||||
}
|
||||
else {
|
||||
nullableType = true;
|
||||
}
|
||||
}
|
||||
else if (kind == JvmMethodParameterKind.RECEIVER) {
|
||||
ReceiverParameterDescriptor receiver = ((functionDescriptor instanceof PropertyAccessorDescriptor)
|
||||
? ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty()
|
||||
: functionDescriptor).getExtensionReceiverParameter();
|
||||
if (receiver != null) {
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper);
|
||||
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType());
|
||||
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER);
|
||||
|
||||
AnnotationVisitor av =
|
||||
mv.visitParameterAnnotation(i, asmDescByFqNameWithoutInnerClasses(OLD_JET_VALUE_PARAMETER_ANNOTATION), true);
|
||||
if (av != null) {
|
||||
av.visit("name", name);
|
||||
if (nullableType) {
|
||||
av.visit("type", "?");
|
||||
}
|
||||
av.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,8 +343,8 @@ public class FunctionCodegen {
|
||||
JetTypeMapper typeMapper = parentCodegen.typeMapper;
|
||||
|
||||
Label methodEnd;
|
||||
if (context.getParentContext() instanceof DelegatingFacadeContext) {
|
||||
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
|
||||
if (context.getParentContext() instanceof PackageFacadeContext) {
|
||||
generatePackageDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext());
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else {
|
||||
@@ -423,10 +416,10 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateFacadeDelegateMethodBody(
|
||||
private static void generatePackageDelegateMethodBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Method asmMethod,
|
||||
@NotNull DelegatingFacadeContext context
|
||||
@NotNull PackageFacadeContext context
|
||||
) {
|
||||
generateDelegateToMethodBody(true, mv, asmMethod, context.getDelegateToClassType().getInternalName());
|
||||
}
|
||||
@@ -509,7 +502,7 @@ public class FunctionCodegen {
|
||||
if (isMethodOfAny(descriptor)) return;
|
||||
|
||||
// If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges
|
||||
if (CallResolverUtilPackage.isOrOverridesSynthesized(descriptor)) return;
|
||||
if (CallResolverUtil.isOrOverridesSynthesized(descriptor)) return;
|
||||
|
||||
Set<Bridge<Method>> bridgesToGenerate = BridgesPackage.generateBridgesForFunctionDescriptor(
|
||||
descriptor,
|
||||
@@ -544,13 +537,9 @@ public class FunctionCodegen {
|
||||
@NotNull
|
||||
public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull final JetTypeMapper mapper) {
|
||||
AnnotationDescriptor annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.throws"));
|
||||
if (annotation == null) {
|
||||
annotation = function.getAnnotations().findAnnotation(new FqName("kotlin.jvm.Throws"));
|
||||
}
|
||||
|
||||
if (annotation == null) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
|
||||
Collection<ConstantValue<?>> values = annotation.getAllValueArguments().values();
|
||||
Collection<CompileTimeConstant<?>> values = annotation.getAllValueArguments().values();
|
||||
if (values.isEmpty()) return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
|
||||
Object value = values.iterator().next();
|
||||
@@ -559,9 +548,9 @@ public class FunctionCodegen {
|
||||
|
||||
List<String> strings = ContainerUtil.mapNotNull(
|
||||
arrayValue.getValue(),
|
||||
new Function<ConstantValue<?>, String>() {
|
||||
new Function<CompileTimeConstant<?>, String>() {
|
||||
@Override
|
||||
public String fun(ConstantValue<?> constant) {
|
||||
public String fun(CompileTimeConstant<?> constant) {
|
||||
if (constant instanceof KClassValue) {
|
||||
KClassValue classValue = (KClassValue) constant;
|
||||
ClassDescriptor classDescriptor = DescriptorUtils.getClassDescriptorForType(classValue.getValue());
|
||||
@@ -583,7 +572,9 @@ public class FunctionCodegen {
|
||||
) {
|
||||
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
|
||||
|
||||
if (kind != OwnerKind.TRAIT_IMPL && isTrait(contextClass)) {
|
||||
if (kind != OwnerKind.TRAIT_IMPL &&
|
||||
contextClass instanceof ClassDescriptor &&
|
||||
((ClassDescriptor) contextClass).getKind() == ClassKind.INTERFACE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -600,7 +591,7 @@ public class FunctionCodegen {
|
||||
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
|
||||
flags &= ~ACC_PRIVATE;
|
||||
|
||||
Method defaultMethod = typeMapper.mapDefaultMethod(functionDescriptor, kind);
|
||||
Method defaultMethod = typeMapper.mapDefaultMethod(functionDescriptor, kind, owner);
|
||||
|
||||
MethodVisitor mv = v.newMethod(
|
||||
Synthetic(function, functionDescriptor),
|
||||
@@ -615,9 +606,9 @@ public class FunctionCodegen {
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
if (this.owner instanceof DelegatingFacadeContext) {
|
||||
if (this.owner instanceof PackageFacadeContext) {
|
||||
mv.visitCode();
|
||||
generateFacadeDelegateMethodBody(mv, defaultMethod, (DelegatingFacadeContext) this.owner);
|
||||
generatePackageDelegateMethodBody(mv, defaultMethod, (PackageFacadeContext) this.owner);
|
||||
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
|
||||
}
|
||||
else {
|
||||
@@ -682,7 +673,13 @@ public class FunctionCodegen {
|
||||
generator.putValueIfNeeded(parameterDescriptor, type, StackValue.local(parameterIndex, type));
|
||||
}
|
||||
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
|
||||
CallableMethod method;
|
||||
if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||
method = state.getTypeMapper().mapToCallableMethod((ConstructorDescriptor) functionDescriptor);
|
||||
}
|
||||
else {
|
||||
method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, methodContext);
|
||||
}
|
||||
|
||||
generator.genCallWithoutAssertions(method, codegen);
|
||||
|
||||
@@ -837,10 +834,10 @@ public class FunctionCodegen {
|
||||
StackValue stackValue = AsmUtil.genNotNullAssertions(
|
||||
state,
|
||||
StackValue.onStack(delegateToMethod.getReturnType()),
|
||||
RuntimeAssertionInfo.create(
|
||||
delegateFunction.getReturnType(),
|
||||
TypesPackage.getApproximationTo(
|
||||
delegatedTo.getReturnType(),
|
||||
new RuntimeAssertionInfo.DataFlowExtras.OnlyMessage(delegatedTo.getName() + "(...)")
|
||||
delegateFunction.getReturnType(),
|
||||
new Approximation.DataFlowExtras.OnlyMessage(delegatedTo.getName() + "(...)")
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -134,14 +133,8 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
}
|
||||
|
||||
private void computeAndSaveArguments(@NotNull List<? extends ValueArgument> fakeArguments, @NotNull ExpressionCodegen codegen) {
|
||||
int receivers = (referencedFunction.getDispatchReceiverParameter() != null ? 1 : 0) +
|
||||
(referencedFunction.getExtensionReceiverParameter() != null ? 1 : 0);
|
||||
|
||||
List<ValueParameterDescriptor> parameters = KotlinPackage.drop(callableDescriptor.getValueParameters(), receivers);
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
ValueParameterDescriptor parameter = parameters.get(i);
|
||||
ValueArgument fakeArgument = fakeArguments.get(i);
|
||||
|
||||
for (ValueParameterDescriptor parameter : callableDescriptor.getValueParameters()) {
|
||||
ValueArgument fakeArgument = fakeArguments.get(parameter.getIndex());
|
||||
Type type = state.getTypeMapper().mapType(parameter);
|
||||
int localIndex = codegen.myFrameMap.getIndex(parameter);
|
||||
codegen.tempVariables.put(fakeArgument.getArgumentExpression(), StackValue.local(localIndex, type));
|
||||
|
||||
@@ -19,8 +19,6 @@ package org.jetbrains.kotlin.codegen;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.List;
|
||||
@@ -34,15 +32,6 @@ public class GeneratedClassLoader extends URLClassLoader {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
OutputFile outputFile = factory.get(name);
|
||||
if (outputFile != null) {
|
||||
return new ByteArrayInputStream(outputFile.asByteArray());
|
||||
}
|
||||
return super.getResourceAsStream(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Class<?> findClass(@NotNull String name) throws ClassNotFoundException {
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
@@ -50,7 +49,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
||||
@@ -66,8 +65,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.serialization.*;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver;
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
|
||||
@@ -139,7 +138,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
isAbstract = true;
|
||||
isInterface = true;
|
||||
}
|
||||
else if (descriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
|
||||
else if (jetClass.isAnnotation()) {
|
||||
isAbstract = true;
|
||||
isInterface = true;
|
||||
isAnnotation = true;
|
||||
@@ -248,13 +247,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
kind = KotlinClass.Kind.LOCAL_CLASS;
|
||||
}
|
||||
|
||||
// Temporarily write class kind anyway because old compiler may not expect its absence
|
||||
// TODO: remove after M13
|
||||
if (kind == null) {
|
||||
kind = KotlinClass.Kind.CLASS;
|
||||
}
|
||||
|
||||
DescriptorSerializer serializer =
|
||||
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), typeMapper));
|
||||
|
||||
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
||||
|
||||
StringTable strings = serializer.getStringTable();
|
||||
NameResolver nameResolver = new NameResolver(strings.serializeSimpleNames(), strings.serializeQualifiedNames());
|
||||
ClassData data = new ClassData(nameResolver, classProto);
|
||||
|
||||
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS), true);
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||
//noinspection ConstantConditions
|
||||
if (kind != null) {
|
||||
av.visitEnum(
|
||||
JvmAnnotationNames.KIND_FIELD_NAME,
|
||||
@@ -263,7 +273,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
);
|
||||
}
|
||||
AnnotationVisitor array = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME);
|
||||
for (String string : BitEncoding.encodeBytes(serializer.serialize(classProto))) {
|
||||
for (String string : BitEncoding.encodeBytes(SerializationUtil.serializeClassData(data))) {
|
||||
array.visit(null, string);
|
||||
}
|
||||
array.visitEnd();
|
||||
@@ -391,10 +401,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private boolean isGenericToArrayPresent() {
|
||||
Collection<FunctionDescriptor> functions =
|
||||
descriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier("toArray"), NoLookupLocation.FROM_BACKEND);
|
||||
Collection<FunctionDescriptor> functions = descriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier("toArray"));
|
||||
for (FunctionDescriptor function : functions) {
|
||||
if (CallResolverUtilPackage.isOrOverridesSynthesized(function)) {
|
||||
if (CallResolverUtil.isOrOverridesSynthesized(function)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -473,9 +482,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(function), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
|
||||
public void generateEqualsMethod(@NotNull List<PropertyDescriptor> properties) {
|
||||
KotlinBuiltIns builtins = getBuiltIns(descriptor);
|
||||
FunctionDescriptor equalsFunction = CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||
descriptor, Name.identifier(CodegenUtil.EQUALS_METHOD_NAME), builtins.getBoolean(), builtins.getAny()
|
||||
);
|
||||
|
||||
assert equalsFunction != null : String.format("Should be called only for classes with non-trivial '%s'. In %s, %s",
|
||||
CodegenUtil.EQUALS_METHOD_NAME, descriptor.getName(), descriptor);
|
||||
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(equalsFunction);
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(equalsFunction), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
mv.visitCode();
|
||||
@@ -503,7 +520,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Type otherPropertyType = genPropertyOnStack(iv, context, propertyDescriptor, 2);
|
||||
StackValue.coerce(otherPropertyType, asmType, iv);
|
||||
|
||||
if (asmType.getSort() == Type.FLOAT) {
|
||||
if (asmType.getSort() == Type.ARRAY) {
|
||||
Type elementType = correctElementType(asmType);
|
||||
if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) {
|
||||
iv.invokestatic("java/util/Arrays", "equals", "([Ljava/lang/Object;[Ljava/lang/Object;)Z", false);
|
||||
}
|
||||
else {
|
||||
iv.invokestatic("java/util/Arrays", "equals",
|
||||
"(" + asmType.getDescriptor() + asmType.getDescriptor() + ")Z", false);
|
||||
}
|
||||
iv.ifeq(ne);
|
||||
}
|
||||
else if (asmType.getSort() == Type.FLOAT) {
|
||||
iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
|
||||
iv.ifne(ne);
|
||||
}
|
||||
@@ -530,9 +558,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(function), ACC_PUBLIC, "hashCode", "()I", null, null);
|
||||
public void generateHashCodeMethod(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor hashCodeFunction = CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||
descriptor, Name.identifier(CodegenUtil.HASH_CODE_METHOD_NAME), getBuiltIns(descriptor).getInt()
|
||||
);
|
||||
|
||||
assert hashCodeFunction != null : String.format("Should be called only for classes with non-trivial '%s'. In %s, %s",
|
||||
CodegenUtil.HASH_CODE_METHOD_NAME, descriptor.getName(), descriptor);
|
||||
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(hashCodeFunction);
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(hashCodeFunction), ACC_PUBLIC, "hashCode", "()I", null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
mv.visitCode();
|
||||
@@ -579,9 +614,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(function), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
|
||||
public void generateToStringMethod(@NotNull List<PropertyDescriptor> properties) {
|
||||
FunctionDescriptor toString = CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||
descriptor, Name.identifier(CodegenUtil.TO_STRING_METHOD_NAME), getBuiltIns(descriptor).getString()
|
||||
);
|
||||
|
||||
assert toString != null : String.format("Should be called only for classes with non-trivial '%s'. In %s, %s",
|
||||
CodegenUtil.TO_STRING_METHOD_NAME, descriptor.getName(), descriptor);
|
||||
|
||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(toString);
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(toString), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
mv.visitCode();
|
||||
@@ -773,7 +815,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Type type = typeMapper.mapType(getBuiltIns(descriptor).getArrayType(INVARIANT, descriptor.getDefaultType()));
|
||||
|
||||
FunctionDescriptor valuesFunction =
|
||||
KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUES, NoLookupLocation.FROM_BACKEND), new Function1<FunctionDescriptor, Boolean>() {
|
||||
KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUES), new Function1<FunctionDescriptor, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(FunctionDescriptor descriptor) {
|
||||
return CodegenUtil.isEnumValuesMethod(descriptor);
|
||||
@@ -793,7 +835,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateEnumValueOfMethod() {
|
||||
FunctionDescriptor valueOfFunction =
|
||||
KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUE_OF, NoLookupLocation.FROM_BACKEND), new Function1<FunctionDescriptor, Boolean>() {
|
||||
KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUE_OF), new Function1<FunctionDescriptor, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(FunctionDescriptor descriptor) {
|
||||
return CodegenUtil.isEnumValueOfMethod(descriptor);
|
||||
@@ -813,31 +855,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
protected void generateSyntheticAccessors() {
|
||||
for (AccessorForCallableDescriptor<?> accessor : ((CodegenContext<?>) context).getAccessors()) {
|
||||
generateSyntheticAccessor(accessor);
|
||||
Map<DeclarationDescriptor, DeclarationDescriptor> accessors = ((CodegenContext<?>) context).getAccessors();
|
||||
for (Map.Entry<DeclarationDescriptor, DeclarationDescriptor> entry : accessors.entrySet()) {
|
||||
generateSyntheticAccessor(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSyntheticAccessor(@NotNull AccessorForCallableDescriptor<?> accessorForCallableDescriptor) {
|
||||
if (accessorForCallableDescriptor instanceof FunctionDescriptor) {
|
||||
final FunctionDescriptor accessor = (FunctionDescriptor) accessorForCallableDescriptor;
|
||||
final FunctionDescriptor original = (FunctionDescriptor) accessorForCallableDescriptor.getCalleeDescriptor();
|
||||
private void generateSyntheticAccessor(Map.Entry<DeclarationDescriptor, DeclarationDescriptor> entry) {
|
||||
if (entry.getValue() instanceof FunctionDescriptor) {
|
||||
final FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue();
|
||||
final FunctionDescriptor original = (FunctionDescriptor) entry.getKey();
|
||||
functionCodegen.generateMethod(
|
||||
Synthetic(null, original), accessor,
|
||||
new FunctionGenerationStrategy.CodegenBased<FunctionDescriptor>(state, accessor) {
|
||||
Synthetic(null, original), bridge,
|
||||
new FunctionGenerationStrategy.CodegenBased<FunctionDescriptor>(state, bridge) {
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
markLineNumberForSyntheticFunction(descriptor, codegen.v);
|
||||
|
||||
generateMethodCallTo(original, accessor, codegen.v);
|
||||
generateMethodCallTo(original, bridge, codegen.v);
|
||||
codegen.v.areturn(signature.getReturnType());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (accessorForCallableDescriptor instanceof AccessorForPropertyDescriptor) {
|
||||
final AccessorForPropertyDescriptor accessor = (AccessorForPropertyDescriptor) accessorForCallableDescriptor;
|
||||
final PropertyDescriptor original = accessor.getCalleeDescriptor();
|
||||
else if (entry.getValue() instanceof PropertyDescriptor) {
|
||||
final PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue();
|
||||
final PropertyDescriptor original = (PropertyDescriptor) entry.getKey();
|
||||
|
||||
class PropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased<PropertyAccessorDescriptor> {
|
||||
public PropertyAccessorStrategy(@NotNull PropertyAccessorDescriptor callableDescriptor) {
|
||||
@@ -847,10 +890,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
!isCompanionObject(accessor.getContainingDeclaration());
|
||||
StackValue property = codegen.intermediateValueForProperty(
|
||||
original, forceField, accessor.getSuperCallExpression(), true, StackValue.none()
|
||||
);
|
||||
!isCompanionObject(bridge.getContainingDeclaration());
|
||||
StackValue property =
|
||||
codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR,
|
||||
StackValue.none());
|
||||
|
||||
InstructionAdapter iv = codegen.v;
|
||||
|
||||
@@ -875,14 +918,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
PropertyGetterDescriptor getter = accessor.getGetter();
|
||||
PropertyGetterDescriptor getter = bridge.getGetter();
|
||||
assert getter != null;
|
||||
functionCodegen.generateMethod(Synthetic(null, original.getGetter() != null ? original.getGetter() : original),
|
||||
getter, new PropertyAccessorStrategy(getter));
|
||||
|
||||
|
||||
if (accessor.isVar()) {
|
||||
PropertySetterDescriptor setter = accessor.getSetter();
|
||||
if (bridge.isVar()) {
|
||||
PropertySetterDescriptor setter = bridge.getSetter();
|
||||
assert setter != null;
|
||||
|
||||
functionCodegen.generateMethod(Synthetic(null, original.getSetter() != null ? original.getSetter() : original),
|
||||
@@ -912,24 +955,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateMethodCallTo(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@Nullable FunctionDescriptor accessorDescriptor,
|
||||
@Nullable FunctionDescriptor bridgeDescriptor,
|
||||
@NotNull InstructionAdapter iv
|
||||
) {
|
||||
CallableMethod callableMethod = typeMapper.mapToCallableMethod(
|
||||
functionDescriptor,
|
||||
accessorDescriptor instanceof AccessorForCallableDescriptor &&
|
||||
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallExpression() != null
|
||||
);
|
||||
boolean isConstructor = functionDescriptor instanceof ConstructorDescriptor;
|
||||
boolean bridgeIsAccessorConstructor = bridgeDescriptor instanceof AccessorForConstructorDescriptor;
|
||||
boolean callFromAccessor = bridgeIsAccessorConstructor
|
||||
|| (bridgeDescriptor != null && JetTypeMapper.isAccessor(bridgeDescriptor));
|
||||
CallableMethod callableMethod = isConstructor ?
|
||||
typeMapper.mapToCallableMethod((ConstructorDescriptor) functionDescriptor) :
|
||||
typeMapper.mapToCallableMethod(functionDescriptor, callFromAccessor, context);
|
||||
|
||||
int reg = 1;
|
||||
|
||||
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
||||
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
|
||||
if (isConstructor && !bridgeIsAccessorConstructor) {
|
||||
iv.anew(callableMethod.getOwner());
|
||||
iv.dup();
|
||||
reg = 0;
|
||||
}
|
||||
else if (accessorIsConstructor || (accessorDescriptor != null && JetTypeMapper.isAccessor(accessorDescriptor))) {
|
||||
else if (callFromAccessor) {
|
||||
if (!AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
}
|
||||
@@ -944,7 +987,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
reg += argType.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
callableMethod.genInvokeInstruction(iv);
|
||||
}
|
||||
|
||||
@@ -1030,9 +1072,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
|
||||
KotlinPackage.single(companionObject.getConstructors()), /* superCallExpression = */ null
|
||||
);
|
||||
FunctionDescriptor constructor = context.accessibleFunctionDescriptor(KotlinPackage.single(companionObject.getConstructors()));
|
||||
generateMethodCallTo(constructor, null, codegen.v);
|
||||
codegen.v.dup();
|
||||
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
|
||||
@@ -1061,7 +1101,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generateConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass);
|
||||
new DefaultParameterValueSubstitutor(state).generateConstructorOverloadsIfNeeded(constructorDescriptor, v,
|
||||
constructorContext, myClass);
|
||||
|
||||
if (isCompanionObject(descriptor)) {
|
||||
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
|
||||
@@ -1086,9 +1127,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(
|
||||
myClass, constructorDescriptor, constructorDescriptor, kind, v
|
||||
);
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(myClass, constructorDescriptor, constructorDescriptor,
|
||||
constructorContext, v);
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructorImpl(
|
||||
@@ -1473,8 +1513,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
ConstructorDescriptor delegateConstructor = SamCodegenUtil.resolveSamAdapter(codegen.getConstructorDescriptor(delegationConstructorCall));
|
||||
|
||||
CallableMethod delegateConstructorCallable = typeMapper.mapToCallableMethod(delegateConstructor, false);
|
||||
CallableMethod callable = typeMapper.mapToCallableMethod(constructorDescriptor, false);
|
||||
CallableMethod delegateConstructorCallable = typeMapper.mapToCallableMethod(delegateConstructor);
|
||||
CallableMethod callable = typeMapper.mapToCallableMethod(constructorDescriptor);
|
||||
|
||||
List<JvmMethodParameterSignature> delegatingParameters = delegateConstructorCallable.getValueParameters();
|
||||
List<JvmMethodParameterSignature> parameters = callable.getValueParameters();
|
||||
@@ -1688,7 +1728,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (delegationSpecifiers.size() == 1 && !enumEntryNeedSubclass(bindingContext, enumEntry)) {
|
||||
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCallWithAssert(delegationSpecifiers.get(0), bindingContext);
|
||||
|
||||
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) resolvedCall.getResultingDescriptor(), false);
|
||||
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) resolvedCall.getResultingDescriptor());
|
||||
|
||||
codegen.invokeMethodWithArguments(method, resolvedCall, StackValue.none());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
@@ -25,14 +28,11 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext;
|
||||
import org.jetbrains.kotlin.codegen.context.RootContext;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment;
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.psi.JetFunction;
|
||||
@@ -43,13 +43,11 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT;
|
||||
import static org.jetbrains.kotlin.descriptors.Modality.FINAL;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTrait;
|
||||
|
||||
public class JvmCodegenUtil {
|
||||
|
||||
@@ -108,20 +106,49 @@ public class JvmCodegenUtil {
|
||||
@NotNull CodegenContext context,
|
||||
@Nullable File outDirectory
|
||||
) {
|
||||
if (context instanceof RootContext) {
|
||||
if (context == CodegenContext.STATIC) {
|
||||
return true;
|
||||
}
|
||||
DeclarationDescriptor contextDescriptor = context.getContextDescriptor();
|
||||
|
||||
CallableMemberDescriptor directMember = getDirectMember(declarationDescriptor);
|
||||
if (directMember instanceof DeserializedCallableMemberDescriptor) {
|
||||
return ModuleVisibilityUtilsKt.isContainedByCompiledPartOfOurModule(directMember, outDirectory);
|
||||
return isContainedByCompiledPartOfOurModule(((DeserializedCallableMemberDescriptor) directMember), outDirectory);
|
||||
}
|
||||
else {
|
||||
return DescriptorUtils.areInSameModule(directMember, contextDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isContainedByCompiledPartOfOurModule(
|
||||
@NotNull DeserializedCallableMemberDescriptor descriptor,
|
||||
@Nullable File outDirectory
|
||||
) {
|
||||
DeclarationDescriptor packageFragment = descriptor.getContainingDeclaration();
|
||||
if (packageFragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (outDirectory == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(packageFragment instanceof LazyJavaPackageFragment)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KotlinJvmBinaryClass binaryClass = ((LazyJavaPackageFragment) packageFragment).getMemberScope().getKotlinBinaryClass();
|
||||
if (binaryClass instanceof VirtualFileKotlinClass) {
|
||||
VirtualFile file = ((VirtualFileKotlinClass) binaryClass).getFile();
|
||||
if (file.getFileSystem().getProtocol() == StandardFileSystems.FILE_PROTOCOL) {
|
||||
File ioFile = VfsUtilCore.virtualToIoFile(file);
|
||||
return ioFile.getAbsolutePath().startsWith(outDirectory.getAbsolutePath() + File.separator);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
|
||||
return KotlinPackage.any(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors(),
|
||||
new Function1<DeclarationDescriptor, Boolean>() {
|
||||
@@ -210,28 +237,4 @@ public class JvmCodegenUtil {
|
||||
return InlineUtil.canBeInlineArgument(declaration) &&
|
||||
InlineUtil.isInlinedArgument((JetFunction) declaration, bindingContext, false);
|
||||
}
|
||||
|
||||
public static boolean shouldUseJavaClassForClassLiteral(@NotNull ClassifierDescriptor descriptor) {
|
||||
ModuleDescriptor module = DescriptorUtils.getContainingModule(descriptor);
|
||||
return descriptor instanceof JavaClassDescriptor ||
|
||||
module == module.getBuiltIns().getBuiltInsModule() ||
|
||||
DescriptorUtils.isAnnotationClass(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getModuleName(ModuleDescriptor module) {
|
||||
return KotlinPackage.removeSurrounding(module.getName().asString(), "<", ">");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getMappingFileName(@NotNull String moduleName) {
|
||||
return "META-INF/" + moduleName + "." + ModuleMapping.MAPPING_FILE_EXT;
|
||||
}
|
||||
|
||||
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
|
||||
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
|
||||
|
||||
// TODO: drop after some time
|
||||
av.visit(JvmAnnotationNames.OLD_ABI_VERSION_FIELD_NAME, JvmAbi.VERSION.getMinor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -28,15 +29,15 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
|
||||
|
||||
public class JvmRuntimeTypes {
|
||||
private final ClassDescriptor lambda;
|
||||
private final ClassDescriptor functionReference;
|
||||
private final List<ClassDescriptor> propertyReferences;
|
||||
private final List<ClassDescriptor> mutablePropertyReferences;
|
||||
|
||||
public JvmRuntimeTypes() {
|
||||
ModuleDescriptorImpl module = new ModuleDescriptorImpl(
|
||||
@@ -48,19 +49,12 @@ public class JvmRuntimeTypes {
|
||||
|
||||
this.lambda = createClass(kotlinJvmInternal, "Lambda");
|
||||
this.functionReference = createClass(kotlinJvmInternal, "FunctionReference");
|
||||
this.propertyReferences = new ArrayList<ClassDescriptor>(3);
|
||||
this.mutablePropertyReferences = new ArrayList<ClassDescriptor>(3);
|
||||
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
propertyReferences.add(createClass(kotlinJvmInternal, "PropertyReference" + i));
|
||||
mutablePropertyReferences.add(createClass(kotlinJvmInternal, "MutablePropertyReference" + i));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClassDescriptor createClass(@NotNull PackageFragmentDescriptor packageFragment, @NotNull String name) {
|
||||
MutableClassDescriptor descriptor = new MutableClassDescriptor(
|
||||
packageFragment, ClassKind.CLASS, false, Name.identifier(name), SourceElement.NO_SOURCE
|
||||
packageFragment, packageFragment.getMemberScope(), ClassKind.CLASS, false, Name.identifier(name), SourceElement.NO_SOURCE
|
||||
);
|
||||
|
||||
descriptor.setModality(Modality.FINAL);
|
||||
@@ -104,11 +98,4 @@ public class JvmRuntimeTypes {
|
||||
|
||||
return Arrays.asList(functionReference.getDefaultType(), functionType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType getSupertypeForPropertyReference(@NotNull PropertyDescriptor descriptor) {
|
||||
int arity = (descriptor.getExtensionReceiverParameter() != null ? 1 : 0) +
|
||||
(descriptor.getDispatchReceiverParameter() != null ? 1 : 0);
|
||||
return (descriptor.isVar() ? mutablePropertyReferences : propertyReferences).get(arity).getDefaultType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,9 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeCapabilities;
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureDeserializer;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -47,21 +45,12 @@ import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
|
||||
public class JvmSerializerExtension extends SerializerExtension {
|
||||
private final JvmSerializationBindings bindings;
|
||||
private final JetTypeMapper typeMapper;
|
||||
private final AnnotationSerializer annotationSerializer = new AnnotationSerializer();
|
||||
|
||||
public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull JetTypeMapper typeMapper) {
|
||||
this.bindings = bindings;
|
||||
this.typeMapper = typeMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeClass(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class.Builder proto, @NotNull StringTable stringTable) {
|
||||
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(KotlinBuiltIns.FQ_NAMES.annotation);
|
||||
if (annotation != null) {
|
||||
proto.addExtension(JvmProtoBuf.classAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serializeCallable(
|
||||
@NotNull CallableMemberDescriptor callable,
|
||||
@@ -88,11 +77,7 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
public void serializeType(@NotNull JetType type, @NotNull ProtoBuf.Type.Builder proto, @NotNull StringTable stringTable) {
|
||||
// TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead
|
||||
for (AnnotationDescriptor annotation : type.getAnnotations()) {
|
||||
proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable));
|
||||
}
|
||||
|
||||
if (type.getCapabilities() instanceof RawTypeCapabilities) {
|
||||
proto.setExtension(JvmProtoBuf.isRaw, true);
|
||||
proto.addExtension(JvmProtoBuf.typeAnnotation, AnnotationSerializer.INSTANCE$.serializeAnnotation(annotation, stringTable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +125,7 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
fieldType = field.first;
|
||||
fieldName = field.second;
|
||||
isStaticInOuter = bindings.get(STATIC_FIELD_IN_OUTER_CLASS, property);
|
||||
syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, property);
|
||||
syntheticMethod = null;
|
||||
}
|
||||
else {
|
||||
fieldType = null;
|
||||
|
||||
@@ -20,8 +20,6 @@ import com.google.common.collect.Sets;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
@@ -46,7 +44,7 @@ public class KotlinCodegenFacade {
|
||||
|
||||
FqName name = ScriptNameUtil.classNameForScript(script);
|
||||
Type type = AsmUtil.asmTypeByFqNameWithoutInnerClasses(name);
|
||||
registerClassNameForScript(state.getBindingTrace(), script, type, state.getFileClassesProvider());
|
||||
registerClassNameForScript(state.getBindingTrace(), script, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,37 +61,16 @@ public class KotlinCodegenFacade {
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
|
||||
MultiMap<FqName, JetFile> filesInPackageClasses = new MultiMap<FqName, JetFile>();
|
||||
MultiMap<FqName, JetFile> filesInMultifileClasses = new MultiMap<FqName, JetFile>();
|
||||
|
||||
MultiMap<FqName, JetFile> packageFqNameToFiles = new MultiMap<FqName, JetFile>();
|
||||
for (JetFile file : state.getFiles()) {
|
||||
if (file == null) throw new IllegalArgumentException("A null file given for compilation");
|
||||
|
||||
JvmFileClassInfo fileClassInfo = state.getFileClassesProvider().getFileClassInfo(file);
|
||||
|
||||
if (fileClassInfo.getIsMultifileClass()) {
|
||||
filesInMultifileClasses.putValue(fileClassInfo.getFacadeClassFqName(), file);
|
||||
}
|
||||
|
||||
if (state.getPackageFacadesAsMultifileClasses()) {
|
||||
if (!fileClassInfo.getIsMultifileClass()) {
|
||||
filesInMultifileClasses.putValue(PackageClassUtils.getPackageClassFqName(file.getPackageFqName()), file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
filesInPackageClasses.putValue(file.getPackageFqName(), file);
|
||||
}
|
||||
packageFqNameToFiles.putValue(file.getPackageFqName(), file);
|
||||
}
|
||||
|
||||
Set<FqName> packagesWithObsoleteParts = new HashSet<FqName>(state.getPackagesWithObsoleteParts());
|
||||
for (FqName packageFqName : Sets.union(packagesWithObsoleteParts, filesInPackageClasses.keySet())) {
|
||||
for (FqName fqName : Sets.union(packagesWithObsoleteParts, packageFqNameToFiles.keySet())) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
generatePackage(state, packageFqName, filesInPackageClasses.get(packageFqName), errorHandler);
|
||||
}
|
||||
|
||||
for (FqName multifileClassFqName : filesInMultifileClasses.keySet()) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler);
|
||||
generatePackage(state, fqName, packageFqNameToFiles.get(fqName), errorHandler);
|
||||
}
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
@@ -102,23 +79,13 @@ public class KotlinCodegenFacade {
|
||||
|
||||
public static void generatePackage(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FqName packageFqName,
|
||||
@NotNull FqName fqName,
|
||||
@NotNull Collection<JetFile> jetFiles,
|
||||
@NotNull CompilationErrorHandler errorHandler
|
||||
) {
|
||||
PackageCodegen codegen = state.getFactory().forPackage(packageFqName, jetFiles);
|
||||
PackageCodegen codegen = state.getFactory().forPackage(fqName, jetFiles);
|
||||
codegen.generate(errorHandler);
|
||||
}
|
||||
|
||||
private static void generateMultifileClass(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FqName multifileClassFqName,
|
||||
@NotNull Collection<JetFile> files,
|
||||
@NotNull CompilationErrorHandler handler
|
||||
) {
|
||||
MultifileClassCodegen codegen = state.getFactory().forMultifileClass(multifileClassFqName, files);
|
||||
codegen.generate(handler);
|
||||
}
|
||||
|
||||
private KotlinCodegenFacade() {}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
@@ -29,9 +27,8 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.name.SpecialNames;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -40,11 +37,10 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.source.SourcePackage;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
@@ -59,6 +55,7 @@ import java.util.*;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlags;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.DiagnosticsPackage.OtherOrigin;
|
||||
@@ -75,7 +72,6 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
protected final PropertyCodegen propertyCodegen;
|
||||
protected final JetTypeMapper typeMapper;
|
||||
protected final BindingContext bindingContext;
|
||||
protected final JvmFileClassesProvider fileClassesProvider;
|
||||
private final MemberCodegen<?> parentCodegen;
|
||||
private final ReifiedTypeParametersUsages reifiedTypeParametersUsages = new ReifiedTypeParametersUsages();
|
||||
protected final Collection<ClassDescriptor> innerClasses = new LinkedHashSet<ClassDescriptor>();
|
||||
@@ -84,7 +80,6 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
private NameGenerator inlineNameGenerator;
|
||||
|
||||
private SourceMapper sourceMapper;
|
||||
private final ConstantExpressionEvaluator constantExpressionEvaluator;
|
||||
|
||||
public MemberCodegen(
|
||||
@NotNull GenerationState state,
|
||||
@@ -96,14 +91,12 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
this.state = state;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.bindingContext = state.getBindingContext();
|
||||
this.fileClassesProvider = state.getFileClassesProvider();
|
||||
this.element = element;
|
||||
this.context = context;
|
||||
this.v = builder;
|
||||
this.functionCodegen = new FunctionCodegen(context, v, state, this);
|
||||
this.propertyCodegen = new PropertyCodegen(context, v, functionCodegen, this);
|
||||
this.parentCodegen = parentCodegen;
|
||||
this.constantExpressionEvaluator = new ConstantExpressionEvaluator(state.getModule().getBuiltIns());
|
||||
}
|
||||
|
||||
protected MemberCodegen(@NotNull MemberCodegen<T> wrapped, T declaration, FieldOwnerContext codegenContext) {
|
||||
@@ -290,16 +283,9 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
if (outermost instanceof ClassContext) {
|
||||
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
|
||||
}
|
||||
else if (outermost instanceof DelegatingFacadeContext || outermost instanceof DelegatingToPartContext) {
|
||||
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
|
||||
if (implementationOwnerType != null) {
|
||||
return implementationOwnerType;
|
||||
}
|
||||
else {
|
||||
return FileClassesPackage.getFileClassType(fileClassesProvider, element.getContainingJetFile());
|
||||
}
|
||||
}
|
||||
/*disabled cause of KT-7775
|
||||
else if (outermost instanceof PackageContext && !(outermost instanceof PackageFacadeContext)) {
|
||||
return PackagePartClassUtils.getPackagePartType(element.getContainingJetFile());
|
||||
}/*disabled cause of KT-7775
|
||||
else if (outermost instanceof ScriptContext) {
|
||||
return asmTypeForScriptDescriptor(bindingContext, ((ScriptContext) outermost).getScriptDescriptor());
|
||||
}*/
|
||||
@@ -320,7 +306,7 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
@NotNull
|
||||
public NameGenerator getInlineNameGenerator() {
|
||||
if (inlineNameGenerator == null) {
|
||||
String prefix = InlineCodegenUtil.getInlineName(context, typeMapper, fileClassesProvider);
|
||||
String prefix = InlineCodegenUtil.getInlineName(context, typeMapper);
|
||||
inlineNameGenerator = new NameGenerator(prefix);
|
||||
}
|
||||
return inlineNameGenerator;
|
||||
@@ -332,12 +318,11 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
if (clInit == null) {
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(descriptor), ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
SimpleFunctionDescriptorImpl clInit =
|
||||
SimpleFunctionDescriptorImpl.create(descriptor, Annotations.EMPTY, Name.special("<clinit>"), SYNTHESIZED,
|
||||
SourcePackage.toSourceElement(element));
|
||||
SimpleFunctionDescriptorImpl.create(descriptor, Annotations.EMPTY, Name.special("<clinit>"), SYNTHESIZED, NO_SOURCE);
|
||||
clInit.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>emptyList(),
|
||||
DescriptorUtilPackage.getModule(descriptor).getBuiltIns().getUnitType(),
|
||||
null, Visibilities.PRIVATE, false);
|
||||
null, Visibilities.PRIVATE);
|
||||
|
||||
this.clInit = new ExpressionCodegen(mv, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state, this);
|
||||
}
|
||||
@@ -368,7 +353,8 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
JetExpression initializer = property.getDelegateExpressionOrInitializer();
|
||||
assert initializer != null : "shouldInitializeProperty must return false if initializer is null";
|
||||
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, true, StackValue.LOCAL_0);
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER,
|
||||
StackValue.LOCAL_0);
|
||||
|
||||
propValue.store(codegen.gen(initializer), codegen.v);
|
||||
|
||||
@@ -391,28 +377,26 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
|
||||
JetExpression initializer = property.getInitializer();
|
||||
|
||||
ConstantValue<?> initializerValue = computeInitializerValue(property, propertyDescriptor, initializer);
|
||||
CompileTimeConstant<?> initializerValue;
|
||||
if (property.isVar() && initializer != null) {
|
||||
BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer");
|
||||
initializerValue = ConstantExpressionEvaluator.evaluate(initializer, tempTrace, propertyDescriptor.getType());
|
||||
}
|
||||
else {
|
||||
initializerValue = propertyDescriptor.getCompileTimeInitializer();
|
||||
}
|
||||
// we must write constant values for fields in light classes,
|
||||
// because Java's completion for annotation arguments uses this information
|
||||
if (initializerValue == null) return state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES;
|
||||
|
||||
//TODO: OPTIMIZATION: don't initialize static final fields
|
||||
|
||||
Object value = initializerValue instanceof IntegerValueTypeConstant
|
||||
? ((IntegerValueTypeConstant) initializerValue).getValue(propertyDescriptor.getType())
|
||||
: initializerValue.getValue();
|
||||
JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
|
||||
Type type = typeMapper.mapType(jetType);
|
||||
return !skipDefaultValue(propertyDescriptor, initializerValue.getValue(), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ConstantValue<?> computeInitializerValue(
|
||||
@NotNull JetProperty property,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@Nullable JetExpression initializer
|
||||
) {
|
||||
if (property.isVar() && initializer != null) {
|
||||
BindingTrace tempTrace = TemporaryBindingTrace.create(state.getBindingTrace(), "property initializer");
|
||||
return constantExpressionEvaluator.evaluateToConstantValue(initializer, tempTrace, propertyDescriptor.getType());
|
||||
}
|
||||
return propertyDescriptor.getCompileTimeInitializer();
|
||||
return !skipDefaultValue(propertyDescriptor, value, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -478,21 +462,10 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
|
||||
|
||||
v.aconst(thisAsmType);
|
||||
if (factory.getArgumentTypes().length == 2) {
|
||||
v.aconst(state.getModuleName());
|
||||
}
|
||||
v.invokestatic(REFLECTION, factory.getName(), factory.getDescriptor(), false);
|
||||
v.putstatic(thisAsmType.getInternalName(), fieldName, type);
|
||||
}
|
||||
|
||||
public static void generateModuleNameField(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull ClassBuilder classBuilder
|
||||
) {
|
||||
classBuilder.newField(NO_ORIGIN, ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.MODULE_NAME_FIELD,
|
||||
AsmTypes.JAVA_STRING_TYPE.getDescriptor(), null, state.getModuleName());
|
||||
}
|
||||
|
||||
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
|
||||
List<JetProperty> delegatedProperties = new ArrayList<JetProperty>();
|
||||
for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) {
|
||||
@@ -559,22 +532,4 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
}
|
||||
return sourceMapper;
|
||||
}
|
||||
|
||||
protected void generateConstInstance(
|
||||
@NotNull Type thisAsmType,
|
||||
@NotNull Type fieldAsmType,
|
||||
@NotNull Function1<InstructionAdapter, Unit> initialization
|
||||
) {
|
||||
v.newField(OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor(),
|
||||
null, null);
|
||||
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
InstructionAdapter iv = createOrGetClInitCodegen().v;
|
||||
iv.anew(thisAsmType);
|
||||
iv.dup();
|
||||
iv.invokespecial(thisAsmType.getInternalName(), "<init>", "()V", false);
|
||||
initialization.invoke(iv);
|
||||
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, fieldAsmType.getDescriptor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public enum MethodKind {
|
||||
GENERAL,
|
||||
INITIALIZER,
|
||||
SYNTHETIC_ACCESSOR
|
||||
}
|
||||
@@ -1,257 +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
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.util.ArrayUtil
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.fileClasses.getFileClassType
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClassPart
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.*
|
||||
|
||||
|
||||
public class MultifileClassCodegen(
|
||||
private val state: GenerationState,
|
||||
public val files: Collection<JetFile>,
|
||||
private val facadeFqName: FqName
|
||||
) {
|
||||
private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName)
|
||||
|
||||
private val packageFragment = getOnlyPackageFragment(facadeFqName.parent(), files, state.bindingContext)
|
||||
|
||||
private val compiledPackageFragment = getCompiledPackageFragment(facadeFqName.parent(), state)
|
||||
|
||||
public val packageParts = PackageParts(facadeFqName.parent().asString())
|
||||
|
||||
// TODO incremental compilation support
|
||||
// TODO previouslyCompiledCallables
|
||||
// We can do this (probably without 'compiledPackageFragment') after modifications to part codegen.
|
||||
|
||||
private val classBuilder = ClassBuilderOnDemand {
|
||||
val originFile = files.firstOrNull()
|
||||
val actualPackageFragment = packageFragment ?:
|
||||
compiledPackageFragment ?:
|
||||
throw AssertionError("No package fragment for multifile facade $facadeFqName; files: $files")
|
||||
val declarationOrigin = MultifileClass(originFile, actualPackageFragment, facadeFqName)
|
||||
val classBuilder = state.factory.newVisitor(declarationOrigin, facadeClassType, files)
|
||||
|
||||
val filesWithCallables = files.filter { it.declarations.any { it is JetNamedFunction || it is JetProperty } }
|
||||
val singleSourceFile = filesWithCallables.singleOrNull()
|
||||
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES,
|
||||
facadeClassType.internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY)
|
||||
if (singleSourceFile != null) {
|
||||
classBuilder.visitSource(singleSourceFile.name, null)
|
||||
}
|
||||
classBuilder
|
||||
}
|
||||
|
||||
public fun generate(errorHandler: CompilationErrorHandler) {
|
||||
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
|
||||
val partFqNames = arrayListOf<FqName>()
|
||||
|
||||
for (file in files) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
try {
|
||||
generatePart(file, generateCallableMemberTasks, partFqNames)
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
val vFile = file.virtualFile
|
||||
errorHandler.reportException(e, if (vFile == null) "no file" else vFile.url)
|
||||
DiagnosticUtils.throwIfRunningOnServer(e)
|
||||
if (ApplicationManager.getApplication().isInternal) {
|
||||
//noinspection CallToPrintStackTrace
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generateDelegationsToPreviouslyCompiled(generateCallableMemberTasks)
|
||||
|
||||
if (!generateCallableMemberTasks.isEmpty()) {
|
||||
generateMultifileFacadeClass(generateCallableMemberTasks, partFqNames)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateMultifileFacadeClass(
|
||||
tasks: Map<CallableMemberDescriptor, () -> Unit>,
|
||||
partFqNames: List<FqName>
|
||||
) {
|
||||
generateKotlinPackageReflectionField()
|
||||
MemberCodegen.generateModuleNameField(state, classBuilder)
|
||||
|
||||
for (member in tasks.keySet().sortedWith(MemberComparator.INSTANCE)) {
|
||||
tasks[member]!!()
|
||||
}
|
||||
|
||||
writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames)
|
||||
}
|
||||
|
||||
public fun generateClassOrObject(classOrObject: JetClassOrObject) {
|
||||
val file = classOrObject.getContainingJetFile()
|
||||
val partType = state.fileClassesProvider.getFileClassType(file)
|
||||
val context = state.rootContext.intoMultifileClassPart(packageFragment!!, facadeClassType, partType)
|
||||
MemberCodegen.genClassOrObject(context, classOrObject, state, null)
|
||||
}
|
||||
|
||||
private fun generatePart(
|
||||
file: JetFile,
|
||||
generateCallableMemberTasks: MutableMap<CallableMemberDescriptor, () -> Unit>,
|
||||
partFqNames: MutableList<FqName>
|
||||
) {
|
||||
val packageFragment = this.packageFragment ?:
|
||||
throw AssertionError("File part $file of $facadeFqName: no package fragment")
|
||||
|
||||
var generatePart = false
|
||||
val partClassInfo = state.fileClassesProvider.getFileClassInfo(file)
|
||||
val partType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(partClassInfo.fileClassFqName)
|
||||
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType)
|
||||
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration is JetProperty || declaration is JetNamedFunction) {
|
||||
generatePart = true
|
||||
}
|
||||
else if (declaration is JetClassOrObject) {
|
||||
if (state.generateDeclaredClassFilter.shouldGenerateClass(declaration)) {
|
||||
generateClassOrObject(declaration)
|
||||
}
|
||||
}
|
||||
else if (declaration is JetScript) {
|
||||
// SCRIPT: generate script code, should be separate execution branch
|
||||
if (state.generateDeclaredClassFilter.shouldGenerateScript(declaration)) {
|
||||
ScriptCodegen.createScriptCodegen(declaration, state, partContext).generate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!generatePart || !state.generateDeclaredClassFilter.shouldGeneratePackagePart(file)) return
|
||||
|
||||
partFqNames.add(partClassInfo.fileClassFqName)
|
||||
|
||||
val name = partType.internalName
|
||||
packageParts.parts.add(name.substring(name.lastIndexOf('/') + 1))
|
||||
|
||||
val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment, facadeFqName), partType, file)
|
||||
|
||||
MultifileClassPartCodegen(builder, file, partType, facadeFqName, partContext, state).generate()
|
||||
|
||||
val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType)
|
||||
val memberCodegen = createCodegenForPartOfMultifileFacade(facadeContext)
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration is JetNamedFunction || declaration is JetProperty) {
|
||||
val descriptor = state.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||
assert(descriptor is CallableMemberDescriptor) { "Expected callable member, was " + descriptor + " for " + declaration.text }
|
||||
generateCallableMemberTasks.put(descriptor as CallableMemberDescriptor,
|
||||
{ memberCodegen.genFunctionOrProperty(declaration) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateKotlinPackageReflectionField() {
|
||||
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null)
|
||||
val method = AsmUtil.method("createKotlinPackage",
|
||||
AsmTypes.K_PACKAGE_TYPE, AsmTypes.getType(Class::class.java), AsmTypes.getType(String::class.java))
|
||||
val iv = InstructionAdapter(mv)
|
||||
MemberCodegen.generateReflectionObjectField(state, facadeClassType, classBuilder, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv)
|
||||
iv.areturn(Type.VOID_TYPE)
|
||||
FunctionCodegen.endVisit(mv, "package facade static initializer", null)
|
||||
}
|
||||
|
||||
private fun writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames: List<FqName>) {
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) return
|
||||
if (files.any { it.isScript }) return
|
||||
|
||||
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
|
||||
JvmCodegenUtil.writeAbiVersion(av)
|
||||
|
||||
val shortNames = partFqNames.map { it.shortName().asString() }.sorted()
|
||||
val filePartClassNamesArray = av.visitArray(JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
|
||||
for (shortName in shortNames) {
|
||||
filePartClassNamesArray.visit(null, shortName)
|
||||
}
|
||||
filePartClassNamesArray.visitEnd()
|
||||
|
||||
av.visitEnd()
|
||||
}
|
||||
|
||||
private fun createCodegenForPartOfMultifileFacade(facadeContext: FieldOwnerContext<*>): MemberCodegen<JetFile> =
|
||||
object : MemberCodegen<JetFile>(state, null, facadeContext, null, classBuilder) {
|
||||
override fun generateDeclaration() = throw UnsupportedOperationException()
|
||||
override fun generateBody() = throw UnsupportedOperationException()
|
||||
override fun generateKotlinAnnotation() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
public fun done() {
|
||||
classBuilder.done()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL
|
||||
|
||||
private fun getOnlyPackageFragment(packageFqName: FqName, files: Collection<JetFile>, bindingContext: BindingContext): PackageFragmentDescriptor? {
|
||||
val fragments = SmartList<PackageFragmentDescriptor>()
|
||||
for (file in files) {
|
||||
val fragment = bindingContext.get(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file)
|
||||
assert(fragment != null) { "package fragment is null for " + file + "\n" + file.text }
|
||||
|
||||
assert(packageFqName == fragment!!.fqName) { "expected package fq name: " + packageFqName + ", actual: " + fragment.fqName }
|
||||
|
||||
if (!fragments.contains(fragment)) {
|
||||
fragments.add(fragment)
|
||||
}
|
||||
}
|
||||
if (fragments.size() > 1) {
|
||||
throw IllegalStateException("More than one package fragment, files: $files | fragments: $fragments")
|
||||
}
|
||||
return fragments.firstOrNull()
|
||||
}
|
||||
|
||||
private fun getCompiledPackageFragment(packageFqName: FqName, state: GenerationState): PackageFragmentDescriptor? =
|
||||
if (!IncrementalCompilation.isEnabled()) null
|
||||
else state.module.getPackage(packageFqName).fragments.firstOrNull { fragment ->
|
||||
fragment is IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
||||
fragment.target == state.targetId
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,108 +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
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||
import org.jetbrains.kotlin.psi.JetProperty
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.util.*
|
||||
|
||||
public class MultifileClassPartCodegen(
|
||||
v: ClassBuilder,
|
||||
file: JetFile,
|
||||
private val filePartType: Type,
|
||||
private val multifileClassFqName: FqName,
|
||||
partContext: FieldOwnerContext<*>,
|
||||
state: GenerationState
|
||||
) : MemberCodegen<JetFile>(state, null, partContext, file, v) {
|
||||
override fun generate() {
|
||||
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) return
|
||||
super.generate()
|
||||
}
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(element, Opcodes.V1_6,
|
||||
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC,
|
||||
filePartType.internalName,
|
||||
null,
|
||||
"java/lang/Object",
|
||||
ArrayUtil.EMPTY_STRING_ARRAY)
|
||||
v.visitSource(element.name, null)
|
||||
|
||||
generatePropertyMetadataArrayFieldIfNeeded(filePartType)
|
||||
}
|
||||
|
||||
override fun generateBody() {
|
||||
for (declaration in element.declarations) {
|
||||
if (declaration is JetNamedFunction || declaration is JetProperty) {
|
||||
genFunctionOrProperty(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.FULL) {
|
||||
generateInitializers { createOrGetClInitCodegen() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateKotlinAnnotation() {
|
||||
if (state.classBuilderMode != ClassBuilderMode.FULL) {
|
||||
return
|
||||
}
|
||||
|
||||
val members = ArrayList<DeclarationDescriptor>()
|
||||
for (declaration in element.declarations) {
|
||||
when (declaration) {
|
||||
is JetNamedFunction -> {
|
||||
val functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration)
|
||||
members.add(functionDescriptor ?: throw AssertionError("Function ${declaration.name} is not bound in ${element.name}"))
|
||||
}
|
||||
is JetProperty -> {
|
||||
val property = bindingContext.get(BindingContext.VARIABLE, declaration)
|
||||
members.add(property ?: throw AssertionError("Property ${declaration.name} is not bound in ${element.name}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val bindings = v.serializationBindings
|
||||
|
||||
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(bindings, state.typeMapper))
|
||||
val packageProto = serializer.packagePartProto(members).build()
|
||||
|
||||
if (packageProto.memberCount == 0) return
|
||||
|
||||
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS_PART), true)
|
||||
JvmCodegenUtil.writeAbiVersion(av)
|
||||
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassFqName.shortName().asString())
|
||||
val dataArray = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME)
|
||||
for (string in BitEncoding.encodeBytes(serializer.serialize(packageProto))) {
|
||||
dataArray.visit(null, string)
|
||||
}
|
||||
dataArray.visitEnd()
|
||||
av.visitEnd()
|
||||
}
|
||||
}
|
||||
@@ -1,172 +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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorImpl;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||
import org.jetbrains.kotlin.types.TypeConstructorImpl;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MutableClassDescriptor extends ClassDescriptorBase implements ClassDescriptor {
|
||||
private final ClassKind kind;
|
||||
private final boolean isInner;
|
||||
|
||||
private Modality modality;
|
||||
private Visibility visibility;
|
||||
private TypeConstructor typeConstructor;
|
||||
private List<TypeParameterDescriptor> typeParameters;
|
||||
private final Collection<JetType> supertypes = new ArrayList<JetType>();
|
||||
|
||||
public MutableClassDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull ClassKind kind,
|
||||
boolean isInner,
|
||||
@NotNull Name name,
|
||||
@NotNull SourceElement source
|
||||
) {
|
||||
super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name, source);
|
||||
assert kind != ClassKind.OBJECT : "Fix isCompanionObject()";
|
||||
|
||||
this.kind = kind;
|
||||
this.isInner = isInner;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ClassDescriptor getCompanionObjectDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Annotations getAnnotations() {
|
||||
return Annotations.EMPTY;
|
||||
}
|
||||
|
||||
public void setModality(@NotNull Modality modality) {
|
||||
this.modality = modality;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Modality getModality() {
|
||||
return modality;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ClassKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public void setVisibility(@NotNull Visibility visibility) {
|
||||
this.visibility = visibility;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return visibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInner() {
|
||||
return isInner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompanionObject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TypeConstructor getTypeConstructor() {
|
||||
return typeConstructor;
|
||||
}
|
||||
|
||||
public void addSupertype(@NotNull JetType supertype) {
|
||||
assert !supertype.isError() : "Error types must be filtered out in DescriptorResolver";
|
||||
if (TypeUtils.getClassDescriptor(supertype) != null) {
|
||||
// See the Errors.SUPERTYPE_NOT_A_CLASS_OR_TRAIT
|
||||
supertypes.add(supertype);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<ConstructorDescriptor> getConstructors() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setTypeParameterDescriptors(@NotNull List<TypeParameterDescriptor> typeParameters) {
|
||||
if (this.typeParameters != null) {
|
||||
throw new IllegalStateException("Type parameters are already set for " + getName());
|
||||
}
|
||||
this.typeParameters = new ArrayList<TypeParameterDescriptor>(typeParameters);
|
||||
}
|
||||
|
||||
public void createTypeConstructor() {
|
||||
assert typeConstructor == null : typeConstructor;
|
||||
this.typeConstructor = TypeConstructorImpl.createForClass(
|
||||
this,
|
||||
Annotations.EMPTY,
|
||||
!getModality().isOverridable(),
|
||||
getName().asString(),
|
||||
typeParameters,
|
||||
supertypes
|
||||
);
|
||||
for (FunctionDescriptor functionDescriptor : getConstructors()) {
|
||||
((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JetScope getUnsubstitutedMemberScope() {
|
||||
return JetScope.Empty.INSTANCE$; // used for getDefaultType
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JetScope getStaticScope() {
|
||||
return JetScope.Empty.INSTANCE$;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return DeclarationDescriptorImpl.toString(this);
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.Mutable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -34,27 +35,24 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.PackageContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts;
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.MemberComparator;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.serialization.*;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
||||
@@ -85,13 +83,7 @@ public class PackageCodegen {
|
||||
private final PackageFragmentDescriptor compiledPackageFragment;
|
||||
private final List<DeserializedCallableMemberDescriptor> previouslyCompiledCallables;
|
||||
|
||||
private final PackageParts packageParts;
|
||||
|
||||
public PackageCodegen(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull Collection<JetFile> files,
|
||||
@NotNull FqName fqName
|
||||
) {
|
||||
public PackageCodegen(@NotNull GenerationState state, @NotNull Collection<JetFile> files, @NotNull FqName fqName) {
|
||||
this.state = state;
|
||||
this.files = files;
|
||||
this.packageFragment = getOnlyPackageFragment(fqName);
|
||||
@@ -109,10 +101,10 @@ public class PackageCodegen {
|
||||
|
||||
ClassBuilder v = PackageCodegen.this.state.getFactory().newVisitor(
|
||||
PackageFacade(packageFragment == null ? compiledPackageFragment : packageFragment),
|
||||
packageClassType, PackagePartClassUtils.getFilesWithCallables(files)
|
||||
packageClassType, PackagePartClassUtils.getPackageFilesWithCallables(files)
|
||||
);
|
||||
v.defineClass(sourceFile, V1_6,
|
||||
ACC_PUBLIC | ACC_FINAL | ACC_DEPRECATED,
|
||||
ACC_PUBLIC | ACC_FINAL,
|
||||
packageClassType.getInternalName(),
|
||||
null,
|
||||
"java/lang/Object",
|
||||
@@ -125,7 +117,6 @@ public class PackageCodegen {
|
||||
return v;
|
||||
}
|
||||
});
|
||||
packageParts = new PackageParts(fqName.asString());
|
||||
}
|
||||
|
||||
// Returns null if file has callables in several files
|
||||
@@ -135,20 +126,20 @@ public class PackageCodegen {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<JetFile> packageFilesWithCallables = PackagePartClassUtils.getFilesWithCallables(packageFiles);
|
||||
List<JetFile> packageFilesWithCallables = PackagePartClassUtils.getPackageFilesWithCallables(packageFiles);
|
||||
return packageFilesWithCallables.size() == 1 ? packageFilesWithCallables.get(0) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PackageFragmentDescriptor getCompiledPackageFragment(@NotNull FqName fqName) {
|
||||
if (!IncrementalCompilation.isEnabled()) {
|
||||
if (!IncrementalCompilation.ENABLED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO rewrite it to something more robust when module system is implemented
|
||||
for (PackageFragmentDescriptor fragment : state.getModule().getPackage(fqName).getFragments()) {
|
||||
if (fragment instanceof IncrementalPackageFragmentProvider.IncrementalPackageFragment &&
|
||||
((IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment).getTarget().equals(state.getTargetId())) {
|
||||
((IncrementalPackageFragmentProvider.IncrementalPackageFragment) fragment).getModuleId().equals(state.getModuleId())) {
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
@@ -174,7 +165,7 @@ public class PackageCodegen {
|
||||
generateCallableMemberTasks.put(member, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FieldOwnerContext context = state.getRootContext().intoPackageFacade(
|
||||
FieldOwnerContext context = CodegenContext.STATIC.intoPackageFacade(
|
||||
AsmUtil.asmTypeByFqNameWithoutInnerClasses(PackagePartClassUtils.getPackagePartFqName(member)),
|
||||
compiledPackageFragment
|
||||
);
|
||||
@@ -223,7 +214,7 @@ public class PackageCodegen {
|
||||
for (JetFile file : files) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
|
||||
try {
|
||||
ClassBuilder builder = generateFile(file, generateCallableMemberTasks);
|
||||
ClassBuilder builder = generate(file, generateCallableMemberTasks);
|
||||
if (builder != null) {
|
||||
bindings.add(builder.getSerializationBindings());
|
||||
}
|
||||
@@ -254,32 +245,33 @@ public class PackageCodegen {
|
||||
@NotNull List<JvmSerializationBindings> bindings
|
||||
) {
|
||||
generateKotlinPackageReflectionField();
|
||||
MemberCodegen.generateModuleNameField(state, v);
|
||||
|
||||
for (CallableMemberDescriptor member : Ordering.from(MemberComparator.INSTANCE).sortedCopy(tasks.keySet())) {
|
||||
tasks.get(member).run();
|
||||
}
|
||||
|
||||
bindings.add(v.getSerializationBindings());
|
||||
writeDeprecatedAnnotation();
|
||||
writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings));
|
||||
writeKotlinPackageAnnotationIfNeeded(JvmSerializationBindings.union(bindings), tasks.keySet());
|
||||
}
|
||||
|
||||
private void generateKotlinPackageReflectionField() {
|
||||
MethodVisitor mv = v.newMethod(NO_ORIGIN, ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
Method method = method("createKotlinPackage", K_PACKAGE_TYPE, getType(Class.class), getType(String.class));
|
||||
Method method = method("createKotlinPackage", K_PACKAGE_TYPE, getType(Class.class));
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
MemberCodegen.generateReflectionObjectField(state, packageClassType, v, method, JvmAbi.KOTLIN_PACKAGE_FIELD_NAME, iv);
|
||||
iv.areturn(Type.VOID_TYPE);
|
||||
FunctionCodegen.endVisit(mv, "package facade static initializer", null);
|
||||
}
|
||||
|
||||
private void writeKotlinPackageAnnotationIfNeeded(@NotNull JvmSerializationBindings bindings) {
|
||||
private void writeKotlinPackageAnnotationIfNeeded(
|
||||
@NotNull JvmSerializationBindings bindings,
|
||||
@NotNull final Collection<CallableMemberDescriptor> relevantCallables
|
||||
) {
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// SCRIPT: Do not write KotlinPackage annotation for scripts (if any is??)
|
||||
// SCRIPT: Do not write annotations for scripts (if any is??)
|
||||
for (JetFile file : files) {
|
||||
if (file.isScript()) return;
|
||||
}
|
||||
@@ -288,37 +280,34 @@ public class PackageCodegen {
|
||||
Collection<PackageFragmentDescriptor> packageFragments = Lists.newArrayList();
|
||||
ContainerUtil.addIfNotNull(packageFragments, packageFragment);
|
||||
ContainerUtil.addIfNotNull(packageFragments, compiledPackageFragment);
|
||||
ProtoBuf.Package packageProto = serializer.packageProtoWithoutDescriptors().build();
|
||||
ProtoBuf.Package packageProto = serializer.packageProto(packageFragments, new Function1<DeclarationDescriptor, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(DeclarationDescriptor descriptor) {
|
||||
return !(descriptor instanceof CallableMemberDescriptor && relevantCallables.contains(descriptor));
|
||||
}
|
||||
}).build();
|
||||
|
||||
if (packageProto.getMemberCount() == 0) return;
|
||||
|
||||
StringTable strings = serializer.getStringTable();
|
||||
NameResolver nameResolver = new NameResolver(strings.serializeSimpleNames(), strings.serializeQualifiedNames());
|
||||
PackageData data = new PackageData(nameResolver, packageProto);
|
||||
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_PACKAGE), true);
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||
AnnotationVisitor array = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME);
|
||||
for (String string : BitEncoding.encodeBytes(serializer.serialize(packageProto))) {
|
||||
for (String string : BitEncoding.encodeBytes(SerializationUtil.serializePackageData(data))) {
|
||||
array.visit(null, string);
|
||||
}
|
||||
array.visitEnd();
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
private void writeDeprecatedAnnotation() {
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.JAVA_LANG_DEPRECATED), true);
|
||||
av.visitEnd();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassBuilder generateFile(@NotNull JetFile file, @NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||
JvmFileClassInfo fileClassInfo = state.getFileClassesProvider().getFileClassInfo(file);
|
||||
|
||||
if (fileClassInfo.getIsMultifileClass()) {
|
||||
Type fileFacadeType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFacadeClassFqName());
|
||||
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, fileFacadeType);
|
||||
return null;
|
||||
}
|
||||
|
||||
Type fileClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.getFileClassFqName());
|
||||
PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, fileClassType);
|
||||
|
||||
private ClassBuilder generate(@NotNull JetFile file, @NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||
boolean generatePackagePart = false;
|
||||
Type packagePartType = PackagePartClassUtils.getPackagePartType(file);
|
||||
PackageContext packagePartContext = CodegenContext.STATIC.intoPackagePart(packageFragment, packagePartType);
|
||||
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
|
||||
@@ -333,7 +322,7 @@ public class PackageCodegen {
|
||||
else if (declaration instanceof JetScript) {
|
||||
JetScript script = (JetScript) declaration;
|
||||
|
||||
// SCRIPT: generate script code, should be separate execution branch
|
||||
// SCRIPT: generate script code, should be separate execution branch
|
||||
if (state.getGenerateDeclaredClassFilter().shouldGenerateScript(script)) {
|
||||
ScriptCodegen.createScriptCodegen(script, state, packagePartContext).generate();
|
||||
}
|
||||
@@ -342,24 +331,12 @@ public class PackageCodegen {
|
||||
|
||||
if (!generatePackagePart || !state.getGenerateDeclaredClassFilter().shouldGeneratePackagePart(file)) return null;
|
||||
|
||||
String name = fileClassType.getInternalName();
|
||||
packageParts.getParts().add(name.substring(name.lastIndexOf('/') + 1));
|
||||
ClassBuilder builder = state.getFactory().newVisitor(PackagePart(file, packageFragment), packagePartType, file);
|
||||
|
||||
ClassBuilder builder = state.getFactory().newVisitor(PackagePart(file, packageFragment), fileClassType, file);
|
||||
new PackagePartCodegen(builder, file, packagePartType, packagePartContext, state).generate();
|
||||
|
||||
new PackagePartCodegen(builder, file, fileClassType, packagePartContext, state).generate();
|
||||
FieldOwnerContext packageFacade = CodegenContext.STATIC.intoPackageFacade(packagePartType, packageFragment);
|
||||
|
||||
addDelegateToFileClassMemberTasks(file, generateCallableMemberTasks, fileClassType);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void addDelegateToFileClassMemberTasks(
|
||||
@NotNull JetFile file,
|
||||
@NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks,
|
||||
@NotNull Type fileClassType
|
||||
) {
|
||||
FieldOwnerContext packageFacade = state.getRootContext().intoPackageFacade(fileClassType, packageFragment);
|
||||
final MemberCodegen<?> memberCodegen = createCodegenForPartOfPackageFacade(packageFacade);
|
||||
|
||||
for (final JetDeclaration declaration : file.getDeclarations()) {
|
||||
@@ -378,6 +355,8 @@ public class PackageCodegen {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private MemberCodegen<?> createCodegenForPartOfPackageFacade(@NotNull FieldOwnerContext packageFacade) {
|
||||
@@ -425,20 +404,12 @@ public class PackageCodegen {
|
||||
|
||||
public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||
JetFile file = classOrObject.getContainingJetFile();
|
||||
Type packagePartType = FileClassesPackage.getFileClassType(state.getFileClassesProvider(), file);
|
||||
CodegenContext context = state.getRootContext().intoPackagePart(packageFragment, packagePartType);
|
||||
Type packagePartType = PackagePartClassUtils.getPackagePartType(file);
|
||||
CodegenContext context = CodegenContext.STATIC.intoPackagePart(packageFragment, packagePartType);
|
||||
MemberCodegen.genClassOrObject(context, classOrObject, state, null);
|
||||
}
|
||||
|
||||
public void done() {
|
||||
v.done();
|
||||
}
|
||||
|
||||
public PackageParts getPackageParts() {
|
||||
return packageParts;
|
||||
}
|
||||
|
||||
public Collection<JetFile> getFiles() {
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,28 +19,16 @@ package org.jetbrains.kotlin.codegen;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding;
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.JetProperty;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class PackagePartCodegen extends MemberCodegen<JetFile> {
|
||||
@@ -69,20 +57,6 @@ public class PackagePartCodegen extends MemberCodegen<JetFile> {
|
||||
v.visitSource(element.getName(), null);
|
||||
|
||||
generatePropertyMetadataArrayFieldIfNeeded(packagePartType);
|
||||
|
||||
generateAnnotationsForPartClass();
|
||||
}
|
||||
|
||||
private void generateAnnotationsForPartClass() {
|
||||
List<AnnotationDescriptor> fileAnnotationDescriptors = new ArrayList<AnnotationDescriptor>();
|
||||
for (JetAnnotationEntry annotationEntry : element.getAnnotationEntries()) {
|
||||
AnnotationDescriptor annotationDescriptor = state.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
|
||||
if (annotationDescriptor != null) {
|
||||
fileAnnotationDescriptors.add(annotationDescriptor);
|
||||
}
|
||||
}
|
||||
Annotated annotatedFile = new AnnotatedSimple(new AnnotationsImpl(fileAnnotationDescriptors));
|
||||
AnnotationCodegen.forClass(v.getVisitor(), state.getTypeMapper()).genAnnotations(annotatedFile, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,35 +79,6 @@ public class PackagePartCodegen extends MemberCodegen<JetFile> {
|
||||
|
||||
@Override
|
||||
protected void generateKotlinAnnotation() {
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
|
||||
for (JetDeclaration declaration : element.getDeclarations()) {
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
members.add(functionDescriptor);
|
||||
} else if (declaration instanceof JetProperty) {
|
||||
VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||
members.add(property);
|
||||
}
|
||||
}
|
||||
|
||||
JvmSerializationBindings bindings = v.getSerializationBindings();
|
||||
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(bindings, state.getTypeMapper()));
|
||||
ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
|
||||
|
||||
if (packageProto.getMemberCount() == 0) return;
|
||||
|
||||
AnnotationVisitor av = v.newAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_FILE_FACADE), true);
|
||||
JvmCodegenUtil.writeAbiVersion(av);
|
||||
AnnotationVisitor array = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME);
|
||||
for (String string : BitEncoding.encodeBytes(serializer.serialize(packageProto))) {
|
||||
array.visit(null, string);
|
||||
}
|
||||
array.visitEnd();
|
||||
av.visitEnd();
|
||||
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.PACKAGE_PART);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,19 +23,20 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.psi.JetElement
|
||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
class PlatformStaticGenerator(
|
||||
val descriptor: FunctionDescriptor,
|
||||
val declarationOrigin: JvmDeclarationOrigin,
|
||||
val state: GenerationState
|
||||
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
|
||||
private val typeMapper = state.typeMapper
|
||||
|
||||
override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) {
|
||||
val staticFunctionDescriptor = createStaticFunctionDescriptor(descriptor)
|
||||
@@ -50,36 +51,40 @@ class PlatformStaticGenerator(
|
||||
frameMap: FrameMap,
|
||||
signature: JvmMethodSignature,
|
||||
context: MethodContext,
|
||||
parentCodegen: MemberCodegen<*>
|
||||
parentCodegen: MemberCodegen<out JetElement>
|
||||
) {
|
||||
val typeMapper = parentCodegen.typeMapper
|
||||
|
||||
val iv = InstructionAdapter(mv)
|
||||
val classDescriptor = descriptor.containingDeclaration as ClassDescriptor
|
||||
val classDescriptor = descriptor.getContainingDeclaration() as ClassDescriptor
|
||||
val singletonValue = StackValue.singleton(classDescriptor, typeMapper)
|
||||
singletonValue.put(singletonValue.type, iv)
|
||||
var index = 0
|
||||
val asmMethod = signature.asmMethod
|
||||
for (paramType in asmMethod.argumentTypes) {
|
||||
iv.load(index, paramType)
|
||||
index += paramType.size
|
||||
singletonValue.put(singletonValue.type, iv);
|
||||
var index = 0;
|
||||
val asmMethod = signature.getAsmMethod()
|
||||
for (paramType in asmMethod.getArgumentTypes()) {
|
||||
iv.load(index, paramType);
|
||||
index += paramType.getSize();
|
||||
}
|
||||
|
||||
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
|
||||
codegen.getContext().accessibleDescriptor(descriptor, /* superCallExpression = */ null),
|
||||
false
|
||||
codegen.getContext().accessibleFunctionDescriptor(descriptor),
|
||||
false,
|
||||
codegen.getContext()
|
||||
)
|
||||
syntheticOrOriginalMethod.genInvokeInstruction(iv)
|
||||
iv.areturn(asmMethod.returnType)
|
||||
iv.areturn(asmMethod.getReturnType());
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
if (originElement is JetNamedFunction) {
|
||||
codegen.functionCodegen.generateOverloadsWithDefaultValues(originElement, staticFunctionDescriptor, descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@platformStatic
|
||||
public fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
|
||||
val copies = CodegenUtil.copyFunctions(
|
||||
|
||||
@@ -17,19 +17,16 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
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.annotation.AnnotatedSimple;
|
||||
import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.*;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -37,13 +34,11 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter;
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
@@ -110,24 +105,15 @@ public class PropertyCodegen {
|
||||
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL
|
||||
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
||||
|
||||
String implClassName = CodegenContextUtil.getImplementationClassShortName(context);
|
||||
if (implClassName != null) {
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, implClassName);
|
||||
if (context instanceof PackageFacadeContext) {
|
||||
Type ownerType = ((PackageFacadeContext) context).getDelegateToClassType();
|
||||
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, shortNameByAsmType(ownerType));
|
||||
}
|
||||
|
||||
if (CodegenContextUtil.isImplClassOwner(context)) {
|
||||
else {
|
||||
assert declaration != null : "Declaration is null for different context: " + context;
|
||||
|
||||
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
||||
|
||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
|
||||
descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(false, descriptor.isVar(), hasBackingField));
|
||||
|
||||
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
||||
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
||||
|
||||
generateBackingField(declaration, descriptor, fieldAnnotations);
|
||||
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
|
||||
if (!generateBackingField(declaration, descriptor)) {
|
||||
generateSyntheticMethodIfNeeded(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (isAccessorNeeded(declaration, descriptor, getter)) {
|
||||
@@ -173,15 +159,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
public void generatePrimaryConstructorProperty(JetParameter p, PropertyDescriptor descriptor) {
|
||||
AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS,
|
||||
descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(true, descriptor.isVar(), hasBackingField(p, descriptor)));
|
||||
|
||||
Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
|
||||
Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
|
||||
|
||||
generateBackingField(p, descriptor, fieldAnnotations);
|
||||
generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
|
||||
|
||||
generateBackingField(p, descriptor);
|
||||
if (!Visibilities.isPrivate(descriptor.getVisibility())) {
|
||||
generateGetter(p, descriptor, null);
|
||||
if (descriptor.isVar()) {
|
||||
@@ -204,7 +182,7 @@ public class PropertyCodegen {
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||
JetExpression defaultValue = p.getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext);
|
||||
CompileTimeConstant<?> constant = ExpressionCodegen.getCompileTimeConstant(defaultValue, bindingContext);
|
||||
assert constant != null : "Default value for annotation parameter should be compile time value: " + defaultValue.getText();
|
||||
AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(mv, typeMapper);
|
||||
annotationCodegen.generateAnnotationDefaultValue(constant, descriptor.getType());
|
||||
@@ -214,26 +192,16 @@ public class PropertyCodegen {
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private boolean hasBackingField(@NotNull JetNamedDeclaration p, @NotNull PropertyDescriptor descriptor) {
|
||||
return !isInterface(descriptor.getContainingDeclaration()) &&
|
||||
kind != OwnerKind.TRAIT_IMPL &&
|
||||
!Boolean.FALSE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor));
|
||||
}
|
||||
|
||||
private boolean generateBackingField(
|
||||
@NotNull JetNamedDeclaration p,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull Annotations annotations
|
||||
) {
|
||||
private boolean generateBackingField(@NotNull JetNamedDeclaration p, @NotNull PropertyDescriptor descriptor) {
|
||||
if (isInterface(descriptor.getContainingDeclaration()) || kind == OwnerKind.TRAIT_IMPL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p instanceof JetProperty && ((JetProperty) p).hasDelegate()) {
|
||||
generatePropertyDelegateAccess((JetProperty) p, descriptor, annotations);
|
||||
generatePropertyDelegateAccess((JetProperty) p, descriptor);
|
||||
}
|
||||
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
||||
generateBackingFieldAccess(p, descriptor, annotations);
|
||||
generateBackingFieldAccess(p, descriptor);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -241,10 +209,10 @@ public class PropertyCodegen {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Annotations on properties are stored in bytecode on an empty synthetic method. This way they're still
|
||||
// Annotations on properties without backing fields are stored in bytecode on an empty synthetic method. This way they're still
|
||||
// accessible via reflection, and 'deprecated' and 'private' flags prevent this method from being called accidentally
|
||||
private void generateSyntheticMethodIfNeeded(@NotNull PropertyDescriptor descriptor, Annotations annotations) {
|
||||
if (annotations.getAllAnnotations().isEmpty()) return;
|
||||
private void generateSyntheticMethodIfNeeded(@NotNull PropertyDescriptor descriptor) {
|
||||
if (descriptor.getAnnotations().isEmpty()) return;
|
||||
|
||||
ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter();
|
||||
String name = JvmAbi.getSyntheticMethodNameForAnnotatedProperty(descriptor.getName());
|
||||
@@ -253,8 +221,7 @@ public class PropertyCodegen {
|
||||
if (!isTrait(context.getContextDescriptor()) || kind == OwnerKind.TRAIT_IMPL) {
|
||||
int flags = ACC_DEPRECATED | ACC_FINAL | ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC;
|
||||
MethodVisitor mv = v.newMethod(OtherOrigin(descriptor), flags, name, desc, null, null);
|
||||
AnnotationCodegen.forMethod(mv, typeMapper)
|
||||
.genAnnotations(new AnnotatedSimple(annotations), Type.VOID_TYPE, AnnotationUseSiteTarget.PROPERTY);
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(descriptor, Type.VOID_TYPE);
|
||||
mv.visitCode();
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitEnd();
|
||||
@@ -269,14 +236,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateBackingField(
|
||||
JetNamedDeclaration element,
|
||||
PropertyDescriptor propertyDescriptor,
|
||||
boolean isDelegate,
|
||||
JetType jetType,
|
||||
Object defaultValue,
|
||||
Annotations annotations
|
||||
) {
|
||||
private void generateBackingField(JetNamedDeclaration element, PropertyDescriptor propertyDescriptor, boolean isDelegate, JetType jetType, Object defaultValue) {
|
||||
int modifiers = getDeprecatedAccessFlag(propertyDescriptor);
|
||||
|
||||
for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.FIELD_FLAGS) {
|
||||
@@ -289,7 +249,7 @@ public class PropertyCodegen {
|
||||
modifiers |= ACC_STATIC;
|
||||
}
|
||||
|
||||
if (!propertyDescriptor.isLateInit() && (!propertyDescriptor.isVar() || isDelegate)) {
|
||||
if (!propertyDescriptor.isVar() || isDelegate) {
|
||||
modifiers |= ACC_FINAL;
|
||||
}
|
||||
|
||||
@@ -300,14 +260,10 @@ public class PropertyCodegen {
|
||||
boolean hasPublicFieldAnnotation = AnnotationsPackage.findPublicFieldAnnotation(propertyDescriptor) != null;
|
||||
|
||||
FieldOwnerContext backingFieldContext = context;
|
||||
boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst();
|
||||
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||
modifiers |= ACC_STATIC;
|
||||
|
||||
if (takeVisibilityFromDescriptor) {
|
||||
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
|
||||
}
|
||||
else if (hasPublicFieldAnnotation && !isDelegate) {
|
||||
if (hasPublicFieldAnnotation && !isDelegate) {
|
||||
modifiers |= ACC_PUBLIC;
|
||||
}
|
||||
else {
|
||||
@@ -321,9 +277,6 @@ public class PropertyCodegen {
|
||||
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
else if (takeVisibilityFromDescriptor) {
|
||||
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
|
||||
}
|
||||
else if (!isDelegate && hasPublicFieldAnnotation) {
|
||||
modifiers |= ACC_PUBLIC;
|
||||
}
|
||||
@@ -342,12 +295,10 @@ public class PropertyCodegen {
|
||||
|
||||
FieldVisitor fv = builder.newField(OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||
typeMapper.mapFieldSignature(jetType), defaultValue);
|
||||
|
||||
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD);
|
||||
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(propertyDescriptor, type);
|
||||
}
|
||||
|
||||
private void generatePropertyDelegateAccess(JetProperty p, PropertyDescriptor propertyDescriptor, Annotations annotations) {
|
||||
private void generatePropertyDelegateAccess(JetProperty p, PropertyDescriptor propertyDescriptor) {
|
||||
JetExpression delegateExpression = p.getDelegateExpression();
|
||||
JetType delegateType = delegateExpression != null ? bindingContext.getType(p.getDelegateExpression()) : null;
|
||||
if (delegateType == null) {
|
||||
@@ -355,20 +306,20 @@ public class PropertyCodegen {
|
||||
delegateType = ErrorUtils.createErrorType("Delegate type");
|
||||
}
|
||||
|
||||
generateBackingField(p, propertyDescriptor, true, delegateType, null, annotations);
|
||||
generateBackingField(p, propertyDescriptor, true, delegateType, null);
|
||||
}
|
||||
|
||||
private void generateBackingFieldAccess(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, Annotations annotations) {
|
||||
private void generateBackingFieldAccess(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor) {
|
||||
Object value = null;
|
||||
|
||||
if (shouldWriteFieldInitializer(propertyDescriptor)) {
|
||||
ConstantValue<?> initializer = propertyDescriptor.getCompileTimeInitializer();
|
||||
CompileTimeConstant<?> initializer = propertyDescriptor.getCompileTimeInitializer();
|
||||
if (initializer != null) {
|
||||
value = initializer.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
generateBackingField(p, propertyDescriptor, false, propertyDescriptor.getType(), value, annotations);
|
||||
generateBackingField(p, propertyDescriptor, false, propertyDescriptor.getType(), value);
|
||||
}
|
||||
|
||||
private boolean shouldWriteFieldInitializer(@NotNull PropertyDescriptor descriptor) {
|
||||
@@ -383,7 +334,7 @@ public class PropertyCodegen {
|
||||
private void generateGetter(@Nullable JetNamedDeclaration p, @NotNull PropertyDescriptor descriptor, @Nullable JetPropertyAccessor getter) {
|
||||
generateAccessor(p, getter, descriptor.getGetter() != null
|
||||
? descriptor.getGetter()
|
||||
: DescriptorFactory.createDefaultGetter(descriptor, Annotations.EMPTY));
|
||||
: DescriptorFactory.createDefaultGetter(descriptor));
|
||||
}
|
||||
|
||||
private void generateSetter(@Nullable JetNamedDeclaration p, @NotNull PropertyDescriptor descriptor, @Nullable JetPropertyAccessor setter) {
|
||||
@@ -391,7 +342,7 @@ public class PropertyCodegen {
|
||||
|
||||
generateAccessor(p, setter, descriptor.getSetter() != null
|
||||
? descriptor.getSetter()
|
||||
: DescriptorFactory.createDefaultSetter(descriptor, Annotations.EMPTY));
|
||||
: DescriptorFactory.createDefaultSetter(descriptor));
|
||||
}
|
||||
|
||||
private void generateAccessor(
|
||||
@@ -494,9 +445,6 @@ public class PropertyCodegen {
|
||||
else if (ownerContext instanceof PackageContext) {
|
||||
owner = ((PackageContext) ownerContext).getPackagePartType();
|
||||
}
|
||||
else if (ownerContext instanceof MultifileClassContextBase) {
|
||||
owner = ((MultifileClassContextBase) ownerContext).getFilePartType();
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown context: " + ownerContext);
|
||||
}
|
||||
@@ -543,6 +491,16 @@ public class PropertyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getterName(Name propertyName) {
|
||||
return JvmAbi.GETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String setterName(Name propertyName) {
|
||||
return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.asString());
|
||||
}
|
||||
|
||||
public void genDelegate(@NotNull PropertyDescriptor delegate, @NotNull PropertyDescriptor delegateTo, @NotNull StackValue field) {
|
||||
ClassDescriptor toClass = (ClassDescriptor) delegateTo.getContainingDeclaration();
|
||||
|
||||
|
||||
@@ -1,202 +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
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.method
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.JetCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ScriptReceiver
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_FINAL
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_PUBLIC
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_SUPER
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.V1_6
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
public class PropertyReferenceCodegen(
|
||||
state: GenerationState,
|
||||
parentCodegen: MemberCodegen<*>,
|
||||
context: ClassContext,
|
||||
expression: JetCallableReferenceExpression,
|
||||
classBuilder: ClassBuilder,
|
||||
private val classDescriptor: ClassDescriptor,
|
||||
private val resolvedCall: ResolvedCall<VariableDescriptor>
|
||||
) : MemberCodegen<JetCallableReferenceExpression>(state, parentCodegen, context, expression, classBuilder) {
|
||||
private val target = resolvedCall.getResultingDescriptor()
|
||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||
|
||||
// e.g. MutablePropertyReference0
|
||||
private val superAsmType = typeMapper.mapClass(classDescriptor.getSuperClassNotAny().sure { "No super class for $classDescriptor" })
|
||||
|
||||
// e.g. mutableProperty0(Lkotlin/jvm/internal/MutablePropertyReference0;)Lkotlin/reflect/KMutableProperty0;
|
||||
private val wrapperMethod: Method
|
||||
|
||||
init {
|
||||
val hasReceiver = target.getDispatchReceiverParameter() != null || target.getExtensionReceiverParameter() != null
|
||||
val isMutable = target.isVar()
|
||||
|
||||
wrapperMethod = when {
|
||||
hasReceiver -> when {
|
||||
isMutable -> method("mutableProperty1", K_MUTABLE_PROPERTY1_TYPE, MUTABLE_PROPERTY_REFERENCE1)
|
||||
else -> method("property1", K_PROPERTY1_TYPE, PROPERTY_REFERENCE1)
|
||||
}
|
||||
else -> when {
|
||||
isMutable -> method("mutableProperty0", K_MUTABLE_PROPERTY0_TYPE, MUTABLE_PROPERTY_REFERENCE0)
|
||||
else -> method("property0", K_PROPERTY0_TYPE, PROPERTY_REFERENCE0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateDeclaration() {
|
||||
v.defineClass(
|
||||
element,
|
||||
V1_6,
|
||||
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor),
|
||||
asmType.getInternalName(),
|
||||
null,
|
||||
superAsmType.getInternalName(),
|
||||
emptyArray()
|
||||
)
|
||||
|
||||
v.visitSource(element.getContainingFile().getName(), null)
|
||||
}
|
||||
|
||||
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
|
||||
override fun generateBody() {
|
||||
generateConstInstance(asmType, wrapperMethod.getReturnType()) { iv ->
|
||||
iv.invokestatic(REFLECTION, wrapperMethod.getName(), wrapperMethod.getDescriptor(), false)
|
||||
}
|
||||
|
||||
generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) {
|
||||
load(0, OBJECT_TYPE)
|
||||
invokespecial(superAsmType.getInternalName(), "<init>", "()V", false)
|
||||
}
|
||||
|
||||
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, typeMapper)
|
||||
}
|
||||
|
||||
generateMethod("property reference getName", ACC_PUBLIC, method("getName", JAVA_STRING_TYPE)) {
|
||||
aconst(target.getName().asString())
|
||||
}
|
||||
|
||||
generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) {
|
||||
target as PropertyDescriptor
|
||||
|
||||
val getter = target.getGetter() ?: run {
|
||||
val defaultGetter = DescriptorFactory.createDefaultGetter(target, Annotations.EMPTY)
|
||||
defaultGetter.initialize(target.getType())
|
||||
defaultGetter
|
||||
}
|
||||
|
||||
val method = typeMapper.mapSignature(getter).getAsmMethod()
|
||||
aconst(method.getName() + method.getDescriptor())
|
||||
}
|
||||
|
||||
generateAccessors()
|
||||
}
|
||||
|
||||
private fun generateAccessors() {
|
||||
val dispatchReceiver = resolvedCall.getDispatchReceiver()
|
||||
val extensionReceiver = resolvedCall.getExtensionReceiver()
|
||||
val receiverType =
|
||||
when {
|
||||
dispatchReceiver is ScriptReceiver -> {
|
||||
// TODO: fix receiver for scripts, see ScriptReceiver#getType
|
||||
dispatchReceiver.getDeclarationDescriptor().getClassDescriptor().getDefaultType()
|
||||
}
|
||||
dispatchReceiver.exists() -> dispatchReceiver.getType()
|
||||
extensionReceiver.exists() -> extensionReceiver.getType()
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun generateAccessor(method: Method, accessorBody: InstructionAdapter.(StackValue) -> Unit) {
|
||||
generateMethod("property reference $method", ACC_PUBLIC, method) {
|
||||
// Note: this descriptor is an inaccurate representation of the get/set method. In particular, it has incorrect
|
||||
// return type and value parameter types. However, it's created only to be able to use
|
||||
// ExpressionCodegen#intermediateValueForProperty, which is poorly coupled with everything else.
|
||||
val fakeDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(method.getName()), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
fakeDescriptor.initialize(null, classDescriptor.getThisAsReceiverParameter(), emptyList(), emptyList(),
|
||||
classDescriptor.builtIns.getAnyType(), Modality.OPEN, Visibilities.PUBLIC, false)
|
||||
|
||||
val fakeCodegen = ExpressionCodegen(
|
||||
this, FrameMap(), OBJECT_TYPE, context.intoFunction(fakeDescriptor), state, this@PropertyReferenceCodegen
|
||||
)
|
||||
|
||||
val receiver =
|
||||
if (receiverType != null) StackValue.coercion(StackValue.local(1, OBJECT_TYPE), typeMapper.mapType(receiverType))
|
||||
else StackValue.none()
|
||||
val value = fakeCodegen.intermediateValueForProperty(target as PropertyDescriptor, false, null, receiver)
|
||||
|
||||
accessorBody(value)
|
||||
}
|
||||
}
|
||||
|
||||
val getterParameters = if (receiverType != null) arrayOf(OBJECT_TYPE) else emptyArray()
|
||||
generateAccessor(method("get", OBJECT_TYPE, *getterParameters)) { value ->
|
||||
value.put(OBJECT_TYPE, this)
|
||||
}
|
||||
|
||||
if (!target.isVar()) return
|
||||
|
||||
val setterParameters = (getterParameters + arrayOf(OBJECT_TYPE))
|
||||
generateAccessor(method("set", Type.VOID_TYPE, *setterParameters)) { value ->
|
||||
// Hard-coded 1 or 2 is safe here because there's only java/lang/Object in the signature, no double/long parameters
|
||||
value.store(StackValue.local(if (receiverType != null) 2 else 1, OBJECT_TYPE), this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) {
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.getName(), method.getDescriptor(), null, null)
|
||||
|
||||
if (state.classBuilderMode == ClassBuilderMode.FULL) {
|
||||
val iv = InstructionAdapter(mv)
|
||||
iv.visitCode()
|
||||
iv.generate()
|
||||
iv.areturn(method.getReturnType())
|
||||
FunctionCodegen.endVisit(mv, debugString, element)
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateKotlinAnnotation() {
|
||||
writeKotlinSyntheticClassAnnotation(v, KotlinSyntheticClass.Kind.CALLABLE_REFERENCE_WRAPPER)
|
||||
}
|
||||
|
||||
public fun putInstanceOnStack(): StackValue =
|
||||
StackValue.operation(wrapperMethod.getReturnType()) { iv ->
|
||||
iv.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, wrapperMethod.getReturnType().getDescriptor())
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
|
||||
public class SamCodegenUtil {
|
||||
@Nullable
|
||||
@@ -31,10 +30,6 @@ public class SamCodegenUtil {
|
||||
return ((SamAdapterDescriptor<?>) original).getOriginForSam();
|
||||
}
|
||||
|
||||
if (original instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
return ((SamAdapterExtensionFunctionDescriptor) original).getSourceFunction();
|
||||
}
|
||||
|
||||
if (original.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||
for (FunctionDescriptor overridden : original.getOverriddenDescriptors()) {
|
||||
FunctionDescriptor originalIfSamAdapter = getOriginalIfSamAdapter(overridden);
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
@@ -144,12 +143,12 @@ public class SamWrapperCodegen {
|
||||
SimpleFunctionDescriptor erasedInterfaceFunction,
|
||||
JetType functionJetType
|
||||
) {
|
||||
// using root context to avoid creating ClassDescriptor and everything else
|
||||
FunctionCodegen codegen = new FunctionCodegen(state.getRootContext().intoClass(
|
||||
// using static context to avoid creating ClassDescriptor and everything else
|
||||
FunctionCodegen codegen = new FunctionCodegen(CodegenContext.STATIC.intoClass(
|
||||
(ClassDescriptor) erasedInterfaceFunction.getContainingDeclaration(), OwnerKind.IMPLEMENTATION, state), cv, state, parentCodegen);
|
||||
|
||||
FunctionDescriptor invokeFunction =
|
||||
functionJetType.getMemberScope().getFunctions(OperatorConventions.INVOKE, NoLookupLocation.FROM_BACKEND).iterator().next().getOriginal();
|
||||
functionJetType.getMemberScope().getFunctions(OperatorConventions.INVOKE).iterator().next().getOriginal();
|
||||
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false, StackValue.none());
|
||||
codegen.genDelegate(erasedInterfaceFunction, invokeFunction, functionField);
|
||||
|
||||
@@ -162,8 +161,8 @@ public class SamWrapperCodegen {
|
||||
|
||||
descriptorForBridges
|
||||
.initialize(null, originalInterfaceErased.getDispatchReceiverParameter(), originalInterfaceErased.getTypeParameters(),
|
||||
originalInterfaceErased.getValueParameters(), originalInterfaceErased.getReturnType(),
|
||||
Modality.OPEN, originalInterfaceErased.getVisibility(), false);
|
||||
originalInterfaceErased.getValueParameters(), originalInterfaceErased.getReturnType(), Modality.OPEN,
|
||||
originalInterfaceErased.getVisibility());
|
||||
|
||||
descriptorForBridges.addOverriddenDescriptor(originalInterfaceErased);
|
||||
codegen.generateBridges(descriptorForBridges);
|
||||
|
||||
@@ -26,8 +26,9 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
|
||||
|
||||
public abstract class SignatureCollectingClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
private val delegate: ClassBuilderFactory
|
||||
|
||||
) : ClassBuilderFactory by delegate {
|
||||
|
||||
protected abstract fun handleClashingSignatures(data: ConflictingJvmDeclarationsData)
|
||||
protected abstract fun onClassDone(classOrigin: JvmDeclarationOrigin,
|
||||
@@ -38,6 +39,18 @@ public abstract class SignatureCollectingClassBuilderFactory(
|
||||
return SignatureCollectingClassBuilder(origin, delegate.newClassBuilder(origin))
|
||||
}
|
||||
|
||||
public override fun asBytes(builder: ClassBuilder?): ByteArray? {
|
||||
return delegate.asBytes((builder as SignatureCollectingClassBuilder)._delegate)
|
||||
}
|
||||
|
||||
public override fun asText(builder: ClassBuilder?): String? {
|
||||
return delegate.asText((builder as SignatureCollectingClassBuilder)._delegate)
|
||||
}
|
||||
|
||||
public override fun close() {
|
||||
delegate.close()
|
||||
}
|
||||
|
||||
private inner class SignatureCollectingClassBuilder(
|
||||
private val classCreatedFor: JvmDeclarationOrigin,
|
||||
internal val _delegate: ClassBuilder
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -36,7 +35,6 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
@@ -250,7 +248,7 @@ public abstract class StackValue {
|
||||
@NotNull
|
||||
public static Property property(
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable Type backingFieldOwner,
|
||||
@NotNull Type backingFieldOwner,
|
||||
@NotNull Type type,
|
||||
boolean isStaticBackingField,
|
||||
@Nullable String fieldName,
|
||||
@@ -487,29 +485,15 @@ public abstract class StackValue {
|
||||
ExpressionCodegen codegen,
|
||||
@Nullable Callable callableMethod
|
||||
) {
|
||||
ReceiverValue callDispatchReceiver = resolvedCall.getDispatchReceiver();
|
||||
ReceiverValue callExtensionReceiver = resolvedCall.getExtensionReceiver();
|
||||
if (callDispatchReceiver.exists() || callExtensionReceiver.exists() || isLocalFunCall(callableMethod)) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
|
||||
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
|
||||
if (descriptor.getOriginal() instanceof SamAdapterExtensionFunctionDescriptor) {
|
||||
callDispatchReceiver = callExtensionReceiver;
|
||||
callExtensionReceiver = ReceiverValue.NO_RECEIVER;
|
||||
dispatchReceiverParameter = extensionReceiverParameter;
|
||||
extensionReceiverParameter = null;
|
||||
}
|
||||
|
||||
boolean hasExtensionReceiver = callExtensionReceiver.exists();
|
||||
if (resolvedCall.getDispatchReceiver().exists() || resolvedCall.getExtensionReceiver().exists() || isLocalFunCall(callableMethod)) {
|
||||
boolean hasExtensionReceiver = resolvedCall.getExtensionReceiver().exists();
|
||||
StackValue dispatchReceiver = platformStaticCallIfPresent(
|
||||
genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, callDispatchReceiver, false),
|
||||
descriptor
|
||||
genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, false),
|
||||
resolvedCall.getResultingDescriptor()
|
||||
);
|
||||
StackValue extensionReceiver = genReceiver(receiver, codegen, resolvedCall, callableMethod, callExtensionReceiver, true);
|
||||
Type type = CallReceiver.calcType(resolvedCall, dispatchReceiverParameter, extensionReceiverParameter, codegen.typeMapper, callableMethod);
|
||||
assert type != null : "Could not map receiver type for " + resolvedCall;
|
||||
return new CallReceiver(dispatchReceiver, extensionReceiver, type);
|
||||
StackValue extensionReceiver = genReceiver(receiver, codegen, resolvedCall, callableMethod, true);
|
||||
return new CallReceiver(dispatchReceiver, extensionReceiver,
|
||||
CallReceiver.calcType(resolvedCall, codegen.typeMapper, callableMethod));
|
||||
}
|
||||
return receiver;
|
||||
}
|
||||
@@ -519,9 +503,9 @@ public abstract class StackValue {
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull ResolvedCall resolvedCall,
|
||||
@Nullable Callable callableMethod,
|
||||
ReceiverValue receiverValue,
|
||||
boolean isExtension
|
||||
) {
|
||||
ReceiverValue receiverValue = isExtension ? resolvedCall.getExtensionReceiver() : resolvedCall.getDispatchReceiver();
|
||||
if (receiver == none()) {
|
||||
if (receiverValue.exists()) {
|
||||
return codegen.generateReceiverValue(receiverValue);
|
||||
@@ -1005,7 +989,7 @@ public abstract class StackValue {
|
||||
private final String fieldName;
|
||||
|
||||
public Property(
|
||||
@NotNull PropertyDescriptor descriptor, @Nullable Type backingFieldOwner,
|
||||
@NotNull PropertyDescriptor descriptor, @NotNull Type backingFieldOwner,
|
||||
@Nullable CallableMethod getter, @Nullable CallableMethod setter, boolean isStaticBackingField,
|
||||
@Nullable String fieldName, @NotNull Type type, @NotNull GenerationState state,
|
||||
@NotNull StackValue receiver
|
||||
@@ -1023,11 +1007,8 @@ public abstract class StackValue {
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
if (getter == null) {
|
||||
assert fieldName != null : "Property should have either a getter or a field name: " + descriptor;
|
||||
assert backingFieldOwner != null : "Property should have either a getter or a backingFieldOwner: " + descriptor;
|
||||
v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
if (!genNotNullAssertionForField(v, state, descriptor)) {
|
||||
genNotNullAssertionForLateInitIfNeeded(v);
|
||||
}
|
||||
genNotNullAssertionForField(v, state, descriptor);
|
||||
coerceTo(type, v);
|
||||
}
|
||||
else {
|
||||
@@ -1036,23 +1017,11 @@ public abstract class StackValue {
|
||||
}
|
||||
}
|
||||
|
||||
private void genNotNullAssertionForLateInitIfNeeded(@NotNull InstructionAdapter v) {
|
||||
if (!descriptor.isLateInit()) return;
|
||||
|
||||
v.dup();
|
||||
Label ok = new Label();
|
||||
v.ifnonnull(ok);
|
||||
v.visitLdcInsn(descriptor.getName().asString());
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwUninitializedPropertyAccessException", "(Ljava/lang/String;)V", false);
|
||||
v.mark(ok);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSelector(@NotNull Type topOfStackType, @NotNull InstructionAdapter v) {
|
||||
coerceFrom(topOfStackType, v);
|
||||
if (setter == null) {
|
||||
assert fieldName != null : "Property should have either a setter or a field name: " + descriptor;
|
||||
assert backingFieldOwner != null : "Property should have either a setter or a backingFieldOwner: " + descriptor;
|
||||
v.visitFieldInsn(isStaticStore ? PUTSTATIC : PUTFIELD, backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
@@ -1282,36 +1251,24 @@ public abstract class StackValue {
|
||||
this.extensionReceiver = extensionReceiver;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Type calcType(
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@Nullable ReceiverParameterDescriptor dispatchReceiver,
|
||||
@Nullable ReceiverParameterDescriptor extensionReceiver,
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
@Nullable Callable callableMethod
|
||||
) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
Type dispatchReceiverType = smartDispatchReceiverType(descriptor, typeMapper);
|
||||
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
|
||||
|
||||
if (extensionReceiver != null) {
|
||||
return callableMethod != null ? callableMethod.getExtensionReceiverType() : typeMapper.mapType(extensionReceiver.getType());
|
||||
}
|
||||
else if (dispatchReceiver != null) {
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
else if (dispatchReceiverType != null) {
|
||||
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
|
||||
if (callableMethod != null) {
|
||||
return callableMethod.getDispatchReceiverType();
|
||||
}
|
||||
|
||||
// Extract the receiver from the resolved call, workarounding the fact that ResolvedCall#dispatchReceiver doesn't have
|
||||
// all the needed information, for example there's no way to find out whether or not a smart cast was applied to the receiver.
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container instanceof ClassDescriptor) {
|
||||
return typeMapper.mapClass((ClassDescriptor) container);
|
||||
}
|
||||
|
||||
return typeMapper.mapType(dispatchReceiver);
|
||||
return callableMethod != null ? callableMethod.getDispatchReceiverType() : dispatchReceiverType;
|
||||
}
|
||||
else if (isLocalFunCall(callableMethod)) {
|
||||
return callableMethod.getGenerateCalleeType();
|
||||
@@ -1320,6 +1277,23 @@ public abstract class StackValue {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the receiver from the resolved call, workarounding the fact that ResolvedCall#dispatchReceiver doesn't have
|
||||
* all the needed information, for example there's no way to find out whether or not a smart cast was applied to the receiver.
|
||||
*/
|
||||
@Nullable
|
||||
private static Type smartDispatchReceiverType(@NotNull CallableDescriptor descriptor, @NotNull JetTypeMapper typeMapper) {
|
||||
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
|
||||
if (dispatchReceiverParameter == null) return null;
|
||||
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
if (container instanceof ClassDescriptor) {
|
||||
return typeMapper.mapClass((ClassDescriptor) container);
|
||||
}
|
||||
|
||||
return typeMapper.mapType(dispatchReceiverParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
StackValue currentExtensionReceiver = extensionReceiver;
|
||||
|
||||
@@ -101,7 +101,7 @@ public class TraitImplBodyCodegen(
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
val iv = codegen.v
|
||||
|
||||
val method = typeMapper.mapToCallableMethod(delegateTo, true)
|
||||
val method = typeMapper.mapToCallableMethod(delegateTo, true, context)
|
||||
val myParameters = signature.getValueParameters()
|
||||
val calleeParameters = method.getValueParameters()
|
||||
|
||||
|
||||
@@ -1,55 +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.annotation
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotatedImpl
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
public interface WrappedAnnotated : Annotated {
|
||||
public val originalAnnotated: Annotated
|
||||
}
|
||||
|
||||
public class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated {
|
||||
override fun getAnnotations() = actual
|
||||
}
|
||||
|
||||
public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
|
||||
private val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
|
||||
|
||||
override fun getAnnotations() = annotations
|
||||
|
||||
private class UseSiteTargetedAnnotations(private val additionalAnnotations: Annotations) : Annotations {
|
||||
override fun isEmpty() = true
|
||||
|
||||
override fun findAnnotation(fqName: FqName) = null
|
||||
|
||||
override fun findExternalAnnotation(fqName: FqName) = null
|
||||
|
||||
override fun getUseSiteTargetedAnnotations() = getAdditionalTargetedAnnotations()
|
||||
|
||||
override fun getAllAnnotations() = getAdditionalTargetedAnnotations()
|
||||
|
||||
override fun iterator() = emptyList<AnnotationDescriptor>().iterator()
|
||||
|
||||
private fun getAdditionalTargetedAnnotations() = additionalAnnotations.getUseSiteTargetedAnnotations()
|
||||
}
|
||||
}
|
||||
|
||||
public class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)
|
||||
@@ -33,9 +33,8 @@ import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -46,7 +45,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.NullValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
@@ -76,26 +75,24 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
private final BindingContext bindingContext;
|
||||
private final GenerationState.GenerateClassFilter filter;
|
||||
private final JvmRuntimeTypes runtimeTypes;
|
||||
private final JvmFileClassesProvider fileClassesProvider;
|
||||
|
||||
public CodegenAnnotatingVisitor(@NotNull GenerationState state) {
|
||||
this.bindingTrace = state.getBindingTrace();
|
||||
this.bindingContext = state.getBindingContext();
|
||||
this.filter = state.getGenerateDeclaredClassFilter();
|
||||
this.runtimeTypes = state.getJvmRuntimeTypes();
|
||||
this.fileClassesProvider = state.getFileClassesProvider();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassDescriptor recordClassForCallable(
|
||||
private ClassDescriptor recordClassForFunction(
|
||||
@NotNull JetElement element,
|
||||
@NotNull CallableDescriptor callableDescriptor,
|
||||
@NotNull FunctionDescriptor funDescriptor,
|
||||
@NotNull Collection<JetType> supertypes,
|
||||
@NotNull String name
|
||||
) {
|
||||
String simpleName = name.substring(name.lastIndexOf('/') + 1);
|
||||
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
|
||||
correctContainerForLambda(callableDescriptor, element),
|
||||
correctContainerForLambda(funDescriptor, element),
|
||||
Name.special("<closure-" + simpleName + ">"),
|
||||
Modality.FINAL,
|
||||
supertypes,
|
||||
@@ -103,13 +100,13 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
);
|
||||
classDescriptor.initialize(JetScope.Empty.INSTANCE$, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||
|
||||
bindingTrace.record(CLASS_FOR_CALLABLE, callableDescriptor, classDescriptor);
|
||||
bindingTrace.record(CLASS_FOR_FUNCTION, funDescriptor, classDescriptor);
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private DeclarationDescriptor correctContainerForLambda(@NotNull CallableDescriptor descriptor, @NotNull JetElement function) {
|
||||
private DeclarationDescriptor correctContainerForLambda(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
|
||||
// In almost all cases the function's direct container is the correct container to consider in JVM back-end
|
||||
@@ -289,7 +286,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
|
||||
String name = inventAnonymousClassName(expression);
|
||||
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
||||
ClassDescriptor classDescriptor = recordClassForCallable(functionLiteral, functionDescriptor, supertypes, name);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(functionLiteral, functionDescriptor, supertypes, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
classStack.push(classDescriptor);
|
||||
@@ -301,31 +298,17 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
|
||||
@Override
|
||||
public void visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression) {
|
||||
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
|
||||
// working around a problem with shallow analysis
|
||||
if (functionDescriptor == null) return;
|
||||
|
||||
ResolvedCall<?> referencedFunction = CallUtilPackage.getResolvedCall(expression.getCallableReference(), bindingContext);
|
||||
if (referencedFunction == null) return;
|
||||
CallableDescriptor target = referencedFunction.getResultingDescriptor();
|
||||
|
||||
CallableDescriptor callableDescriptor;
|
||||
Collection<JetType> supertypes;
|
||||
|
||||
if (target instanceof FunctionDescriptor) {
|
||||
callableDescriptor = bindingContext.get(FUNCTION, expression);
|
||||
if (callableDescriptor == null) return;
|
||||
|
||||
supertypes = runtimeTypes.getSupertypesForFunctionReference((FunctionDescriptor) target);
|
||||
}
|
||||
else if (target instanceof PropertyDescriptor) {
|
||||
callableDescriptor = bindingContext.get(VARIABLE, expression);
|
||||
if (callableDescriptor == null) return;
|
||||
|
||||
supertypes = Collections.singleton(runtimeTypes.getSupertypeForPropertyReference((PropertyDescriptor) target));
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
Collection<JetType> supertypes =
|
||||
runtimeTypes.getSupertypesForFunctionReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
|
||||
|
||||
String name = inventAnonymousClassName(expression);
|
||||
ClassDescriptor classDescriptor = recordClassForCallable(expression, callableDescriptor, supertypes, name);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(expression, functionDescriptor, supertypes, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
classStack.push(classDescriptor);
|
||||
@@ -336,8 +319,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
}
|
||||
|
||||
private void recordClosure(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
|
||||
CodegenBinding.recordClosure(bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name),
|
||||
fileClassesProvider);
|
||||
CodegenBinding.recordClosure(bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -372,7 +354,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
else {
|
||||
String name = inventAnonymousClassName(function);
|
||||
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
||||
ClassDescriptor classDescriptor = recordClassForCallable(function, functionDescriptor, supertypes, name);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(function, functionDescriptor, supertypes, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
classStack.push(classDescriptor);
|
||||
@@ -395,7 +377,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
JetFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor);
|
||||
assert containingFile != null : "File not found for " + descriptor;
|
||||
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, containingFile) + '$' + name;
|
||||
return PackagePartClassUtils.getPackagePartInternalName(containingFile) + '$' + name;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -420,8 +402,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
if (original == null) return;
|
||||
|
||||
List<ResolvedValueArgument> valueArguments = call.getValueArgumentsByIndex();
|
||||
if (valueArguments == null) return;
|
||||
|
||||
if (valueArguments == null) {
|
||||
throw new IllegalStateException("Failed to arrange value arguments by index: " + descriptor);
|
||||
}
|
||||
for (ValueParameterDescriptor valueParameter : original.getValueParameters()) {
|
||||
SamType samType = SamType.create(valueParameter.getType());
|
||||
if (samType == null) continue;
|
||||
@@ -540,7 +523,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
|
||||
WhenByEnumsMapping mapping = new WhenByEnumsMapping(classDescriptor, currentClassName, fieldNumber);
|
||||
|
||||
for (ConstantValue<?> constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext)) {
|
||||
for (CompileTimeConstant constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext)) {
|
||||
if (constant instanceof NullValue) continue;
|
||||
|
||||
assert constant instanceof EnumValue : "expression in when should be EnumValue";
|
||||
@@ -557,9 +540,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
SwitchCodegenUtil.checkAllItemsAreConstantsSatisfying(
|
||||
expression,
|
||||
bindingContext,
|
||||
new Function1<ConstantValue<?>, Boolean>() {
|
||||
new Function1<CompileTimeConstant, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(@NotNull ConstantValue<?> constant) {
|
||||
public Boolean invoke(@NotNull CompileTimeConstant constant) {
|
||||
return constant instanceof EnumValue || constant instanceof NullValue;
|
||||
}
|
||||
}
|
||||
@@ -576,7 +559,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
}
|
||||
}
|
||||
|
||||
return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
|
||||
return PackagePartClassUtils.getPackagePartInternalName(file);
|
||||
}
|
||||
|
||||
private static <T> T peekFromStack(@NotNull Stack<T> stack) {
|
||||
|
||||
@@ -19,20 +19,19 @@ package org.jetbrains.kotlin.codegen.binding;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil;
|
||||
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.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
|
||||
import org.jetbrains.kotlin.util.slicedMap.Slices;
|
||||
@@ -41,14 +40,16 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isInterface;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||
import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCall;
|
||||
import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement;
|
||||
|
||||
public class CodegenBinding {
|
||||
public static final WritableSlice<ClassDescriptor, MutableClosure> CLOSURE = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<CallableDescriptor, ClassDescriptor> CLASS_FOR_CALLABLE = Slices.createSimpleSlice();
|
||||
public static final WritableSlice<FunctionDescriptor, ClassDescriptor> CLASS_FOR_FUNCTION = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<ScriptDescriptor, ClassDescriptor> CLASS_FOR_SCRIPT = Slices.createSimpleSlice();
|
||||
|
||||
@@ -62,10 +63,11 @@ public class CodegenBinding {
|
||||
|
||||
public static final WritableSlice<JetCallElement, JetExpression> SAM_CONSTRUCTOR_TO_ARGUMENT = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<JetWhenExpression, WhenByEnumsMapping> MAPPING_FOR_WHEN_BY_ENUM = Slices.createSimpleSlice();
|
||||
public static final WritableSlice<JetWhenExpression, WhenByEnumsMapping> MAPPING_FOR_WHEN_BY_ENUM =
|
||||
Slices.<JetWhenExpression, WhenByEnumsMapping>sliceBuilder().build();
|
||||
|
||||
public static final WritableSlice<String, List<WhenByEnumsMapping>> MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE =
|
||||
Slices.createSimpleSlice();
|
||||
Slices.<String, List<WhenByEnumsMapping>>sliceBuilder().build();
|
||||
|
||||
static {
|
||||
BasicWritableSlice.initSliceDebugNames(CodegenBinding.class);
|
||||
@@ -108,41 +110,34 @@ public class CodegenBinding {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor anonymousClassForCallable(
|
||||
public static ClassDescriptor anonymousClassForFunction(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull CallableDescriptor descriptor
|
||||
@NotNull FunctionDescriptor descriptor
|
||||
) {
|
||||
//noinspection ConstantConditions
|
||||
return bindingContext.get(CLASS_FOR_CALLABLE, descriptor);
|
||||
return bindingContext.get(CLASS_FOR_FUNCTION, descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull JetElement expression) {
|
||||
if (expression instanceof JetObjectLiteralExpression) {
|
||||
expression = ((JetObjectLiteralExpression) expression).getObjectDeclaration();
|
||||
JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression;
|
||||
expression = jetObjectLiteralExpression.getObjectDeclaration();
|
||||
}
|
||||
|
||||
ClassDescriptor descriptor = bindingContext.get(CLASS, expression);
|
||||
if (descriptor != null) {
|
||||
return getAsmType(bindingContext, descriptor);
|
||||
}
|
||||
|
||||
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
|
||||
if (functionDescriptor != null) {
|
||||
if (descriptor == null) {
|
||||
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
|
||||
assert functionDescriptor != null : "Couldn't find function descriptor for " + PsiUtilPackage.getElementTextWithContext(expression);
|
||||
return asmTypeForAnonymousClass(bindingContext, functionDescriptor);
|
||||
}
|
||||
|
||||
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
|
||||
if (variableDescriptor != null) {
|
||||
return asmTypeForAnonymousClass(bindingContext, variableDescriptor);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Couldn't compute ASM type for " + PsiUtilPackage.getElementTextWithContext(expression));
|
||||
return getAsmType(bindingContext, descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type asmTypeForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull CallableDescriptor descriptor) {
|
||||
return getAsmType(bindingContext, anonymousClassForCallable(bindingContext, descriptor));
|
||||
public static Type asmTypeForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull FunctionDescriptor descriptor) {
|
||||
return getAsmType(bindingContext, anonymousClassForFunction(bindingContext, descriptor));
|
||||
}
|
||||
|
||||
public static boolean canHaveOuter(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor classDescriptor) {
|
||||
@@ -162,8 +157,7 @@ public class CodegenBinding {
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@Nullable ClassDescriptor enclosing,
|
||||
@NotNull Type asmType,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
@NotNull Type asmType
|
||||
) {
|
||||
JetElement element = (JetElement) descriptorToDeclaration(classDescriptor);
|
||||
assert element != null : "No source element for " + classDescriptor;
|
||||
@@ -174,7 +168,7 @@ public class CodegenBinding {
|
||||
closure.setCaptureThis();
|
||||
}
|
||||
|
||||
assert PsiCodegenPredictor.checkPredictedNameFromPsi(classDescriptor, asmType, fileClassesManager);
|
||||
assert PsiCodegenPredictor.checkPredictedNameFromPsi(classDescriptor, asmType);
|
||||
trace.record(ASM_TYPE, classDescriptor, asmType);
|
||||
trace.record(CLOSURE, classDescriptor, closure);
|
||||
|
||||
@@ -199,12 +193,7 @@ public class CodegenBinding {
|
||||
}
|
||||
|
||||
// SCRIPT: register asmType for script, move to ScriptingUtil
|
||||
public static void registerClassNameForScript(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull JetScript script,
|
||||
@NotNull Type asmType,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
) {
|
||||
public static void registerClassNameForScript(@NotNull BindingTrace trace, @NotNull JetScript script, @NotNull Type asmType) {
|
||||
ScriptDescriptor descriptor = trace.getBindingContext().get(SCRIPT, script);
|
||||
if (descriptor == null) {
|
||||
throw new IllegalStateException("Script descriptor is not found for PSI: " + PsiUtilPackage.getElementTextWithContext(script));
|
||||
@@ -213,11 +202,10 @@ public class CodegenBinding {
|
||||
String simpleName = asmType.getInternalName().substring(asmType.getInternalName().lastIndexOf('/') + 1);
|
||||
ClassDescriptorImpl classDescriptor =
|
||||
new ClassDescriptorImpl(descriptor, Name.special("<script-" + simpleName + ">"), Modality.FINAL,
|
||||
Collections.singleton(DescriptorUtilPackage.getBuiltIns(descriptor).getAnyType()),
|
||||
toSourceElement(script));
|
||||
Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()), toSourceElement(script));
|
||||
classDescriptor.initialize(JetScope.Empty.INSTANCE$, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||
|
||||
recordClosure(trace, classDescriptor, null, asmType, fileClassesManager);
|
||||
recordClosure(trace, classDescriptor, null, asmType);
|
||||
|
||||
trace.record(CLASS_FOR_SCRIPT, descriptor, classDescriptor);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -34,14 +34,10 @@ public final class PsiCodegenPredictor {
|
||||
private PsiCodegenPredictor() {
|
||||
}
|
||||
|
||||
public static boolean checkPredictedNameFromPsi(
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
@Nullable Type nameFromDescriptors,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
) {
|
||||
public static boolean checkPredictedNameFromPsi(@NotNull DeclarationDescriptor descriptor, @Nullable Type nameFromDescriptors) {
|
||||
PsiElement element = descriptorToDeclaration(descriptor);
|
||||
if (element instanceof JetDeclaration) {
|
||||
String classNameFromPsi = getPredefinedJvmInternalName((JetDeclaration) element, fileClassesManager);
|
||||
String classNameFromPsi = getPredefinedJvmInternalName((JetDeclaration) element);
|
||||
assert classNameFromPsi == null || Type.getObjectType(classNameFromPsi).equals(nameFromDescriptors) :
|
||||
String.format("Invalid algorithm for getting qualified name from psi! Predicted: %s, actual %s\n" +
|
||||
"Element: %s", classNameFromPsi, nameFromDescriptors, element.getText());
|
||||
@@ -54,10 +50,7 @@ public final class PsiCodegenPredictor {
|
||||
* @return null if no prediction can be done.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getPredefinedJvmInternalName(
|
||||
@NotNull JetDeclaration declaration,
|
||||
@NotNull JvmFileClassesProvider fileClassesProvider
|
||||
) {
|
||||
public static String getPredefinedJvmInternalName(@NotNull JetDeclaration declaration) {
|
||||
// TODO: Method won't work for declarations inside companion objects
|
||||
// TODO: Method won't give correct class name for traits implementations
|
||||
|
||||
@@ -65,7 +58,7 @@ public final class PsiCodegenPredictor {
|
||||
|
||||
String parentInternalName;
|
||||
if (parentDeclaration != null) {
|
||||
parentInternalName = getPredefinedJvmInternalName(parentDeclaration, fileClassesProvider);
|
||||
parentInternalName = getPredefinedJvmInternalName(parentDeclaration);
|
||||
if (parentInternalName == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -75,16 +68,16 @@ public final class PsiCodegenPredictor {
|
||||
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
Name name = ((JetNamedFunction) declaration).getNameAsName();
|
||||
return name == null ? null : FileClassesPackage.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
|
||||
return name == null ? null : PackagePartClassUtils.getPackagePartInternalName(containingFile) + "$" + name.asString();
|
||||
}
|
||||
|
||||
parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(containingFile.getPackageFqName());
|
||||
}
|
||||
|
||||
if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) ||
|
||||
isEnumEntryWithoutBody(declaration)) {
|
||||
declaration instanceof JetEnumEntry) {
|
||||
// Other subclasses are not valid for class name prediction.
|
||||
// For example JetFunctionLiteral
|
||||
// For example EnumEntry, JetFunctionLiteral
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -112,12 +105,4 @@ public final class PsiCodegenPredictor {
|
||||
|
||||
return parentInternalName + (parentDeclaration == null ? "/" : "$") + name.asString();
|
||||
}
|
||||
|
||||
private static boolean isEnumEntryWithoutBody(JetDeclaration declaration) {
|
||||
if (!(declaration instanceof JetEnumEntry)) {
|
||||
return false;
|
||||
}
|
||||
JetClassBody body = ((JetEnumEntry) declaration).getBody();
|
||||
return body == null || body.getDeclarations().size() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +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
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts
|
||||
|
||||
fun ClassFileFactory.getClassFiles(): Iterable<OutputFile> {
|
||||
return asList().filterClassFiles()
|
||||
}
|
||||
|
||||
fun List<OutputFile>.filterClassFiles(): Iterable<OutputFile> {
|
||||
return filter { it.relativePath.endsWith(".class") }
|
||||
}
|
||||
|
||||
fun List<PackageParts>.addCompiledPartsAndSort(state: GenerationState): List<PackageParts> =
|
||||
addCompiledParts(state).sortedBy { it.packageFqName }
|
||||
|
||||
private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<PackageParts> {
|
||||
if (state.incrementalCompilationComponents == null || state.targetId == null) return this
|
||||
|
||||
val incrementalCache = state.incrementalCompilationComponents.getIncrementalCache(state.targetId)
|
||||
val moduleMappingData = incrementalCache.getModuleMappingData() ?: return this
|
||||
|
||||
val mapping = ModuleMapping.create(moduleMappingData)
|
||||
|
||||
incrementalCache.getObsoletePackageParts().forEach {
|
||||
val i = it.lastIndexOf('/')
|
||||
val qualifier = if (i == -1) "" else it.substring(0, i).replace('/', '.')
|
||||
val name = it.substring(i + 1)
|
||||
mapping.findPackageParts(qualifier)?.run { parts.remove(name) }
|
||||
}
|
||||
|
||||
return (this + mapping.packageFqName2Parts.values())
|
||||
.groupBy { it.packageFqName }
|
||||
.map {
|
||||
val (packageFqName, packageParts) = it
|
||||
val newPackageParts = PackageParts(packageFqName)
|
||||
packageParts.forEach { newPackageParts.parts.addAll(it.parts) }
|
||||
newPackageParts
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.OwnerKind;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.anonymousClassForCallable;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.anonymousClassForFunction;
|
||||
|
||||
public class ClosureContext extends ClassContext {
|
||||
private final FunctionDescriptor functionDescriptor;
|
||||
@@ -33,7 +33,7 @@ public class ClosureContext extends ClassContext {
|
||||
@Nullable CodegenContext parentContext,
|
||||
@NotNull LocalLookup localLookup
|
||||
) {
|
||||
super(typeMapper, anonymousClassForCallable(typeMapper.getBindingContext(), functionDescriptor),
|
||||
super(typeMapper, anonymousClassForFunction(typeMapper.getBindingContext(), functionDescriptor),
|
||||
OwnerKind.IMPLEMENTATION, parentContext, localLookup);
|
||||
|
||||
this.functionDescriptor = functionDescriptor;
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.JetSuperExpression;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
@@ -35,11 +34,12 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.NEED_SYNTHETIC_ACCESSOR;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
|
||||
public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
public static final CodegenContext STATIC = new RootContext();
|
||||
|
||||
private final T contextDescriptor;
|
||||
private final OwnerKind contextKind;
|
||||
private final CodegenContext parentContext;
|
||||
@@ -48,38 +48,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
private final LocalLookup enclosingLocalLookup;
|
||||
private final NullableLazyValue<StackValue.Field> outerExpression;
|
||||
|
||||
private Map<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
||||
private Map<DeclarationDescriptor, CodegenContext> childContexts;
|
||||
private Map<AccessorKey, AccessorForCallableDescriptor<?>> accessors;
|
||||
|
||||
private static class AccessorKey {
|
||||
public final DeclarationDescriptor descriptor;
|
||||
public final ClassDescriptor superCallLabelTarget;
|
||||
|
||||
public AccessorKey(@NotNull DeclarationDescriptor descriptor, @Nullable ClassDescriptor superCallLabelTarget) {
|
||||
this.descriptor = descriptor;
|
||||
this.superCallLabelTarget = superCallLabelTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof AccessorKey)) return false;
|
||||
AccessorKey other = (AccessorKey) obj;
|
||||
return descriptor.equals(other.descriptor) &&
|
||||
(superCallLabelTarget == null
|
||||
? other.superCallLabelTarget == null
|
||||
: superCallLabelTarget.equals(other.superCallLabelTarget));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * descriptor.hashCode() + (superCallLabelTarget == null ? 0 : superCallLabelTarget.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return descriptor.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public CodegenContext(
|
||||
@NotNull T contextDescriptor,
|
||||
@@ -107,11 +77,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GenerationState getState() {
|
||||
return parentContext.getState();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final ClassDescriptor getThisDescriptor() {
|
||||
if (thisDescriptor == null) {
|
||||
@@ -189,24 +154,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return new PackageFacadeContext(descriptor, this, delegateTo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldOwnerContext<PackageFragmentDescriptor> intoMultifileClassPart(
|
||||
@NotNull PackageFragmentDescriptor descriptor,
|
||||
@NotNull Type multifileClassType,
|
||||
@NotNull Type filePartType
|
||||
) {
|
||||
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FieldOwnerContext<PackageFragmentDescriptor> intoMultifileClass(
|
||||
@NotNull PackageFragmentDescriptor descriptor,
|
||||
@NotNull Type multifileClassType,
|
||||
@NotNull Type filePartType
|
||||
) {
|
||||
return new MultifileClassFacadeContext(descriptor, this, multifileClassType, filePartType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) {
|
||||
return new ClassContext(state.getTypeMapper(), descriptor, kind, this, null);
|
||||
@@ -276,60 +223,43 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable JetSuperExpression superCallExpression) {
|
||||
return getAccessor(descriptor, false, null, superCallExpression);
|
||||
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor) {
|
||||
return getAccessor(descriptor, false, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessor(
|
||||
@NotNull D possiblySubstitutedDescriptor,
|
||||
boolean isForBackingFieldInOuterClass,
|
||||
@Nullable JetType delegateType,
|
||||
@Nullable JetSuperExpression superCallExpression
|
||||
) {
|
||||
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor, boolean isForBackingFieldInOuterClass, @Nullable JetType delegateType) {
|
||||
if (accessors == null) {
|
||||
accessors = new LinkedHashMap<AccessorKey, AccessorForCallableDescriptor<?>>();
|
||||
accessors = new LinkedHashMap<DeclarationDescriptor, DeclarationDescriptor>();
|
||||
}
|
||||
|
||||
D descriptor = (D) possiblySubstitutedDescriptor.getOriginal();
|
||||
AccessorKey key = new AccessorKey(
|
||||
descriptor, superCallExpression == null ? null : ExpressionCodegen.getSuperCallLabelTarget(this, superCallExpression)
|
||||
);
|
||||
|
||||
AccessorForCallableDescriptor<?> accessor = accessors.get(key);
|
||||
descriptor = descriptor.getOriginal();
|
||||
DeclarationDescriptor accessor = accessors.get(descriptor);
|
||||
if (accessor != null) {
|
||||
assert !isForBackingFieldInOuterClass ||
|
||||
accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context";
|
||||
return (D) accessor;
|
||||
return accessor;
|
||||
}
|
||||
|
||||
int accessorIndex = accessors.size();
|
||||
if (descriptor instanceof SimpleFunctionDescriptor) {
|
||||
accessor = new AccessorForFunctionDescriptor(
|
||||
(FunctionDescriptor) descriptor, contextDescriptor, accessorIndex, superCallExpression
|
||||
);
|
||||
accessor = new AccessorForFunctionDescriptor((FunctionDescriptor) descriptor, contextDescriptor, accessorIndex);
|
||||
}
|
||||
else if (descriptor instanceof ConstructorDescriptor) {
|
||||
accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor, superCallExpression);
|
||||
accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor);
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
if (isForBackingFieldInOuterClass) {
|
||||
accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor,
|
||||
accessorIndex, delegateType);
|
||||
}
|
||||
else {
|
||||
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor,
|
||||
accessorIndex, superCallExpression);
|
||||
} else {
|
||||
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessorIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor);
|
||||
}
|
||||
|
||||
accessors.put(key, accessor);
|
||||
|
||||
return (D) accessor;
|
||||
accessors.put(descriptor, accessor);
|
||||
return accessor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -376,32 +306,39 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<? extends AccessorForCallableDescriptor<?>> getAccessors() {
|
||||
return accessors == null ? Collections.<AccessorForCallableDescriptor<CallableMemberDescriptor>>emptySet() : accessors.values();
|
||||
public Map<DeclarationDescriptor, DeclarationDescriptor> getAccessors() {
|
||||
return accessors == null ? Collections.<DeclarationDescriptor, DeclarationDescriptor>emptyMap() : accessors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D accessibleDescriptor(
|
||||
@NotNull D descriptor,
|
||||
@Nullable JetSuperExpression superCallExpression
|
||||
) {
|
||||
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
|
||||
if (!hasThisDescriptor() || enclosing == getThisDescriptor() ||
|
||||
enclosing == getClassOrPackageParentContext().getContextDescriptor()) {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
return accessibleDescriptorIfNeeded(descriptor, superCallExpression);
|
||||
public PropertyDescriptor accessiblePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
||||
return (PropertyDescriptor) accessibleDescriptorIfNeeded(propertyDescriptor, true);
|
||||
}
|
||||
|
||||
public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
|
||||
if (hasThisDescriptor() &&
|
||||
(descriptor instanceof ConstructorDescriptor || Boolean.TRUE.equals(bindingContext.get(NEED_SYNTHETIC_ACCESSOR, descriptor)))) {
|
||||
// Not a super call because neither constructors nor private members can be targets of super calls
|
||||
accessibleDescriptorIfNeeded(descriptor, /* superCallExpression = */ null);
|
||||
@NotNull
|
||||
public FunctionDescriptor accessibleFunctionDescriptor(FunctionDescriptor fd) {
|
||||
return (FunctionDescriptor) accessibleDescriptorIfNeeded(fd, true);
|
||||
}
|
||||
|
||||
public void recordSyntheticAccessorIfNeeded(@NotNull FunctionDescriptor fd, @NotNull BindingContext bindingContext) {
|
||||
if (fd instanceof ConstructorDescriptor || needSyntheticAccessorInBindingTrace(fd, bindingContext)) {
|
||||
accessibleDescriptorIfNeeded(fd, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void recordSyntheticAccessorIfNeeded(@NotNull PropertyDescriptor propertyDescriptor, @NotNull BindingContext typeMapper) {
|
||||
if (needSyntheticAccessorInBindingTrace(propertyDescriptor, typeMapper)) {
|
||||
accessibleDescriptorIfNeeded(propertyDescriptor, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean needSyntheticAccessorInBindingTrace(
|
||||
@NotNull CallableMemberDescriptor descriptor,
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
return Boolean.TRUE.equals(bindingContext.get(BindingContext.NEED_SYNTHETIC_ACCESSOR, descriptor));
|
||||
}
|
||||
|
||||
private static int getAccessFlags(@NotNull CallableMemberDescriptor descriptor) {
|
||||
int flag = getVisibilityAccessFlag(descriptor);
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
@@ -416,24 +353,39 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return flag;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
private <D extends CallableMemberDescriptor> D accessibleDescriptorIfNeeded(
|
||||
@NotNull D descriptor,
|
||||
@Nullable JetSuperExpression superCallExpression
|
||||
) {
|
||||
private MemberDescriptor accessibleDescriptorIfNeeded(CallableMemberDescriptor descriptor, boolean fromOutsideContext) {
|
||||
CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor);
|
||||
int flag = getAccessFlags(unwrappedDescriptor);
|
||||
if ((flag & ACC_PRIVATE) == 0 && (flag & ACC_PROTECTED) == 0) {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
DeclarationDescriptor enclosed = descriptor.getContainingDeclaration();
|
||||
CodegenContext descriptorContext = findParentContextWithDescriptor(enclosed);
|
||||
if (descriptorContext == null && DescriptorUtils.isCompanionObject(enclosed)) {
|
||||
CodegenContext classContext = findParentContextWithDescriptor(enclosed.getContainingDeclaration());
|
||||
if (classContext instanceof ClassContext) {
|
||||
descriptorContext = ((ClassContext) classContext).getCompanionObjectContext();
|
||||
CodegenContext descriptorContext = null;
|
||||
if (!fromOutsideContext || getClassOrPackageParentContext().getContextDescriptor() != descriptor.getContainingDeclaration()) {
|
||||
DeclarationDescriptor enclosed = descriptor.getContainingDeclaration();
|
||||
boolean isCompanionObjectMember = DescriptorUtils.isCompanionObject(enclosed);
|
||||
//go upper
|
||||
if (hasThisDescriptor() && (enclosed != getThisDescriptor() || !fromOutsideContext)) {
|
||||
CodegenContext currentContext = this;
|
||||
while (currentContext != null) {
|
||||
if (currentContext.getContextDescriptor() == enclosed) {
|
||||
descriptorContext = currentContext;
|
||||
break;
|
||||
}
|
||||
|
||||
//accessors for private members in companion object for call from class
|
||||
if (isCompanionObjectMember && currentContext instanceof ClassContext) {
|
||||
ClassContext classContext = (ClassContext) currentContext;
|
||||
CodegenContext companionObjectContext = classContext.getCompanionObjectContext();
|
||||
if (companionObjectContext != null && companionObjectContext.getContextDescriptor() == enclosed) {
|
||||
descriptorContext = companionObjectContext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentContext = currentContext.getParentContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +406,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
}
|
||||
|
||||
return (D) descriptorContext.getAccessor(descriptor, superCallExpression);
|
||||
return (MemberDescriptor) descriptorContext.getAccessor(descriptor);
|
||||
}
|
||||
|
||||
private void addChild(@NotNull CodegenContext child) {
|
||||
|
||||
@@ -1,39 +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.context
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
|
||||
public object CodegenContextUtil {
|
||||
@JvmStatic
|
||||
public fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
|
||||
when (owner) {
|
||||
is DelegatingFacadeContext -> owner.delegateToClassType
|
||||
is DelegatingToPartContext -> owner.implementationOwnerClassType
|
||||
else -> null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun getImplementationClassShortName(owner: CodegenContext<*>): String? =
|
||||
getImplementationOwnerClassType(owner)?.let { AsmUtil.shortNameByAsmType(it) }
|
||||
|
||||
@JvmStatic
|
||||
public fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
|
||||
owner !is DelegatingFacadeContext
|
||||
}
|
||||
@@ -1,25 +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.context;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public interface DelegatingFacadeContext {
|
||||
@Nullable
|
||||
Type getDelegateToClassType();
|
||||
}
|
||||
@@ -1,25 +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.context;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public interface DelegatingToPartContext {
|
||||
@Nullable
|
||||
Type getImplementationOwnerClassType();
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public interface LocalLookup {
|
||||
BindingContext bindingContext = state.getBindingContext();
|
||||
Type localType = asmTypeForAnonymousClass(bindingContext, vd);
|
||||
|
||||
MutableClosure localFunClosure = bindingContext.get(CLOSURE, bindingContext.get(CLASS_FOR_CALLABLE, vd));
|
||||
MutableClosure localFunClosure = bindingContext.get(CLOSURE, bindingContext.get(CLASS_FOR_FUNCTION, vd));
|
||||
if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) {
|
||||
// This is an optimization: we can obtain an instance of a const closure simply by GETSTATIC ...$instance
|
||||
// (instead of passing this instance to the constructor and storing as a field)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user