Compare commits

..

17 Commits

Author SHA1 Message Date
Natalia Ukhorskaya
22add1ee89 Correct resource path for flavors in android-extensions-plugin
(cherry picked from commit 51abb021bc)
2015-12-04 17:25:02 +03:00
Natalia Ukhorskaya
2ecc21b440 Do not cache AndroidModule in IDEAndroidLayoutXmlManager
(cherry picked from commit c523817)
2015-12-04 17:22:50 +03:00
Dmitry Jemerov
0113ccaad1 fix compilation after changes in markdown library
(cherry picked from commit ce9012c)
2015-12-03 15:33:25 +01:00
Natalia Ukhorskaya
41141fbe23 Fix NoSuchMethod in android-extensions-plugin
#KT-10263 Fixed
(cherry picked from commit a197fc8)
2015-12-03 16:19:12 +03:00
Nikolay Krasko
1d076154b1 Exclude idl2k module from build in beta3 2015-12-02 17:46:43 +03:00
Mikhail Glukhikh
58d78011c0 Creating deep copy of local function declaration instructions in CFA, regression test #KT-10243 Fixed
(cherry picked from commit 60e457167d)
2015-12-01 23:50:02 +03:00
Zalim Bashorov
b33ad0c528 Minor: don't process changes for incremental build during rebuild 2015-12-01 21:27:45 +03:00
Ilya Gorbunov
6dbec92bfe Remove replacement with upcast. Remove deprecation from *Raw methods until beta4. 2015-12-01 19:51:12 +03:00
Alexey Sedunov
bb57825d21 Introduce Variable: Forbid multi-declaration for collections and arrays
#KT-10242 Fixed
2015-12-01 19:39:56 +03:00
Alexey Sedunov
ddb50031d8 Introduce Variable: Suggest choosing between single variable and multi-declaration
#KT-10242 Fixed
2015-12-01 19:36:34 +03:00
Nikolay Krasko
50dcd08cb5 Enable auto-increment 2015-12-01 15:27:00 +03:00
Pavel V. Talanov
df6298de39 Minor, getModuleInfo: improve on failure messages 2015-12-01 14:55:41 +03:00
Pavel V. Talanov
a9c1e57230 getModuleInfo: Provide utility to default to null instead of logging an error
Use it to workaround cases when java resolve references some unexpected classes/files, referencing non-physical Dummy.java in particular
2015-12-01 14:55:39 +03:00
Pavel V. Talanov
378a964c2f getModuleInfo: Correct module info for members of light classes for decompiled Kotlin classes 2015-12-01 14:55:38 +03:00
Stanislav Erokhin
170a0393f6 Revert "Original type is taken into account when intersecting possible types in resolve #KT-10232 Fixed"
This reverts commit fe04cc513b.
2015-12-01 13:02:45 +03:00
Nikolay Krasko
95d4dd4962 Enable bootstrapping in branch 2015-12-01 00:02:09 +03:00
Nikolay Krasko
288248c964 Remove android extension plugin from relay 2015-11-30 23:58:28 +03:00
4962 changed files with 25335 additions and 60325 deletions

2
.idea/ant.xml generated
View File

@@ -3,7 +3,7 @@
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/compiler/frontend/buildLexer.xml" />
<buildFile url="file://$PROJECT_DIR$/build.xml">
<antCommandLine value="-J-XX:MaxPermSize=100m -J-ea" />
<antCommandLine value="-J-XX:MaxPermSize=100m" />
<maximumHeapSize value="1024" />
</buildFile>
<buildFile url="file://$PROJECT_DIR$/update_dependencies.xml" />

View File

@@ -2,7 +2,6 @@
<dictionary name="Nikolay.Krasko">
<words>
<w>accessors</w>
<w>fqname</w>
<w>goto</w>
<w>gradle</w>
<w>intrinsics</w>

View File

@@ -1,8 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="dzharkov">
<words>
<w>checkcast</w>
<w>insn</w>
</words>
</dictionary>
</component>

BIN
.idea/icon.png generated

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="kotlin-reflect">
<CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -2,12 +2,11 @@
<library name="kotlin-runtime">
<CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/libraries/stdlib/src" />
<root url="file://$PROJECT_DIR$/core/builtins/native" />
<root url="file://$PROJECT_DIR$/core/builtins/src" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="kotlin-test">
<CLASSES>
<root url="jar://$PROJECT_DIR$/dependencies/bootstrap-compiler/Kotlin/kotlinc/lib/kotlin-test.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin" />
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin.jvm" />
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/junit/src/main/kotlin" />
</SOURCES>
</library>
</component>

3
.idea/modules.xml generated
View File

@@ -40,7 +40,7 @@
<module fileurl="file://$PROJECT_DIR$/idea/idea-core/idea-core.iml" filepath="$PROJECT_DIR$/idea/idea-core/idea-core.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" filepath="$PROJECT_DIR$/idea/idea-jps-common/idea-jps-common.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" filepath="$PROJECT_DIR$/idea/idea-live-templates/idea-live-templates.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/idea/idea-repl/idea-repl.iml" filepath="$PROJECT_DIR$/idea/idea-repl/idea-repl.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" />
@@ -62,7 +62,6 @@
<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$/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$/temp-jdk8/temp-jdk8.iml" filepath="$PROJECT_DIR$/temp-jdk8/temp-jdk8.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler/util/util.iml" filepath="$PROJECT_DIR$/compiler/util/util.iml" />
<module fileurl="file://$PROJECT_DIR$/core/util.runtime/util.runtime.iml" filepath="$PROJECT_DIR$/core/util.runtime/util.runtime.iml" group="core" />
</modules>

View File

@@ -5,7 +5,7 @@
<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="false" />
<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" />

View File

@@ -158,11 +158,11 @@
<print-file-size-statistic path="${kotlin-home}/lib" file-name="kotlin-reflect.jar"/>
<print-file-size-statistic path="${kotlin-home}/lib" file-name="kotlin-jslib.jar"/>
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="kotlin.js"/>
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="builtins.js"/>
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="builtins.meta.js"/>
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="stdlib.js"/>
<print-file-size-statistic path="${js.stdlib.output.dir}" file-name="stdlib.meta.js"/>
<print-file-size-statistic path="${output}" file-name="kotlin.js"/>
<print-file-size-statistic path="${output}" file-name="builtins.js"/>
<print-file-size-statistic path="${output}" file-name="builtins.meta.js"/>
<print-file-size-statistic path="${output}" file-name="stdlib.js"/>
<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"/>

View File

@@ -88,12 +88,5 @@
origin.version="${relay.origin.version}"
plugin.subdir="BareKotlin"
substituted.version="${relay.substitute.version}"/>
<substitudeVersionInPlugin
plugin.jar.name="kotlin-android-extensions"
plugin.path="${relay.plugins.dir}/kotlin-android-extensions-plugin-${relay.origin.version}.zip"
origin.version="${relay.origin.version}"
plugin.subdir="KotlinAndroidExtensions"
substituted.version="${relay.substitute.version}"/>
</target>
</project>

View File

@@ -9,7 +9,6 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="ant" level="project" />
<orderEntry type="library" name="kotlin-runtime" level="project" />
<orderEntry type="library" name="kotlin-reflect" level="project" />
<orderEntry type="module" module-name="preloader" />
</component>
</module>

View File

@@ -0,0 +1,7 @@
<!-- NOTE: this Antlib is deprecated. Use org/jetbrains/kotlin/ant/antlib.xml instead -->
<!-- TODO: delete this file -->
<antlib>
<taskdef name="kotlinc" classname="org.jetbrains.kotlin.ant.Kotlin2JvmTask"/>
<taskdef name="kotlin2js" classname="org.jetbrains.kotlin.ant.Kotlin2JsTask"/>
<typedef name="withKotlin" classname="org.jetbrains.kotlin.ant.KotlinCompilerAdapter"/>
</antlib>

View File

@@ -70,7 +70,7 @@ class KotlinCompilerAdapter : Javac13() {
// Javac13#execute passes everything in compileList to javac, which doesn't recognize .kt files
val compileListForJavac = filterOutKotlinSources(compileList)
val hasKotlinFilesInSources = compileListForJavac.size < compileList.size
val hasKotlinFilesInSources = compileListForJavac.size() < compileList.size()
if (hasKotlinFilesInSources) {
kotlinc.execute()

View File

@@ -54,7 +54,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
}
public fun setSrcRef(ref: Reference) {
createSrc().refid = ref
createSrc().setRefid(ref)
}
public fun createCompilerArg(): Commandline.Argument {
@@ -75,7 +75,7 @@ public abstract class KotlinCompilerBaseTask : Task() {
if (verbose) args.add("-verbose")
if (printVersion) args.add("-version")
args.addAll(additionalArguments.flatMap { it.parts.toList() })
args.addAll(additionalArguments.flatMap { it.getParts().toList() })
fillSpecificArguments()
}
@@ -85,12 +85,12 @@ public abstract class KotlinCompilerBaseTask : Task() {
val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName)
val compiler = compilerClass.newInstance()
val exec = compilerClass.getMethod("execFullPathsInMessages", PrintStream::class.java, Array<String>::class.java)
val exec = compilerClass.getMethod("execFullPathsInMessages", javaClass<PrintStream>(), javaClass<Array<String>>())
log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]");
val result = exec(compiler, System.err, args.toTypedArray())
exitCode = (result as Enum<*>).ordinal
exitCode = (result as Enum<*>).ordinal()
if (failOnError && exitCode != 0) {
throw BuildException("Compile failed; see the compiler error output for details.")

View File

@@ -12,10 +12,8 @@
<property name="bootstrap.compiler.home" value="${bootstrap.home}/Kotlin/kotlinc"/>
<property name="bootstrap.runtime" value="${bootstrap.compiler.home}/lib/kotlin-runtime.jar"/>
<property name="bootstrap.reflect" value="${bootstrap.compiler.home}/lib/kotlin-reflect.jar"/>
<property name="bootstrap.kotlin.test" value="${bootstrap.compiler.home}/lib/kotlin-test.jar" />
<property name="output" value="${basedir}/dist"/>
<property name="js.stdlib.output.dir" value="${output}/js"/>
<property name="intermediate-sources" value="out/src" />
<property name="kotlin-home" value="${output}/kotlinc"/>
<property name="build.number" value="snapshot"/>
@@ -57,7 +55,6 @@
<path id="classpath">
<file file="${bootstrap.runtime}"/>
<file file="${bootstrap.kotlin.test}" />
<file file="${bootstrap.reflect}"/>
<fileset dir="${idea.sdk}" includes="core/*.jar"/>
<pathelement location="${protobuf.jar}"/>
@@ -180,33 +177,19 @@
<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"/>
<copy file="${bootstrap.kotlin.test}" tofile="${kotlin-home}/lib/kotlin-test-internal-bootstrap.jar" failonerror="false"/>
<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>
<jar destfile="${kotlin-home}/lib/kotlin-test-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"/>
<copy file="${bootstrap.kotlin.test}" todir="${kotlin-home}/lib"/>
</sequential>
</target>
<target name="copy-dist-to-bootstrap">
<delete dir="${basedir}/dependencies/bootstrap-compiler/Kotlin/kotlinc" />
<copy todir="${basedir}/dependencies/bootstrap-compiler/Kotlin/kotlinc">
<fileset dir="${basedir}/dist/kotlinc" />
</copy>
</target>
<target name="compiler-sources">
<jar jarfile="${output}/kotlin-compiler-sources.jar">
<!-- TODO How to convert it from pathset or dirset ? -->
@@ -325,13 +308,13 @@
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
<new-kotlin2js output="${js.stdlib.output.dir}/${compiled.builtins.js}">
<new-kotlin2js output="${output}/js/${compiled.builtins.js}">
<src>
<fileset refid="kotlin.builtin.files"/>
</src>
</new-kotlin2js>
<new-kotlin2js output="${js.stdlib.output.dir}/${compiled.stdlib.js}">
<new-kotlin2js output="${output}/js/${compiled.stdlib.js}">
<src>
<resources refid="js.lib.files"/>
</src>
@@ -351,7 +334,7 @@
prettyprint="true"
languagein="ECMASCRIPT5_STRICT"
warning="${warningLevel}"
output="${js.stdlib.output.dir}/kotlin.js">
output="${output}/js/kotlin.js">
<sources dir="${stdlib.js.dir}">
<file name="kotlin_lib_ecma5.js"/>
@@ -360,11 +343,11 @@
<file name="long.js"/>
</sources>
<sources dir="${js.stdlib.output.dir}">
<sources dir="${output}/js">
<file name="${compiled.builtins.js}"/>
</sources>
<sources dir="${js.stdlib.output.dir}">
<sources dir="${output}/js">
<file name="${compiled.stdlib.js}"/>
</sources>
@@ -379,7 +362,7 @@
<jar jarfile="${kotlin-home}/lib/kotlin-jslib.jar" duplicate="fail">
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<zipfileset dir="${js.stdlib.output.dir}" prefix="">
<zipfileset dir="${output}/js" prefix="">
<include name="kotlin.js"/>
<include name="${compiled.stdlib.meta.js}"/>
<include name="stdlib/**"/>
@@ -798,7 +781,7 @@
</target>
<target name="stdlib">
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib" additionalOptions="-Xmultifile-facades-open">
<new-kotlinc output="${output}/classes/stdlib" moduleName="kotlin-stdlib">
<src>
<include name="libraries/stdlib/src"/>
</src>
@@ -808,20 +791,6 @@
</new-kotlinc>
</target>
<target name="kotlin.test">
<new-kotlinc output="${output}/classes/kotlin.test" moduleName="kotlin-test">
<src>
<include name="libraries/kotlin.test/shared/src/main/kotlin" />
<include name="libraries/kotlin.test/shared/src/main/kotlin.jvm" />
<include name="libraries/kotlin.test/junit/src/main/kotlin" />
</src>
<class-path>
<pathelement path="${output}/classes/builtins"/>
<pathelement path="libraries/lib/junit-4.11.jar"/>
</class-path>
</new-kotlinc>
</target>
<target name="core">
<new-kotlinc output="${output}/classes/core" moduleName="kotlin-core">
<src>
@@ -966,23 +935,15 @@
</pack-runtime-jar>
</target>
<target name="pack-kotlin-test">
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
<jar-content>
<fileset dir="${output}/classes/kotlin.test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
</jar-content>
</pack-runtime-jar>
</target>
<target name="runtime"
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.test,pack-kotlin-test,kotlin-js-stdlib,android-compiler-plugin,daemon-client"
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,daemon-client"
description="Builds redistributables from sources"/>
<target name="dist-quick"
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin.test,pack-kotlin-test,kotlin-js-stdlib,android-compiler-plugin"
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,jdk-annotations,android-sdk-annotations,runtime,kotlin-js-stdlib,android-compiler-plugin"
description="Builds everything, but classes are reused from project out dir, doesn't run proguard and javadoc"/>
<target name="dist-quick-compiler-only"

View File

@@ -93,14 +93,14 @@ public class CodegenUtil {
}
@NotNull
public static Map<FunctionDescriptor, FunctionDescriptor> getNonPrivateTraitMethods(ClassDescriptor descriptor) {
public static Map<FunctionDescriptor, FunctionDescriptor> getTraitMethods(ClassDescriptor descriptor) {
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>();
for (DeclarationDescriptor declaration : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
if (!(declaration instanceof CallableMemberDescriptor)) continue;
CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration;
CallableMemberDescriptor traitMember = ImplKt.findTraitImplementation(inheritedMember);
if (traitMember == null || Visibilities.isPrivate(traitMember.getVisibility())) continue;
if (traitMember == null) continue;
assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember;
@@ -140,7 +140,7 @@ public class CodegenUtil {
}
@NotNull
public static ClassDescriptor getSuperClassBySuperTypeListEntry(@NotNull KtSuperTypeListEntry specifier, @NotNull BindingContext bindingContext) {
public static ClassDescriptor getSuperClassByDelegationSpecifier(@NotNull KtDelegationSpecifier specifier, @NotNull BindingContext bindingContext) {
KotlinType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
assert superType != null : "superType should not be null: " + specifier.getText();

View File

@@ -31,43 +31,39 @@ public object CodegenUtilKt {
// class Foo : Bar by baz
// descriptor = Foo
// toInterface = Bar
// toTrait = Bar
// delegateExpressionType = typeof(baz)
// return Map<member of Foo, corresponding member of typeOf(baz)>
@JvmStatic
public fun getDelegates(
descriptor: ClassDescriptor,
toInterface: ClassDescriptor,
toTrait: ClassDescriptor,
delegateExpressionType: KotlinType? = null
): Map<CallableMemberDescriptor, CallableDescriptor> {
if (delegateExpressionType?.isDynamic() ?: false) return mapOf();
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
return descriptor.getDefaultType().getMemberScope().getContributedDescriptors().asSequence()
.filterIsInstance<CallableMemberDescriptor>()
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
.filter { it.getKind() == CallableMemberDescriptor.Kind.DELEGATION }
.asIterable()
.sortedWith(MemberComparator.INSTANCE)
.keysToMapExceptNulls {
delegatingMember ->
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
.mapNotNull {
.filter { it.getContainingDeclaration() == toTrait }
.map {
overriddenDescriptor ->
if (overriddenDescriptor.containingDeclaration == toInterface) {
val scope = (delegateExpressionType ?: toInterface.defaultType).memberScope
val name = overriddenDescriptor.name
val scope = (delegateExpressionType ?: toTrait.getDefaultType()).getMemberScope()
val name = overriddenDescriptor.getName()
// this is the actual member of delegateExpressionType that we are delegating to
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
.firstOrNull {
(listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it))
.map { it.original }
.contains(overriddenDescriptor.original)
}
}
else null
// this is the actual member of delegateExpressionType that we are delegating to
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
.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) { "Many delegates found for $delegatingMember: $actualDelegates" }
actualDelegates.firstOrNull()
}

View File

@@ -109,7 +109,7 @@ public fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Fu
result.removeAll(toRemove)
val concreteRelevantDeclarations = result.filter { !it.isAbstract }
if (concreteRelevantDeclarations.size != 1) {
if (concreteRelevantDeclarations.size() != 1) {
error("Concrete fake override $function should have exactly one concrete super-declaration: $concreteRelevantDeclarations")
}

View File

@@ -90,9 +90,10 @@ public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor)
val overridden = OverrideResolver.getOverriddenDeclarations(descriptor)
val filtered = OverrideResolver.filterOutOverridden(overridden)
val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null
val result = filtered.firstOrNull { it.getModality() != Modality.ABSTRACT } ?: return null
if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null
val container = result.getContainingDeclaration()
if (DescriptorUtils.isClass(container) || DescriptorUtils.isEnumClass(container)) return null
return result
}

View File

@@ -41,14 +41,6 @@ public class AccessorForConstructorDescriptor(
override fun substitute(substitutor: TypeSubstitutor) = super.substitute(substitutor) as ConstructorDescriptor
override fun copy(
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?, kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
): AccessorForConstructorDescriptor {
throw UnsupportedOperationException("Trying to copy synthetic accessor $this")
}
override fun getOriginal(): AccessorForConstructorDescriptor = this
init {
initialize(
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),

View File

@@ -32,8 +32,8 @@ abstract class ArgumentGenerator {
* @see kotlin.reflect.jvm.internal.KCallableImpl.callBy
*/
open fun generate(valueArgumentsByIndex: List<ResolvedValueArgument>, actualArgs: List<ResolvedValueArgument>): DefaultCallMask {
assert(valueArgumentsByIndex.size == actualArgs.size) {
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size} != ${actualArgs.size}"
assert(valueArgumentsByIndex.size() == actualArgs.size()) {
"Value arguments collection should have same size, but ${valueArgumentsByIndex.size()} != ${actualArgs.size()}"
}
val arg2Index = valueArgumentsByIndex.mapToIndex()
@@ -48,7 +48,7 @@ abstract class ArgumentGenerator {
}
}
val masks = DefaultCallMask(valueArgumentsByIndex.size)
val masks = DefaultCallMask(valueArgumentsByIndex.size())
for (argumentWithDeclIndex in actualArgsWithDeclIndex) {
val argument = argumentWithDeclIndex.arg

View File

@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.resolve.DeprecationUtilKt;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
@@ -62,11 +61,11 @@ 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.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.kotlin.types.TypeUtils.isNullableType;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -227,9 +226,9 @@ public class AsmUtil {
int flags = getVisibilityAccessFlag(functionDescriptor);
flags |= getVarargsFlag(functionDescriptor);
flags |= getDeprecatedAccessFlag(functionDescriptor);
if (DeprecationUtilKt.isHiddenInResolution(functionDescriptor)
if (DeprecationUtilKt.isAnnotatedAsHidden(functionDescriptor)
|| functionDescriptor instanceof PropertyAccessorDescriptor
&& DeprecationUtilKt.isHiddenInResolution(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
&& DeprecationUtilKt.isAnnotatedAsHidden(((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty())) {
flags |= ACC_SYNTHETIC;
}
return flags;
@@ -300,6 +299,9 @@ 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());
@@ -323,6 +325,9 @@ public class AsmUtil {
private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) {
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
Visibility memberVisibility = memberDescriptor.getVisibility();
if (isJvmInterface(containingDeclaration)) {
return memberVisibility == Visibilities.PRIVATE ? NO_FLAG_PACKAGE_PRIVATE : ACC_PUBLIC;
}
if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) {
return ACC_PUBLIC;
@@ -374,6 +379,11 @@ public class AsmUtil {
}
}
if (memberDescriptor instanceof PropertyDescriptor &&
((PropertyDescriptor) memberDescriptor).isConst() || hasJvmFieldAnnotation(memberDescriptor)) {
return null;
}
return null;
}
@@ -540,7 +550,7 @@ public class AsmUtil {
if (opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ) {
genInvertBoolean(v);
}
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -679,17 +689,28 @@ public class AsmUtil {
}
public static boolean isInstancePropertyWithStaticBackingField(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
isObject(propertyDescriptor.getContainingDeclaration());
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
return false;
}
DeclarationDescriptor container = propertyDescriptor.getContainingDeclaration();
return isNonCompanionObject(container) ||
isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ||
(isCompanionObject(container) && isInterface(container.getContainingDeclaration()));
}
public static int getVisibilityForBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
}
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
if (isDelegate || isExtensionProperty) {
return ACC_PRIVATE;
}
else {
return propertyDescriptor.isLateInit() || isConstOrHasJvmFieldAnnotation(propertyDescriptor)
return areBothAccessorDefault(propertyDescriptor)
? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor))
: ACC_PRIVATE;
}
@@ -705,10 +726,27 @@ public class AsmUtil {
}
public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
return propertyDescriptor.isConst()
return !propertyDescriptor.isVar()
&& !isExtensionProperty
&& isCompanionObject(propertyContainer) && isInterface(propertyContainer.getContainingDeclaration())
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
&& areBothAccessorDefault(propertyDescriptor)
&& getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC;
}
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
DeclarationDescriptor containingClass = companionObject.getContainingDeclaration();
return isCompanionObject(companionObject) && (isClass(containingClass) || isEnumClass(containingClass));
}
private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) {
return isAccessorWithEmptyBody(propertyDescriptor.getGetter())
&& (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter()));
}
private static boolean isAccessorWithEmptyBody(@Nullable PropertyAccessorDescriptor accessorDescriptor) {
return accessorDescriptor == null || !accessorDescriptor.hasBody();
}
public static Type comparisonOperandType(Type left, Type right) {
@@ -813,6 +851,13 @@ public class AsmUtil {
return asmTypeByFqNameWithoutInnerClasses(fqName).getDescriptor();
}
@NotNull
public static String shortNameByAsmType(@NotNull Type type) {
String internalName = type.getInternalName();
int lastSlash = internalName.lastIndexOf('/');
return lastSlash < 0 ? internalName : internalName.substring(lastSlash + 1);
}
@NotNull
public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));

View File

@@ -90,7 +90,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
}
@Override
protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex) {
protected void reorderArgumentsIfNeeded(@NotNull List<? extends ArgumentAndDeclIndex> actualArgsWithDeclIndex) {
callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes);
}
}

View File

@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -52,19 +51,11 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
@Override
protected void generateBody() {
List<KtObjectDeclaration> companions = new ArrayList<KtObjectDeclaration>();
if (kind != OwnerKind.DEFAULT_IMPLS) {
//generate nested classes first and only then generate class body. It necessary to access to nested CodegenContexts
for (KtDeclaration declaration : myClass.getDeclarations()) {
if (shouldProcessFirst(declaration)) {
//Generate companions after class body generation (need to record all synthetic accessors)
if (declaration instanceof KtObjectDeclaration && ((KtObjectDeclaration) declaration).isCompanion()) {
companions.add((KtObjectDeclaration) declaration);
CodegenUtilKt.populateCompanionBackingFieldNamesToOuterContextIfNeeded((KtObjectDeclaration) declaration, context, state);
}
else {
generateDeclaration(declaration);
}
generateDeclaration(declaration);
}
}
}
@@ -75,14 +66,6 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
}
}
generatePrimaryConstructorProperties();
generateConstructors();
generateDefaultImplsIfNeeded();
for (KtObjectDeclaration companion : companions) {
generateDeclaration(companion);
}
if (!DescriptorUtils.isInterface(descriptor)) {
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
if (memberDescriptor instanceof CallableMemberDescriptor) {
@@ -105,14 +88,8 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtClassOrObject> {
}
}
}
}
protected void generateConstructors() {
}
protected void generateDefaultImplsIfNeeded() {
generatePrimaryConstructorProperties();
}
private static boolean shouldProcessFirst(KtDeclaration declaration) {

View File

@@ -22,7 +22,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.DataOutputStream;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;

View File

@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.codegen;
import com.google.common.collect.Lists;
import com.intellij.util.ArrayUtil;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
import org.jetbrains.kotlin.util.OperatorNameConventions;
import org.jetbrains.kotlin.utils.FunctionsKt;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
@@ -211,7 +212,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
this.constructor = generateConstructor();
if (isConst(closure)) {
generateConstInstance(asmType, asmType);
generateConstInstance(asmType, asmType, FunctionsKt.<InstructionAdapter>doNothing());
}
genClosureFields(closure, v, typeMapper);
@@ -258,7 +259,13 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
}
return Unit.INSTANCE;
if (functionReferenceTarget != null) {
if (!"true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.callable.references"))) {
v.invokestatic(REFLECTION, "function", Type.getMethodDescriptor(K_FUNCTION, FUNCTION_REFERENCE), false);
}
}
return Unit.INSTANCE$;
}
}
);

