Compare commits

..

1 Commits
M14 ... inline

Author SHA1 Message Date
Evgeny Gerashchenko
3d84f225ab Simplest inline function handler. 2015-07-08 17:55:00 +03:00
12948 changed files with 106872 additions and 192394 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
View File

@@ -26,4 +26,4 @@
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_STRING" value="-target 1.6" />
</component>
</project>
</project>

View File

@@ -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>

View File

@@ -2,8 +2,6 @@
<dictionary name="bashor">
<words>
<w>ctor</w>
<w>lookups</w>
<w>unescape</w>
</words>
</dictionary>
</component>

View File

@@ -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
View File

@@ -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>

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
View File

@@ -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
View File

@@ -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" />

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -47,4 +47,4 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
</module>

View File

@@ -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

View File

@@ -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>

View File

@@ -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")
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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>

View File

@@ -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;

View File

@@ -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()
}

View File

@@ -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;
}
}

View File

@@ -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())
}

View File

@@ -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

View File

@@ -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

View File

@@ -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" />

View File

@@ -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();
}

View File

@@ -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
)
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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(),

View File

@@ -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) {

View File

@@ -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?

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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()
}
}
}

View File

@@ -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();
}
}

View File

@@ -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
}
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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())
}
}

View File

@@ -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(

View File

@@ -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() + "(...)")
)
);

View File

@@ -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));

View File

@@ -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 {

View File

@@ -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());
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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() {}
}

View File

@@ -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());
}
}
}

View File

@@ -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
}

View File

@@ -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
}
}
}

View File

@@ -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()
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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(

View File

@@ -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();

View File

@@ -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())
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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()

View File

@@ -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)

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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
}
}

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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