View File

@@ -108,13 +108,15 @@ class CollectionStubMethodGenerator(
val genericSignatureInfo = overriddenMethod.getSpecialSignatureInfo()
val specialGenericSignature =
genericSignatureInfo?.replaceValueParametersIn(overriddenMethodSignature.genericsSignature)
?: overriddenMethodSignature.genericsSignature
if (genericSignatureInfo != null)
genericSignatureInfo.signature
else
overriddenMethodSignature.genericsSignature
val (asmMethod, valueParameters) =
// if current method has special generic signature,
// like `Collection.remove(E): Boolean` in Kotlin, use original signature to obtain `remove(Object)`
if (genericSignatureInfo?.isObjectReplacedWithTypeParameter ?: false)
// if remove(E) in Kotlin -> remove(Object) in Java
// so choose original signature
if (genericSignatureInfo == SpecialSignatureInfo.GENERIC_PARAMETER)
Pair(originalSignature.asmMethod, originalSignature.valueParameters)
else
Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters)
@@ -214,7 +216,7 @@ class CollectionStubMethodGenerator(
private fun Collection<KotlinType>.findMostSpecificTypeForClass(klass: ClassDescriptor): KotlinType {
val types = this.filter { it.getConstructor().getDeclarationDescriptor() == klass }
if (types.isEmpty()) error("No supertype of $klass in $this")
if (types.size == 1) return types.first()
if (types.size() == 1) return types.first()
// Find the first type in the list such that it's a subtype of every other type in that list
return types.first { type ->
types.all { other -> KotlinTypeChecker.DEFAULT.isSubtypeOf(type, other) }
@@ -227,7 +229,7 @@ class CollectionStubMethodGenerator(
child.setModality(Modality.FINAL)
child.setVisibility(Visibilities.PUBLIC)
val typeParameters = descriptor.getTypeConstructor().getParameters()
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size())
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
child.setTypeParameterDescriptors(typeParameters)
return Pair(child, newTypeParameters)

View File

@@ -24,7 +24,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.Stack;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
@@ -39,6 +39,7 @@ 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.TypeIntrinsics;
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -53,10 +54,10 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.jvm.bindingContextSlices.BindingContextSlicesKt;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
@@ -92,13 +93,15 @@ import java.util.*;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.couldUseDirectAccessToProperty;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -478,7 +481,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
markLineNumber(expression, isStatement);
v.mark(end);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -666,7 +669,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
});
}
else {
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
KtMultiDeclaration multiParameter = forExpression.getMultiParameter();
assert multiParameter != null;
// E tmp<e> = tmp<iterator>.next()
@@ -684,15 +687,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assignToLoopParameter();
if (forExpression.getLoopParameter() == null) {
KtDestructuringDeclaration multiParameter = forExpression.getDestructuringParameter();
KtMultiDeclaration multiParameter = forExpression.getMultiParameter();
assert multiParameter != null;
generateMultiVariables(multiParameter.getEntries());
}
}
private void generateMultiVariables(List<KtDestructuringDeclarationEntry> entries) {
for (KtDestructuringDeclarationEntry variableDeclaration : entries) {
private void generateMultiVariables(List<KtMultiDeclarationEntry> entries) {
for (KtMultiDeclarationEntry variableDeclaration : entries) {
final VariableDescriptor componentDescriptor = bindingContext.get(VARIABLE, variableDeclaration);
@SuppressWarnings("ConstantConditions") final Type componentAsmType = asmType(componentDescriptor.getReturnType());
@@ -1292,7 +1295,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -1329,7 +1332,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@Override
public StackValue visitLambdaExpression(@NotNull KtLambdaExpression expression, StackValue receiver) {
public StackValue visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression, StackValue receiver) {
if (Boolean.TRUE.equals(bindingContext.get(BLOCK, expression))) {
return gen(expression.getFunctionLiteral().getBodyExpression());
}
@@ -1431,7 +1434,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
JvmMethodSignature constructor = typeMapper.mapSignature(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor(), false);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -1549,7 +1552,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
task.fun(value);
}
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -1566,9 +1569,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
private void putDescriptorIntoFrameMap(@NotNull KtElement statement) {
if (statement instanceof KtDestructuringDeclaration) {
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
if (statement instanceof KtMultiDeclaration) {
KtMultiDeclaration multiDeclaration = (KtMultiDeclaration) statement;
for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
putLocalVariableIntoFrameMap(entry);
}
}
@@ -1606,9 +1609,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull Label blockEnd,
@NotNull List<Function<StackValue, Void>> leaveTasks
) {
if (statement instanceof KtDestructuringDeclaration) {
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) {
if (statement instanceof KtMultiDeclaration) {
KtMultiDeclaration multiDeclaration = (KtMultiDeclaration) statement;
for (KtMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
addLeaveTaskToRemoveLocalVariableFromFrameMap(entry, blockEnd, leaveTasks);
}
}
@@ -2069,10 +2072,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyGetterDescriptor getter = descriptor.getGetter();
if (getter != null) {
Call call = bindingContext.get(DELEGATED_PROPERTY_CALL, getter);
if (call != null) {
assert call.getExplicitReceiver() != null : "No explicit receiver for call:" + call;
return ((ReceiverValue) call.getExplicitReceiver()).getType();
}
return call != null ? ((ReceiverValue) call.getExplicitReceiver()).getType() : null;
}
return null;
}
@@ -2116,11 +2116,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
boolean isBackingFieldInClassCompanion = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
if (isBackingFieldInClassCompanion && forceField) {
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
}
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {
else if (syntheticBackingField && context.getParentContext().getContextDescriptor() != containingDeclaration) {
fieldAccessorKind = FieldAccessorKind.FIELD_FROM_LOCAL;
}
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
@@ -2140,7 +2140,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
if (!skipPropertyAccessors) {
//noinspection ConstantConditions
@@ -2161,12 +2161,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (!skipPropertyAccessors) {
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget);
if (isSuper && !isJvmInterface(containingDeclaration)) {
CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor;
if (c != context.getParentContext()) {
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor, superCallTarget);
}
}
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if (getter != null && !isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
if (getter != null && !hasJvmFieldAnnotation(propertyDescriptor)) {
callableGetter = typeMapper.mapToCallableMethod(getter, isSuper);
}
}
@@ -2175,7 +2181,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (setter != null &&
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context) &&
!isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
!hasJvmFieldAnnotation(propertyDescriptor)) {
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
}
}
@@ -2245,8 +2251,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
final SamType samType = bindingContext.get(SAM_VALUE, probablyParenthesizedExpression);
if (samType == null || expression == null) return null;
if (expression instanceof KtLambdaExpression) {
return genClosure(((KtLambdaExpression) expression).getFunctionLiteral(), samType);
if (expression instanceof KtFunctionLiteralExpression) {
return genClosure(((KtFunctionLiteralExpression) expression).getFunctionLiteral(), samType);
}
if (expression instanceof KtNamedFunction) {
@@ -2319,8 +2325,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
public StackValue invokeFunction(@NotNull Call call, @NotNull ResolvedCall<?> resolvedCall, @NotNull StackValue receiver) {
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
ClassDescriptor superCallTarget = getSuperCallTarget(call);
boolean superCall = superCallTarget != null;
fd = context.getAccessorForSuperCallIfNeeded(fd, superCallTarget);
if (superCall && !isJvmInterface(fd.getContainingDeclaration())) {
CodegenContext c = context.findParentContextWithDescriptor(superCallTarget);
assert c != null : "Couldn't find a context for a super-call: " + fd;
if (c != context.getParentContext()) {
fd = (FunctionDescriptor) c.getAccessor(fd, superCallTarget);
}
}
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
if (!codegenExtensions.isEmpty()) {
@@ -2331,7 +2344,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
Callable callable = resolveToCallable(fd, superCallTarget != null, resolvedCall);
Callable callable = resolveToCallable(fd, superCall, resolvedCall);
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
}
@@ -2420,12 +2433,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
v.aconst(null);
v.athrow();
}
}
@NotNull
@@ -2476,8 +2483,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
else {
mappings.addParameterMappingToNewParameter(
key.getName().getIdentifier(), type,
parameterDescriptor.getName().getIdentifier());
key.getName().getIdentifier(),
parameterDescriptor.getName().getIdentifier()
);
}
}
return getOrCreateCallGenerator(
@@ -2486,7 +2494,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
public StackValue generateReceiverValue(@NotNull ReceiverValue receiverValue, boolean isSuper) {
if (receiverValue instanceof ImplicitClassReceiver) {
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
@@ -2738,17 +2746,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, expression);
if (variableDescriptor != null) {
return generatePropertyReference(expression, variableDescriptor, resolvedCall);
return generatePropertyReference(expression, variableDescriptor, (VariableDescriptor) resolvedCall.getResultingDescriptor(),
resolvedCall.getDispatchReceiver());
}
throw new UnsupportedOperationException("Unsupported callable reference expression: " + expression.getText());
}
@NotNull
private StackValue generatePropertyReference(
public StackValue generatePropertyReference(
@NotNull KtElement element,
@NotNull VariableDescriptor variableDescriptor,
@NotNull ResolvedCall<?> resolvedCall
@NotNull VariableDescriptor target,
@NotNull ReceiverValue dispatchReceiver
) {
ClassDescriptor classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor);
@@ -2760,7 +2770,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyReferenceCodegen codegen = new PropertyReferenceCodegen(
state, parentCodegen, context.intoAnonymousClass(classDescriptor, this, OwnerKind.IMPLEMENTATION),
element, classBuilder, resolvedCall
element, classBuilder, classDescriptor, target, dispatchReceiver
);
codegen.generate();
@@ -2785,13 +2795,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
assert codegen != null :
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS);
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
}
putJavaLangClassInstance(v, classAsmType);
wrapJavaClassIntoKClass(v);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3250,7 +3260,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
value.store(StackValue.onStack(storeType), v, true);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3266,7 +3276,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@Override
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
public StackValue visitMultiDeclaration(@NotNull KtMultiDeclaration multiDeclaration, StackValue receiver) {
KtExpression initializer = multiDeclaration.getInitializer();
if (initializer == null) return StackValue.none();
@@ -3283,7 +3293,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
v.store(tempVarIndex, initializerAsmType);
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
for (KtDestructuringDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
for (KtMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) {
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration);
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
Call call = makeFakeCall(initializerAsReceiver);
@@ -3375,7 +3385,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
CallableMethod method = typeMapper.mapToCallableMethod(constructor, false);
invokeMethodWithArguments(method, resolvedCall, StackValue.none());
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3391,7 +3401,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
public Unit invoke(InstructionAdapter v) {
gen(sizeExpression, Type.INT_TYPE);
newArrayInstruction(arrayType);
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3399,9 +3409,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
public void newArrayInstruction(@NotNull KotlinType arrayType) {
if (KotlinBuiltIns.isArray(arrayType)) {
KotlinType elementJetType = arrayType.getArguments().get(0).getType();
putReifiedOperationMarkerIfTypeIsReifiedParameter(
putReifierMarkerIfTypeIsReifiedParameter(
elementJetType,
ReifiedTypeInliner.OperationKind.NEW_ARRAY
ReifiedTypeInliner.NEW_ARRAY_MARKER_METHOD_NAME
);
v.newarray(boxType(asmType(elementJetType)));
}
@@ -3630,7 +3640,7 @@ The "returned" value of try expression with no finally is either the last expres
if (finallyBlock != null) {
blockStackElements.pop();
}
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
});
}
@@ -3678,19 +3688,28 @@ The "returned" value of try expression with no finally is either the last expres
StackValue.putUnitInstance(v);
}
boolean safeAs = opToken == KtTokens.AS_SAFE;
Type type = boxType(asmType(rightType));
if (TypeUtils.isReifiedTypeParameter(rightType)) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(rightType,
safeAs ? ReifiedTypeInliner.OperationKind.SAFE_AS
: ReifiedTypeInliner.OperationKind.AS);
v.checkcast(type);
return Unit.INSTANCE;
if (opToken != KtTokens.AS_SAFE) {
if (!TypeUtils.isNullableType(rightType)) {
v.dup();
Label nonnull = new Label();
v.ifnonnull(nonnull);
genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " +
DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(rightType));
v.mark(nonnull);
}
}
else {
v.dup();
generateInstanceOfInstruction(rightType);
Label ok = new Label();
v.ifne(ok);
v.pop();
v.aconst(null);
v.mark(ok);
}
CodegenUtilKt.generateAsCast(v, rightType, type, safeAs);
return Unit.INSTANCE;
generateCheckCastInstruction(rightType, opToken == KtTokens.AS_SAFE);
return Unit.INSTANCE$;
}
});
}
@@ -3728,11 +3747,11 @@ The "returned" value of try expression with no finally is either the last expres
private StackValue generateIsCheck(StackValue expressionToMatch, KtTypeReference typeReference, boolean negated) {
KotlinType jetType = bindingContext.get(TYPE, typeReference);
markStartLineNumber(typeReference);
StackValue value = generateIsCheck(expressionToMatch, jetType, false);
StackValue value = generateInstanceOf(expressionToMatch, jetType, false);
return negated ? StackValue.not(value) : value;
}
private StackValue generateIsCheck(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
private StackValue generateInstanceOf(final StackValue expressionToGen, final KotlinType kotlinType, final boolean leaveExpressionOnStack) {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
@@ -3740,35 +3759,46 @@ The "returned" value of try expression with no finally is either the last expres
if (leaveExpressionOnStack) {
v.dup();
}
Type type = boxType(asmType(kotlinType));
if (TypeUtils.isReifiedTypeParameter(kotlinType)) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(kotlinType, ReifiedTypeInliner.OperationKind.IS);
v.instanceOf(type);
return null;
}
CodegenUtilKt.generateIsCheck(v, kotlinType, type);
CodegenUtilKt.generateIsCheck(v, kotlinType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
generateInstanceOfInstruction(kotlinType);
return Unit.INSTANCE;
}
});
return null;
}
});
}
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
) {
private void generateInstanceOfInstruction(@NotNull KotlinType jetType) {
Type type = boxType(asmType(jetType));
putReifierMarkerIfTypeIsReifiedParameter(jetType, ReifiedTypeInliner.INSTANCEOF_MARKER_METHOD_NAME);
TypeIntrinsics.instanceOf(v, jetType, type);
}
@NotNull
private StackValue generateCheckCastInstruction(@NotNull KotlinType jetType, boolean safeAs) {
Type type = boxType(asmType(jetType));
putReifierMarkerIfTypeIsReifiedParameter(jetType,
safeAs ? ReifiedTypeInliner.SAFE_CHECKCAST_MARKER_METHOD_NAME
: ReifiedTypeInliner.CHECKCAST_MARKER_METHOD_NAME);
TypeIntrinsics.checkcast(v, jetType, type, safeAs);
return StackValue.onStack(type);
}
public void putReifierMarkerIfTypeIsReifiedParameter(@NotNull KotlinType type, @NotNull String markerMethodName) {
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
if (typeParameterDescriptor != null && typeParameterDescriptor.isReified()) {
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
parentCodegen.getReifiedTypeParametersUsages().
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
}
v.iconst(operationKind.getId());
boolean putNullableFlag = operationKind.isTypeNullabilityAware() && type.isMarkedNullable();
v.visitLdcInsn(typeParameterDescriptor.getName().asString() + (putNullableFlag ? "?" : ""));
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
v.invokestatic(
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.REIFIED_OPERATION_MARKER_METHOD_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.getType(String.class)), false
IntrinsicMethods.INTRINSICS_CLASS_NAME, markerMethodName,
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
);
}
}
@@ -3791,12 +3821,11 @@ The "returned" value of try expression with no finally is either the last expres
return StackValue.operation(resultType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(
expression, isStatement, isExhaustive(expression, isStatement), ExpressionCodegen.this
);
SwitchCodegen switchCodegen =
SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, ExpressionCodegen.this);
if (switchCodegen != null) {
switchCodegen.generate();
return Unit.INSTANCE;
return Unit.INSTANCE$;
}
int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;
@@ -3839,7 +3868,9 @@ The "returned" value of try expression with no finally is either the last expres
}
if (!hasElse && nextCondition != null) {
v.mark(nextCondition);
putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
if (!isStatement) {
putUnitInstanceOntoStackForNonExhaustiveWhen(expression);
}
}
markLineNumber(expression, isStatement);
@@ -3852,24 +3883,14 @@ The "returned" value of try expression with no finally is either the last expres
});
}
private boolean isExhaustive(@NotNull KtWhenExpression whenExpression, boolean isStatement) {
if (isStatement) {
return Boolean.TRUE.equals(bindingContext.get(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN, whenExpression));
}
else {
return Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression));
}
}
public void putUnitInstanceOntoStackForNonExhaustiveWhen(
@NotNull KtWhenExpression whenExpression,
boolean isStatement
@NotNull KtWhenExpression expression
) {
if (isExhaustive(whenExpression, isStatement)) {
if (Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, expression))) {
// when() is supposed to be exhaustive
genThrow(v, "kotlin/NoWhenBranchMatchedException", null);
}
else if (!isStatement) {
else {
// non-exhaustive when() with no else -> Unit must be expected
StackValue.putUnitInstance(v);
}

View File

@@ -33,12 +33,17 @@ public class FieldInfo {
@NotNull
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) {
return createForSingleton(classDescriptor, typeMapper, false);
}
@NotNull
public static FieldInfo createForSingleton(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper, boolean oldSingleton) {
if (!classDescriptor.getKind().isSingleton() || DescriptorUtils.isEnumEntry(classDescriptor)) {
throw new UnsupportedOperationException("Can't create singleton field for class: " + classDescriptor);
}
if (isNonCompanionObject(classDescriptor) || COMPANION_OBJECT_MAPPING.hasMappingToObject(classDescriptor)) {
return createSingletonViaInstance(classDescriptor, typeMapper);
return createSingletonViaInstance(classDescriptor, typeMapper, oldSingleton);
}
else {
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
@@ -51,10 +56,11 @@ public class FieldInfo {
@NotNull
public static FieldInfo createSingletonViaInstance(
@NotNull ClassDescriptor classDescriptor,
@NotNull JetTypeMapper typeMapper
@NotNull JetTypeMapper typeMapper,
boolean oldSingleton
) {
Type type = typeMapper.mapType(classDescriptor);
return new FieldInfo(type, type, JvmAbi.INSTANCE_FIELD, true);
return new FieldInfo(type, type, oldSingleton ? JvmAbi.DEPRECATED_INSTANCE_FIELD : JvmAbi.INSTANCE_FIELD, true);
}
@NotNull

View File

@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo;
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeKt;
import org.jetbrains.kotlin.name.FqName;
@@ -76,12 +77,11 @@ import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -161,7 +161,7 @@ public class FunctionCodegen {
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
boolean isNative = NativeKt.hasNativeAnnotation(functionDescriptor);
if (isNative && owner instanceof MultifileClassFacadeContext) {
if (isNative && owner instanceof DelegatingFacadeContext) {
// Native methods are only defined in facades and do not need package part implementations
return;
}
@@ -172,6 +172,10 @@ 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 (CodegenContextUtil.isImplClassOwner(owner)) {
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
}
@@ -217,6 +221,8 @@ public class FunctionCodegen {
}
endVisit(mv, null, origin.getElement());
methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, bindingContext);
}
private void generateMethodAnnotations(
@@ -233,6 +239,22 @@ public class FunctionCodegen {
else {
annotationCodegen.genAnnotations(functionDescriptor, asmMethod.getReturnType());
}
writePackageFacadeMethodAnnotationsIfNeeded(mv);
}
private void writePackageFacadeMethodAnnotationsIfNeeded(MethodVisitor mv) {
if (owner instanceof PackageFacadeContext) {
PackageFacadeContext packageFacadeContext = (PackageFacadeContext) owner;
Type delegateToClassType = packageFacadeContext.getPublicFacadeType();
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(
@@ -253,6 +275,9 @@ public class FunctionCodegen {
if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = iterator.next();
if (parameter.getIndex() != i) {
v.getSerializationBindings().put(INDEX_FOR_VALUE_PARAMETER, parameter, i);
}
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, typeMapper);
if (functionDescriptor instanceof PropertySetterDescriptor) {
@@ -341,18 +366,18 @@ public class FunctionCodegen {
int functionFakeIndex = -1;
int lambdaFakeIndex = -1;
if (context.getParentContext() instanceof MultifileClassFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
if (context.getParentContext() instanceof DelegatingFacadeContext) {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (DelegatingFacadeContext) context.getParentContext());
methodEnd = new Label();
}
else {
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
functionDescriptor));
if (context.isInlineMethodContext()) {
if (context.isInlineFunction()) {
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
}
if (context instanceof InlineLambdaContext) {
if (context.isInliningLambda()) {
lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
}
@@ -373,7 +398,7 @@ public class FunctionCodegen {
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind());
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
if (context.isInlineFunction() && functionFakeIndex != -1) {
mv.visitLocalVariable(
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
Type.INT_TYPE.getDescriptor(), null,
@@ -381,7 +406,7 @@ public class FunctionCodegen {
functionFakeIndex);
}
if (context instanceof InlineLambdaContext && thisType != null && lambdaFakeIndex != -1) {
if (context.isInliningLambda() && thisType != null && lambdaFakeIndex != -1) {
String name = thisType.getClassName();
int indexOfLambdaOrdinal = name.lastIndexOf("$");
if (indexOfLambdaOrdinal > 0) {
@@ -445,9 +470,9 @@ public class FunctionCodegen {
private static void generateFacadeDelegateMethodBody(
@NotNull MethodVisitor mv,
@NotNull Method asmMethod,
@NotNull MultifileClassFacadeContext context
@NotNull DelegatingFacadeContext context
) {
generateDelegateToMethodBody(true, mv, asmMethod, context.getFilePartType().getInternalName());
generateDelegateToMethodBody(true, mv, asmMethod, context.getDelegateToClassType().getInternalName());
}
private static void generateDelegateToMethodBody(
@@ -530,7 +555,7 @@ public class FunctionCodegen {
// If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges
if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return;
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor) != null;
Set<Bridge<Method>> bridgesToGenerate;
if (!isSpecial) {
@@ -564,7 +589,7 @@ public class FunctionCodegen {
}
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor);
assert overridden != null;
Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
@@ -670,9 +695,9 @@ public class FunctionCodegen {
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
if (this.owner instanceof MultifileClassFacadeContext) {
if (this.owner instanceof DelegatingFacadeContext) {
mv.visitCode();
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
generateFacadeDelegateMethodBody(mv, defaultMethod, (DelegatingFacadeContext) this.owner);
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else {
@@ -886,7 +911,13 @@ public class FunctionCodegen {
iv.ifnonnull(afterBarrier);
}
else {
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterType));
CodegenUtilKt.generateIsCheck(iv, kotlinType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter adapter) {
TypeIntrinsics.instanceOf(adapter, kotlinType, boxType(delegateParameterType));
return Unit.INSTANCE;
}
});
iv.ifne(afterBarrier);
}

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -36,6 +36,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.*;
import static org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased<FunctionDescriptor> {
private final ResolvedCall<?> resolvedCall;
private final FunctionDescriptor referencedFunction;
@@ -80,13 +82,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
}
@Nullable
@NotNull
@Override
public ReceiverValue getExtensionReceiver() {
return extensionReceiver;
}
@Nullable
@NotNull
@Override
public ReceiverValue getDispatchReceiver() {
return dispatchReceiver;
@@ -117,7 +119,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
}
else {
Call call = CallMaker.makeCall(fakeExpression, null, null, fakeExpression, fakeArguments);
Call call = CallMaker.makeCall(fakeExpression, NO_RECEIVER, null, fakeExpression, fakeArguments);
result = codegen.invokeFunction(call, fakeResolvedCall, StackValue.none());
}
@@ -155,13 +157,13 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
}
@Nullable
@NotNull
private ReceiverValue computeAndSaveReceiver(
@NotNull JvmMethodSignature signature,
@NotNull ExpressionCodegen codegen,
@Nullable ReceiverParameterDescriptor receiver
) {
if (receiver == null) return null;
if (receiver == null) return NO_RECEIVER;
KtExpression receiverExpression = KtPsiFactoryKt
.KtPsiFactory(state.getProject()).createExpression("callableReferenceFakeReceiver");

View File

@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
@@ -62,8 +62,8 @@ 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.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
import org.jetbrains.kotlin.serialization.ProtoBuf;
import org.jetbrains.kotlin.types.KotlinType;
@@ -98,8 +98,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private List<PropertyAndDefaultValue> companionObjectPropertiesToCopy;
private final DelegationFieldsInfo delegationFieldsInfo;
private final List<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>> additionalTasks =
new ArrayList<Function2<ImplementationBodyCodegen, ClassBuilder, Unit>>();
@@ -114,7 +112,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
super(aClass, context, v, state, parentCodegen);
this.classAsmType = typeMapper.mapClass(descriptor);
this.isLocal = isLocal;
delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries());
}
@Override
@@ -230,7 +227,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void generateDefaultImplsIfNeeded() {
protected void generateBody() {
super.generateBody();
if (isInterface(descriptor) && !isLocal) {
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
ClassBuilder defaultImplsBuilder =
@@ -239,7 +237,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CodegenContext parentContext = context.getParentContext();
assert parentContext != null : "Parent context of interface declaration should not be null";
ClassContext defaultImplsContext = parentContext.intoDefaultImplsClass(descriptor, (ClassContext) context, state);
ClassContext defaultImplsContext = parentContext.intoClass(descriptor, OwnerKind.DEFAULT_IMPLS, state);
new InterfaceImplBodyCodegen(myClass, defaultImplsContext, defaultImplsBuilder, state, this).generate();
}
}
@@ -247,7 +245,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override
protected void generateKotlinAnnotation() {
if (!isTopLevelOrInnerClass(descriptor)) {
v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true).visitEnd();
AnnotationVisitor av = v.getVisitor().visitAnnotation(
asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true
);
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
av.visitEnd();
}
DescriptorSerializer serializer =
@@ -369,31 +371,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateCompanionObjectBackingFieldCopies();
generateTraitMethods();
generateDelegates(delegationFieldsInfo);
if (!isInterface(descriptor) || kind == OwnerKind.DEFAULT_IMPLS) {
generateSyntheticAccessors();
}
generateEnumMethods();
generateFunctionsForDataClasses();
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
generateToArray();
genClosureFields(context.closure, v, typeMapper);
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
}
}
@Override
protected void generateConstructors() {
DelegationFieldsInfo delegationFieldsInfo = getDelegationFieldsInfo(myClass.getDelegationSpecifiers());
try {
lookupConstructorExpressionsInClosureIfPresent();
generatePrimaryConstructor(delegationFieldsInfo);
@@ -410,6 +388,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
catch (RuntimeException e) {
throw new RuntimeException("Error generating constructors of class " + myClass.getName() + " with kind " + kind, e);
}
generateTraitMethods();
generateDelegates(delegationFieldsInfo);
generateSyntheticAccessors();
generateEnumMethods();
generateFunctionsForDataClasses();
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
generateToArray();
genClosureFields(context.closure, v, typeMapper);
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
extension.generateClassSyntheticParts(v, state, myClass, descriptor);
}
}
private boolean isGenericToArrayPresent() {
@@ -836,16 +834,22 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generateFieldForSingleton() {
if (isEnumEntry(descriptor) || isCompanionObject(descriptor)) return;
if (isEnumEntry(descriptor)) return;
if (isNonCompanionObject(descriptor)) {
boolean isCompanionObject = isCompanionObject(descriptor);
if (isNonCompanionObject(descriptor) || isCompanionObject) {
StackValue.Field field = StackValue.singletonViaInstance(descriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass),
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
ACC_PUBLIC | ACC_STATIC | ACC_FINAL | (isCompanionObject ? ACC_DEPRECATED : 0),
field.name, field.type.getDescriptor(), null, null);
if (isNonCompanionObject(descriptor)) {
StackValue.Field oldField = StackValue.oldSingleton(descriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass), ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_DEPRECATED, oldField.name, oldField.type.getDescriptor(), null, null);
}
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
// Invoke the object constructor but ignore the result because INSTANCE will be initialized in the first line of <init>
// Invoke the object constructor but ignore the result because INSTANCE$ will be initialized in the first line of <init>
InstructionAdapter v = createOrGetClInitCodegen().v;
markLineNumberForElement(element, v);
v.anew(classAsmType);
@@ -864,6 +868,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject), ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
if (!isCompanionObjectWithBackingFieldsInOuter(companionObjectDescriptor)) {
generateCompanionObjectInitializer(companionObjectDescriptor);
}
}
private void generateCompanionObjectBackingFieldCopies() {
@@ -873,10 +883,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
PropertyDescriptor property = info.descriptor;
Type type = typeMapper.mapType(property);
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC;
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (property.isConst() ? 0 : ACC_DEPRECATED);
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
modifiers, context.getFieldName(property, false),
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType()),
info.defaultValue);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(property, type);
@@ -915,13 +925,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateCompanionObjectInitializer(@NotNull ClassDescriptor companionObject) {
ExpressionCodegen codegen = createOrGetClInitCodegen();
FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
);
generateMethodCallTo(constructor, null, codegen.v);
StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
StackValue.singleton(companionObject, typeMapper).store(instance, codegen.v, true);
//TODO: uncomment when DEPRECATED INSTANCE is removed
//FunctionDescriptor constructor = (FunctionDescriptor) context.accessibleDescriptor(
// CollectionsKt.single(companionObject.getConstructors()), /* superCallExpression = */ null
//);
//generateMethodCallTo(constructor, null, codegen.v);
//StackValue instance = StackValue.onStack(typeMapper.mapClass(companionObject));
StackValue.singleton(companionObject, typeMapper).store(StackValue.singletonViaInstance(companionObject, typeMapper), codegen.v, true);
}
private void generatePrimaryConstructor(final DelegationFieldsInfo delegationFieldsInfo) {
@@ -948,6 +958,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DefaultParameterValueLoader.DEFAULT, null);
new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, kind, myClass);
if (isCompanionObject(descriptor)) {
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
}
}
private void generateSecondaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
@@ -991,13 +1005,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateDelegatorToConstructorCall(iv, codegen, constructorDescriptor,
getDelegationConstructorCall(bindingContext, constructorDescriptor));
if (isNonCompanionObject(descriptor)) {
if (isObject(descriptor)) {
StackValue.singletonViaInstance(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
if (isNonCompanionObject(descriptor)) {
StackValue.oldSingleton(descriptor, typeMapper).store(StackValue.LOCAL_0, iv);
}
}
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatedSuperTypeEntry) specifier, fieldsInfo);
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
genCallToDelegatorByExpressionSpecifier(iv, codegen, (KtDelegatorByExpressionSpecifier) specifier, fieldsInfo);
}
}
@@ -1016,13 +1033,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
curParam++;
}
if (isCompanionObject(descriptor)) {
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
parentCodegen.generateCompanionObjectInitializer(descriptor);
}
if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
final ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
parentCodegen.generateCompanionObjectInitializer(descriptor);
generateInitializers(new Function0<ExpressionCodegen>() {
@Override
public ExpressionCodegen invoke() {
@@ -1140,41 +1153,41 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
return StackValue.field(type, classAsmType, name, false, StackValue.none());
}
}
private final Map<KtDelegatedSuperTypeEntry, Field> fields = new HashMap<KtDelegatedSuperTypeEntry, Field>();
private final Map<KtDelegatorByExpressionSpecifier, Field> fields = new HashMap<KtDelegatorByExpressionSpecifier, Field>();
@NotNull
public Field getInfo(KtDelegatedSuperTypeEntry specifier) {
public Field getInfo(KtDelegatorByExpressionSpecifier specifier) {
return fields.get(specifier);
}
private void addField(KtDelegatedSuperTypeEntry specifier, PropertyDescriptor propertyDescriptor) {
private void addField(KtDelegatorByExpressionSpecifier specifier, PropertyDescriptor propertyDescriptor) {
fields.put(specifier,
new Field(typeMapper.mapType(propertyDescriptor), propertyDescriptor.getName().asString(), false));
}
private void addField(KtDelegatedSuperTypeEntry specifier, Type type, String name) {
private void addField(KtDelegatorByExpressionSpecifier specifier, Type type, String name) {
fields.put(specifier, new Field(type, name, true));
}
}
@NotNull
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtSuperTypeListEntry> delegationSpecifiers) {
private DelegationFieldsInfo getDelegationFieldsInfo(@NotNull List<KtDelegationSpecifier> delegationSpecifiers) {
DelegationFieldsInfo result = new DelegationFieldsInfo();
int n = 0;
for (KtSuperTypeListEntry specifier : delegationSpecifiers) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
for (KtDelegationSpecifier specifier : delegationSpecifiers) {
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
KtExpression expression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext);
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor);
result.addField((KtDelegatorByExpressionSpecifier) specifier, propertyDescriptor);
}
else {
KotlinType expressionType = expression != null ? bindingContext.getType(expression) : null;
Type asmType =
expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(getSuperClass(specifier));
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, "$delegate_" + n);
result.addField((KtDelegatorByExpressionSpecifier) specifier, asmType, "$delegate_" + n);
}
n++;
}
@@ -1183,14 +1196,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@NotNull
private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) {
return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
private ClassDescriptor getSuperClass(@NotNull KtDelegationSpecifier specifier) {
return CodegenUtil.getSuperClassByDelegationSpecifier(specifier, bindingContext);
}
private void genCallToDelegatorByExpressionSpecifier(
InstructionAdapter iv,
ExpressionCodegen codegen,
KtDelegatedSuperTypeEntry specifier,
KtDelegatorByExpressionSpecifier specifier,
DelegationFieldsInfo fieldsInfo
) {
KtExpression expression = specifier.getDelegateExpression();
@@ -1235,7 +1248,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private void lookupReceiver(@Nullable ReceiverValue value) {
private void lookupReceiver(@NotNull ReceiverValue value) {
if (value instanceof ImplicitReceiver) {
if (value instanceof ExtensionReceiver) {
ReceiverParameterDescriptor parameter =
@@ -1290,9 +1303,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
KtExpression delegateExpression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
assert delegateExpression != null;
delegateExpression.accept(visitor);
}
@@ -1318,7 +1331,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateTraitMethods() {
if (isInterface(descriptor)) return;
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getTraitMethods(descriptor).entrySet()) {
FunctionDescriptor traitFun = entry.getKey();
//skip java 8 default methods
if (!(traitFun instanceof JavaCallableMemberDescriptor)) {
@@ -1546,7 +1559,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void reorderArgumentsIfNeeded(@NotNull List<ArgumentAndDeclIndex> args) {
protected void reorderArgumentsIfNeeded(@NotNull List<? extends ArgumentAndDeclIndex> args) {
}
}
@@ -1558,8 +1571,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (KtEnumEntry enumEntry : enumEntries) {
ClassDescriptor descriptor = getNotNull(bindingContext, BindingContext.CLASS, enumEntry);
int isDeprecated = KotlinBuiltIns.isDeprecated(descriptor) ? ACC_DEPRECATED : 0;
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL | isDeprecated,
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(enumEntry, descriptor), ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL,
descriptor.getName().asString(), classAsmType.getDescriptor(), null, null);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(descriptor, null);
}
@@ -1607,7 +1619,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.aconst(enumEntry.getName());
iv.iconst(ordinal);
List<KtSuperTypeListEntry> delegationSpecifiers = enumEntry.getSuperTypeListEntries();
List<KtDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
if (delegationSpecifiers.size() == 1 && !enumEntryNeedSubclass(bindingContext, enumEntry)) {
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(delegationSpecifiers.get(0), bindingContext);
@@ -1625,11 +1637,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generateDelegates(DelegationFieldsInfo delegationFieldsInfo) {
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatedSuperTypeEntry) specifier);
for (KtDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
if (specifier instanceof KtDelegatorByExpressionSpecifier) {
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatorByExpressionSpecifier) specifier);
generateDelegateField(field);
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
KtExpression delegateExpression = ((KtDelegatorByExpressionSpecifier) specifier).getDelegateExpression();
KotlinType delegateExpressionType = delegateExpression != null ? bindingContext.getType(delegateExpression) : null;
generateDelegates(getSuperClass(specifier), delegateExpressionType, field);
}

View File

@@ -32,9 +32,9 @@ public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
if (call != null) {
val callElement = call.getCall().getCallElement()
if (processingFunctions.contains(callElement)) {
val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement }
val cycle = processingFunctions.asSequence().dropWhile { it.getKey() != callElement }
cycle.forEach {
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.key, it.value))
diagnostics.report(Errors.INLINE_CALL_CYCLE.on(it.getKey(), it.getValue()))
}
return false
}

View File

@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_INTERFACE_DEFAULT_IMPLS
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.name.Name
@@ -62,7 +63,7 @@ public class InterfaceImplBodyCodegen(
if (DescriptorUtils.isLocal(descriptor)) return null
val classDescriptorImpl = ClassDescriptorImpl(
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE)
Modality.FINAL, Collections.emptyList(), SourceElement.NO_SOURCE)
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
return classDescriptorImpl
@@ -102,8 +103,6 @@ public class InterfaceImplBodyCodegen(
}
}
}
generateSyntheticAccessors()
}
private fun generateDelegationToSuperTraitImpl(descriptor: FunctionDescriptor, implementation: FunctionDescriptor) {
@@ -123,7 +122,7 @@ public class InterfaceImplBodyCodegen(
val myParameters = signature.getValueParameters()
val calleeParameters = method.getValueParameters()
if (myParameters.size != calleeParameters.size) {
if (myParameters.size() != calleeParameters.size()) {
throw AssertionError(
"Method from super interface has a different signature.\n" +
"This method:\n%s\n%s\n%s\nSuper method:\n%s\n%s\n%s".format(
@@ -150,7 +149,9 @@ public class InterfaceImplBodyCodegen(
override fun generateKotlinAnnotation() {
(v as InterfaceImplClassBuilder).stopCounting()
v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true).visitEnd()
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
av.visitEnd()
AsmUtil.writeKotlinSyntheticClassAnnotation(v, state)
}

View File

@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.collections.CollectionsKt;
import kotlin.text.StringsKt;
import kotlin.CollectionsKt;
import kotlin.StringsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -50,7 +50,6 @@ 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.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
public class JvmCodegenUtil {
@@ -131,21 +130,16 @@ public class JvmCodegenUtil {
);
}
public static boolean isConstOrHasJvmFieldAnnotation(@NotNull PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.isConst() || hasJvmFieldAnnotation(propertyDescriptor);
}
public static boolean couldUseDirectAccessToProperty(
@NotNull PropertyDescriptor property,
boolean forGetter,
boolean isDelegated,
@NotNull MethodContext contextBeforeInline
@NotNull MethodContext context
) {
if (JetTypeMapper.isAccessor(property)) return false;
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();
// Inline functions can't use direct access because a field may not be visible at the call site
if (context.isInlineMethodContext()) {
if (context.isInlineFunction()) {
return false;
}
@@ -170,7 +164,7 @@ public class JvmCodegenUtil {
return Visibilities.isPrivate(property.getVisibility()) || accessor.getModality() == FINAL;
}
private static boolean isDebuggerContext(@NotNull CodegenContext context) {
private static boolean isDebuggerContext(@NotNull MethodContext context) {
KtFile file = DescriptorToSourceUtils.getContainingFile(context.getContextDescriptor());
return file != null && CodeFragmentUtilKt.getSuppressDiagnosticsInDebugMode(file);
}
@@ -224,6 +218,9 @@ public class JvmCodegenUtil {
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, 32);
}
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {

View File

@@ -40,7 +40,7 @@ public class JvmRuntimeTypes {
public JvmRuntimeTypes() {
ModuleDescriptorImpl module = TargetPlatformKt.createModule(
JvmPlatform.INSTANCE,
JvmPlatform.INSTANCE$,
Name.special("<jvm functions impl>"),
LockBasedStorageManager.NO_LOCKS
);

View File

@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement;
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.backend.common.CodegenUtil;
@@ -44,6 +46,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.NotNullLazyValue;
@@ -61,7 +65,8 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.calculateInnerClassAccessFlag
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.kotlin.resolve.BindingContext.VARIABLE;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticDeclaration;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt.Synthetic;
@@ -276,8 +281,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
protected void writeOuterClassAndEnclosingMethod() {
CodegenContext context = this.context.getParentContext();
while (context instanceof InlineLambdaContext) {
while (context instanceof MethodContext && ((MethodContext) context).isInliningLambda()) {
// If this is a lambda which will be inlined, skip its MethodContext and enclosing ClosureContext
//noinspection ConstantConditions
context = context.getParentContext().getParentContext();
@@ -302,7 +306,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
if (outermost instanceof ClassContext) {
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
}
else if (outermost instanceof MultifileClassFacadeContext || outermost instanceof DelegatingToPartContext) {
else if (outermost instanceof DelegatingFacadeContext || outermost instanceof DelegatingToPartContext) {
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
if (implementationOwnerType != null) {
return implementationOwnerType;
@@ -495,23 +499,37 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
iv.dup();
iv.iconst(i);
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
(property.getExtensionReceiverParameter() != null ? 1 : 0);
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
iv.anew(implType);
iv.dup();
// TODO: generate the container once and save to a local field instead (KT-10495)
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
iv.aconst(property.getName().asString());
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
iv.invokespecial(
implType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
);
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
StackValue value;
// TODO: remove this option and always generate PropertyReferenceNImpl creation
if ("true".equalsIgnoreCase(System.getProperty("kotlin.jvm.optimize.delegated.properties"))) {
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
(property.getExtensionReceiverParameter() != null ? 1 : 0);
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
iv.anew(implType);
iv.dup();
// TODO: generate the container once and save to a local field instead
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
iv.aconst(property.getName().asString());
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
iv.invokespecial(
implType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
);
value = StackValue.onStack(implType);
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
}
else {
ReceiverParameterDescriptor dispatchReceiver = property.getDispatchReceiverParameter();
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
//noinspection ConstantConditions
value = createOrGetClInitCodegen().generatePropertyReference(
delegatedProperties.get(i).getDelegate(), property, property,
dispatchReceiver != null ? new TransientReceiver(dispatchReceiver.getType()) : ReceiverValue.NO_RECEIVER
);
}
value.put(K_PROPERTY_TYPE, iv);
iv.astore(K_PROPERTY_TYPE);
}
@@ -550,17 +568,20 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
return sourceMapper;
}
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
v.newField(
JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
fieldAsmType.getDescriptor(), null, null
);
protected void generateConstInstance(
@NotNull Type thisAsmType,
@NotNull Type fieldAsmType,
@NotNull Function1<InstructionAdapter, Unit> initialization
) {
v.newField(JvmDeclarationOriginKt.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());
}
}
@@ -601,7 +622,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
boolean forceField = (JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration())) ||
syntheticBackingField ||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
@@ -652,7 +673,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
}
}
protected StackValue generateMethodCallTo(
private StackValue generateMethodCallTo(
@NotNull FunctionDescriptor functionDescriptor,
@Nullable FunctionDescriptor accessorDescriptor,
@NotNull InstructionAdapter iv
@@ -663,7 +684,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
);
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) && !isInterface(functionDescriptor.getContainingDeclaration());
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor);
int reg = hasDispatchReceiver ? 1 : 0;
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {

View File

@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
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.kotlin.resolve.jvm.diagnostics.OtherOrigin
@@ -51,7 +50,6 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
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 java.util.*
public class MultifileClassCodegen(
@@ -88,18 +86,12 @@ public class MultifileClassCodegen(
val singleSourceFile = if (previouslyCompiledCallables.isNotEmpty()) null else filesWithCallables.singleOrNull()
classBuilder.defineClass(singleSourceFile, Opcodes.V1_6,
if (state.generateOpenMultifileClasses) OPEN_FACADE_CLASS_ATTRIBUTES else FACADE_CLASS_ATTRIBUTES,
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)
}
if (state.generateOpenMultifileClasses) {
generateMultifileFacadeClassConstructor(classBuilder, originFile)
}
classBuilder
}
@@ -156,16 +148,6 @@ public class MultifileClassCodegen(
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null)
}
private fun generateMultifileFacadeClassConstructor(classBuilder: ClassBuilder, originFile: KtFile?) {
val mv = classBuilder.newMethod(JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null)
val v = InstructionAdapter(mv)
v.load(0, facadeClassType)
v.invokespecial("java/lang/Object", "<init>", "()V", false)
v.visitInsn(Opcodes.RETURN)
FunctionCodegen.endVisit(v, "multifile class constructor", originFile)
}
private fun generatePart(
file: KtFile,
generateCallableMemberTasks: MutableMap<CallableMemberDescriptor, () -> Unit>,
@@ -298,7 +280,6 @@ public class MultifileClassCodegen(
companion object {
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL
private val OPEN_FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC
private fun getOnlyPackageFragment(packageFqName: FqName, files: Collection<KtFile>, bindingContext: BindingContext): PackageFragmentDescriptor? {
val fragments = SmartList<PackageFragmentDescriptor>()
@@ -312,7 +293,7 @@ public class MultifileClassCodegen(
fragments.add(fragment)
}
}
if (fragments.size > 1) {
if (fragments.size() > 1) {
throw IllegalStateException("More than one package fragment, files: $files | fragments: $fragments")
}
return fragments.firstOrNull()

View File

@@ -154,7 +154,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
this.typeConstructor = TypeConstructorImpl.createForClass(
this,
Annotations.Companion.getEMPTY(),
ModalityKt.isFinalClass(this),
!getModality().isOverridable(),
getName().asString(),
typeParameters,
supertypes

View File

@@ -54,14 +54,10 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -101,7 +97,7 @@ public class PropertyCodegen {
}
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
assert context instanceof MultifileClassFacadeContext : "should be called only for generating facade: " + context;
assert context instanceof DelegatingFacadeContext : "should be called only for generating facade: " + context;
gen(null, deserializedProperty, null, null);
}
@@ -114,6 +110,11 @@ public class PropertyCodegen {
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
: "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 (CodegenContextUtil.isImplClassOwner(context)) {
assert declaration != null : "Declaration is null for different context: " + context;
@@ -126,6 +127,8 @@ public class PropertyCodegen {
if (isAccessorNeeded(declaration, descriptor, setter)) {
generateSetter(declaration, descriptor, setter);
}
context.recordSyntheticAccessorIfNeeded(descriptor, bindingContext);
}
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
@@ -154,7 +157,7 @@ public class PropertyCodegen {
@NotNull PropertyDescriptor descriptor,
@Nullable KtPropertyAccessor accessor
) {
if (isConstOrHasJvmFieldAnnotation(descriptor)) return false;
if (hasJvmFieldAnnotation(descriptor)) return false;
boolean isDefaultAccessor = accessor == null || !accessor.hasBody();
@@ -264,6 +267,10 @@ public class PropertyCodegen {
mv.visitInsn(Opcodes.RETURN);
mv.visitEnd();
}
else {
Type tImplType = typeMapper.mapDefaultImpls((ClassDescriptor) context.getContextDescriptor());
v.getSerializationBindings().put(IMPL_CLASS_NAME_FOR_CALLABLE, descriptor, shortNameByAsmType(tImplType));
}
if (kind != OwnerKind.DEFAULT_IMPLS) {
v.getSerializationBindings().put(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor, new Method(name, desc));
@@ -302,17 +309,46 @@ public class PropertyCodegen {
ClassBuilder builder = v;
boolean hasJvmFieldAnnotation = hasJvmFieldAnnotation(propertyDescriptor);
FieldOwnerContext backingFieldContext = context;
boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst();
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
modifiers |= ACC_STATIC;
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
if (takeVisibilityFromDescriptor) {
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
}
else if (hasJvmFieldAnnotation && !isDelegate) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else {
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
}
if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
builder = codegen.v;
backingFieldContext = codegen.context;
v.getSerializationBindings().put(STATIC_FIELD_IN_OUTER_CLASS, propertyDescriptor);
}
if (isObject(propertyDescriptor.getContainingDeclaration()) &&
!hasJvmFieldAnnotation &&
!propertyDescriptor.isConst() &&
(modifiers & ACC_PRIVATE) == 0) {
modifiers |= ACC_DEPRECATED;
}
}
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
else if (takeVisibilityFromDescriptor) {
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
}
else if (!isDelegate && hasJvmFieldAnnotation) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else {
modifiers |= ACC_PRIVATE;
}
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
@@ -324,7 +360,7 @@ public class PropertyCodegen {
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, Pair.create(type, name));
FieldVisitor fv = builder.newField(JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
typeMapper.mapFieldSignature(jetType, propertyDescriptor), defaultValue);
typeMapper.mapFieldSignature(jetType), defaultValue);
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD);

View File

@@ -28,11 +28,11 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
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.ReceiverValue
import org.jetbrains.kotlin.utils.sure
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
@@ -45,13 +45,14 @@ public class PropertyReferenceCodegen(
context: ClassContext,
expression: KtElement,
classBuilder: ClassBuilder,
resolvedCall: ResolvedCall<*>
private val classDescriptor: ClassDescriptor,
private val target: VariableDescriptor,
dispatchReceiver: ReceiverValue
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
private val classDescriptor = context.contextDescriptor
private val asmType = typeMapper.mapClass(classDescriptor)
private val target = resolvedCall.resultingDescriptor as VariableDescriptor
private val dispatchReceiverType = resolvedCall.dispatchReceiver?.type
private val dispatchReceiverType = if (dispatchReceiver.exists()) dispatchReceiver.type else null
private val extensionReceiverType = target.extensionReceiverParameter?.type
private val receiverCount =
@@ -79,7 +80,11 @@ public class PropertyReferenceCodegen(
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
override fun generateBody() {
generateConstInstance(asmType, wrapperMethod.getReturnType())
generateConstInstance(asmType, wrapperMethod.getReturnType()) { iv ->
if (!"true".equals(System.getProperty("kotlin.jvm.optimize.callable.references"), ignoreCase = true)) {
iv.invokestatic(REFLECTION, wrapperMethod.getName(), wrapperMethod.getDescriptor(), false)
}
}
generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) {
load(0, OBJECT_TYPE)

View File

@@ -70,7 +70,6 @@ public class SamWrapperCodegen {
samType.getJavaClassDescriptor().getContainingDeclaration(),
fqName.shortName(),
Modality.FINAL,
ClassKind.CLASS,
Collections.singleton(samType.getType()),
SourceElement.NO_SOURCE
);

View File

@@ -67,7 +67,7 @@ public abstract class SignatureCollectingClassBuilderFactory(
override fun done() {
for ((signature, elementsAndDescriptors) in signatures.entrySet()) {
if (elementsAndDescriptors.size == 1) continue // no clash
if (elementsAndDescriptors.size() == 1) continue // no clash
handleClashingSignatures(ConflictingJvmDeclarationsData(
classInternalName,
classCreatedFor,

View File

@@ -17,13 +17,12 @@
package org.jetbrains.kotlin.codegen;
import com.intellij.psi.tree.IElementType;
import kotlin.collections.ArraysKt;
import kotlin.ArraysKt;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
@@ -46,7 +45,6 @@ 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.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -504,19 +502,19 @@ public abstract class StackValue {
}
ReceiverValue callExtensionReceiver = (ReceiverValue) resolvedCall.getExtensionReceiver();
if (callDispatchReceiver != null || callExtensionReceiver != null
if (callDispatchReceiver.exists() || callExtensionReceiver.exists()
|| isLocalFunCall(callableMethod) || isCallToMemberObjectImportedByName(resolvedCall)) {
ReceiverParameterDescriptor dispatchReceiverParameter = descriptor.getDispatchReceiverParameter();
ReceiverParameterDescriptor extensionReceiverParameter = descriptor.getExtensionReceiverParameter();
if (descriptor.getOriginal() instanceof SamAdapterExtensionFunctionDescriptor) {
callDispatchReceiver = callExtensionReceiver;
callExtensionReceiver = null;
callExtensionReceiver = ReceiverValue.NO_RECEIVER;
dispatchReceiverParameter = extensionReceiverParameter;
extensionReceiverParameter = null;
}
boolean hasExtensionReceiver = callExtensionReceiver != null;
boolean hasExtensionReceiver = callExtensionReceiver.exists();
StackValue dispatchReceiver = platformStaticCallIfPresent(
genReceiver(hasExtensionReceiver ? none() : receiver, codegen, resolvedCall, callableMethod, callDispatchReceiver, false),
descriptor
@@ -534,11 +532,11 @@ public abstract class StackValue {
@NotNull ExpressionCodegen codegen,
@NotNull ResolvedCall resolvedCall,
@Nullable Callable callableMethod,
@Nullable ReceiverValue receiverValue,
ReceiverValue receiverValue,
boolean isExtension
) {
if (receiver == none()) {
if (receiverValue != null) {
if (receiverValue.exists()) {
return codegen.generateReceiverValue(receiverValue, false);
}
else if (isLocalFunCall(callableMethod) && !isExtension) {
@@ -550,7 +548,7 @@ public abstract class StackValue {
return singleton(((ImportedFromObjectCallableDescriptor) resolvedCall.getResultingDescriptor()).getContainingObject(), codegen.typeMapper);
}
}
else if (receiverValue != null) {
else if (receiverValue.exists()) {
return receiver;
}
return none();
@@ -599,7 +597,11 @@ public abstract class StackValue {
}
public static Field singletonViaInstance(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper), none());
return field(FieldInfo.createSingletonViaInstance(classDescriptor, typeMapper, false), none());
}
public static Field oldSingleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) {
return field(FieldInfo.createForSingleton(classDescriptor, typeMapper, true), none());
}
public static StackValue operation(Type type, Function1<InstructionAdapter, Unit> lambda) {
@@ -832,7 +834,7 @@ public abstract class StackValue {
ReceiverValue receiverParameter = (ReceiverValue) resolvedGetCall.getExtensionReceiver();
int receiverIndex = -1;
if (receiverParameter != null) {
if (receiverParameter.exists()) {
Type type = codegen.typeMapper.mapType(receiverParameter.getType());
receiverIndex = frame.enterTemp(type);
v.store(receiverIndex, type);
@@ -840,7 +842,7 @@ public abstract class StackValue {
ReceiverValue dispatchReceiver = resolvedGetCall.getDispatchReceiver();
int thisIndex = -1;
if (dispatchReceiver != null) {
if (dispatchReceiver.exists()) {
thisIndex = frame.enterTemp(OBJECT_TYPE);
v.store(thisIndex, OBJECT_TYPE);
}
@@ -861,14 +863,14 @@ public abstract class StackValue {
throw new UnsupportedOperationException();
}
if (resolvedSetCall.getDispatchReceiver() != null) {
if (resolvedSetCall.getExtensionReceiver() != null) {
if (resolvedSetCall.getDispatchReceiver().exists()) {
if (resolvedSetCall.getExtensionReceiver().exists()) {
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, v);
}
v.load(realReceiverIndex, realReceiverType);
}
else {
if (resolvedSetCall.getExtensionReceiver() != null) {
if (resolvedSetCall.getExtensionReceiver().exists()) {
v.load(realReceiverIndex, realReceiverType);
}
else {
@@ -968,8 +970,8 @@ public abstract class StackValue {
}
}
if (call.getDispatchReceiver() != null) {
if (call.getExtensionReceiver() != null) {
if (call.getDispatchReceiver().exists()) {
if (call.getExtensionReceiver().exists()) {
return false;
}
}
@@ -1088,12 +1090,6 @@ public abstract class StackValue {
else {
getter.genInvokeInstruction(v);
coerce(getter.getReturnType(), type, v);
KotlinType returnType = descriptor.getReturnType();
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
v.aconst(null);
v.athrow();
}
}
}

View File

@@ -98,7 +98,6 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
correctContainerForLambda(callableDescriptor, element),
Name.special("<closure-" + simpleName + ">"),
Modality.FINAL,
ClassKind.CLASS,
supertypes,
KotlinSourceElementKt.toSourceElement(element)
);
@@ -129,7 +128,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
if (element instanceof KtObjectDeclaration &&
element.getParent() instanceof KtObjectLiteralExpression &&
child instanceof KtSuperTypeList) {
child instanceof KtDelegationSpecifierList) {
// If we're passing an anonymous object's super call, it means "container" is ConstructorDescriptor of that object.
// To reach outer context, we should call getContainingDeclaration() twice
// TODO: this is probably not entirely correct, mostly because DECLARATION_TO_DESCRIPTOR can return null
@@ -178,7 +177,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
@Override
public void visitEnumEntry(@NotNull KtEnumEntry enumEntry) {
if (enumEntry.getDeclarations().isEmpty()) {
for (KtSuperTypeListEntry specifier : enumEntry.getSuperTypeListEntries()) {
for (KtDelegationSpecifier specifier : enumEntry.getDelegationSpecifiers()) {
specifier.accept(this);
}
return;
@@ -248,7 +247,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
String name = inventAnonymousClassName();
recordClosure(classDescriptor, name);
KtSuperTypeList delegationSpecifierList = object.getSuperTypeList();
KtDelegationSpecifierList delegationSpecifierList = object.getDelegationSpecifierList();
if (delegationSpecifierList != null) {
delegationSpecifierList.accept(this);
}
@@ -264,8 +263,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
}
@Override
public void visitLambdaExpression(@NotNull KtLambdaExpression lambdaExpression) {
KtFunctionLiteral functionLiteral = lambdaExpression.getFunctionLiteral();
public void visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression) {
KtFunctionLiteral functionLiteral = expression.getFunctionLiteral();
FunctionDescriptor functionDescriptor =
(FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, functionLiteral);
// working around a problem with shallow analysis
@@ -278,7 +277,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
classStack.push(classDescriptor);
nameStack.push(name);
super.visitLambdaExpression(lambdaExpression);
super.visitFunctionLiteralExpression(expression);
nameStack.pop();
classStack.pop();
}
@@ -432,8 +431,8 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
}
@Override
public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
super.visitSuperTypeCallEntry(call);
public void visitDelegationToSuperCallSpecifier(@NotNull KtDelegatorToSuperCall call) {
super.visitDelegationToSuperCallSpecifier(call);
checkSamCall(call);
}

View File

@@ -61,9 +61,6 @@ public final class PsiCodegenPredictor {
// TODO: Method won't work for declarations inside companion objects
// TODO: Method won't give correct class name for traits implementations
if (declaration instanceof KtPropertyAccessor) {
return getPredefinedJvmInternalName(((KtPropertyAccessor) declaration).getProperty(), fileClassesProvider);
}
KtDeclaration parentDeclaration = KtStubbedPsiUtil.getContainingDeclaration(declaration);
String parentInternalName;
@@ -76,8 +73,8 @@ public final class PsiCodegenPredictor {
else {
KtFile containingFile = declaration.getContainingKtFile();
if (declaration instanceof KtNamedFunction || declaration instanceof KtProperty) {
Name name = ((KtNamedDeclaration) declaration).getNameAsName();
if (declaration instanceof KtNamedFunction) {
Name name = ((KtNamedFunction) declaration).getNameAsName();
return name == null ? null : FileClasses.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
}

View File

@@ -19,20 +19,16 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.bridges.DescriptorBasedFunctionHandle
import org.jetbrains.kotlin.backend.common.bridges.findAllReachableDeclarations
import org.jetbrains.kotlin.backend.common.bridges.findConcreteSuperDeclaration
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.*
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.util.*
@@ -51,7 +47,7 @@ object BuiltinSpecialBridgesUtil {
val functionHandle = DescriptorBasedFunctionHandle(function)
val fake = !functionHandle.isDeclaration
val overriddenBuiltin = function.getOverriddenBuiltinReflectingJvmDescriptor()!!
val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmDescriptor()!!
val reachableDeclarations = findAllReachableDeclarations(function)
@@ -99,7 +95,7 @@ object BuiltinSpecialBridgesUtil {
): Boolean {
if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false
val builtin = getOverriddenBuiltinReflectingJvmDescriptor()!!
val builtin = getOverriddenBuiltinWithDifferentJvmDescriptor()!!
return signatureByDescriptor(this) == signatureByDescriptor(builtin)
}
}
@@ -134,7 +130,7 @@ private fun <Signature> needGenerateSpecialBridge(
|| originalOverridden.containingDeclaration is JavaClassDescriptor
|| DescriptorUtils.isInterface(originalOverridden.containingDeclaration)) return@firstOverridden false
val overriddenSpecial = originalOverridden.getOverriddenBuiltinReflectingJvmDescriptor()?.original ?: return@firstOverridden false
val overriddenSpecial = originalOverridden.getOverriddenBuiltinWithDifferentJvmDescriptor()?.original ?: return@firstOverridden false
signatureByDescriptor(originalOverridden) != signatureByDescriptor(overriddenSpecial)
} != null) return false
@@ -153,7 +149,12 @@ public fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
if (KtPsiUtil.deparenthesize(argumentExpression) !== element) return false
val candidateDescriptor = parentCall.getResolvedCall(bindingContext)?.candidateDescriptor as CallableMemberDescriptor?
?: return false
?: return false
return candidateDescriptor.getSpecialSignatureInfo()?.isObjectReplacedWithTypeParameter ?: false
if (candidateDescriptor.getSpecialSignatureInfo() == BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo.GENERIC_PARAMETER) {
return true
}
return false
}

View File

@@ -47,7 +47,7 @@ private fun List<PackageParts>.addCompiledParts(state: GenerationState): List<Pa
mapping.findPackageParts(qualifier)?.run { parts.remove(name) }
}
return (this + mapping.packageFqName2Parts.values)
return (this + mapping.packageFqName2Parts.values())
.groupBy { it.packageFqName }
.map {
val (packageFqName, packageParts) = it

View File

@@ -17,29 +17,16 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
fun generateIsCheck(
v: InstructionAdapter,
kotlinType: KotlinType,
asmType: Type
type: KotlinType,
generateInstanceOfInstruction: (InstructionAdapter) -> Unit
) {
if (TypeUtils.isNullableType(kotlinType)) {
if (type.isMarkedNullable) {
val nope = Label()
val end = Label()
@@ -48,8 +35,7 @@ fun generateIsCheck(
ifnull(nope)
TypeIntrinsics.instanceOf(this, kotlinType, asmType)
generateInstanceOfInstruction(this)
goTo(end)
mark(nope)
@@ -60,69 +46,6 @@ fun generateIsCheck(
}
}
else {
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
generateInstanceOfInstruction(v)
}
}
fun generateAsCast(
v: InstructionAdapter,
kotlinType: KotlinType,
asmType: Type,
isSafe: Boolean
) {
if (!isSafe) {
if (!TypeUtils.isNullableType(kotlinType)) {
generateNullCheckForNonSafeAs(v, kotlinType)
}
}
else {
with(v) {
dup()
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
val ok = Label()
ifne(ok)
pop()
aconst(null)
mark(ok)
}
}
TypeIntrinsics.checkcast(v, kotlinType, asmType, isSafe)
}
private fun generateNullCheckForNonSafeAs(
v: InstructionAdapter,
type: KotlinType
) {
with(v) {
dup()
val nonnull = Label()
ifnonnull(nonnull)
AsmUtil.genThrow(v, "kotlin/TypeCastException", "null cannot be cast to non-null type " + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type))
mark(nonnull)
}
}
public fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }
fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) {
val descriptor = state.bindingContext.get(BindingContext.CLASS, companion)
if (descriptor == null || ErrorUtils.isError(descriptor)) {
return
}
if (!JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
return
}
val properties = companion.declarations.filterIsInstance<KtProperty>()
properties.forEach {
val variableDescriptor = state.bindingContext.get(BindingContext.VARIABLE, it)
if (variableDescriptor is PropertyDescriptor) {
outerContext.getFieldName(variableDescriptor, it.hasDelegate())
}
}
}

View File

@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen.context;
import kotlin.jvm.functions.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -28,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.storage.NullableLazyValue;
@@ -37,7 +37,7 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
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;
@@ -267,10 +267,6 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return new MultifileClassFacadeContext(descriptor, this, multifileClassType, filePartType);
}
public ClassContext intoDefaultImplsClass(ClassDescriptor descriptor, ClassContext interfaceContext, GenerationState state) {
return new DefaultImplsClassContext(state.getTypeMapper(), descriptor, OwnerKind.DEFAULT_IMPLS, this, null, interfaceContext);
}
@NotNull
public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) {
if (descriptor.isCompanionObject()) {
@@ -283,7 +279,11 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
ClassContext classContext = new ClassContext(state.getTypeMapper(), descriptor, kind, this, null);
if (descriptor.getCompanionObjectDescriptor() != null) {
//We can't call descriptor.getCompanionObjectDescriptor() on light class generation
// because it triggers companion light class generation via putting it to BindingContext.CLASS
// (so MemberCodegen doesn't skip it in genClassOrObject).
if (state.getTypeMapper().getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES &&
descriptor.getCompanionObjectDescriptor() != null) {
//We need to create companion object context ahead of time
// because otherwise we can't generate synthetic accessor for private members in companion object
classContext.intoClass(descriptor.getCompanionObjectDescriptor(), OwnerKind.IMPLEMENTATION, state);
@@ -298,12 +298,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull
public MethodContext intoFunction(FunctionDescriptor descriptor) {
return new MethodContext(descriptor, getContextKind(), this, null);
return new MethodContext(descriptor, getContextKind(), this, null, false);
}
@NotNull
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor, boolean isCrossInline) {
return new InlineLambdaContext(descriptor, getContextKind(), this, null, isCrossInline);
public MethodContext intoInlinedLambda(FunctionDescriptor descriptor) {
return new MethodContext(descriptor, getContextKind(), this, null, true);
}
@NotNull
@@ -365,24 +365,11 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
private <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallTarget);
}
@SuppressWarnings("unchecked")
@NotNull
public <D extends CallableMemberDescriptor> D getAccessorForSuperCallIfNeeded(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
if (superCallTarget != null && !isJvmInterface(descriptor.getContainingDeclaration())) {
CodegenContext afterInline = getFirstCrossInlineOrNonInlineContext();
CodegenContext c = afterInline.findParentContextWithDescriptor(superCallTarget);
assert c != null : "Couldn't find a context for a super-call: " + descriptor;
if (c != afterInline.getParentContext()) {
return (D) c.getAccessor(descriptor, superCallTarget);
}
}
return descriptor;
}
@NotNull
public <D extends CallableMemberDescriptor> D getAccessor(
@NotNull D possiblySubstitutedDescriptor,
@@ -515,27 +502,32 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
@ReadOnly
public Collection<? extends AccessorForCallableDescriptor<?>> getAccessors() {
return accessors == null ? Collections.<AccessorForCallableDescriptor<CallableMemberDescriptor>>emptySet() : accessors.values();
}
@SuppressWarnings("unchecked")
@NotNull
public <D extends CallableMemberDescriptor> D accessibleDescriptor(
@NotNull D descriptor,
@Nullable ClassDescriptor superCallTarget
) {
CodegenContext properContext = getFirstCrossInlineOrNonInlineContext();
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
boolean isInliningContext = properContext.isInlineMethodContext();
boolean isInliningContext = isInlineMethodContext();
if (!isInliningContext && (
!properContext.hasThisDescriptor() ||
enclosing == properContext.getThisDescriptor() ||
enclosing == properContext.getClassOrPackageParentContext().getContextDescriptor())) {
!hasThisDescriptor() ||
enclosing == getThisDescriptor() ||
enclosing == getClassOrPackageParentContext().getContextDescriptor())) {
return descriptor;
}
return (D) properContext.accessibleDescriptorIfNeeded(descriptor, superCallTarget, isInliningContext);
return accessibleDescriptorIfNeeded(descriptor, superCallTarget, isInliningContext);
}
public void recordSyntheticAccessorIfNeeded(@NotNull CallableMemberDescriptor descriptor, @NotNull BindingContext bindingContext) {
if (hasThisDescriptor() && 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, /* superCallTarget = */ null, false);
}
}
@SuppressWarnings("unchecked")
@@ -640,7 +632,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@Nullable
protected CodegenContext findChildContext(@NotNull DeclarationDescriptor child) {
public CodegenContext findChildContext(@NotNull DeclarationDescriptor child) {
return childContexts == null ? null : childContexts.get(child);
}
@@ -648,12 +640,18 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return value instanceof StackValue.Field && ((StackValue.Field) value).isStaticPut;
}
public boolean isInlineMethodContext() {
private boolean isInsideInliningContext() {
CodegenContext current = this;
while (current != null) {
if (current instanceof MethodContext && ((MethodContext) current).isInlineFunction()) {
return true;
}
current = current.getParentContext();
}
return false;
}
@NotNull
public CodegenContext getFirstCrossInlineOrNonInlineContext() {
return this;
private boolean isInlineMethodContext() {
return this instanceof MethodContext && ((MethodContext) this).isInlineFunction();
}
}

View File

@@ -16,18 +16,24 @@
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 MultifileClassFacadeContext -> owner.filePartType
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 MultifileClassFacadeContext
}
owner !is DelegatingFacadeContext
}

View File

@@ -34,7 +34,7 @@ public class ConstructorContext extends MethodContext {
@NotNull CodegenContext parent,
@Nullable MutableClosure closure
) {
super(contextDescriptor, kind, parent, closure);
super(contextDescriptor, kind, parent, closure, false);
}
@Override

View File

@@ -1,44 +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.AccessorForCallableDescriptor
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.state.JetTypeMapper
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
class DefaultImplsClassContext(
typeMapper: JetTypeMapper,
contextDescriptor: ClassDescriptor,
contextKind: OwnerKind,
parentContext: CodegenContext<*>?,
localLookup: ((DeclarationDescriptor) -> Boolean)?,
val interfaceContext: ClassContext
) : ClassContext(typeMapper, contextDescriptor, contextKind, parentContext, localLookup) {
override fun getCompanionObjectContext(): CodegenContext<*>? {
return interfaceContext.companionObjectContext
}
override fun getAccessors(): Collection<AccessorForCallableDescriptor<*>> {
val accessors = super.getAccessors()
val alreadyExistKeys = accessors.map ({ Pair(it.calleeDescriptor, it.superCallTarget) })
val filtered = interfaceContext.accessors.toMapBy({ Pair(it.calleeDescriptor, it.superCallTarget) }, { it }) - alreadyExistKeys
return accessors + filtered.values
}
}

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.renderer
package org.jetbrains.kotlin.codegen.context;
public interface Renderer<in O> {
fun render(obj: O): String
}
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
fun <O> Renderer(block: (O) -> String) = object : Renderer<O> {
override fun render(obj: O) = block(obj)
public interface DelegatingFacadeContext {
@Nullable
Type getDelegateToClassType();
}

View File

@@ -1,43 +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.OwnerKind
import org.jetbrains.kotlin.codegen.binding.MutableClosure
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
class InlineLambdaContext(
functionDescriptor: FunctionDescriptor,
contextKind: OwnerKind,
parentContext: CodegenContext<*>,
closure: MutableClosure?,
val isCrossInline: Boolean
) : MethodContext(functionDescriptor, contextKind, parentContext, closure) {
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
if (isCrossInline) return this
val parent = parentContext as? ClosureContext ?:
throw AssertionError("Parent of inlining lambda body should be ClosureContext, but: $parentContext")
val grandParent = parent.parentContext ?:
throw AssertionError("Parent context of lambda class context should exist: $contextDescriptor")
return grandParent.firstCrossInlineOrNonInlineContext
}
}

View File

@@ -32,6 +32,7 @@ import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
private final boolean isInliningLambda;
private Label methodStartLabel;
private Label methodEndLabel;
@@ -43,10 +44,12 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
@NotNull FunctionDescriptor functionDescriptor,
@NotNull OwnerKind contextKind,
@NotNull CodegenContext parentContext,
@Nullable MutableClosure closure
@Nullable MutableClosure closure,
boolean isInliningLambda
) {
super(JvmCodegenUtil.getDirectMember(functionDescriptor), contextKind, parentContext, closure,
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null);
this.isInliningLambda = isInliningLambda;
this.functionDescriptor = functionDescriptor;
}
@@ -114,10 +117,14 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
return "Method: " + getContextDescriptor();
}
public boolean isInlineMethodContext() {
public boolean isInlineFunction() {
return InlineUtil.isInline(getContextDescriptor());
}
public boolean isInliningLambda() {
return isInliningLambda;
}
@NotNull
public FunctionDescriptor getFunctionDescriptor() {
return functionDescriptor;

View File

@@ -16,10 +16,11 @@
package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassFacadeContext extends MultifileClassContextBase {
public class MultifileClassFacadeContext extends MultifileClassContextBase implements DelegatingFacadeContext {
public MultifileClassFacadeContext(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
@@ -28,4 +29,10 @@ public class MultifileClassFacadeContext extends MultifileClassContextBase {
) {
super(descriptor, parent, multifileClassType, filePartType);
}
@Nullable
@Override
public Type getDelegateToClassType() {
return getFilePartType();
}
}

View File

@@ -25,7 +25,7 @@ import org.jetbrains.org.objectweb.asm.Type;
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> implements DelegatingToPartContext, FacadePartWithSourceFile {
private final Type packagePartType;
private final KtFile sourceFile;
@Nullable private KtFile sourceFile;
public PackageContext(
@NotNull PackageFragmentDescriptor contextDescriptor,

View File

@@ -0,0 +1,55 @@
/*
* 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.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.org.objectweb.asm.Type;
public class PackageFacadeContext extends PackageContext implements DelegatingFacadeContext {
private final Type publicFacadeType;
public PackageFacadeContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@NotNull Type packagePartType
) {
this(contextDescriptor, parent, packagePartType, packagePartType);
}
public PackageFacadeContext(
@NotNull PackageFragmentDescriptor contextDescriptor,
@NotNull CodegenContext parent,
@NotNull Type packagePartType,
@NotNull Type publicFacadeType
) {
super(contextDescriptor, parent, packagePartType, null);
this.publicFacadeType = publicFacadeType;
}
@Override
@Nullable
public Type getDelegateToClassType() {
return getPackagePartType();
}
public Type getPublicFacadeType() {
return publicFacadeType;
}
}

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.codegen.context;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.FieldInfo;

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen.inline;
import com.intellij.openapi.util.Pair;
import com.intellij.util.ArrayUtil;
import kotlin.jvm.functions.Function0;
import org.jetbrains.annotations.NotNull;
@@ -27,7 +28,10 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.tree.*;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode;
import java.util.*;
@@ -62,6 +66,8 @@ public class AnonymousObjectTransformer {
private final Map<String, List<String>> fieldNames = new HashMap<String, List<String>>();
private final TypeRemapper typeRemapper;
public AnonymousObjectTransformer(
@NotNull String objectInternalName,
@NotNull InliningContext inliningContext,
@@ -76,20 +82,18 @@ public class AnonymousObjectTransformer {
this.newLambdaType = newLambdaType;
reader = InlineCodegenUtil.buildClassReaderByInternalName(state, objectInternalName);
typeRemapper = new TypeRemapper(inliningContext.typeMapping);
transformationResult = InlineResult.create();
}
@NotNull
public InlineResult doTransform(@NotNull AnonymousObjectGeneration anonymousObjectGen, @NotNull FieldRemapper parentRemapper) {
final List<InnerClassNode> innerClassNodes = new ArrayList<InnerClassNode>();
ClassBuilder classBuilder = createClassBuilder();
final List<MethodNode> methodsToTransform = new ArrayList<MethodNode>();
reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version);
if (signature != null) {
ReifiedTypeInliner.SignatureReificationResult signatureResult = inliningContext.reifedTypeInliner.reifySignature(signature);
signature = signatureResult.getNewSignature();
@@ -98,11 +102,6 @@ public class AnonymousObjectTransformer {
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) {
innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access));
}
@Override
public void visitOuterClass(@NotNull String owner, String name, String desc) {
InliningContext parent = inliningContext.getParent();
@@ -164,7 +163,7 @@ public class AnonymousObjectTransformer {
}
else {
//seems we can't do any clever mapping cause we don't know any about original class name
sourceMapper = IdenticalSourceMapper.INSTANCE;
sourceMapper = IdenticalSourceMapper.INSTANCE$;
}
if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) {
classBuilder.visitSource(sourceInfo, debugInfo);
@@ -174,7 +173,7 @@ public class AnonymousObjectTransformer {
if (sourceInfo != null) {
classBuilder.visitSource(sourceInfo, debugInfo);
}
sourceMapper = IdenticalSourceMapper.INSTANCE;
sourceMapper = IdenticalSourceMapper.INSTANCE$;
}
ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder();
@@ -182,7 +181,7 @@ public class AnonymousObjectTransformer {
List<CapturedParamInfo> additionalFakeParams =
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder,
anonymousObjectGen, parentRemapper);
List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();
List<MethodVisitor> deferringMethods = new ArrayList();
for (MethodNode next : methodsToTransform) {
MethodVisitor deferringVisitor = newMethod(classBuilder, next);
@@ -194,7 +193,7 @@ public class AnonymousObjectTransformer {
String oldFunReturnType = returnType.getInternalName();
String newFunReturnType = funResult.getChangedTypes().get(oldFunReturnType);
if (newFunReturnType != null) {
inliningContext.typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
}
}
deferringMethods.add(deferringVisitor);
@@ -208,10 +207,6 @@ public class AnonymousObjectTransformer {
SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder);
for (InnerClassNode node : innerClassNodes) {
classBuilder.getVisitor().visitInnerClass(node.name, node.outerName, node.innerName, node.access);
}
classBuilder.done();
anonymousObjectGen.setNewLambdaType(newLambdaType);
@@ -242,7 +237,7 @@ public class AnonymousObjectTransformer {
@NotNull ParametersBuilder capturedBuilder,
boolean isConstructor
) {
ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode);
ReifiedTypeParametersUsages typeParametersToReify = inliningContext.reifedTypeInliner.reifyInstructions(sourceNode.instructions);
Parameters parameters = isConstructor ? capturedBuilder.buildParameters() : getMethodParametersWithCaptured(capturedBuilder, sourceNode);
RegeneratedLambdaFieldRemapper remapper =
@@ -350,7 +345,7 @@ public class AnonymousObjectTransformer {
@NotNull
private ClassBuilder createClassBuilder() {
ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
return new RemappingClassBuilder(classBuilder, inliningContext.typeRemapper);
return new RemappingClassBuilder(classBuilder, typeRemapper);
}
@NotNull

View File

@@ -33,11 +33,9 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents;
import org.jetbrains.kotlin.modules.TargetId;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
@@ -193,15 +191,11 @@ public class InlineCodegen extends CallGenerator {
JetTypeMapper.ContainingClassesInfo containingClasses = typeMapper.getContainingClassesForDeserializedCallable(
(DeserializedSimpleFunctionDescriptor) functionDescriptor);
ClassId containerId = containingClasses.getImplClassId();
VirtualFile file = InlineCodegenUtil.findVirtualFile(state, containerId);
if (file == null) {
throw new IllegalStateException("Couldn't find declaration file for " + containerId);
}
nodeAndSMAP = InlineCodegenUtil.getMethodNode(
file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(), containingClasses.getFacadeClassId()
);
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable(containingClasses.getImplClassId(), state);
nodeAndSMAP = InlineCodegenUtil.getMethodNode(file.contentsToByteArray(),
asmMethod.getName(),
asmMethod.getDescriptor(),
containingClasses.getFacadeClassId());
if (nodeAndSMAP == null) {
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
@@ -251,7 +245,7 @@ public class InlineCodegen extends CallGenerator {
private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
MethodNode node = nodeAndSmap.getNode();
ReifiedTypeParametersUsages reificationResult = reifiedTypeInliner.reifyInstructions(node);
ReifiedTypeParametersUsages reificationResult = reifiedTypeInliner.reifyInstructions(node.instructions);
generateClosuresBodies();
//through generation captured parameters will be added to invocationParamBuilder
@@ -315,7 +309,7 @@ public class InlineCodegen extends CallGenerator {
MethodContext parentContext = codegen.getContext();
MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor, info.isCrossInline);
MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor);
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(descriptor);
Method asmMethod = jvmMethodSignature.getAsmMethod();
@@ -544,34 +538,26 @@ public class InlineCodegen extends CallGenerator {
}
/*lambda or callable reference*/
public boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
public static boolean isInliningParameter(KtExpression expression, ValueParameterDescriptor valueParameterDescriptor) {
//TODO deparenthisise typed
KtExpression deparenthesized = KtPsiUtil.deparenthesize(expression);
if (deparenthesized instanceof KtCallableReferenceExpression) {
// TODO: support inline of property references passed to inlinable function parameters
SimpleFunctionDescriptor functionReference = state.getBindingContext().get(BindingContext.FUNCTION, deparenthesized);
if (functionReference == null) return false;
}
return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) &&
isInlinableParameterExpression(deparenthesized);
}
protected static boolean isInlinableParameterExpression(KtExpression deparenthesized) {
return deparenthesized instanceof KtLambdaExpression ||
return deparenthesized instanceof KtFunctionLiteralExpression ||
deparenthesized instanceof KtNamedFunction ||
deparenthesized instanceof KtCallableReferenceExpression;
}
public void rememberClosure(KtExpression expression, Type type, ValueParameterDescriptor parameter) {
public void rememberClosure(KtExpression expression, Type type, int parameterIndex) {
KtExpression lambda = KtPsiUtil.deparenthesize(expression);
assert isInlinableParameterExpression(lambda) : "Couldn't find inline expression in " + expression.getText();
LambdaInfo info = new LambdaInfo(lambda, typeMapper);
LambdaInfo info = new LambdaInfo(lambda, typeMapper, parameter.isCrossinline());
ParameterInfo closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.getIndex());
ParameterInfo closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameterIndex);
closureInfo.setLambda(info);
expressionMap.put(closureInfo.getIndex(), info);
}
@@ -644,7 +630,7 @@ public class InlineCodegen extends CallGenerator {
int parameterIndex
) {
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
rememberClosure(argumentExpression, parameterType, valueParameterDescriptor);
rememberClosure(argumentExpression, parameterType, valueParameterDescriptor.getIndex());
}
else {
StackValue value = codegen.gen(argumentExpression);
@@ -792,7 +778,7 @@ public class InlineCodegen extends CallGenerator {
@Override
public void reorderArgumentsIfNeeded(
@NotNull List<ArgumentAndDeclIndex> actualArgsWithDeclIndex, @NotNull List<? extends Type> valueParameterTypes
@NotNull List<? extends ArgumentAndDeclIndex> actualArgsWithDeclIndex, @NotNull List<? extends Type> valueParameterTypes
) {
}

View File

@@ -16,10 +16,11 @@
package org.jetbrains.kotlin.codegen.inline;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.text.StringsKt;
import kotlin.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -28,7 +29,6 @@ import org.jetbrains.kotlin.codegen.MemberCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -75,7 +75,6 @@ public class InlineCodegenUtil {
public static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun";
public static final String INLINE_FUN_VAR_SUFFIX = "$iv";
@Nullable
public static SMAPAndMethodNode getMethodNode(
@@ -91,10 +90,6 @@ public class InlineCodegenUtil {
lines[0] = Integer.MAX_VALUE;
lines[1] = Integer.MIN_VALUE;
cr.accept(new ClassVisitor(API) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
assertVersionNotGreaterThanJava6(version);
}
@Override
public void visitSource(String source, String debug) {
@@ -130,44 +125,40 @@ public class InlineCodegenUtil {
return new SMAPAndMethodNode(node[0], smap);
}
public static void assertVersionNotGreaterThanJava6(int version) {
// TODO: report a proper diagnostic
if (version > Opcodes.V1_6) {
throw new UnsupportedOperationException(
"Cannot inline bytecode of version " + version + ". " +
"This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")"
);
}
}
public static void initDefaultSourceMappingIfNeeded(
@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state
) {
if (!state.isInlineEnabled()) return;
CodegenContext<?> parentContext = context.getParentContext();
while (parentContext != null) {
if (parentContext.isInlineMethodContext()) {
//just init default one to one mapping
codegen.getOrCreateSourceMapper();
break;
public static void initDefaultSourceMappingIfNeeded(@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state) {
if (state.isInlineEnabled()) {
CodegenContext<?> parentContext = context.getParentContext();
while (parentContext != null) {
if (parentContext instanceof MethodContext) {
if (((MethodContext) parentContext).isInlineFunction()) {
//just init default one to one mapping
codegen.getOrCreateSourceMapper();
break;
}
}
parentContext = parentContext.getParentContext();
}
parentContext = parentContext.getParentContext();
}
}
@Nullable
public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) {
return JvmVirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId);
@NotNull
public static VirtualFile getVirtualFileForCallable(@NotNull ClassId containerClassId, @NotNull GenerationState state) {
JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(state.getProject());
VirtualFile file = fileFinder.findVirtualFileWithHeader(containerClassId);
if (file == null) {
throw new IllegalStateException("Couldn't find declaration file for " + containerClassId);
}
return file;
}
@Nullable
public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) {
public static VirtualFile findVirtualFile(@NotNull Project project, @NotNull String internalClassName) {
FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName();
String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName);
JvmVirtualFileFinder fileFinder = JvmVirtualFileFinder.SERVICE.getInstance(project);
//TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file
// we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE
return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
return fileFinder.findVirtualFileWithHeader(new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
}
public static String getInlineName(
@@ -319,7 +310,8 @@ public class InlineCodegenUtil {
}
}
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull InsnList instructions, @NotNull AbstractInsnNode beforeNode) {
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) {
InsnList instructions = to.instructions;
ListIterator<AbstractInsnNode> iterator = from.instructions.iterator();
while (iterator.hasNext()) {
AbstractInsnNode next = iterator.next();
@@ -327,10 +319,6 @@ public class InlineCodegenUtil {
}
}
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) {
insertNodeBefore(from, to.instructions, beforeNode);
}
public static MethodNode createEmptyMethodNode() {
return new MethodNode(API, 0, "fake", "()V", null, null);
@@ -369,9 +357,8 @@ public class InlineCodegenUtil {
OutputFile outputFile = state.getFactory().get(internalName + ".class");
if (outputFile != null) {
return new ClassReader(outputFile.asByteArray());
}
else {
VirtualFile file = findVirtualFileImprecise(state, internalName);
} else {
VirtualFile file = findVirtualFile(state.getProject(), internalName);
if (file == null) {
throw new RuntimeException("Couldn't find virtual file for " + internalName);
}
@@ -407,7 +394,7 @@ public class InlineCodegenUtil {
}
public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) {
return context.isInlineMethodContext() || context instanceof InlineLambdaContext;
return context.isInlineFunction() || context.isInliningLambda();
}
public static int getConstant(AbstractInsnNode ins) {

View File

@@ -35,7 +35,7 @@ public class InliningContext {
public final NameGenerator nameGenerator;
public final TypeRemapper typeRemapper;
public final Map<String, String> typeMapping;
public final ReifiedTypeInliner reifedTypeInliner;
@@ -48,7 +48,7 @@ public class InliningContext {
@NotNull Map<Integer, LambdaInfo> map,
@NotNull GenerationState state,
@NotNull NameGenerator nameGenerator,
@NotNull TypeRemapper typeRemapper,
@NotNull Map<String, String> typeMapping,
@NotNull ReifiedTypeInliner reifedTypeInliner,
boolean isInliningLambda,
boolean classRegeneration
@@ -57,7 +57,7 @@ public class InliningContext {
expressionMap = map;
this.state = state;
this.nameGenerator = nameGenerator;
this.typeRemapper = typeRemapper;
this.typeMapping = typeMapping;
this.reifedTypeInliner = reifedTypeInliner;
this.isInliningLambda = isInliningLambda;
this.classRegeneration = classRegeneration;
@@ -78,12 +78,13 @@ public class InliningContext {
}
public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator,
@NotNull Map<String, String> newTypeMappings,
@NotNull Map<String, String> additionalTypeMappings,
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
) {
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
newTypeMappings.putAll(additionalTypeMappings);
return new RegeneratedClassContext(this, expressionMap, state, generator,
new TypeRemapper(typeRemapper, newTypeMappings),
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
newTypeMappings, reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
}
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
@@ -96,8 +97,10 @@ public class InliningContext {
boolean isInliningLambda,
boolean isRegeneration
) {
Map<String, String> newTypeMappings = new HashMap<String, String>(typeMapping);
newTypeMappings.putAll(additionalTypeMappings);
return new InliningContext(this, expressionMap, state, generator,
new TypeRemapper(typeRemapper, additionalTypeMappings), reifedTypeInliner, isInliningLambda, isRegeneration);
newTypeMappings, reifedTypeInliner, isInliningLambda, isRegeneration);
}
public boolean isRoot() {

View File

@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtLambdaExpression;
import org.jetbrains.kotlin.psi.KtFunctionLiteralExpression;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
@@ -50,8 +50,6 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
private final CalculatedClosure closure;
public final boolean isCrossInline;
private SMAPAndMethodNode node;
private List<CapturedParamDesc> capturedVars;
@@ -62,10 +60,9 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
private final Type closureClassType;
LambdaInfo(@NotNull KtExpression expr, @NotNull JetTypeMapper typeMapper, boolean isCrossInline) {
this.isCrossInline = isCrossInline;
this.expression = expr instanceof KtLambdaExpression ?
((KtLambdaExpression) expr).getFunctionLiteral() : expr;
LambdaInfo(@NotNull KtExpression expr, @NotNull JetTypeMapper typeMapper) {
this.expression = expr instanceof KtFunctionLiteralExpression ?
((KtFunctionLiteralExpression) expr).getFunctionLiteral() : expr;
this.typeMapper = typeMapper;
BindingContext bindingContext = typeMapper.getBindingContext();

View File

@@ -97,6 +97,10 @@ public class LocalVarRemapper {
//add entries only for shifted vars
if (SHIFT == info.status) {
int newIndex = ((StackValue.Local) info.value).index;
if (newIndex != 0 && "this".equals(name)) {
/*skip additional this for now*/
return;
}
mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
}
}

View File

@@ -78,7 +78,7 @@ public class MethodInliner {
public MethodInliner(
@NotNull MethodNode node,
@NotNull Parameters parameters,
@NotNull InliningContext inliningContext,
@NotNull InliningContext parent,
@NotNull FieldRemapper nodeRemapper,
boolean isSameModule,
@NotNull String errorPrefix,
@@ -86,12 +86,12 @@ public class MethodInliner {
) {
this.node = node;
this.parameters = parameters;
this.inliningContext = inliningContext;
this.inliningContext = parent;
this.nodeRemapper = nodeRemapper;
this.isSameModule = isSameModule;
this.errorPrefix = errorPrefix;
this.sourceMapper = sourceMapper;
this.typeMapper = inliningContext.state.getTypeMapper();
this.typeMapper = parent.state.getTypeMapper();
this.result = InlineResult.create();
}
@@ -153,9 +153,8 @@ public class MethodInliner {
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode,
remapper);
new TypeRemapper(currentTypeMapping));
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
@@ -168,7 +167,7 @@ public class MethodInliner {
//TODO: need poping of type but what to do with local funs???
String oldClassName = anonymousObjectGen.getOwnerInternalName();
String newClassName = inliningContext.nameGenerator.genLambdaClassName();
remapper.addMapping(oldClassName, newClassName);
currentTypeMapping.put(oldClassName, newClassName);
AnonymousObjectTransformer transformer =
new AnonymousObjectTransformer(oldClassName,
inliningContext
@@ -262,14 +261,7 @@ public class MethodInliner {
visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor());
}
String newInternalName = anonymousObjectGen.getNewLambdaType().getInternalName();
super.visitMethodInsn(opcode, newInternalName, name, anonymousObjectGen.getNewConstructorDescriptor(), itf);
//TODO: add new inner class also for other contexts
if (inliningContext.getParent() instanceof RegeneratedClassContext) {
inliningContext.getParent().typeRemapper.addAdditionalMappings(anonymousObjectGen.getOwnerInternalName(), newInternalName);
}
super.visitMethodInsn(opcode, anonymousObjectGen.getNewLambdaType().getInternalName(), name, anonymousObjectGen.getNewConstructorDescriptor(), itf);
anonymousObjectGen = null;
} else {
super.visitMethodInsn(opcode, changeOwnerForExternalPackage(owner, opcode), name, desc, itf);
@@ -361,9 +353,7 @@ public class MethodInliner {
@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index
) {
if (isInliningLambda || InlineCodegenUtil.GENERATE_SMAP) {
String varSuffix = inliningContext.isRoot() && !InlineCodegenUtil.isFakeLocalVariableForInline(name) ? INLINE_FUN_VAR_SUFFIX : "";
String varName = !varSuffix.isEmpty() && name.equals("this") ? name + "_" : name;
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index));
super.visitLocalVariable(name, desc, signature, start, end, getNewIndex(index));
}
}
};
@@ -559,7 +549,7 @@ public class MethodInliner {
}
private boolean isAlreadyRegenerated(@NotNull String owner) {
return inliningContext.typeRemapper.hasNoAdditionalMapping(owner);
return inliningContext.typeMapping.containsKey(owner);
}
@Nullable

View File

@@ -54,10 +54,10 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
}
private fun get(index: Int): ParameterInfo {
if (index < real.size) {
if (index < real.size()) {
return real.get(index)
}
return captured.get(index - real.size)
return captured.get(index - real.size())
}
override fun iterator(): Iterator<ParameterInfo> {

View File

@@ -35,18 +35,18 @@ internal class ParametersBuilder private constructor(){
private var nextCaptured = 0
fun addThis(type: Type, skipped: Boolean): ParameterInfo {
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size)
val info = ParameterInfo(type, skipped, nextValueParameterIndex, -1, valueAndHiddenParams.size())
addParameter(info)
return info
}
fun addNextParameter(type: Type, skipped: Boolean, remapValue: StackValue?): ParameterInfo {
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size))
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue, valueAndHiddenParams.size()))
}
fun addNextValueParameter(type: Type, skipped: Boolean, remapValue: StackValue?, parameterIndex: Int): ParameterInfo {
return addParameter(ParameterInfo(type, skipped, nextValueParameterIndex, remapValue,
if (parameterIndex == -1) valueAndHiddenParams.size else { parameterIndex + valueParamStart }))
if (parameterIndex == -1) valueAndHiddenParams.size() else { parameterIndex + valueParamStart }))
}
fun addCapturedParam(
@@ -102,7 +102,7 @@ internal class ParametersBuilder private constructor(){
}
fun markValueParametesStart(){
this.valueParamStart = valueAndHiddenParams.size
this.valueParamStart = valueAndHiddenParams.size()
}
fun listCaptured(): List<CapturedParamInfo> {

View File

@@ -30,12 +30,12 @@ public class RegeneratedClassContext extends InliningContext {
@NotNull Map<Integer, LambdaInfo> map,
@NotNull GenerationState state,
@NotNull NameGenerator nameGenerator,
@NotNull TypeRemapper typeRemapper,
@NotNull Map<String, String> typeMapping,
@NotNull ReifiedTypeInliner reifiedTypeInliner,
boolean isInliningLambda,
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
) {
super(parent, map, state, nameGenerator, typeRemapper, reifiedTypeInliner, isInliningLambda, true);
super(parent, map, state, nameGenerator, typeMapping, reifiedTypeInliner, isInliningLambda, true);
this.anonymousObjectGeneration = anonymousObjectGeneration;
}

View File

@@ -16,40 +16,36 @@
package org.jetbrains.kotlin.codegen.inline
import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.generateAsCast
import org.jetbrains.kotlin.codegen.generateIsCheck
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
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.signature.SignatureReader
import org.jetbrains.org.objectweb.asm.signature.SignatureWriter
import org.jetbrains.org.objectweb.asm.tree.*
private class ParameterNameAndNullability(val name: String, val nullable: Boolean)
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
enum class OperationKind {
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
val id: Int get() = ordinal
val isTypeNullabilityAware: Boolean get() = this == AS || this == IS
}
companion object {
@JvmField
public val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
@JvmField
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
public val NEW_ARRAY_MARKER_METHOD_NAME: String = "reifyNewArray"
public val CHECKCAST_MARKER_METHOD_NAME: String = "reifyCheckcast"
public val SAFE_CHECKCAST_MARKER_METHOD_NAME: String = "reifySafeCheckcast"
public val INSTANCEOF_MARKER_METHOD_NAME: String = "reifyInstanceof"
public val JAVA_CLASS_MARKER_METHOD_NAME: String = "reifyJavaClass"
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME: String = "needClassReification"
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
private val PARAMETRISED_MARKERS = ImmutableSet.of(
NEW_ARRAY_MARKER_METHOD_NAME,
CHECKCAST_MARKER_METHOD_NAME, SAFE_CHECKCAST_MARKER_METHOD_NAME,
INSTANCEOF_MARKER_METHOD_NAME, JAVA_CLASS_MARKER_METHOD_NAME
)
private fun isParametrisedReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { PARAMETRISED_MARKERS.contains(it) }
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
@@ -70,20 +66,16 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
}
}
private var maxStackSize = 0
/**
* @return set of type parameters' identifiers contained in markers that should be reified further
* e.g. when we're generating inline function containing reified T
* and another function containing reifiable parts is inlined into that function
*/
public fun reifyInstructions(node: MethodNode): ReifiedTypeParametersUsages {
public fun reifyInstructions(instructions: InsnList): ReifiedTypeParametersUsages {
if (parametersMapping == null) return ReifiedTypeParametersUsages()
val instructions = node.instructions
maxStackSize = 0
var result = ReifiedTypeParametersUsages()
for (insn in instructions.toArray()) {
if (isOperationReifiedMarker(insn)) {
if (isParametrisedReifiedMarker(insn)) {
val newName: String? = processReifyMarker(insn as MethodInsnNode, instructions)
if (newName != null) {
result.addUsedReifiedParameter(newName)
@@ -91,7 +83,6 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
}
}
node.maxStack = node.maxStack + maxStackSize
return result
}
@@ -136,37 +127,30 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
* or null if it shouldn't
*/
private fun processReifyMarker(insn: MethodInsnNode, instructions: InsnList): String? {
val operationKind = insn.operationKind ?: return null
val parameter = insn.parameterNameAndNullability ?: return null
val mapping = parametersMapping?.get(parameter.name) ?: return null
val kotlinType =
if (operationKind.isTypeNullabilityAware && parameter.nullable)
TypeUtils.makeNullable(mapping.type)
else
mapping.type
val mapping = getTypeParameterMapping(insn) ?: return null
val asmType = mapping.asmType
if (asmType != null) {
val jetType = mapping.type ?: return null
// process* methods return false if marker should be reified further
// or it's invalid (may be emitted explicitly in code)
// they return true if instruction is reified and marker can be deleted
if (when (operationKind) {
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
OperationKind.AS -> processAs(insn, instructions, kotlinType, asmType, safe = false)
OperationKind.SAFE_AS -> processAs(insn, instructions, kotlinType, asmType, safe = true)
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
if (when (insn.name) {
NEW_ARRAY_MARKER_METHOD_NAME -> processNewArray(insn, asmType)
CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = false)
SAFE_CHECKCAST_MARKER_METHOD_NAME -> processCheckcast(insn, instructions, jetType, asmType, safe = true)
INSTANCEOF_MARKER_METHOD_NAME -> processInstanceof(insn, instructions, jetType, asmType)
JAVA_CLASS_MARKER_METHOD_NAME -> processJavaClass(insn, asmType)
else -> false
}) {
instructions.remove(insn.previous.previous!!) // PUSH operation ID
instructions.remove(insn.previous!!) // PUSH type parameter
instructions.remove(insn) // INVOKESTATIC marker method
instructions.remove(insn.getPrevious()!!)
instructions.remove(insn)
}
return null
} else {
val nullableSuffix = if (operationKind.isTypeNullabilityAware && kotlinType.isMarkedNullable) "?" else ""
instructions.set(insn.previous!!, LdcInsnNode(mapping.newName + nullableSuffix))
instructions.set(insn.getPrevious()!!, LdcInsnNode(mapping.newName))
return mapping.newName
}
}
@@ -174,41 +158,17 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
private fun processAs(insn: MethodInsnNode,
instructions: InsnList,
kotlinType: KotlinType,
asmType: Type,
safe: Boolean) =
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
if (stubCheckcast !is TypeInsnNode) return false
val newMethodNode = MethodNode(InlineCodegenUtil.API)
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
instructions.insert(insn, newMethodNode.instructions)
instructions.remove(stubCheckcast)
// TODO: refine max stack calculation (it's not always as big as +4)
maxStackSize = Math.max(maxStackSize, 4)
private fun processCheckcast(insn: MethodInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type, safe: Boolean) =
rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { instanceofInsn: AbstractInsnNode ->
if (instanceofInsn !is TypeInsnNode) return false
TypeIntrinsics.checkcast(instanceofInsn, instructions, jetType, asmType, safe)
return true
}
private fun processIs(insn: MethodInsnNode,
instructions: InsnList,
kotlinType: KotlinType,
asmType: Type) =
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
if (stubInstanceOf !is TypeInsnNode) return false
val newMethodNode = MethodNode(InlineCodegenUtil.API)
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
instructions.insert(insn, newMethodNode.instructions)
instructions.remove(stubInstanceOf)
// TODO: refine max stack calculation (it's not always as big as +2)
maxStackSize = Math.max(maxStackSize, 2)
private fun processInstanceof(insn: MethodInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type) =
rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { instanceofInsn: AbstractInsnNode ->
if (instanceofInsn !is TypeInsnNode) return false
TypeIntrinsics.instanceOf(instanceofInsn, instructions, jetType, asmType)
return true
}
@@ -235,25 +195,19 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
return true
}
}
private fun getParameterName(insn: MethodInsnNode): String? {
val prev = insn.getPrevious()!!
private val MethodInsnNode.parameterNameAndNullability: ParameterNameAndNullability?
get() {
val prev = previous!!
val parameterNameWithFlag = when (prev.opcode) {
return when (prev.getOpcode()) {
Opcodes.LDC -> (prev as LdcInsnNode).cst as String
else -> return null
else -> null
}
val parameterName = if (parameterNameWithFlag.endsWith("?")) parameterNameWithFlag.dropLast(1) else parameterNameWithFlag
return ParameterNameAndNullability(parameterName, parameterName !== parameterNameWithFlag)
}
private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get() =
previous?.previous?.intConstant?.let {
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
private fun getTypeParameterMapping(insn: MethodInsnNode): ReifiedTypeParameterMapping? {
return parametersMapping?.get(getParameterName(insn) ?: return null)
}
}
public class ReifiedTypeParameterMappings() {
private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>()
@@ -262,8 +216,8 @@ public class ReifiedTypeParameterMappings() {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type, asmType, newName = null, signature = signature)
}
public fun addParameterMappingToNewParameter(name: String, type: KotlinType, newName: String) {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type = type, asmType = null, newName = newName, signature = null)
public fun addParameterMappingToNewParameter(name: String, newName: String) {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type = null, asmType = null, newName = newName, signature = null)
}
operator fun get(name: String): ReifiedTypeParameterMapping? {
@@ -272,7 +226,7 @@ public class ReifiedTypeParameterMappings() {
}
public class ReifiedTypeParameterMapping(
val name: String, val type: KotlinType, val asmType: Type?, val newName: String?, val signature: String?
val name: String, val type: KotlinType?, val asmType: Type?, val newName: String?, val signature: String?
)
public class ReifiedTypeParametersUsages {

View File

@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.psi.KtElement;
import java.util.Collections;
import java.util.Map;
public class RootInliningContext extends InliningContext {
@@ -37,7 +38,7 @@ public class RootInliningContext extends InliningContext {
@NotNull String classNameToInline,
@NotNull ReifiedTypeInliner inliner
) {
super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false);
super(null, map, state, nameGenerator, Collections.<String, String>emptyMap(), inliner, false, false);
this.callElement = callElement;
this.startContext = startContext;
this.classNameToInline = classNameToInline;

View File

@@ -202,7 +202,7 @@ public open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val p
private fun createKey(name: String, path: String) = "$name#$path"
override val resultMappings: List<FileMapping>
get() = fileMappings.values.map { it.toFileMapping() }
get() = fileMappings.values().map { it.toFileMapping() }
override fun visitSource(name: String, path: String) {
lastVisited = fileMappings.getOrPut(createKey(name, path), { RawFileMapping(name, path) })

View File

@@ -44,7 +44,7 @@ object SMAPParser {
public fun parse(mappingInfo: String): SMAP {
val fileMappings = linkedMapOf<Int, FileMapping>()
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length()
val lineSectionAnchor = mappingInfo.indexOf(SMAP.LINE_SECTION)
val files = mappingInfo.substring(fileSectionStart, lineSectionAnchor)
@@ -63,7 +63,7 @@ object SMAPParser {
}
val lines = mappingInfo.substring(lineSectionAnchor + SMAP.LINE_SECTION.length, mappingInfo.indexOf(SMAP.END)).trim().split('\n')
val lines = mappingInfo.substring(lineSectionAnchor + SMAP.LINE_SECTION.length(), mappingInfo.indexOf(SMAP.END)).trim().split('\n')
for (lineMapping in lines) {
/*only simple mapping now*/
val targetSplit = lineMapping.indexOf(':')
@@ -79,6 +79,6 @@ object SMAPParser {
fileMappings[fileIndex]!!.addRangeMapping(RangeMapping(originalIndex, targetIndex, range))
}
return SMAP(fileMappings.values.toList())
return SMAP(fileMappings.values().toList())
}
}

View File

@@ -97,5 +97,5 @@ fun <T : IntervalWithHandler> doClustering(blocks: List<T>): List<TryBlockCluste
cluster.blocks.add(block)
}
return clusters.values.toList()
return clusters.values().toList()
}

View File

@@ -23,43 +23,14 @@ import java.util.HashMap;
import java.util.Map;
public class TypeRemapper extends Remapper {
//typeMapping field could be changed outside through method processing
private final Map<String, String> typeMapping;
private Map<String, String> additionalMappings;
//typeMapping field could be changed outside through method processing
private TypeRemapper(@NotNull Map<String, String> typeMapping) {
//typeMapping could be changed outside through method processing
public TypeRemapper(@NotNull Map<String, String> typeMapping) {
this.typeMapping = typeMapping;
}
public TypeRemapper(@NotNull TypeRemapper remapper, @NotNull Map<String, String> newTypeMappings) {
this(createNewAndMerge(remapper, newTypeMappings));
}
public static TypeRemapper createEmpty() {
return new TypeRemapper(new HashMap<String, String>());
}
public static TypeRemapper createFrom(Map<String, String> mappings) {
return new TypeRemapper(mappings);
}
@NotNull
private static Map<String, String> createNewAndMerge(@NotNull TypeRemapper remapper, @NotNull Map<String, String> additionalTypeMappings) {
Map<String, String> map = new HashMap<String, String>(remapper.typeMapping);
map.putAll(additionalTypeMappings);
return map;
}
public void addMapping(String type, String newType) {
typeMapping.put(type, newType);
}
public boolean hasNoAdditionalMapping(String type) {
return typeMapping.containsKey(type);
}
@Override
public String map(String type) {
String newType = typeMapping.get(type);

View File

@@ -31,7 +31,7 @@ public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
val returnType = method.returnType
assert(method.getValueParameters().size == 1)
assert(method.getValueParameters().size() == 1)
val operandType = numberFunctionOperandType(returnType)
val paramType = if (shift()) Type.INT_TYPE else operandType

View File

@@ -17,27 +17,25 @@
package org.jetbrains.kotlin.codegen.intrinsics;
import com.google.common.collect.ImmutableList;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils;
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import java.util.HashMap;
import java.util.Map;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class IntrinsicMethods {
public static final String INTRINSICS_CLASS_NAME = "kotlin/jvm/internal/Intrinsics";
private static final FqName KOTLIN_JVM = new FqName("kotlin.jvm");
/* package */ static final FqNameUnsafe RECEIVER_PARAMETER_FQ_NAME = new FqNameUnsafe("T");
private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus();
private static final IntrinsicMethod UNARY_PLUS = new UnaryPlus();
private static final IntrinsicMethod NUMBER_CAST = new NumberCast();
@@ -57,21 +55,18 @@ public class IntrinsicMethods {
private static final ToString TO_STRING = new ToString();
private static final Clone CLONE = new Clone();
private final Map<String, IntrinsicMethod> namedMethods = new HashMap<String, IntrinsicMethod>();
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
private final IntrinsicsMap intrinsicsMap = new IntrinsicsMap();
public IntrinsicMethods() {
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "javaClass", 0, new JavaClassFunction());
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, new JavaClassProperty());
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.kClass, "java", -1, new KClassJavaProperty());
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorEnter", 1, MonitorInstruction.MONITOR_ENTER);
intrinsicsMap.registerIntrinsic(new FqName("kotlin.jvm.internal.unsafe"), null, "monitorExit", 1, MonitorInstruction.MONITOR_EXIT);
intrinsicsMap.registerIntrinsic(KOTLIN_JVM, KotlinBuiltIns.FQ_NAMES.array, "isArrayOf", 0, new IsArrayOf());
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOf", 1, new JavaClassArray());
// TODO: drop when deprecated kotlin.javaClass property is gone
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, RECEIVER_PARAMETER_FQ_NAME, "javaClass", -1, new JavaClassProperty());
namedMethods.put("kotlin.javaClass.function", new JavaClassFunction());
namedMethods.put("kotlin.javaClass.property", new JavaClassProperty());
namedMethods.put("kotlin.KClass.java.property", new KClassJavaProperty());
namedMethods.put("kotlin.arrays.array", new JavaClassArray());
namedMethods.put("kotlin.jvm.internal.unsafe.monitorEnter", MonitorInstruction.MONITOR_ENTER);
namedMethods.put("kotlin.jvm.internal.unsafe.monitorExit", MonitorInstruction.MONITOR_EXIT);
namedMethods.put("kotlin.jvm.isArrayOf", new IsArrayOf());
ImmutableList<Name> primitiveCastMethods = OperatorConventions.NUMBER_CONVERSIONS.asList();
for (Name method : primitiveCastMethods) {
@@ -99,10 +94,6 @@ public class IntrinsicMethods {
declareIntrinsicFunction(typeName, "equals", 1, EQUALS);
declareIntrinsicFunction(typeName, "hashCode", 0, HASH_CODE);
declareIntrinsicFunction(typeName, "toString", 0, TO_STRING);
intrinsicsMap.registerIntrinsic(
BUILT_INS_PACKAGE_FQ_NAME, null, StringsKt.decapitalize(type.getArrayTypeName().asString()) + "Of", 1, new JavaClassArray()
);
}
declareBinaryOp("plus", IADD);
@@ -182,6 +173,16 @@ public class IntrinsicMethods {
@Nullable
public IntrinsicMethod getIntrinsic(@NotNull CallableMemberDescriptor descriptor) {
return intrinsicsMap.getIntrinsic(descriptor);
IntrinsicMethod intrinsicMethod = intrinsicsMap.getIntrinsic(descriptor);
if (intrinsicMethod != null) {
return intrinsicMethod;
}
String value = CompileTimeConstantUtils.getIntrinsicAnnotationArgument(descriptor);
if (value != null) {
return namedMethods.get(value);
}
return null;
}
}

View File

@@ -19,7 +19,10 @@ package org.jetbrains.kotlin.codegen.intrinsics;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -109,10 +112,6 @@ class IntrinsicsMap {
ClassifierDescriptor classifier = receiverParameter.getType().getConstructor().getDeclarationDescriptor();
if (classifier == null) return null;
if (classifier instanceof TypeParameterDescriptor) {
return IntrinsicMethods.RECEIVER_PARAMETER_FQ_NAME;
}
return DescriptorUtils.getFqName(classifier);
}
}

View File

@@ -32,7 +32,7 @@ class IsArrayOf : IntrinsicMethod() {
val method = typeMapper.mapToCallableMethod(fd, false)
val builtIns = fd.module.builtIns
val elementType = typeArguments.values.first()
val elementType = typeArguments.values().first()
val arrayKtType = builtIns.getArrayType(Variance.INVARIANT, elementType)
val arrayType = typeMapper.mapType(arrayKtType)

View File

@@ -28,9 +28,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class JavaClassFunction : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType()
return object : IntrinsicCallable(getType(Class::class.java), listOf(), null, null) {
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
putJavaLangClassInstance(v, codegen.getState().typeMapper.mapType(javaClass))
}
}

View File

@@ -54,12 +54,12 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
}
return getType(Class::class.java)
return getType(javaClass<Class<Any>>())
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver()!!.getType())
return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) {
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver().getType())
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), classType, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
if (isPrimitive(classType)) {
v.getstatic(boxType(classType).getInternalName(), "TYPE", "Ljava/lang/Class;")

View File

@@ -39,7 +39,7 @@ public class KClassJavaProperty : IntrinsicPropertyGetter() {
return when {
isReifiedTypeParameter(type) -> {
StackValue.operation(returnType) { iv ->
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
AsmUtil.putJavaLangClassInstance(iv, asmType)
coerceToJavaLangClass(iv, returnType)
}

View File

@@ -23,13 +23,10 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class MonitorInstruction private constructor(private val opcode: Int) : IntrinsicMethod() {
public class MonitorInstruction private constructor(private val opcode: Int) : IntrinsicMethod() {
companion object {
@JvmField
val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
@JvmField
val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
public val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
public val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
}
override fun toCallable(method: CallableMethod): Callable {

View File

@@ -78,28 +78,26 @@ public object TypeIntrinsics {
instanceofInsn.desc = asmType.internalName
}
@JvmStatic
public fun checkcast(
v: InstructionAdapter,
kotlinType: KotlinType, asmType: Type,
// This parameter is just for sake of optimization:
// when we generate 'as?' we do necessary intrinsic checks
// when calling TypeIntrinsics.instanceOf, so here we can just make checkcast
safe: Boolean) {
public @JvmStatic fun checkcast(v: InstructionAdapter, jetType: KotlinType, asmType: Type, safe: Boolean) {
if (safe) {
v.checkcast(asmType)
return
}
val functionTypeArity = getFunctionTypeArity(kotlinType)
val functionTypeArity = getFunctionTypeArity(jetType)
if (functionTypeArity >= 0) {
v.iconst(functionTypeArity)
v.typeIntrinsic(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
if (safe) {
v.typeIntrinsic(BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
}
else {
v.typeIntrinsic(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
}
v.checkcast(asmType)
return
}
val asMutableCollectionMethodName = getAsMutableCollectionMethodName(kotlinType)
val asMutableCollectionMethodName = getAsMutableCollectionMethodName(jetType)
if (asMutableCollectionMethodName != null) {
v.typeIntrinsic(asMutableCollectionMethodName, getAsMutableCollectionDescriptor(asmType))
return
@@ -108,6 +106,38 @@ public object TypeIntrinsics {
v.checkcast(asmType)
}
public @JvmStatic fun checkcast(checkcastInsn: TypeInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type, safe: Boolean) {
if (safe) {
checkcastInsn.desc = asmType.internalName
return
}
val functionTypeArity = getFunctionTypeArity(jetType)
if (functionTypeArity >= 0) {
instructions.insertBefore(checkcastInsn, iconstNode(functionTypeArity))
val beforeCheckcast = if (safe)
typeIntrinsicNode(BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
else
typeIntrinsicNode(BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY, BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR)
instructions.insertBefore(checkcastInsn, beforeCheckcast)
instructions.insertBefore(checkcastInsn, TypeInsnNode(Opcodes.CHECKCAST, asmType.internalName))
instructions.remove(checkcastInsn)
return
}
val asMutableCollectionMethodName = getAsMutableCollectionMethodName(jetType)
if (asMutableCollectionMethodName != null) {
instructions.insertBefore(checkcastInsn,
typeIntrinsicNode(asMutableCollectionMethodName, getAsMutableCollectionDescriptor(asmType)))
instructions.remove(checkcastInsn)
return
}
checkcastInsn.desc = asmType.internalName
}
private val INTRINSICS_CLASS = "kotlin/jvm/internal/TypeIntrinsics"
private val IS_FUNCTON_OF_ARITY_METHOD_NAME = "isFunctionOfArity"
@@ -181,4 +211,9 @@ public object TypeIntrinsics {
private val BEFORE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR =
Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, Type.INT_TYPE)
private val BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY = "beforeSafeCheckcastToFunctionOfArity"
private val BEFORE_SAFE_CHECKCAST_TO_FUNCTION_OF_ARITY_DESCRIPTOR =
Type.getMethodDescriptor(OBJECT_TYPE, OBJECT_TYPE, Type.INT_TYPE)
}

View File

@@ -110,10 +110,10 @@ public open class MethodAnalyzer<V : Value>(
}
catch (e: AnalyzerException) {
throw AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.message, e)
throw AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e)
}
catch (e: Exception) {
throw AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.message, e)
throw AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e)
}
}

View File

@@ -91,28 +91,27 @@ public class OptimizationBasicInterpreter extends BasicInterpreter {
public BasicValue merge(
@NotNull BasicValue v, @NotNull BasicValue w
) {
if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) {
if (!v.equals(w)) {
if (v == BasicValue.UNINITIALIZED_VALUE || w == BasicValue.UNINITIALIZED_VALUE) {
return BasicValue.UNINITIALIZED_VALUE;
}
// if merge of two references then `lub` is java/lang/Object
// arrays also are BasicValues with reference type's
if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) {
return BasicValue.REFERENCE_VALUE;
}
assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays";
// if merge of something can be stored in int var (int, char, boolean, byte, character)
if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE &&
w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) {
return BasicValue.INT_VALUE;
}
return BasicValue.UNINITIALIZED_VALUE;
}
// Objects must be equal, others can just have the same sort
if (v.getType().getSort() == w.getType().getSort() && (v.getType().getSort() != Type.OBJECT || v.equals(w))) {
return v;
}
// if merge of two references then `lub` is java/lang/Object
// arrays also are BasicValues with reference type's
if (v.getType().getSort() == Type.OBJECT && w.getType().getSort() == Type.OBJECT) {
return BasicValue.REFERENCE_VALUE;
}
assert v.getType().getSort() != Type.ARRAY && w.getType().getSort() != Type.ARRAY : "There should not be arrays";
// if merge of something can be stored in int var (int, char, boolean, byte, character)
if (v.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE &&
w.getType().getOpcode(Opcodes.ISTORE) == Opcodes.ISTORE) {
return BasicValue.INT_VALUE;
}
return BasicValue.UNINITIALIZED_VALUE;
return v;
}
}

View File

@@ -16,8 +16,9 @@
package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
val AbstractInsnNode.isMeaningful: Boolean get() =
@@ -96,24 +97,3 @@ inline fun AbstractInsnNode.findPreviousOrNull(predicate: (AbstractInsnNode) ->
fun AbstractInsnNode.hasOpcode(): Boolean =
getOpcode() >= 0
// See InstructionAdapter
//
// public void iconst(final int cst) {
// if (cst >= -1 && cst <= 5) {
// mv.visitInsn(Opcodes.ICONST_0 + cst);
// } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
// mv.visitIntInsn(Opcodes.BIPUSH, cst);
// } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
// mv.visitIntInsn(Opcodes.SIPUSH, cst);
// } else {
// mv.visitLdcInsn(new Integer(cst));
// }
// }
val AbstractInsnNode.intConstant: Int? get() =
when (opcode) {
in ICONST_M1..ICONST_5 -> opcode - ICONST_0
BIPUSH, SIPUSH -> (this as IntInsnNode).operand
LDC -> (this as LdcInsnNode).cst as? Int
else -> null
}

View File

@@ -71,7 +71,7 @@ private fun insertSaveRestoreStackMarkers(
val doneTryStartLabels = hashSetOf<LabelNode>()
val doneHandlerLabels = hashSetOf<LabelNode>()
for (decompiledTryDescriptor in decompiledTryDescriptorForStart.values) {
for (decompiledTryDescriptor in decompiledTryDescriptorForStart.values()) {
with(decompiledTryDescriptor) {
if (!doneTryStartLabels.contains(tryStartLabel)) {
doneTryStartLabels.add(tryStartLabel)

View File

@@ -96,7 +96,7 @@ internal class FixStackAnalyzer(
}
else {
extraStack.add(value)
maxExtraStackSize = Math.max(maxExtraStackSize, extraStack.size)
maxExtraStackSize = Math.max(maxExtraStackSize, extraStack.size())
}
}

View File

@@ -107,7 +107,7 @@ internal class FixStackContext(val methodNode: MethodNode) {
if (saveNodes.isEmpty()) {
throw AssertionError("${indexOf(insnNode)}: in handler ${indexOf(restoreLabel)} restore is not matched with save")
}
else if (saveNodes.size > 1) {
else if (saveNodes.size() > 1) {
throw AssertionError("${indexOf(insnNode)}: in handler ${indexOf(restoreLabel)} restore is matched with several saves")
}
val saveNode = saveNodes.first()

View File

@@ -39,7 +39,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
}
fun allocateVariablesForSaveStackMarker(saveStackMarker: AbstractInsnNode, savedStackValues: List<BasicValue>): SavedStackDescriptor {
val numRestoreStackMarkers = context.restoreStackMarkersForSaveMarker[saveStackMarker]!!.size
val numRestoreStackMarkers = context.restoreStackMarkersForSaveMarker[saveStackMarker]!!.size()
return allocateNewHandle(numRestoreStackMarkers, saveStackMarker, savedStackValues)
}
@@ -58,7 +58,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
}
private fun getFirstUnusedLocalVariableIndex(): Int =
allocatedHandles.values.fold(initialMaxLocals) {
allocatedHandles.values().fold(initialMaxLocals) {
index, handle -> Math.max(index, handle.savedStackDescriptor.firstUnusedLocalVarIndex)
}

View File

@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.codegen.serialization;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice;
import org.jetbrains.kotlin.util.slicedMap.MutableSlicedMap;
import org.jetbrains.kotlin.util.slicedMap.SlicedMapImpl;
@@ -35,6 +37,12 @@ public final class JvmSerializationBindings {
SerializationMappingSlice.create();
public static final SerializationMappingSlice<PropertyDescriptor, Method> SYNTHETIC_METHOD_FOR_PROPERTY =
SerializationMappingSlice.create();
public static final SerializationMappingSlice<CallableMemberDescriptor, String> IMPL_CLASS_NAME_FOR_CALLABLE =
SerializationMappingSlice.create();
public static final SerializationMappingSetSlice<PropertyDescriptor> STATIC_FIELD_IN_OUTER_CLASS =
SerializationMappingSetSlice.create();
public static final SerializationMappingSlice<ValueParameterDescriptor, Integer> INDEX_FOR_VALUE_PARAMETER =
SerializationMappingSlice.create();
private static final class SerializationMappingSlice<K, V> extends BasicWritableSlice<K, V> {
public SerializationMappingSlice() {

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen.serialization;
import com.google.protobuf.MessageLite;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -60,6 +61,14 @@ public class JvmSerializerExtension extends SerializerExtension {
return useTypeTable;
}
@Override
public void serializeValueParameter(@NotNull ValueParameterDescriptor descriptor, @NotNull ProtoBuf.ValueParameter.Builder proto) {
Integer index = bindings.get(INDEX_FOR_VALUE_PARAMETER, descriptor);
if (index != null) {
proto.setExtension(JvmProtoBuf.index, index);
}
}
@Override
public void serializeType(@NotNull KotlinType type, @NotNull ProtoBuf.Type.Builder proto) {
// TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead
@@ -90,6 +99,8 @@ public class JvmSerializerExtension extends SerializerExtension {
proto.setExtension(JvmProtoBuf.constructorSignature, signature);
}
}
saveImplClassName(descriptor, proto);
}
@Override
@@ -101,6 +112,8 @@ public class JvmSerializerExtension extends SerializerExtension {
proto.setExtension(JvmProtoBuf.methodSignature, signature);
}
}
saveImplClassName(descriptor, proto);
}
@Override
@@ -113,18 +126,45 @@ public class JvmSerializerExtension extends SerializerExtension {
Method setterMethod = setter == null ? null : bindings.get(METHOD_FOR_FUNCTION, setter);
Pair<Type, String> field = bindings.get(FIELD_FOR_PROPERTY, descriptor);
String fieldName;
String fieldDesc;
boolean isStaticInOuter;
if (field != null) {
fieldName = field.second;
fieldDesc = field.first.getDescriptor();
isStaticInOuter = bindings.get(STATIC_FIELD_IN_OUTER_CLASS, descriptor);
}
else {
fieldName = null;
fieldDesc = null;
isStaticInOuter = false;
}
Method syntheticMethod = bindings.get(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor);
JvmProtoBuf.JvmPropertySignature signature = signatureSerializer.propertySignature(
descriptor,
field != null ? field.second : null,
field != null ? field.first.getDescriptor() : null,
descriptor, fieldName, fieldDesc, isStaticInOuter,
syntheticMethod != null ? signatureSerializer.methodSignature(null, syntheticMethod) : null,
getterMethod != null ? signatureSerializer.methodSignature(null, getterMethod) : null,
setterMethod != null ? signatureSerializer.methodSignature(null, setterMethod) : null
);
proto.setExtension(JvmProtoBuf.propertySignature, signature);
saveImplClassName(descriptor, proto);
}
private void saveImplClassName(@NotNull CallableMemberDescriptor callable, @NotNull MessageLite.Builder proto) {
String name = bindings.get(IMPL_CLASS_NAME_FOR_CALLABLE, callable);
if (name == null) return;
int index = stringTable.getStringIndex(name);
if (proto instanceof ProtoBuf.Function.Builder) {
((ProtoBuf.Function.Builder) proto).setExtension(JvmProtoBuf.methodImplClassName, index);
}
else if (proto instanceof ProtoBuf.Property.Builder) {
((ProtoBuf.Property.Builder) proto).setExtension(JvmProtoBuf.propertyImplClassName, index);
}
}
private class SignatureSerializer {
@@ -200,6 +240,7 @@ public class JvmSerializerExtension extends SerializerExtension {
@NotNull PropertyDescriptor descriptor,
@Nullable String fieldName,
@Nullable String fieldDesc,
boolean isStaticInOuter,
@Nullable JvmProtoBuf.JvmMethodSignature syntheticMethod,
@Nullable JvmProtoBuf.JvmMethodSignature getter,
@Nullable JvmProtoBuf.JvmMethodSignature setter
@@ -208,7 +249,7 @@ public class JvmSerializerExtension extends SerializerExtension {
if (fieldDesc != null) {
assert fieldName != null : "Field name shouldn't be null when there's a field type: " + fieldDesc;
signature.setField(fieldSignature(descriptor, fieldName, fieldDesc));
signature.setField(fieldSignature(descriptor, fieldName, fieldDesc, isStaticInOuter));
}
if (syntheticMethod != null) {
@@ -229,7 +270,8 @@ public class JvmSerializerExtension extends SerializerExtension {
public JvmProtoBuf.JvmFieldSignature fieldSignature(
@NotNull PropertyDescriptor descriptor,
@NotNull String name,
@NotNull String desc
@NotNull String desc,
boolean isStaticInOuter
) {
JvmProtoBuf.JvmFieldSignature.Builder builder = JvmProtoBuf.JvmFieldSignature.newBuilder();
if (!descriptor.getName().asString().equals(name)) {
@@ -238,6 +280,9 @@ public class JvmSerializerExtension extends SerializerExtension {
if (requiresSignature(descriptor, desc)) {
builder.setDesc(stringTable.getStringIndex(desc));
}
if (isStaticInOuter) {
builder.setIsStaticInOuter(true);
}
return builder.build();
}
}

View File

@@ -38,7 +38,7 @@ class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable {
override fun getStringIndex(string: String): Int =
map.getOrPut(string) {
strings.size.apply {
strings.size().apply {
strings.add(string)
val lastRecord = records.lastOrNull()
@@ -78,7 +78,7 @@ class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable {
}
}
val index = strings.size
val index = strings.size()
if (classId.isLocal) {
localNames.add(index)
}

View File

@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
@@ -52,18 +53,8 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
// Avoid errors when some classes are not loaded for some reason
private val typeMapper = JetTypeMapper(bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, incrementalCache, moduleName)
private val reportDiagnosticsTasks = ArrayList<() -> Unit>()
fun reportDiagnostics() {
reportDiagnosticsTasks.forEach { it() }
reportDiagnosticsTasks.clear()
}
override fun handleClashingSignatures(data: ConflictingJvmDeclarationsData) {
reportDiagnosticsTasks.add { reportConflictingJvmSignatures(data) }
}
private fun reportConflictingJvmSignatures(data: ConflictingJvmDeclarationsData) {
val noOwnImplementations = data.signatureOrigins.all { it.originKind in EXTERNAL_SOURCES_KINDS }
val elements = LinkedHashSet<PsiElement>()
@@ -91,14 +82,6 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
classOrigin: JvmDeclarationOrigin,
classInternalName: String?,
signatures: MultiMap<RawSignature, JvmDeclarationOrigin>
) {
reportDiagnosticsTasks.add { reportClashingSignaturesInHierarchy(classOrigin, classInternalName, signatures) }
}
private fun reportClashingSignaturesInHierarchy(
classOrigin: JvmDeclarationOrigin,
classInternalName: String?,
signatures: MultiMap<RawSignature, JvmDeclarationOrigin>
) {
val descriptor = classOrigin.descriptor
if (descriptor !is ClassDescriptor) return
@@ -174,7 +157,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
descriptor.getParentJavaStaticClassScope()?.run {
getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
.filter {
it is FunctionDescriptor && Visibilities.isVisibleWithIrrelevantReceiver(it, descriptor)
it is FunctionDescriptor && Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, it, descriptor)
}
.forEach(::processMember)
}
@@ -182,7 +165,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
return groupedBySignature
}
private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
public fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
if (descriptor is SamAdapterDescriptor<*>) return true
return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE

View File

@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.codegen.state
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.ModificationTracker
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.`when`.MappingsClassesForWhenByEnum
@@ -30,7 +28,6 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.TargetId
@@ -66,21 +63,19 @@ public class GenerationState @JvmOverloads constructor(
// TODO: get rid of it with the proper module infrastructure
public val outDirectory: File? = null,
public val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
public val generateOpenMultifileClasses: Boolean = false,
public val progress: Progress = Progress.DEAF
) {
public abstract class GenerateClassFilter {
public abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
public abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean
public abstract fun shouldAnnotateClass(classOrObject: KtClassOrObject): Boolean
public abstract fun shouldGenerateClass(classOrObject: KtClassOrObject): Boolean
public abstract fun shouldGeneratePackagePart(jetFile: KtFile): Boolean
public abstract fun shouldGenerateScript(script: KtScript): Boolean
companion object {
@JvmField
public val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = true
override fun shouldAnnotateClass(classOrObject: KtClassOrObject): Boolean = true
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean = true
override fun shouldGenerateClass(classOrObject: KtClassOrObject): Boolean = true
override fun shouldGenerateScript(script: KtScript): Boolean = true
@@ -101,10 +96,7 @@ public class GenerationState @JvmOverloads constructor(
private var used = false
public val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace
public val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics {
duplicateSignatureFactory.reportDiagnostics()
extraJvmDiagnosticsTrace.bindingContext.diagnostics
}
public val collectedExtraJvmDiagnostics: Diagnostics get() = extraJvmDiagnosticsTrace.bindingContext.diagnostics
public val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode()
@@ -118,7 +110,6 @@ public class GenerationState @JvmOverloads constructor(
public val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
public val factory: ClassFileFactory
private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics
public val replSpecific = ForRepl()
@@ -144,13 +135,12 @@ public class GenerationState @JvmOverloads constructor(
init {
val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization)
duplicateSignatureFactory = BuilderFactoryForDuplicateSignatureDiagnostics(
var interceptedBuilderFactory: ClassBuilderFactory = BuilderFactoryForDuplicateSignatureDiagnostics(
optimizationClassBuilderFactory, this.bindingContext, diagnostics, fileClassesProvider,
getIncrementalCacheForThisTarget(),
this.moduleName)
var interceptedBuilderFactory: ClassBuilderFactory
= BuilderFactoryForDuplicateClassNameDiagnostics(duplicateSignatureFactory, diagnostics)
interceptedBuilderFactory = BuilderFactoryForDuplicateClassNameDiagnostics(interceptedBuilderFactory, diagnostics);
val interceptExtensions = ClassBuilderInterceptorExtension.getInstances(project)
@@ -178,20 +168,3 @@ public class GenerationState @JvmOverloads constructor(
interceptedBuilderFactory.close()
}
}
private class LazyJvmDiagnostics(compute: () -> Diagnostics): Diagnostics {
private val delegate by lazy(LazyThreadSafetyMode.SYNCHRONIZED, compute)
override val modificationTracker: ModificationTracker
get() = delegate.modificationTracker
override fun all(): Collection<Diagnostic> = delegate.all()
override fun forElement(psiElement: PsiElement) = delegate.forElement(psiElement)
override fun isEmpty() = delegate.isEmpty()
override fun noSuppression() = delegate.noSuppression()
override fun iterator() = delegate.iterator()
}

View File

@@ -18,8 +18,9 @@ package org.jetbrains.kotlin.codegen.state;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import kotlin.collections.CollectionsKt;
import kotlin.CollectionsKt;
import kotlin.Pair;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
@@ -49,7 +50,7 @@ import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
import org.jetbrains.kotlin.psi.KtLambdaExpression;
import org.jetbrains.kotlin.psi.KtFunctionLiteralExpression;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
@@ -111,6 +112,40 @@ public class JetTypeMapper {
return bindingContext;
}
private enum JetTypeMapperMode {
/**
* foo.Bar is mapped to Lfoo/Bar;
*/
IMPL,
/**
* kotlin.Int is mapped to I
*/
VALUE,
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
*/
TYPE_PARAMETER,
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
* No projections allowed in immediate arguments
*/
SUPER_TYPE,
/**
* kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as VALUE
*/
VALUE_FOR_ANNOTATION,
/**
* kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as TYPE_PARAMETER
*/
TYPE_PARAMETER_FOR_ANNOTATION;
boolean isForAnnotation() {
return this == VALUE_FOR_ANNOTATION || this == TYPE_PARAMETER_FOR_ANNOTATION;
}
}
@NotNull
public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
return mapOwner(descriptor, true);
@@ -320,53 +355,42 @@ public class JetTypeMapper {
return Type.VOID_TYPE;
}
else if (descriptor instanceof FunctionDescriptor && forceBoxedReturnType((FunctionDescriptor) descriptor)) {
// GENERIC_TYPE is a hack to automatically box the return type
// TYPE_PARAMETER is a hack to automatically box the return type
//noinspection ConstantConditions
return mapType(descriptor.getReturnType(), sw, TypeMappingMode.GENERIC_ARGUMENT);
return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.TYPE_PARAMETER);
}
else if (DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration())) {
//noinspection ConstantConditions
return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
}
else {
return mapType(returnType, sw, JetTypeMapperMode.VALUE, Variance.OUT_VARIANCE);
}
return mapReturnType(descriptor, sw, returnType);
}
@NotNull
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw, @NotNull KotlinType returnType) {
boolean isAnnotationMethod = DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration());
TypeMappingMode typeMappingModeFromAnnotation =
TypeMappingUtil.extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod);
if (typeMappingModeFromAnnotation != null) {
return mapType(returnType, sw, typeMappingModeFromAnnotation);
}
TypeMappingMode mappingMode = TypeMappingMode.getOptimalModeForReturnType(
returnType,
/* isAnnotationMethod = */ isAnnotationMethod);
return mapType(returnType, sw, mappingMode);
}
@NotNull
private Type mapType(@NotNull KotlinType jetType, @NotNull TypeMappingMode mode) {
private Type mapType(@NotNull KotlinType jetType, @NotNull JetTypeMapperMode mode) {
return mapType(jetType, null, mode);
}
@NotNull
public Type mapSupertype(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor) {
return mapType(jetType, signatureVisitor, TypeMappingMode.SUPER_TYPE);
return mapType(jetType, signatureVisitor, JetTypeMapperMode.SUPER_TYPE);
}
@NotNull
public Type mapTypeParameter(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor) {
return mapType(jetType, signatureVisitor, TypeMappingMode.GENERIC_ARGUMENT);
return mapType(jetType, signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
}
@NotNull
public Type mapClass(@NotNull ClassifierDescriptor classifier) {
return mapType(classifier.getDefaultType(), null, TypeMappingMode.DEFAULT);
return mapType(classifier.getDefaultType(), null, JetTypeMapperMode.IMPL);
}
@NotNull
public Type mapType(@NotNull KotlinType jetType) {
return mapType(jetType, null, TypeMappingMode.DEFAULT);
return mapType(jetType, null, JetTypeMapperMode.VALUE);
}
@NotNull
@@ -379,7 +403,7 @@ public class JetTypeMapper {
public JvmMethodSignature mapAnnotationParameterSignature(@NotNull PropertyDescriptor descriptor) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
sw.writeReturnType();
mapType(descriptor.getType(), sw, TypeMappingMode.VALUE_FOR_ANNOTATION);
mapType(descriptor.getType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
sw.writeReturnTypeEnd();
return sw.makeJvmMethodSignature(descriptor.getName().asString(), false);
}
@@ -389,26 +413,44 @@ public class JetTypeMapper {
return mapType(descriptor.getDefaultType());
}
@NotNull
private Type mapType(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor, @NotNull JetTypeMapperMode mode) {
return mapType(jetType, signatureVisitor, mode, Variance.INVARIANT);
}
@NotNull
private Type mapType(
@NotNull KotlinType jetType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull TypeMappingMode mode
@NotNull JetTypeMapperMode kind,
@NotNull Variance howThisTypeIsUsed
) {
Type builtinType = mapBuiltinType(jetType);
Type known = mapBuiltinType(jetType);
if (builtinType != null) {
Type asmType = mode.getNeedPrimitiveBoxing() ? boxType(builtinType) : builtinType;
writeGenericType(jetType, asmType, signatureVisitor, mode);
return asmType;
boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
if (known != null) {
if (kind == JetTypeMapperMode.VALUE || kind == JetTypeMapperMode.VALUE_FOR_ANNOTATION) {
return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
}
else if (kind == JetTypeMapperMode.TYPE_PARAMETER || kind == JetTypeMapperMode.SUPER_TYPE ||
kind == JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION) {
return mapKnownAsmType(jetType, boxType(known), signatureVisitor, howThisTypeIsUsed, projectionsAllowed);
}
else if (kind == JetTypeMapperMode.IMPL) {
// TODO: enable and fix tests
//throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType);
return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
}
else {
throw new IllegalStateException("unknown kind: " + kind);
}
}
TypeConstructor constructor = jetType.getConstructor();
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
if (constructor instanceof IntersectionTypeConstructor) {
jetType = CommonSupertypes.commonSupertype(new ArrayList<KotlinType>(constructor.getSupertypes()));
constructor = jetType.getConstructor();
}
DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
if (descriptor == null) {
throw new UnsupportedOperationException("no descriptor for type constructor of " + jetType);
@@ -442,10 +484,13 @@ public class JetTypeMapper {
}
}
else {
arrayElementType = boxType(mapType(memberType, mode));
arrayElementType = boxType(mapType(memberType, kind));
if (signatureVisitor != null) {
signatureVisitor.writeArrayType();
mapType(memberType, signatureVisitor, mode.toGenericArgumentMode(memberProjection.getProjectionKind()));
JetTypeMapperMode newMode = kind.isForAnnotation() ?
JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION :
JetTypeMapperMode.TYPE_PARAMETER;
mapType(memberType, signatureVisitor, newMode, memberProjection.getProjectionKind());
signatureVisitor.writeArrayEnd();
}
}
@@ -454,15 +499,15 @@ public class JetTypeMapper {
}
if (descriptor instanceof ClassDescriptor) {
Type asmType = mode.isForAnnotationParameter() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
Type asmType = kind.isForAnnotation() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
AsmTypes.JAVA_CLASS_TYPE :
computeAsmType((ClassDescriptor) descriptor.getOriginal());
writeGenericType(jetType, asmType, signatureVisitor, mode);
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed);
return asmType;
}
if (descriptor instanceof TypeParameterDescriptor) {
Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), mode);
Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), kind);
if (signatureVisitor != null) {
signatureVisitor.writeTypeVariable(descriptor.getName(), type);
}
@@ -575,20 +620,14 @@ public class JetTypeMapper {
}
private void writeGenericType(
@NotNull KotlinType type,
@NotNull Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull TypeMappingMode mode
BothSignatureWriter signatureVisitor,
Type asmType,
KotlinType type,
Variance howThisTypeIsUsed,
boolean projectionsAllowed
) {
if (signatureVisitor != null) {
// Nothing mapping rules:
// Map<Nothing, Foo> -> Map
// Map<Foo, List<Nothing>> -> Map<Foo, List>
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
// In<Nothing, Nothing> -> In
// Inv<in Nothing, Foo> -> Inv
if (hasNothingInNonContravariantPosition(type) || type.getArguments().isEmpty()) {
if (hasNothingInArguments(type) || type.getArguments().isEmpty()) {
signatureVisitor.writeAsmType(asmType);
return;
}
@@ -611,14 +650,17 @@ public class JetTypeMapper {
writeGenericArguments(
signatureVisitor,
outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(), mode);
outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(),
howThisTypeIsUsed, projectionsAllowed);
for (PossiblyInnerType innerPart : innerTypesAsList.subList(1, innerTypesAsList.size())) {
ClassDescriptor classDescriptor = innerPart.getClassDescriptor();
signatureVisitor.writeInnerClass(getJvmShortName(classDescriptor));
writeGenericArguments(
signatureVisitor, innerPart.getArguments(),
classDescriptor.getDeclaredTypeParameters(), mode);
classDescriptor.getDeclaredTypeParameters(),
howThisTypeIsUsed, projectionsAllowed
);
}
signatureVisitor.writeClassEnd();
@@ -636,83 +678,61 @@ public class JetTypeMapper {
}
private void writeGenericArguments(
@NotNull BothSignatureWriter signatureVisitor,
@NotNull List<? extends TypeProjection> arguments,
@NotNull List<? extends TypeParameterDescriptor> parameters,
@NotNull TypeMappingMode mode
BothSignatureWriter signatureVisitor,
List<? extends TypeProjection> arguments,
List<? extends TypeParameterDescriptor> parameters,
Variance howThisTypeIsUsed,
boolean projectionsAllowed
) {
for (Pair<? extends TypeParameterDescriptor, ? extends TypeProjection> item : CollectionsKt.zip(parameters, arguments)) {
TypeParameterDescriptor parameter = item.getFirst();
TypeProjection argument = item.getSecond();
if (
argument.isStarProjection() ||
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
KotlinBuiltIns.isNothing(argument.getType()) && parameter.getVariance() == Variance.IN_VARIANCE
) {
if (projectionsAllowed && argument.isStarProjection()) {
signatureVisitor.writeUnboundedWildcard();
}
else {
TypeMappingMode argumentMode = TypeMappingUtil.updateArgumentModeFromAnnotations(mode, argument.getType());
Variance projectionKind = getVarianceForWildcard(parameter, argument, argumentMode);
Variance projectionKind = projectionsAllowed
? getEffectiveVariance(
parameter.getVariance(),
argument.getProjectionKind(),
howThisTypeIsUsed
)
: Variance.INVARIANT;
signatureVisitor.writeTypeArgument(projectionKind);
mapType(argument.getType(), signatureVisitor,
argumentMode.toGenericArgumentMode(
TypeMappingUtil.getEffectiveVariance(parameter.getVariance(), argument.getProjectionKind())));
mapType(argument.getType(), signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
signatureVisitor.writeTypeArgumentEnd();
}
}
}
private static boolean hasNothingInNonContravariantPosition(KotlinType kotlinType) {
List<TypeParameterDescriptor> parameters = kotlinType.getConstructor().getParameters();
List<TypeProjection> arguments = kotlinType.getArguments();
private static boolean hasNothingInArguments(KotlinType jetType) {
boolean hasNothingInArguments = CollectionsKt.any(jetType.getArguments(), new Function1<TypeProjection, Boolean>() {
@Override
public Boolean invoke(TypeProjection projection) {
return KotlinBuiltIns.isNothingOrNullableNothing(projection.getType());
}
});
for (int i = 0; i < arguments.size(); i++) {
TypeProjection projection = arguments.get(i);
if (hasNothingInArguments) return true;
if (projection.isStarProjection()) continue;
KotlinType type = projection.getType();
if (KotlinBuiltIns.isNullableNothing(type) ||
KotlinBuiltIns.isNothing(type) && parameters.get(i).getVariance() != Variance.IN_VARIANCE) return true;
}
return false;
return CollectionsKt.any(jetType.getArguments(), new Function1<TypeProjection, Boolean>() {
@Override
public Boolean invoke(TypeProjection projection) {
return !projection.isStarProjection() && hasNothingInArguments(projection.getType());
}
});
}
@NotNull
private static Variance getVarianceForWildcard(
@NotNull TypeParameterDescriptor parameter,
@NotNull TypeProjection projection,
@NotNull TypeMappingMode mode
) {
Variance projectionKind = projection.getProjectionKind();
private static Variance getEffectiveVariance(Variance parameterVariance, Variance projectionKind, Variance howThisTypeIsUsed) {
// Return type must not contain wildcards
if (howThisTypeIsUsed == Variance.OUT_VARIANCE) return projectionKind;
if (mode.getSkipDeclarationSiteWildcards() && projectionKind == Variance.INVARIANT) {
return Variance.INVARIANT;
}
Variance parameterVariance = parameter.getVariance();
if (parameterVariance == Variance.INVARIANT) {
return projectionKind;
}
if (projectionKind == Variance.INVARIANT) {
if (mode.getSkipDeclarationSiteWildcardsIfPossible() && !projection.isStarProjection()) {
if (parameterVariance == Variance.OUT_VARIANCE && TypeMappingUtil.isMostPreciseCovariantArgument(projection.getType())){
return Variance.INVARIANT;
}
if (parameterVariance == Variance.IN_VARIANCE
&& TypeMappingUtil.isMostPreciseContravariantArgument(projection.getType(), parameter)) {
return Variance.INVARIANT;
}
}
return parameterVariance;
}
if (parameterVariance == projectionKind) {
@@ -724,6 +744,33 @@ public class JetTypeMapper {
return Variance.OUT_VARIANCE;
}
private Type mapKnownAsmType(
KotlinType jetType,
Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull Variance howThisTypeIsUsed
) {
return mapKnownAsmType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, true);
}
private Type mapKnownAsmType(
KotlinType jetType,
Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull Variance howThisTypeIsUsed,
boolean allowProjections
) {
if (signatureVisitor != null) {
if (jetType.getArguments().isEmpty()) {
signatureVisitor.writeAsmType(asmType);
}
else {
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, allowProjections);
}
}
return asmType;
}
@NotNull
public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
if (descriptor instanceof ConstructorDescriptor) {
@@ -759,7 +806,7 @@ public class JetTypeMapper {
ClassDescriptor ownerForDefault = (ClassDescriptor) baseMethodDescriptor.getContainingDeclaration();
ownerForDefaultImpl = isJvmInterface(ownerForDefault) ? mapDefaultImpls(ownerForDefault) : mapClass(ownerForDefault);
if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE || isAccessor(descriptor))) {
if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE)) {
thisClass = mapClass(currentOwner);
if (declarationOwner instanceof JavaClassDescriptor) {
invokeOpcode = INVOKESPECIAL;
@@ -789,7 +836,7 @@ public class JetTypeMapper {
}
FunctionDescriptor overriddenSpecialBuiltinFunction =
SpecialBuiltinMembers.<FunctionDescriptor>getOverriddenBuiltinReflectingJvmDescriptor(functionDescriptor.getOriginal());
SpecialBuiltinMembers.<FunctionDescriptor>getOverriddenBuiltinWithDifferentJvmDescriptor(functionDescriptor.getOriginal());
FunctionDescriptor functionToCall = overriddenSpecialBuiltinFunction != null && !superCall
? overriddenSpecialBuiltinFunction.getOriginal()
: functionDescriptor.getOriginal();
@@ -899,7 +946,7 @@ public class JetTypeMapper {
PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
if (element instanceof KtFunctionLiteral) {
PsiElement expression = element.getParent();
if (expression instanceof KtLambdaExpression) {
if (expression instanceof KtFunctionLiteralExpression) {
SamType samType = bindingContext.get(SAM_VALUE, (KtExpression) expression);
if (samType != null) {
return samType.getAbstractMethod().getName().asString();
@@ -968,7 +1015,7 @@ public class JetTypeMapper {
public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
if (f.getInitialSignatureDescriptor() != null && f != f.getInitialSignatureDescriptor()) {
// Overrides of special builtin in Kotlin classes always have special signature
if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(f) == null ||
if (SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(f) == null ||
f.getContainingDeclaration().getOriginal() instanceof JavaClassDescriptor) {
return mapSignature(f.getInitialSignatureDescriptor(), kind);
}
@@ -994,7 +1041,7 @@ public class JetTypeMapper {
writeAdditionalConstructorParameters((ConstructorDescriptor) f, sw);
for (ValueParameterDescriptor parameter : valueParameters) {
writeParameter(sw, parameter.getType(), f);
writeParameter(sw, parameter.getType());
}
if (f instanceof AccessorForConstructorDescriptor) {
@@ -1011,12 +1058,12 @@ public class JetTypeMapper {
ReceiverParameterDescriptor receiverParameter = f.getExtensionReceiverParameter();
if (receiverParameter != null) {
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType(), f);
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType());
}
for (ValueParameterDescriptor parameter : valueParameters) {
if (writeCustomParameter(f, parameter, sw)) continue;
writeParameter(sw, parameter.getType(), f);
writeParameter(sw, parameter.getType());
}
sw.writeReturnType();
@@ -1030,9 +1077,8 @@ public class JetTypeMapper {
SpecialSignatureInfo specialSignatureInfo = BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo(f);
if (specialSignatureInfo != null) {
String newGenericSignature = CodegenUtilKt.replaceValueParametersIn(
specialSignatureInfo, signature.getGenericsSignature());
return new JvmMethodSignature(signature.getAsmMethod(), newGenericSignature, signature.getValueParameters());
return new JvmMethodSignature(
signature.getAsmMethod(), specialSignatureInfo.getSignature(), signature.getValueParameters());
}
}
@@ -1050,7 +1096,7 @@ public class JetTypeMapper {
if (SpecialBuiltinMembers.isFromJavaOrBuiltins(f)) return false;
if (overridden.getName().asString().equals("remove") && mapType(parameter.getType()).getSort() == Type.INT) {
writeParameter(sw, TypeUtils.makeNullable(parameter.getType()), f);
writeParameter(sw, TypeUtils.makeNullable(parameter.getType()));
return true;
}
@@ -1123,16 +1169,9 @@ public class JetTypeMapper {
}
@Nullable
public String mapFieldSignature(@NotNull KotlinType backingFieldType, @NotNull PropertyDescriptor propertyDescriptor) {
public String mapFieldSignature(@NotNull KotlinType backingFieldType) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
if (!propertyDescriptor.isVar()) {
mapReturnType(propertyDescriptor, sw, backingFieldType);
}
else {
writeParameterType(sw, backingFieldType, propertyDescriptor);
}
mapType(backingFieldType, sw, JetTypeMapperMode.VALUE);
return sw.makeJavaGenericSignature();
}
@@ -1150,7 +1189,7 @@ public class JetTypeMapper {
}
else return;
writeParameter(sw, JvmMethodParameterKind.THIS, thisType.getDefaultType(), descriptor);
writeParameter(sw, JvmMethodParameterKind.THIS, thisType.getDefaultType());
}
@NotNull
@@ -1184,7 +1223,7 @@ public class JetTypeMapper {
for (KotlinType jetType : typeParameterDescriptor.getUpperBounds()) {
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
if (!isJvmInterface(jetType)) {
mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
break classBound;
}
}
@@ -1202,13 +1241,13 @@ public class JetTypeMapper {
if (classifier instanceof ClassDescriptor) {
if (isJvmInterface(jetType)) {
sw.writeInterfaceBound();
mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
sw.writeInterfaceBoundEnd();
}
}
else if (classifier instanceof TypeParameterDescriptor) {
sw.writeInterfaceBound();
mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
sw.writeInterfaceBoundEnd();
}
else {
@@ -1217,50 +1256,16 @@ public class JetTypeMapper {
}
}
private void writeParameter(
@NotNull BothSignatureWriter sw,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
writeParameter(sw, JvmMethodParameterKind.VALUE, type, callableDescriptor);
private void writeParameter(@NotNull BothSignatureWriter sw, @NotNull KotlinType type) {
writeParameter(sw, JvmMethodParameterKind.VALUE, type);
}
private void writeParameter(
@NotNull BothSignatureWriter sw,
@NotNull JvmMethodParameterKind kind,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
private void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull KotlinType type) {
sw.writeParameterType(kind);
writeParameterType(sw, type, callableDescriptor);
mapType(type, sw, JetTypeMapperMode.VALUE);
sw.writeParameterTypeEnd();
}
private void writeParameterType(
@NotNull BothSignatureWriter sw,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
TypeMappingMode typeMappingMode;
TypeMappingMode typeMappingModeFromAnnotation =
TypeMappingUtil.extractTypeMappingModeFromAnnotation(callableDescriptor, type, /* isForAnnotationParameter = */ false);
if (typeMappingModeFromAnnotation != null) {
typeMappingMode = typeMappingModeFromAnnotation;
}
else if (TypeMappingUtil.isMethodWithDeclarationSiteWildcards(callableDescriptor) && !type.getArguments().isEmpty()) {
typeMappingMode = TypeMappingMode.GENERIC_ARGUMENT; // Render all wildcards
}
else {
typeMappingMode = TypeMappingMode.getOptimalModeForValueParameter(type);
}
mapType(type, sw, typeMappingMode);
}
private static void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) {
sw.writeParameterType(kind);
sw.writeAsmType(type);
@@ -1272,20 +1277,18 @@ public class JetTypeMapper {
ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
if (captureThis != null) {
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType(), descriptor);
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType());
}
KotlinType captureReceiverType = closure != null ? closure.getCaptureReceiverType() : null;
if (captureReceiverType != null) {
writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType, descriptor);
writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType);
}
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(), descriptor);
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType(), descriptor);
writeParameter(sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType());
writeParameter(sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType());
}
if (closure == null) return;
@@ -1381,11 +1384,11 @@ public class JetTypeMapper {
sw.writeParametersStart();
for (ScriptDescriptor importedScript : importedScripts) {
writeParameter(sw, importedScript.getDefaultType(), /* callableDescriptor = */ null);
writeParameter(sw, importedScript.getDefaultType());
}
for (ValueParameterDescriptor valueParameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
writeParameter(sw, valueParameter.getType(), /* callableDescriptor = */ null);
writeParameter(sw, valueParameter.getType());
}
writeVoidReturn(sw);

View File

@@ -1,121 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.state
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
internal class TypeMappingMode private constructor(
val needPrimitiveBoxing: Boolean = true,
val isForAnnotationParameter: Boolean = false,
// Here DeclarationSiteWildcards means wildcard generated because of declaration-site variance
val skipDeclarationSiteWildcards: Boolean = false,
val skipDeclarationSiteWildcardsIfPossible: Boolean = false,
private val genericArgumentMode: TypeMappingMode? = null,
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode,
private val genericInvariantArgumentMode: TypeMappingMode? = genericArgumentMode
) {
companion object {
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
*/
@JvmField
val GENERIC_ARGUMENT = TypeMappingMode()
/**
* kotlin.Int is mapped to I
*/
@JvmField
val DEFAULT = TypeMappingMode(genericArgumentMode = GENERIC_ARGUMENT, needPrimitiveBoxing = false)
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
* No projections allowed in immediate arguments
*/
@JvmField
val SUPER_TYPE = TypeMappingMode(skipDeclarationSiteWildcards = true, genericArgumentMode = GENERIC_ARGUMENT)
/**
* kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as DEFAULT
*/
@JvmField
val VALUE_FOR_ANNOTATION = TypeMappingMode(
isForAnnotationParameter = true,
needPrimitiveBoxing = false,
genericArgumentMode = TypeMappingMode(isForAnnotationParameter = true, genericArgumentMode = GENERIC_ARGUMENT))
@JvmStatic
fun getOptimalModeForValueParameter(
type: KotlinType
) = getOptimalModeForSignaturePart(type, isForAnnotationParameter = false, canBeUsedInSupertypePosition = true)
@JvmStatic
fun getOptimalModeForReturnType(
type: KotlinType,
isAnnotationMethod: Boolean
) = getOptimalModeForSignaturePart(type, isForAnnotationParameter = isAnnotationMethod, canBeUsedInSupertypePosition = false)
private fun getOptimalModeForSignaturePart(
type: KotlinType,
isForAnnotationParameter: Boolean,
canBeUsedInSupertypePosition: Boolean
): TypeMappingMode {
if (type.arguments.isEmpty()) return DEFAULT
val contravariantArgumentMode =
if (!canBeUsedInSupertypePosition)
TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = false,
skipDeclarationSiteWildcardsIfPossible = true)
else
null
val invariantArgumentMode =
if (canBeUsedInSupertypePosition)
getOptimalModeForSignaturePart(type, isForAnnotationParameter, canBeUsedInSupertypePosition = false)
else
null
return TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition,
skipDeclarationSiteWildcardsIfPossible = true,
genericContravariantArgumentMode = contravariantArgumentMode,
genericInvariantArgumentMode = invariantArgumentMode)
}
@JvmStatic
fun createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards: Boolean,
isForAnnotationParameter: Boolean,
fallbackMode: TypeMappingMode? = null
) = TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = skipDeclarationSiteWildcards,
genericArgumentMode = fallbackMode)
}
fun toGenericArgumentMode(effectiveVariance: Variance): TypeMappingMode =
when (effectiveVariance) {
Variance.IN_VARIANCE -> genericContravariantArgumentMode ?: this
Variance.INVARIANT -> genericInvariantArgumentMode ?: this
else -> genericArgumentMode ?: this
}
}

Some files were not shown because too many files have changed in this diff Show More