compiler: cleanup 'public', property access syntax

This commit is contained in:
Dmitry Jemerov
2016-01-07 17:57:35 +01:00
parent b72ea1ff07
commit 117a0d8b7b
488 changed files with 3147 additions and 3287 deletions
@@ -27,15 +27,14 @@ import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.utils.keysToMapExceptNulls import org.jetbrains.kotlin.utils.keysToMapExceptNulls
import java.util.Comparator import java.util.Comparator
public object CodegenUtilKt { object CodegenUtilKt {
// class Foo : Bar by baz // class Foo : Bar by baz
// descriptor = Foo // descriptor = Foo
// toInterface = Bar // toInterface = Bar
// delegateExpressionType = typeof(baz) // delegateExpressionType = typeof(baz)
// return Map<member of Foo, corresponding member of typeOf(baz)> // return Map<member of Foo, corresponding member of typeOf(baz)>
@JvmStatic @JvmStatic fun getDelegates(
public fun getDelegates(
descriptor: ClassDescriptor, descriptor: ClassDescriptor,
toInterface: ClassDescriptor, toInterface: ClassDescriptor,
delegateExpressionType: KotlinType? = null delegateExpressionType: KotlinType? = null
@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.backend.common.bridges
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import java.util.HashSet import java.util.HashSet
public interface FunctionHandle { interface FunctionHandle {
public val isDeclaration: Boolean val isDeclaration: Boolean
public val isAbstract: Boolean val isAbstract: Boolean
public fun getOverridden(): Iterable<FunctionHandle> fun getOverridden(): Iterable<FunctionHandle>
} }
public data class Bridge<Signature>( data class Bridge<Signature>(
public val from: Signature, val from: Signature,
public val to: Signature val to: Signature
) { ) {
override fun toString() = "$from -> $to" override fun toString() = "$from -> $to"
} }
public fun <Function : FunctionHandle, Signature> generateBridges( fun <Function : FunctionHandle, Signature> generateBridges(
function: Function, function: Function,
signature: (Function) -> Signature signature: (Function) -> Signature
): Set<Bridge<Signature>> { ): Set<Bridge<Signature>> {
@@ -69,7 +69,7 @@ public fun <Function : FunctionHandle, Signature> generateBridges(
return bridgesToGenerate.map { Bridge(it, method) }.toSet() return bridgesToGenerate.map { Bridge(it, method) }.toSet()
} }
public fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> { fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
val collector = object : DFS.NodeHandlerWithListResult<Function, Function>() { val collector = object : DFS.NodeHandlerWithListResult<Function, Function>() {
override fun afterChildren(current: Function) { override fun afterChildren(current: Function) {
if (current.isDeclaration) { if (current.isDeclaration) {
@@ -86,7 +86,7 @@ public fun <Function : FunctionHandle> findAllReachableDeclarations(function: Fu
* Given a concrete function, finds an implementation (a concrete declaration) of this function in the supertypes. * Given a concrete function, finds an implementation (a concrete declaration) of this function in the supertypes.
* The implementation is guaranteed to exist because if it wouldn't, the given function would've been abstract * The implementation is guaranteed to exist because if it wouldn't, the given function would've been abstract
*/ */
public fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function { fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function {
require(!function.isAbstract, { "Only concrete functions have implementations: $function" }) require(!function.isAbstract, { "Only concrete functions have implementations: $function" })
if (function.isDeclaration) return function if (function.isDeclaration) return function
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverrideResolver import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
public fun <Signature> generateBridgesForFunctionDescriptor( fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature signature: (FunctionDescriptor) -> Signature
): Set<Bridge<Signature>> { ): Set<Bridge<Signature>> {
@@ -47,16 +47,16 @@ public fun <Signature> generateBridgesForFunctionDescriptor(
* can generate a bridge near an implementation (of course, in case it has a super-declaration with a different signature). Ultimately this * can generate a bridge near an implementation (of course, in case it has a super-declaration with a different signature). Ultimately this
* eases the process of determining what bridges are already generated in our supertypes and need to be inherited, not regenerated. * eases the process of determining what bridges are already generated in our supertypes and need to be inherited, not regenerated.
*/ */
public data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle { data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
private val overridden = descriptor.getOverriddenDescriptors().map { DescriptorBasedFunctionHandle(it.getOriginal()) } private val overridden = descriptor.overriddenDescriptors.map { DescriptorBasedFunctionHandle(it.original) }
override val isDeclaration: Boolean = override val isDeclaration: Boolean =
descriptor.getKind().isReal() || descriptor.kind.isReal ||
findTraitImplementation(descriptor) != null findTraitImplementation(descriptor) != null
override val isAbstract: Boolean = override val isAbstract: Boolean =
descriptor.getModality() == Modality.ABSTRACT || descriptor.modality == Modality.ABSTRACT ||
DescriptorUtils.isInterface(descriptor.getContainingDeclaration()) DescriptorUtils.isInterface(descriptor.containingDeclaration)
override fun getOverridden() = overridden override fun getOverridden() = overridden
} }
@@ -67,14 +67,14 @@ public data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescript
* trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake * trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake
* override of any trait implementation or such method was already generated into the superclass or is a method from Any. * override of any trait implementation or such method was already generated into the superclass or is a method from Any.
*/ */
public fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? { fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
if (descriptor.getKind().isReal()) return null if (descriptor.kind.isReal) return null
if (isOrOverridesSynthesized(descriptor)) return null if (isOrOverridesSynthesized(descriptor)) return null
val implementation = findImplementationFromInterface(descriptor) ?: return null val implementation = findImplementationFromInterface(descriptor) ?: return null
val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null
if (!DescriptorUtils.isInterface(immediateConcreteSuper.getContainingDeclaration())) { if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) {
// If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited // If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited
return null return null
} }
@@ -86,7 +86,7 @@ public fun findTraitImplementation(descriptor: CallableMemberDescriptor): Callab
* Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function * Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function
* that should be called when the given fake override is called. * that should be called when the given fake override is called.
*/ */
public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? { fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
val overridden = OverrideResolver.getOverriddenDeclarations(descriptor) val overridden = OverrideResolver.getOverriddenDeclarations(descriptor)
val filtered = OverrideResolver.filterOutOverridden(overridden) val filtered = OverrideResolver.filterOutOverridden(overridden)
@@ -102,12 +102,12 @@ public fun findImplementationFromInterface(descriptor: CallableMemberDescriptor)
* returns the first immediate super function of the given fake override which overrides that implementation. * returns the first immediate super function of the given fake override which overrides that implementation.
* The returned function should be called from TImpl-bridges generated for the given fake override. * The returned function should be called from TImpl-bridges generated for the given fake override.
*/ */
public fun firstSuperMethodFromKotlin( fun firstSuperMethodFromKotlin(
descriptor: CallableMemberDescriptor, descriptor: CallableMemberDescriptor,
implementation: CallableMemberDescriptor implementation: CallableMemberDescriptor
): CallableMemberDescriptor? { ): CallableMemberDescriptor? {
return descriptor.getOverriddenDescriptors().firstOrNull { overridden -> return descriptor.overriddenDescriptors.firstOrNull { overridden ->
overridden.getModality() != Modality.ABSTRACT && overridden.modality != Modality.ABSTRACT &&
(overridden == implementation || OverrideResolver.overrides(overridden, implementation)) (overridden == implementation || OverrideResolver.overrides(overridden, implementation))
} }
} }
@@ -18,24 +18,24 @@ package org.jetbrains.kotlin.backend.common.output
import java.io.File import java.io.File
public interface OutputFileCollection { interface OutputFileCollection {
public fun get(relativePath: String): OutputFile? fun get(relativePath: String): OutputFile?
public fun asList(): List<OutputFile> fun asList(): List<OutputFile>
} }
public class SimpleOutputFileCollection(private val outputFiles: List<OutputFile>) : OutputFileCollection { class SimpleOutputFileCollection(private val outputFiles: List<OutputFile>) : OutputFileCollection {
override fun get(relativePath: String): OutputFile? = outputFiles.firstOrNull { it.relativePath == relativePath } override fun get(relativePath: String): OutputFile? = outputFiles.firstOrNull { it.relativePath == relativePath }
override fun asList(): List<OutputFile> = outputFiles override fun asList(): List<OutputFile> = outputFiles
} }
public interface OutputFile { interface OutputFile {
public val relativePath: String val relativePath: String
public val sourceFiles: List<File> val sourceFiles: List<File>
public fun asByteArray(): ByteArray fun asByteArray(): ByteArray
public fun asText(): String fun asText(): String
} }
public class SimpleOutputFile( class SimpleOutputFile(
override val sourceFiles: List<File>, override val sourceFiles: List<File>,
override val relativePath: String, override val relativePath: String,
private val content: String private val content: String
@@ -46,7 +46,7 @@ public class SimpleOutputFile(
override fun toString() = "$relativePath (compiled from $sourceFiles)" override fun toString() = "$relativePath (compiled from $sourceFiles)"
} }
public class SimpleOutputBinaryFile( class SimpleOutputBinaryFile(
override val sourceFiles: List<File>, override val sourceFiles: List<File>,
override val relativePath: String, override val relativePath: String,
private val content: ByteArray private val content: ByteArray
@@ -24,18 +24,18 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import java.util.* import java.util.*
open public class AbstractAccessorForFunctionDescriptor( open class AbstractAccessorForFunctionDescriptor(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
name: Name name: Name
) : SimpleFunctionDescriptorImpl(containingDeclaration, null, Annotations.EMPTY, ) : SimpleFunctionDescriptorImpl(containingDeclaration, null, Annotations.EMPTY,
name, CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE) { name, CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE) {
protected fun copyTypeParameters(descriptor: FunctionDescriptor): List<TypeParameterDescriptor> = descriptor.getTypeParameters().map { protected fun copyTypeParameters(descriptor: FunctionDescriptor): List<TypeParameterDescriptor> = descriptor.typeParameters.map {
val copy = TypeParameterDescriptorImpl.createForFurtherModification( val copy = TypeParameterDescriptorImpl.createForFurtherModification(
this, it.getAnnotations(), it.isReified(), this, it.annotations, it.isReified,
it.getVariance(), it.getName(), it.variance, it.name,
it.getIndex(), SourceElement.NO_SOURCE) it.index, SourceElement.NO_SOURCE)
for (upperBound in it.getUpperBounds()) { for (upperBound in it.upperBounds) {
copy.addUpperBound(upperBound) copy.addUpperBound(upperBound)
} }
copy.setInitialized() copy.setInitialized()
@@ -43,5 +43,5 @@ open public class AbstractAccessorForFunctionDescriptor(
} }
protected fun copyValueParameters(descriptor: FunctionDescriptor): List<ValueParameterDescriptor> = protected fun copyValueParameters(descriptor: FunctionDescriptor): List<ValueParameterDescriptor> =
descriptor.getValueParameters().map { it.copy(this, it.getName()) } descriptor.valueParameters.map { it.copy(this, it.name) }
} }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.TypeSubstitutor
public class AccessorForConstructorDescriptor( class AccessorForConstructorDescriptor(
private val calleeDescriptor: ConstructorDescriptor, private val calleeDescriptor: ConstructorDescriptor,
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
private val superCallTarget: ClassDescriptor? private val superCallTarget: ClassDescriptor?
@@ -147,8 +147,8 @@ open class BranchedValue(
}, IFEQ) }, IFEQ)
} }
public fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue = fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
if (operandType.getSort() == Type.OBJECT) if (operandType.sort == Type.OBJECT)
ObjectCompare(opToken, operandType, left, right) ObjectCompare(opToken, operandType, left, right)
else else
NumberCompare(opToken, operandType, left, right) NumberCompare(opToken, operandType, left, right)
@@ -20,32 +20,32 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public interface Callable { interface Callable {
public val owner: Type val owner: Type
public val dispatchReceiverType: Type? val dispatchReceiverType: Type?
public val extensionReceiverType: Type? val extensionReceiverType: Type?
public val generateCalleeType: Type? val generateCalleeType: Type?
public val valueParameterTypes: List<Type> val valueParameterTypes: List<Type>
public val parameterTypes: Array<Type> val parameterTypes: Array<Type>
public val returnType: Type val returnType: Type
public fun genInvokeInstruction(v: InstructionAdapter) fun genInvokeInstruction(v: InstructionAdapter)
public fun isStaticCall(): Boolean fun isStaticCall(): Boolean
public fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue { fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
return StackValue.functionCall(returnType) { return StackValue.functionCall(returnType) {
codegen.invokeMethodWithArguments(this, resolvedCall, receiver) codegen.invokeMethodWithArguments(this, resolvedCall, receiver)
} }
} }
public fun afterReceiverGeneration(v: InstructionAdapter) { fun afterReceiverGeneration(v: InstructionAdapter) {
} }
} }
@@ -27,7 +27,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.util.Printer import org.jetbrains.org.objectweb.asm.util.Printer
public class CallableMethod( class CallableMethod(
override val owner: Type, override val owner: Type,
private val defaultImplOwner: Type?, private val defaultImplOwner: Type?,
private val defaultMethodDesc: String, private val defaultMethodDesc: String,
@@ -37,48 +37,48 @@ public class CallableMethod(
override val extensionReceiverType: Type?, override val extensionReceiverType: Type?,
override val generateCalleeType: Type? override val generateCalleeType: Type?
) : Callable { ) : Callable {
public fun getValueParameters(): List<JvmMethodParameterSignature> = fun getValueParameters(): List<JvmMethodParameterSignature> =
signature.getValueParameters() signature.valueParameters
override val valueParameterTypes: List<Type> override val valueParameterTypes: List<Type>
get() = signature.getValueParameters().filter { it.getKind() == JvmMethodParameterKind.VALUE }.map { it.getAsmType() } get() = signature.valueParameters.filter { it.kind == JvmMethodParameterKind.VALUE }.map { it.asmType }
public fun getAsmMethod(): Method = fun getAsmMethod(): Method =
signature.getAsmMethod() signature.asmMethod
override val parameterTypes: Array<Type> override val parameterTypes: Array<Type>
get() = getAsmMethod().getArgumentTypes() get() = getAsmMethod().argumentTypes
public override fun genInvokeInstruction(v: InstructionAdapter) { override fun genInvokeInstruction(v: InstructionAdapter) {
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor()) v.visitMethodInsn(invokeOpcode, owner.internalName, getAsmMethod().name, getAsmMethod().descriptor)
} }
public fun genInvokeDefaultInstruction(v: InstructionAdapter) { fun genInvokeDefaultInstruction(v: InstructionAdapter) {
if (defaultImplOwner == null) { if (defaultImplOwner == null) {
throw IllegalStateException() throw IllegalStateException()
} }
val method = getAsmMethod() val method = getAsmMethod()
if ("<init>".equals(method.getName())) { if ("<init>".equals(method.name)) {
v.aconst(null) v.aconst(null)
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", defaultMethodDesc, false) v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.internalName, "<init>", defaultMethodDesc, false)
} }
else { else {
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(), v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.internalName,
method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false) method.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v) StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v)
} }
} }
override val returnType: Type override val returnType: Type
get() = signature.getReturnType() get() = signature.returnType
override fun isStaticCall(): Boolean = override fun isStaticCall(): Boolean =
invokeOpcode == INVOKESTATIC invokeOpcode == INVOKESTATIC
override fun toString(): String = override fun toString(): String =
"${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature" "${Printer.OPCODES[invokeOpcode]} ${owner.internalName}.$signature"
} }
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
import org.jetbrains.org.objectweb.asm.FieldVisitor import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
public abstract class ClassNameCollectionClassBuilderFactory( abstract class ClassNameCollectionClassBuilderFactory(
delegate: ClassBuilderFactory delegate: ClassBuilderFactory
) : DelegatingClassBuilderFactory(delegate) { ) : DelegatingClassBuilderFactory(delegate) {
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
public class CodegenFileClassesProvider : JvmFileClassesProvider { class CodegenFileClassesProvider : JvmFileClassesProvider {
override public fun getFileClassInfo(file: KtFile): JvmFileClassInfo = override fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
JvmFileClassUtil.getFileClassInfoNoResolve(file) JvmFileClassUtil.getFileClassInfoNoResolve(file)
} }
@@ -65,14 +65,14 @@ class CollectionStubMethodGenerator(
val (child, typeParameters) = createSyntheticSubclass() val (child, typeParameters) = createSyntheticSubclass()
// If the original class has any type parameters, we copied them and now we need to substitute types of the newly created type // If the original class has any type parameters, we copied them and now we need to substitute types of the newly created type
// parameters as arguments for the type parameters of the original class // parameters as arguments for the type parameters of the original class
val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.getDefaultType()) }) val parentType = newType(descriptor, typeParameters.map { TypeProjectionImpl(it.defaultType) })
// Now we need to determine the arguments which should be substituted for the MutableCollection super class. To do that, // Now we need to determine the arguments which should be substituted for the MutableCollection super class. To do that,
// we look for type arguments which were substituted in the inheritance of the original class from Collection and use them // we look for type arguments which were substituted in the inheritance of the original class from Collection and use them
// to construct the needed MutableCollection type. Since getAllSupertypes() may return several types which correspond to the // to construct the needed MutableCollection type. Since getAllSupertypes() may return several types which correspond to the
// Collection class descriptor, we find the most specific one (which is guaranteed to exist by front-end) // Collection class descriptor, we find the most specific one (which is guaranteed to exist by front-end)
val readOnlyCollectionType = TypeUtils.getAllSupertypes(parentType).findMostSpecificTypeForClass(readOnlyClass) val readOnlyCollectionType = TypeUtils.getAllSupertypes(parentType).findMostSpecificTypeForClass(readOnlyClass)
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.getArguments()) val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.arguments)
child.addSupertype(parentType) child.addSupertype(parentType)
child.addSupertype(mutableCollectionType) child.addSupertype(mutableCollectionType)
@@ -81,10 +81,10 @@ class CollectionStubMethodGenerator(
// Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub // Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub
// or save its descriptor to generate all the needed bridges // or save its descriptor to generate all the needed bridges
for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) { for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) {
if (method.getModality() == Modality.ABSTRACT) { if (method.modality == Modality.ABSTRACT) {
// If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already // If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already
// present in the bytecode (abstract) and we don't want a duplicate signature error // present in the bytecode (abstract) and we don't want a duplicate signature error
if (method.findOverriddenFromDirectSuperClass(descriptor)?.getKind() == DECLARATION) continue if (method.findOverriddenFromDirectSuperClass(descriptor)?.kind == DECLARATION) continue
// Otherwise we can safely generate the stub with the substituted signature // Otherwise we can safely generate the stub with the substituted signature
val signature = method.signature() val signature = method.signature()
@@ -160,18 +160,18 @@ class CollectionStubMethodGenerator(
val collectionClasses = with(descriptor.builtIns) { val collectionClasses = with(descriptor.builtIns) {
listOf( listOf(
pair(getCollection(), getMutableCollection()), pair(collection, mutableCollection),
pair(getSet(), getMutableSet()), pair(set, mutableSet),
pair(getList(), getMutableList()), pair(list, mutableList),
pair(getMap(), getMutableMap()), pair(map, mutableMap),
pair(getMapEntry(), getMutableMapEntry()), pair(mapEntry, mutableMapEntry),
pair(getIterable(), getMutableIterable()), pair(iterable, mutableIterable),
pair(getIterator(), getMutableIterator()), pair(iterator, mutableIterator),
pair(getListIterator(), getMutableListIterator()) pair(listIterator, mutableListIterator)
) )
} }
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.getDefaultType()).classes().toHashSet() val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.defaultType).classes().toHashSet()
val ourSuperCollectionClasses = collectionClasses.filter { pair -> val ourSuperCollectionClasses = collectionClasses.filter { pair ->
pair.readOnlyClass in allSuperClasses && pair.mutableClass !in allSuperClasses pair.readOnlyClass in allSuperClasses && pair.mutableClass !in allSuperClasses
@@ -180,13 +180,13 @@ class CollectionStubMethodGenerator(
// Filter out built-in classes which are overridden by other built-in classes in the list, to avoid duplicating methods. // Filter out built-in classes which are overridden by other built-in classes in the list, to avoid duplicating methods.
val redundantClasses = ourSuperCollectionClasses.flatMapTo(HashSet<ClassDescriptor>()) { pair -> val redundantClasses = ourSuperCollectionClasses.flatMapTo(HashSet<ClassDescriptor>()) { pair ->
pair.readOnlyClass.getTypeConstructor().getSupertypes().classes() pair.readOnlyClass.typeConstructor.supertypes.classes()
} }
return ourSuperCollectionClasses.filter { klass -> klass.readOnlyClass !in redundantClasses } return ourSuperCollectionClasses.filter { klass -> klass.readOnlyClass !in redundantClasses }
} }
private fun Collection<KotlinType>.classes(): Collection<ClassDescriptor> = private fun Collection<KotlinType>.classes(): Collection<ClassDescriptor> =
this.map { it.getConstructor().getDeclarationDescriptor() as ClassDescriptor } this.map { it.constructor.declarationDescriptor as ClassDescriptor }
private fun findFakeOverridesForMethodsFromMutableCollection( private fun findFakeOverridesForMethodsFromMutableCollection(
klass: ClassDescriptor, klass: ClassDescriptor,
@@ -212,7 +212,7 @@ class CollectionStubMethodGenerator(
} }
private fun Collection<KotlinType>.findMostSpecificTypeForClass(klass: ClassDescriptor): KotlinType { private fun Collection<KotlinType>.findMostSpecificTypeForClass(klass: ClassDescriptor): KotlinType {
val types = this.filter { it.getConstructor().getDeclarationDescriptor() == klass } val types = this.filter { it.constructor.declarationDescriptor == klass }
if (types.isEmpty()) error("No supertype of $klass in $this") 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 // Find the first type in the list such that it's a subtype of every other type in that list
@@ -222,11 +222,11 @@ class CollectionStubMethodGenerator(
} }
private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> { private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> {
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), ClassKind.CLASS, false, val child = MutableClassDescriptor(descriptor.containingDeclaration, ClassKind.CLASS, false,
Name.special("<synthetic inheritor of ${descriptor.getName()}>"), descriptor.getSource()) Name.special("<synthetic inheritor of ${descriptor.name}>"), descriptor.source)
child.setModality(Modality.FINAL) child.modality = Modality.FINAL
child.setVisibility(Visibilities.PUBLIC) child.visibility = Visibilities.PUBLIC
val typeParameters = descriptor.getTypeConstructor().getParameters() val typeParameters = descriptor.typeConstructor.parameters
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size) val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters) DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
child.setTypeParameterDescriptors(typeParameters) child.setTypeParameterDescriptors(typeParameters)
@@ -234,7 +234,7 @@ class CollectionStubMethodGenerator(
} }
private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(classDescriptor: ClassDescriptor): FunctionDescriptor? { private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(classDescriptor: ClassDescriptor): FunctionDescriptor? {
return this.getOverriddenDescriptors().firstOrNull { it.getContainingDeclaration() == classDescriptor } return this.overriddenDescriptors.firstOrNull { it.containingDeclaration == classDescriptor }
} }
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType { private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType {
@@ -246,13 +246,13 @@ class CollectionStubMethodGenerator(
private fun generateMethodStub(signature: JvmMethodSignature, synthetic: Boolean) { private fun generateMethodStub(signature: JvmMethodSignature, synthetic: Boolean) {
// TODO: investigate if it makes sense to generate abstract stubs in traits // TODO: investigate if it makes sense to generate abstract stubs in traits
var access = ACC_PUBLIC var access = ACC_PUBLIC
if (descriptor.getKind() == ClassKind.INTERFACE) access = access or ACC_ABSTRACT if (descriptor.kind == ClassKind.INTERFACE) access = access or ACC_ABSTRACT
if (synthetic) access = access or ACC_SYNTHETIC if (synthetic) access = access or ACC_SYNTHETIC
val asmMethod = signature.getAsmMethod() val asmMethod = signature.asmMethod
val genericSignature = if (synthetic) null else signature.getGenericsSignature() val genericSignature = if (synthetic) null else signature.genericsSignature
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.getName(), asmMethod.getDescriptor(), genericSignature, null) val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.name, asmMethod.descriptor, genericSignature, null)
if (descriptor.getKind() != ClassKind.INTERFACE) { if (descriptor.kind != ClassKind.INTERFACE) {
mv.visitCode() mv.visitCode()
AsmUtil.genThrow(InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection") AsmUtil.genThrow(InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection")
FunctionCodegen.endVisit(mv, "built-in stub for $signature", null) FunctionCodegen.endVisit(mv, "built-in stub for $signature", null)
@@ -50,7 +50,7 @@ class DefaultCallMask(val size: Int) {
return masks return masks
} }
public fun generateOnStackIfNeeded(callGenerator: CallGenerator): Boolean { fun generateOnStackIfNeeded(callGenerator: CallGenerator): Boolean {
val toInts = toInts() val toInts = toInts()
for (mask in toInts) { for (mask in toInts) {
callGenerator.putValueIfNeeded(null, Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE)) callGenerator.putValueIfNeeded(null, Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE))
@@ -33,7 +33,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
* Generates Java overloads for functions and constructors that have the default * Generates Java overloads for functions and constructors that have the default
* parameter values substituted. * parameter values substituted.
*/ */
public class DefaultParameterValueSubstitutor(val state: GenerationState) { class DefaultParameterValueSubstitutor(val state: GenerationState) {
/** /**
* If all of the parameters of the specified constructor declare default values, * If all of the parameters of the specified constructor declare default values,
* generates a no-argument constructor that passes default values for all arguments. * generates a no-argument constructor that passes default values for all arguments.
@@ -118,19 +118,19 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
val typeMapper = state.typeMapper val typeMapper = state.typeMapper
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor) val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0) val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0)
val remainingParameters = getRemainingParameters(functionDescriptor.getOriginal(), substituteCount) val remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount)
val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters) val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters)
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags, val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
signature.getAsmMethod().getName(), signature.asmMethod.name,
signature.getAsmMethod().getDescriptor(), signature.asmMethod.descriptor,
signature.getGenericsSignature(), signature.genericsSignature,
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper)) FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper))
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.getReturnType()) AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.returnType)
remainingParameters.withIndex().forEach { remainingParameters.withIndex().forEach {
val annotationCodegen = AnnotationCodegen.forParameter(it.index, mv, typeMapper) val annotationCodegen = AnnotationCodegen.forParameter(it.index, mv, typeMapper)
annotationCodegen.genAnnotations(it.value, signature.getValueParameters()[it.index].getAsmType()) annotationCodegen.genAnnotations(it.value, signature.valueParameters[it.index].asmType)
} }
if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) { if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) {
@@ -148,14 +148,14 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
v.load(thisIndex, methodOwner) // Load this on stack v.load(thisIndex, methodOwner) // Load this on stack
} }
else { else {
val delegateOwner = delegateFunctionDescriptor.getContainingDeclaration() val delegateOwner = delegateFunctionDescriptor.containingDeclaration
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject()) { if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject) {
val singletonValue = StackValue.singleton(delegateOwner, typeMapper) val singletonValue = StackValue.singleton(delegateOwner, typeMapper)
singletonValue.put(singletonValue.type, v); singletonValue.put(singletonValue.type, v);
} }
} }
val receiver = functionDescriptor.getExtensionReceiverParameter() val receiver = functionDescriptor.extensionReceiverParameter
if (receiver != null) { if (receiver != null) {
val receiverType = typeMapper.mapType(receiver) val receiverType = typeMapper.mapType(receiver)
val receiverIndex = frameMap.enter(receiver, receiverType) val receiverIndex = frameMap.enter(receiver, receiverType)
@@ -167,8 +167,8 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
var mask = 0 var mask = 0
val masks = arrayListOf<Int>() val masks = arrayListOf<Int>()
for (parameterDescriptor in functionDescriptor.getValueParameters()) { for (parameterDescriptor in functionDescriptor.valueParameters) {
val paramType = typeMapper.mapType(parameterDescriptor.getType()) val paramType = typeMapper.mapType(parameterDescriptor.type)
if (parameterDescriptor in remainingParameters) { if (parameterDescriptor in remainingParameters) {
val index = frameMap.getIndex(parameterDescriptor) val index = frameMap.getIndex(parameterDescriptor)
StackValue.local(index, paramType).put(paramType, v) StackValue.local(index, paramType).put(paramType, v)
@@ -195,39 +195,39 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind) val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
if (functionDescriptor is ConstructorDescriptor) { if (functionDescriptor is ConstructorDescriptor) {
v.invokespecial(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false) v.invokespecial(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
} }
else { else {
v.invokestatic(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false) v.invokestatic(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
} }
v.areturn(signature.getReturnType()) v.areturn(signature.returnType)
FunctionCodegen.endVisit(mv, null, methodElement) FunctionCodegen.endVisit(mv, null, methodElement)
} }
private fun getRemainingParameters(functionDescriptor: FunctionDescriptor, private fun getRemainingParameters(functionDescriptor: FunctionDescriptor,
substituteCount: Int): List<ValueParameterDescriptor> { substituteCount: Int): List<ValueParameterDescriptor> {
var remainingCount = functionDescriptor.countDefaultParameters() - substituteCount var remainingCount = functionDescriptor.countDefaultParameters() - substituteCount
return functionDescriptor.getValueParameters().filter { !it.declaresDefaultValue() || --remainingCount >= 0 } return functionDescriptor.valueParameters.filter { !it.declaresDefaultValue() || --remainingCount >= 0 }
} }
private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: KtClassOrObject): Boolean { private fun isEmptyConstructorNeeded(constructorDescriptor: ConstructorDescriptor, classOrObject: KtClassOrObject): Boolean {
val classDescriptor = constructorDescriptor.getContainingDeclaration() val classDescriptor = constructorDescriptor.containingDeclaration
if (classDescriptor.getKind() != ClassKind.CLASS) return false if (classDescriptor.kind != ClassKind.CLASS) return false
if (classOrObject.isLocal()) return false if (classOrObject.isLocal()) return false
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
if (Visibilities.isPrivate(classDescriptor.getVisibility()) || Visibilities.isPrivate(constructorDescriptor.getVisibility())) if (Visibilities.isPrivate(classDescriptor.visibility) || Visibilities.isPrivate(constructorDescriptor.visibility))
return false return false
if (constructorDescriptor.getValueParameters().isEmpty()) return false if (constructorDescriptor.valueParameters.isEmpty()) return false
if (classOrObject is KtClass && hasSecondaryConstructorsWithNoParameters(classOrObject)) return false if (classOrObject is KtClass && hasSecondaryConstructorsWithNoParameters(classOrObject)) return false
return constructorDescriptor.getValueParameters().all { it.declaresDefaultValue() } return constructorDescriptor.valueParameters.all { it.declaresDefaultValue() }
} }
private fun hasSecondaryConstructorsWithNoParameters(klass: KtClass) = private fun hasSecondaryConstructorsWithNoParameters(klass: KtClass) =
klass.getSecondaryConstructors().any { it.getValueParameters().isEmpty() } klass.getSecondaryConstructors().any { it.valueParameters.isEmpty() }
} }
@@ -25,18 +25,18 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
import org.jetbrains.org.objectweb.asm.FieldVisitor import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
public abstract class DelegatingClassBuilderFactory( abstract class DelegatingClassBuilderFactory(
protected val delegate: ClassBuilderFactory protected val delegate: ClassBuilderFactory
) : ClassBuilderFactory by delegate { ) : ClassBuilderFactory by delegate {
abstract override fun newClassBuilder(origin: JvmDeclarationOrigin): DelegatingClassBuilder abstract override fun newClassBuilder(origin: JvmDeclarationOrigin): DelegatingClassBuilder
public override fun asBytes(builder: ClassBuilder?): ByteArray? { override fun asBytes(builder: ClassBuilder?): ByteArray? {
return delegate.asBytes((builder as DelegatingClassBuilder).getDelegate()) return delegate.asBytes((builder as DelegatingClassBuilder).getDelegate())
} }
public override fun asText(builder: ClassBuilder?): String? { override fun asText(builder: ClassBuilder?): String? {
return delegate.asText((builder as DelegatingClassBuilder).getDelegate()) return delegate.asText((builder as DelegatingClassBuilder).getDelegate())
} }
} }
@@ -23,14 +23,14 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
public class InlineCycleReporter(val diagnostics: DiagnosticSink) { class InlineCycleReporter(val diagnostics: DiagnosticSink) {
val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>() val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>()
public fun enterIntoInlining(call: ResolvedCall<*>?): Boolean { fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
//null call for default method inlining //null call for default method inlining
if (call != null) { if (call != null) {
val callElement = call.getCall().getCallElement() val callElement = call.call.callElement
if (processingFunctions.contains(callElement)) { if (processingFunctions.contains(callElement)) {
val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement } val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement }
cycle.forEach { cycle.forEach {
@@ -38,14 +38,14 @@ public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
} }
return false return false
} }
processingFunctions.put(callElement, call.getResultingDescriptor().getOriginal()) processingFunctions.put(callElement, call.resultingDescriptor.original)
} }
return true return true
} }
public fun exitFromInliningOf(call: ResolvedCall<*>?) { fun exitFromInliningOf(call: ResolvedCall<*>?) {
if (call != null) { if (call != null) {
val callElement = call.getCall().getCallElement() val callElement = call.call.callElement
processingFunctions.remove(callElement) processingFunctions.remove(callElement)
} }
} }
@@ -38,7 +38,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Opcodes.*
import java.util.* import java.util.*
public class InterfaceImplBodyCodegen( class InterfaceImplBodyCodegen(
aClass: KtClassOrObject, aClass: KtClassOrObject,
context: ClassContext, context: ClassContext,
v: ClassBuilder, v: ClassBuilder,
@@ -54,7 +54,7 @@ public class InterfaceImplBodyCodegen(
typeMapper.mapDefaultImpls(descriptor).internalName, typeMapper.mapDefaultImpls(descriptor).internalName,
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
) )
v.visitSource(myClass.getContainingFile().getName(), null) v.visitSource(myClass.containingFile.name, null)
} }
override fun classForInnerClassRecord(): ClassDescriptor? { override fun classForInnerClassRecord(): ClassDescriptor? {
@@ -69,12 +69,12 @@ public class InterfaceImplBodyCodegen(
} }
override fun generateSyntheticParts() { override fun generateSyntheticParts() {
for (memberDescriptor in descriptor.getDefaultType().getMemberScope().getContributedDescriptors()) { for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
if (memberDescriptor !is CallableMemberDescriptor) continue if (memberDescriptor !is CallableMemberDescriptor) continue
if (memberDescriptor.getKind().isReal()) continue if (memberDescriptor.kind.isReal) continue
if (memberDescriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) continue if (memberDescriptor.visibility == Visibilities.INVISIBLE_FAKE) continue
if (memberDescriptor.getModality() == Modality.ABSTRACT) continue if (memberDescriptor.modality == Modality.ABSTRACT) continue
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
@@ -82,7 +82,7 @@ public class InterfaceImplBodyCodegen(
if (implementation is JavaMethodDescriptor) continue if (implementation is JavaMethodDescriptor) continue
// We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body // We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body
val copy = memberDescriptor.copy(memberDescriptor.getContainingDeclaration(), Modality.OPEN, memberDescriptor.getVisibility(), val copy = memberDescriptor.copy(memberDescriptor.containingDeclaration, Modality.OPEN, memberDescriptor.visibility,
CallableMemberDescriptor.Kind.DECLARATION, true) CallableMemberDescriptor.Kind.DECLARATION, true)
if (memberDescriptor is FunctionDescriptor) { if (memberDescriptor is FunctionDescriptor) {
@@ -90,13 +90,13 @@ public class InterfaceImplBodyCodegen(
} }
else if (memberDescriptor is PropertyDescriptor) { else if (memberDescriptor is PropertyDescriptor) {
implementation as PropertyDescriptor implementation as PropertyDescriptor
val getter = (copy as PropertyDescriptor).getGetter() val getter = (copy as PropertyDescriptor).getter
val implGetter = implementation.getGetter() val implGetter = implementation.getter
if (getter != null && implGetter != null) { if (getter != null && implGetter != null) {
generateDelegationToSuperTraitImpl(getter, implGetter) generateDelegationToSuperTraitImpl(getter, implGetter)
} }
val setter = copy.getSetter() val setter = copy.setter
val implSetter = implementation.getSetter() val implSetter = implementation.setter
if (setter != null && implSetter != null) { if (setter != null && implSetter != null) {
generateDelegationToSuperTraitImpl(setter, implSetter) generateDelegationToSuperTraitImpl(setter, implSetter)
} }
@@ -120,7 +120,7 @@ public class InterfaceImplBodyCodegen(
val iv = codegen.v val iv = codegen.v
val method = typeMapper.mapToCallableMethod(delegateTo, true) val method = typeMapper.mapToCallableMethod(delegateTo, true)
val myParameters = signature.getValueParameters() val myParameters = signature.valueParameters
val calleeParameters = method.getValueParameters() val calleeParameters = method.getValueParameters()
if (myParameters.size != calleeParameters.size) { if (myParameters.size != calleeParameters.size) {
@@ -135,14 +135,14 @@ public class InterfaceImplBodyCodegen(
var k = 0 var k = 0
val it = calleeParameters.iterator() val it = calleeParameters.iterator()
for (parameter in myParameters) { for (parameter in myParameters) {
val type = parameter.getAsmType() val type = parameter.asmType
StackValue.local(k, type).put(it.next().getAsmType(), iv) StackValue.local(k, type).put(it.next().asmType, iv)
k += type.getSize() k += type.size
} }
method.genInvokeInstruction(iv) method.genInvokeInstruction(iv)
StackValue.coerce(method.returnType, signature.getReturnType(), iv) StackValue.coerce(method.returnType, signature.returnType, iv)
iv.areturn(signature.getReturnType()) iv.areturn(signature.returnType)
} }
}) })
} }
@@ -79,15 +79,14 @@ class JvmStaticGenerator(
} }
companion object { companion object {
@JvmStatic @JvmStatic fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
public fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor { val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
val copies = CodegenUtil.copyFunctions( val copies = CodegenUtil.copyFunctions(
memberDescriptor, memberDescriptor,
memberDescriptor, memberDescriptor,
descriptor.getContainingDeclaration().getContainingDeclaration(), descriptor.containingDeclaration.containingDeclaration,
descriptor.getModality(), descriptor.modality,
descriptor.getVisibility(), descriptor.visibility,
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
false false
) )
@@ -54,9 +54,9 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.* import java.util.*
public class MultifileClassCodegen( class MultifileClassCodegen(
private val state: GenerationState, private val state: GenerationState,
public val files: Collection<KtFile>, val files: Collection<KtFile>,
private val facadeFqName: FqName private val facadeFqName: FqName
) { ) {
private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName) private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName)
@@ -74,7 +74,7 @@ public class MultifileClassCodegen(
private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) = private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) =
compiledPackageFragment.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CALLABLES, MemberScope.ALL_NAME_FILTER).filterIsInstance<DeserializedCallableMemberDescriptor>() compiledPackageFragment.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CALLABLES, MemberScope.ALL_NAME_FILTER).filterIsInstance<DeserializedCallableMemberDescriptor>()
public val packageParts = PackageParts(facadeFqName.parent().asString()) val packageParts = PackageParts(facadeFqName.parent().asString())
private val classBuilder = ClassBuilderOnDemand { private val classBuilder = ClassBuilderOnDemand {
val originFile = files.firstOrNull() val originFile = files.firstOrNull()
@@ -103,7 +103,7 @@ public class MultifileClassCodegen(
classBuilder classBuilder
} }
public fun generate(errorHandler: CompilationErrorHandler) { fun generate(errorHandler: CompilationErrorHandler) {
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>() val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
val partFqNames = arrayListOf<FqName>() val partFqNames = arrayListOf<FqName>()
@@ -152,7 +152,7 @@ public class MultifileClassCodegen(
writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames) writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames)
} }
public fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) { fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null) MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null)
} }
@@ -292,7 +292,7 @@ public class MultifileClassCodegen(
override fun generateKotlinAnnotation() = throw UnsupportedOperationException() override fun generateKotlinAnnotation() = throw UnsupportedOperationException()
} }
public fun done() { fun done() {
classBuilder.done() classBuilder.done()
} }
@@ -31,7 +31,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import java.util.* import java.util.*
public class MultifileClassPartCodegen( class MultifileClassPartCodegen(
v: ClassBuilder, v: ClassBuilder,
file: KtFile, file: KtFile,
private val filePartType: Type, private val filePartType: Type,
@@ -39,7 +39,7 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.commons.Method
public class PropertyReferenceCodegen( class PropertyReferenceCodegen(
state: GenerationState, state: GenerationState,
parentCodegen: MemberCodegen<*>, parentCodegen: MemberCodegen<*>,
context: ClassContext, context: ClassContext,
@@ -68,22 +68,22 @@ public class PropertyReferenceCodegen(
element, element,
V1_6, V1_6,
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor), ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor),
asmType.getInternalName(), asmType.internalName,
null, null,
superAsmType.getInternalName(), superAsmType.internalName,
emptyArray() emptyArray()
) )
v.visitSource(element.getContainingFile().getName(), null) v.visitSource(element.containingFile.name, null)
} }
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction? // TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
override fun generateBody() { override fun generateBody() {
generateConstInstance(asmType, wrapperMethod.getReturnType()) generateConstInstance(asmType, wrapperMethod.returnType)
generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) { generateMethod("property reference init", 0, method("<init>", Type.VOID_TYPE)) {
load(0, OBJECT_TYPE) load(0, OBJECT_TYPE)
invokespecial(superAsmType.getInternalName(), "<init>", "()V", false) invokespecial(superAsmType.internalName, "<init>", "()V", false)
} }
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) { generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
@@ -91,7 +91,7 @@ public class PropertyReferenceCodegen(
} }
generateMethod("property reference getName", ACC_PUBLIC, method("getName", JAVA_STRING_TYPE)) { generateMethod("property reference getName", ACC_PUBLIC, method("getName", JAVA_STRING_TYPE)) {
aconst(target.getName().asString()) aconst(target.name.asString())
} }
generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) { generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) {
@@ -108,11 +108,11 @@ public class PropertyReferenceCodegen(
// return type and value parameter types. However, it's created only to be able to use // return type and value parameter types. However, it's created only to be able to use
// ExpressionCodegen#intermediateValueForProperty, which is poorly coupled with everything else. // ExpressionCodegen#intermediateValueForProperty, which is poorly coupled with everything else.
val fakeDescriptor = SimpleFunctionDescriptorImpl.create( val fakeDescriptor = SimpleFunctionDescriptorImpl.create(
classDescriptor, Annotations.EMPTY, Name.identifier(method.getName()), CallableMemberDescriptor.Kind.DECLARATION, classDescriptor, Annotations.EMPTY, Name.identifier(method.name), CallableMemberDescriptor.Kind.DECLARATION,
SourceElement.NO_SOURCE SourceElement.NO_SOURCE
) )
fakeDescriptor.initialize(null, classDescriptor.getThisAsReceiverParameter(), emptyList(), emptyList(), fakeDescriptor.initialize(null, classDescriptor.thisAsReceiverParameter, emptyList(), emptyList(),
classDescriptor.builtIns.getAnyType(), Modality.OPEN, Visibilities.PUBLIC) classDescriptor.builtIns.anyType, Modality.OPEN, Visibilities.PUBLIC)
val fakeCodegen = ExpressionCodegen( val fakeCodegen = ExpressionCodegen(
this, FrameMap(), OBJECT_TYPE, context.intoFunction(fakeDescriptor), state, this@PropertyReferenceCodegen this, FrameMap(), OBJECT_TYPE, context.intoFunction(fakeDescriptor), state, this@PropertyReferenceCodegen
@@ -147,13 +147,13 @@ public class PropertyReferenceCodegen(
} }
private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) { private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) {
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.getName(), method.getDescriptor(), null, null) val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, method.name, method.descriptor, null, null)
if (state.classBuilderMode == ClassBuilderMode.FULL) { if (state.classBuilderMode == ClassBuilderMode.FULL) {
val iv = InstructionAdapter(mv) val iv = InstructionAdapter(mv)
iv.visitCode() iv.visitCode()
iv.generate() iv.generate()
iv.areturn(method.getReturnType()) iv.areturn(method.returnType)
FunctionCodegen.endVisit(mv, debugString, element) FunctionCodegen.endVisit(mv, debugString, element)
} }
} }
@@ -162,9 +162,9 @@ public class PropertyReferenceCodegen(
writeKotlinSyntheticClassAnnotation(v, state) writeKotlinSyntheticClassAnnotation(v, state)
} }
public fun putInstanceOnStack(): StackValue = fun putInstanceOnStack(): StackValue =
StackValue.operation(wrapperMethod.getReturnType()) { iv -> StackValue.operation(wrapperMethod.returnType) { iv ->
iv.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, wrapperMethod.getReturnType().getDescriptor()) iv.getstatic(asmType.internalName, JvmAbi.INSTANCE_FIELD, wrapperMethod.returnType.descriptor)
} }
companion object { companion object {
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.RawSignature
import org.jetbrains.org.objectweb.asm.FieldVisitor import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
public abstract class SignatureCollectingClassBuilderFactory( abstract class SignatureCollectingClassBuilderFactory(
delegate: ClassBuilderFactory delegate: ClassBuilderFactory
) : DelegatingClassBuilderFactory(delegate) { ) : DelegatingClassBuilderFactory(delegate) {
@@ -22,19 +22,19 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
data public class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) { data class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
companion object { companion object {
fun createInfo(element: KtElement?, internalClassName: String): SourceInfo { fun createInfo(element: KtElement?, internalClassName: String): SourceInfo {
assert(element != null) { "Couldn't create source mapper for null element " + internalClassName } assert(element != null) { "Couldn't create source mapper for null element " + internalClassName }
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.getContainingFile(), true) val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.containingFile, true)
assert(lineNumbers != null) { "Couldn't extract line count in " + element.getContainingFile() } assert(lineNumbers != null) { "Couldn't extract line count in " + element.containingFile }
//TODO hack condition for package parts cleaning //TODO hack condition for package parts cleaning
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile) val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$') val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
return SourceInfo(element.getContainingKtFile().getName(), cleanedClassFqName, lineNumbers!!) return SourceInfo(element.getContainingKtFile().name, cleanedClassFqName, lineNumbers!!)
} }
} }
@@ -44,7 +44,7 @@ class CoercionValue(
} }
public class StackValueWithLeaveTask( class StackValueWithLeaveTask(
val stackValue: StackValue, val stackValue: StackValue,
val leaveTasks: (StackValue) -> Unit val leaveTasks: (StackValue) -> Unit
) : StackValue(stackValue.type) { ) : StackValue(stackValue.type) {
@@ -22,15 +22,15 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
public interface WrappedAnnotated : Annotated { interface WrappedAnnotated : Annotated {
public val originalAnnotated: Annotated val originalAnnotated: Annotated
} }
public class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated { class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, private val actual: Annotations) : WrappedAnnotated {
override fun getAnnotations() = actual override fun getAnnotations() = actual
} }
public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated { class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
private val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations) private val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
override fun getAnnotations() = annotations override fun getAnnotations() = annotations
@@ -52,4 +52,4 @@ public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotate
} }
} }
public class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations) class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)
@@ -43,8 +43,7 @@ class BridgeForBuiltinSpecial<Signature>(
) )
object BuiltinSpecialBridgesUtil { object BuiltinSpecialBridgesUtil {
@JvmStatic @JvmStatic fun <Signature> generateBridgesForBuiltinSpecial(
public fun <Signature> generateBridgesForBuiltinSpecial(
function: FunctionDescriptor, function: FunctionDescriptor,
signatureByDescriptor: (FunctionDescriptor) -> Signature signatureByDescriptor: (FunctionDescriptor) -> Signature
): Set<BridgeForBuiltinSpecial<Signature>> { ): Set<BridgeForBuiltinSpecial<Signature>> {
@@ -93,8 +92,7 @@ object BuiltinSpecialBridgesUtil {
return bridges return bridges
} }
@JvmStatic @JvmStatic fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
public fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
signatureByDescriptor: (FunctionDescriptor) -> Signature signatureByDescriptor: (FunctionDescriptor) -> Signature
): Boolean { ): Boolean {
if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false
@@ -143,7 +141,7 @@ private fun <Signature> needGenerateSpecialBridge(
&& signatureByDescriptor(it) == overriddenBuiltinSignature } && signatureByDescriptor(it) == overriddenBuiltinSignature }
} }
public fun isValueArgumentForCallToMethodWithTypeCheckBarrier( fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
element: KtElement, element: KtElement,
bindingContext: BindingContext bindingContext: BindingContext
): Boolean { ): Boolean {
@@ -103,7 +103,7 @@ private fun generateNullCheckForNonSafeAs(
} }
} }
public fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String? fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") } = valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }
fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) { fun populateCompanionBackingFieldNamesToOuterContextIfNeeded(companion: KtObjectDeclaration, outerContext: FieldOwnerContext<*>, state: GenerationState) {
@@ -18,16 +18,14 @@ package org.jetbrains.kotlin.codegen.context
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
public object CodegenContextUtil { object CodegenContextUtil {
@JvmStatic @JvmStatic fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
public fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
when (owner) { when (owner) {
is MultifileClassFacadeContext -> owner.filePartType is MultifileClassFacadeContext -> owner.filePartType
is DelegatingToPartContext -> owner.implementationOwnerClassType is DelegatingToPartContext -> owner.implementationOwnerClassType
else -> null else -> null
} }
@JvmStatic @JvmStatic fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
public fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
owner !is MultifileClassFacadeContext owner !is MultifileClassFacadeContext
} }
@@ -21,11 +21,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
public interface ClassBuilderInterceptorExtension { interface ClassBuilderInterceptorExtension {
companion object : ProjectExtensionDescriptor<ClassBuilderInterceptorExtension>( companion object : ProjectExtensionDescriptor<ClassBuilderInterceptorExtension>(
"org.jetbrains.kotlin.classBuilderFactoryInterceptorExtension", ClassBuilderInterceptorExtension::class.java) "org.jetbrains.kotlin.classBuilderFactoryInterceptorExtension", ClassBuilderInterceptorExtension::class.java)
public fun interceptClassBuilderFactory( fun interceptClassBuilderFactory(
interceptedFactory: ClassBuilderFactory, interceptedFactory: ClassBuilderFactory,
bindingContext: BindingContext, bindingContext: BindingContext,
diagnostics: DiagnosticSink diagnostics: DiagnosticSink
@@ -26,28 +26,28 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
public interface ExpressionCodegenExtension { interface ExpressionCodegenExtension {
companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>( companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>(
"org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java) "org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java)
public class Context( class Context(
public val typeMapper: JetTypeMapper, val typeMapper: JetTypeMapper,
public val v: InstructionAdapter val v: InstructionAdapter
) )
/** /**
* Used for generating custom byte code for the property value obtain. This function has lazy semantics. * Used for generating custom byte code for the property value obtain. This function has lazy semantics.
* Returns new stack value. * Returns new stack value.
*/ */
public fun applyProperty(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null fun applyProperty(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
/** /**
* Used for generating custom byte code for the function call. This function has lazy semantics. * Used for generating custom byte code for the function call. This function has lazy semantics.
* Returns new stack value. * Returns new stack value.
*/ */
public fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
public fun generateClassSyntheticParts( fun generateClassSyntheticParts(
classBuilder: ClassBuilder, classBuilder: ClassBuilder,
state: GenerationState, state: GenerationState,
classOrObject: KtClassOrObject, classOrObject: KtClassOrObject,
@@ -25,26 +25,26 @@ import org.jetbrains.org.objectweb.asm.tree.*
import java.util.Comparator import java.util.Comparator
import java.util.Collections import java.util.Collections
public abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) { abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
public val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo() val tryBlocksMetaInfo: IntervalMetaInfo<TryCatchBlockNodeInfo> = IntervalMetaInfo()
public val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo() val localVarsMetaInfo: IntervalMetaInfo<LocalVarNodeWrapper> = IntervalMetaInfo()
public var nextFreeLocalIndex: Int = parameterSize var nextFreeLocalIndex: Int = parameterSize
private set private set
public fun getStartNodes(label: LabelNode): List<TryCatchBlockNodeInfo> { fun getStartNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
return tryBlocksMetaInfo.intervalStarts.get(label) return tryBlocksMetaInfo.intervalStarts.get(label)
} }
public fun getEndNodes(label: LabelNode): List<TryCatchBlockNodeInfo> { fun getEndNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
return tryBlocksMetaInfo.intervalEnds.get(label) return tryBlocksMetaInfo.intervalEnds.get(label)
} }
public open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) { open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) {
if (curInstr is VarInsnNode || curInstr is IincInsnNode) { if (curInstr is VarInsnNode || curInstr is IincInsnNode) {
val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.getOpcode()) val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.opcode)
val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var` val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var`
nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize) nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize)
} }
@@ -55,9 +55,9 @@ public abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
} }
} }
public abstract fun instructionIndex(inst: AbstractInsnNode): Int abstract fun instructionIndex(inst: AbstractInsnNode): Int
public fun sortTryCatchBlocks(intervals: List<TryCatchBlockNodeInfo>): List<TryCatchBlockNodeInfo> { fun sortTryCatchBlocks(intervals: List<TryCatchBlockNodeInfo>): List<TryCatchBlockNodeInfo> {
val comp = Comparator { t1: TryCatchBlockNodeInfo, t2: TryCatchBlockNodeInfo -> val comp = Comparator { t1: TryCatchBlockNodeInfo, t2: TryCatchBlockNodeInfo ->
var result = instructionIndex(t1.handler) - instructionIndex(t2.handler) var result = instructionIndex(t1.handler) - instructionIndex(t2.handler)
if (result == 0) { if (result == 0) {
@@ -83,7 +83,7 @@ public abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
} }
public fun substituteLocalVarTable(node: MethodNode) { fun substituteLocalVarTable(node: MethodNode) {
node.localVariables.clear() node.localVariables.clear()
for (info in localVarsMetaInfo.getMeaningfulIntervals()) { for (info in localVarsMetaInfo.getMeaningfulIntervals()) {
node.localVariables.add(info.node) node.localVariables.add(info.node)
@@ -165,16 +165,16 @@ private fun Interval.isMeaningless(): Boolean {
val start = this.startLabel val start = this.startLabel
var end: AbstractInsnNode = this.endLabel var end: AbstractInsnNode = this.endLabel
while (end != start && !end.isMeaningful) { while (end != start && !end.isMeaningful) {
end = end.getPrevious() end = end.previous
} }
return start == end return start == end
} }
public fun <T : SplittableInterval<T>> IntervalMetaInfo<T>.getMeaningfulIntervals(): List<T> { fun <T : SplittableInterval<T>> IntervalMetaInfo<T>.getMeaningfulIntervals(): List<T> {
return allIntervals.filterNot { it.isMeaningless() } return allIntervals.filterNot { it.isMeaningless() }
} }
public class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) { class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) {
init { init {
node.tryCatchBlocks.forEach { addTryNode(it) } node.tryCatchBlocks.forEach { addTryNode(it) }
@@ -194,7 +194,7 @@ public class DefaultProcessor(val node: MethodNode, parameterSize: Int) : Coveri
} }
} }
public class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInterval<LocalVarNodeWrapper> { class LocalVarNodeWrapper(val node: LocalVariableNode) : Interval, SplittableInterval<LocalVarNodeWrapper> {
override val startLabel: LabelNode override val startLabel: LabelNode
get() = node.start get() = node.start
override val endLabel: LabelNode override val endLabel: LabelNode
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
public class DeferredMethodVisitor( class DeferredMethodVisitor(
val intermediate: MethodNode, val intermediate: MethodNode,
val resultNode: () -> MethodVisitor val resultNode: () -> MethodVisitor
) : MethodVisitor(InlineCodegenUtil.API, intermediate) { ) : MethodVisitor(InlineCodegenUtil.API, intermediate) {
@@ -24,10 +24,10 @@ internal class Parameters(val real: List<ParameterInfo>, val captured: List<Capt
private val actualDeclShifts: Array<ParameterInfo?> private val actualDeclShifts: Array<ParameterInfo?>
private val paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf() private val paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf()
public val realArgsSizeOnStack = real.sumBy { it.type.size } val realArgsSizeOnStack = real.sumBy { it.type.size }
public val capturedArgsSizeOnStack = captured.sumBy { it.type.size } val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
public val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack
init { init {
val declIndexesToActual = arrayOfNulls<Int>(argsSizeOnStack) val declIndexesToActual = arrayOfNulls<Int>(argsSizeOnStack)
@@ -33,7 +33,7 @@ import org.jetbrains.org.objectweb.asm.tree.*
private class ParameterNameAndNullability(val name: String, val nullable: Boolean) private class ParameterNameAndNullability(val name: String, val nullable: Boolean)
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) { class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
enum class OperationKind { enum class OperationKind {
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS; NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
@@ -43,25 +43,21 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
} }
companion object { companion object {
@JvmField @JvmField val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
public val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker" @JvmField val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
@JvmField
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
private fun isOperationReifiedMarker(insn: AbstractInsnNode) = private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME } isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean { private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
if (insn.getOpcode() != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false if (insn.opcode != Opcodes.INVOKESTATIC || insn !is MethodInsnNode) return false
return insn.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && namePredicate(insn.name) return insn.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME && namePredicate(insn.name)
} }
@JvmStatic @JvmStatic fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
public fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
isReifiedMarker(insn) { s -> s == NEED_CLASS_REIFICATION_MARKER_METHOD_NAME } isReifiedMarker(insn) { s -> s == NEED_CLASS_REIFICATION_MARKER_METHOD_NAME }
@JvmStatic @JvmStatic fun putNeedClassReificationMarker(v: MethodVisitor) {
public fun putNeedClassReificationMarker(v: MethodVisitor) {
v.visitMethodInsn( v.visitMethodInsn(
Opcodes.INVOKESTATIC, Opcodes.INVOKESTATIC,
IntrinsicMethods.INTRINSICS_CLASS_NAME, NEED_CLASS_REIFICATION_MARKER_METHOD_NAME, IntrinsicMethods.INTRINSICS_CLASS_NAME, NEED_CLASS_REIFICATION_MARKER_METHOD_NAME,
@@ -77,7 +73,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
* e.g. when we're generating inline function containing reified T * e.g. when we're generating inline function containing reified T
* and another function containing reifiable parts is inlined into that function * and another function containing reifiable parts is inlined into that function
*/ */
public fun reifyInstructions(node: MethodNode): ReifiedTypeParametersUsages { fun reifyInstructions(node: MethodNode): ReifiedTypeParametersUsages {
if (parametersMapping == null) return ReifiedTypeParametersUsages() if (parametersMapping == null) return ReifiedTypeParametersUsages()
val instructions = node.instructions val instructions = node.instructions
maxStackSize = 0 maxStackSize = 0
@@ -95,7 +91,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
return result return result
} }
public fun reifySignature(oldSignature: String): SignatureReificationResult { fun reifySignature(oldSignature: String): SignatureReificationResult {
if (parametersMapping == null) return SignatureReificationResult(oldSignature, ReifiedTypeParametersUsages()) if (parametersMapping == null) return SignatureReificationResult(oldSignature, ReifiedTypeParametersUsages())
val signatureRemapper = object : SignatureWriter() { val signatureRemapper = object : SignatureWriter() {
@@ -223,13 +219,13 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
} }
private fun processNextTypeInsn(insn: MethodInsnNode, parameter: Type, expectedNextOpcode: Int): Boolean { private fun processNextTypeInsn(insn: MethodInsnNode, parameter: Type, expectedNextOpcode: Int): Boolean {
if (insn.getNext()?.getOpcode() != expectedNextOpcode) return false if (insn.next?.opcode != expectedNextOpcode) return false
(insn.getNext() as TypeInsnNode).desc = parameter.getInternalName() (insn.next as TypeInsnNode).desc = parameter.internalName
return true return true
} }
private fun processJavaClass(insn: MethodInsnNode, parameter: Type): Boolean { private fun processJavaClass(insn: MethodInsnNode, parameter: Type): Boolean {
val next = insn.getNext() val next = insn.next
if (next !is LdcInsnNode) return false if (next !is LdcInsnNode) return false
next.cst = parameter next.cst = parameter
return true return true
@@ -255,14 +251,14 @@ private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get(
ReifiedTypeInliner.OperationKind.values().getOrNull(it) ReifiedTypeInliner.OperationKind.values().getOrNull(it)
} }
public class ReifiedTypeParameterMappings() { class ReifiedTypeParameterMappings() {
private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>() private val mappingsByName = hashMapOf<String, ReifiedTypeParameterMapping>()
public fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String) { fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String) {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type, asmType, newName = null, signature = signature) mappingsByName[name] = ReifiedTypeParameterMapping(name, type, asmType, newName = null, signature = signature)
} }
public fun addParameterMappingToNewParameter(name: String, type: KotlinType, newName: String) { fun addParameterMappingToNewParameter(name: String, type: KotlinType, newName: String) {
mappingsByName[name] = ReifiedTypeParameterMapping(name, type = type, asmType = null, newName = newName, signature = null) mappingsByName[name] = ReifiedTypeParameterMapping(name, type = type, asmType = null, newName = newName, signature = null)
} }
@@ -271,20 +267,20 @@ public class ReifiedTypeParameterMappings() {
} }
} }
public class ReifiedTypeParameterMapping( 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 { class ReifiedTypeParametersUsages {
val usedTypeParameters: MutableSet<String> = hashSetOf() val usedTypeParameters: MutableSet<String> = hashSetOf()
public fun wereUsedReifiedParameters(): Boolean = usedTypeParameters.isNotEmpty() fun wereUsedReifiedParameters(): Boolean = usedTypeParameters.isNotEmpty()
public fun addUsedReifiedParameter(name: String) { fun addUsedReifiedParameter(name: String) {
usedTypeParameters.add(name) usedTypeParameters.add(name)
} }
public fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) { fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) {
if (!child.wereUsedReifiedParameters()) return if (!child.wereUsedReifiedParameters()) return
// used for propagating reified TP usages from children member codegen to parent's // used for propagating reified TP usages from children member codegen to parent's
// mark enclosing object-literal/lambda as needed reification iff // mark enclosing object-literal/lambda as needed reification iff
@@ -298,7 +294,7 @@ public class ReifiedTypeParametersUsages {
}.forEach { usedTypeParameters.add(it) } }.forEach { usedTypeParameters.add(it) }
} }
public fun mergeAll(other: ReifiedTypeParametersUsages) { fun mergeAll(other: ReifiedTypeParametersUsages) {
if (!other.wereUsedReifiedParameters()) return if (!other.wereUsedReifiedParameters()) return
usedTypeParameters.addAll(other.usedTypeParameters) usedTypeParameters.addAll(other.usedTypeParameters)
} }
@@ -24,7 +24,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
import java.util.* import java.util.*
//TODO join parameter //TODO join parameter
public class SMAPBuilder(val source: String, class SMAPBuilder(val source: String,
val path: String, val path: String,
val fileMappings: List<FileMapping>) { val fileMappings: List<FileMapping>) {
@@ -62,7 +62,7 @@ public class SMAPBuilder(val source: String,
} }
} }
public open class NestedSourceMapper(parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo) : DefaultSourceMapper(sourceInfo, parent) { open class NestedSourceMapper(parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo) : DefaultSourceMapper(sourceInfo, parent) {
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) { override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
val index = Collections.binarySearch(ranges, RangeMapping(lineNumber, lineNumber, 1)) { val index = Collections.binarySearch(ranges, RangeMapping(lineNumber, lineNumber, 1)) {
@@ -81,7 +81,7 @@ public open class NestedSourceMapper(parent: SourceMapper, val ranges: List<Rang
} }
} }
public open class InlineLambdaSourceMapper(parent: SourceMapper, smap: SMAPAndMethodNode) : NestedSourceMapper(parent, smap.ranges, smap.classSMAP.sourceInfo) { open class InlineLambdaSourceMapper(parent: SourceMapper, smap: SMAPAndMethodNode) : NestedSourceMapper(parent, smap.ranges, smap.classSMAP.sourceInfo) {
override fun visitSource(name: String, path: String) { override fun visitSource(name: String, path: String) {
super.visitSource(name, path) super.visitSource(name, path)
@@ -162,7 +162,7 @@ interface SourceMapper {
} }
} }
public object IdenticalSourceMapper : SourceMapper { object IdenticalSourceMapper : SourceMapper {
override val resultMappings: List<FileMapping> override val resultMappings: List<FileMapping>
get() = emptyList() get() = emptyList()
@@ -178,7 +178,7 @@ public object IdenticalSourceMapper : SourceMapper {
} }
} }
public open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent: SourceMapper?): SourceMapper { open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent: SourceMapper?): SourceMapper {
protected var maxUsedValue: Int = sourceInfo.linesInFile protected var maxUsedValue: Int = sourceInfo.linesInFile
@@ -273,7 +273,7 @@ class RawFileMapping(val name: String, val path: String) {
} }
fun initRange(start: Int, end: Int) { fun initRange(start: Int, end: Int) {
assert(lineMappings.isEmpty()) { "initRange should only be called for empty mapping" } assert(lineMappings.isEmpty) { "initRange should only be called for empty mapping" }
for (index in start..end) { for (index in start..end) {
lineMappings.put(index, index) lineMappings.put(index, index)
} }
@@ -319,7 +319,7 @@ class RawFileMapping(val name: String, val path: String) {
} }
} }
open public class FileMapping(val name: String, val path: String) { open class FileMapping(val name: String, val path: String) {
val lineMappings = arrayListOf<RangeMapping>() val lineMappings = arrayListOf<RangeMapping>()
var id = -1; var id = -1;
@@ -329,7 +329,7 @@ open public class FileMapping(val name: String, val path: String) {
lineMapping.parent = this lineMapping.parent = this
} }
public object SKIP : FileMapping("no-source-info", "no-source-info") { object SKIP : FileMapping("no-source-info", "no-source-info") {
init { init {
addRangeMapping(RangeMapping.SKIP) addRangeMapping(RangeMapping.SKIP)
} }
@@ -337,7 +337,7 @@ open public class FileMapping(val name: String, val path: String) {
} }
//TODO comparable //TODO comparable
data public class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) { data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
var parent: FileMapping? = null; var parent: FileMapping? = null;
@@ -366,6 +366,6 @@ data public class RangeMapping(val source: Int, val dest: Int, var range: Int =
} }
companion object { companion object {
public val SKIP = RangeMapping(-1, -1, 1) val SKIP = RangeMapping(-1, -1, 1)
} }
} }
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.codegen.SourceInfo
class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) { class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) {
val lineNumbers = val lineNumbers =
InsnSequence(node.instructions.getFirst(), null).filterIsInstance<LineNumberNode>().map { InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map {
val index = Collections.binarySearch(classSMAP.intervals, RangeMapping(it.line, it.line, 1)) { val index = Collections.binarySearch(classSMAP.intervals, RangeMapping(it.line, it.line, 1)) {
value, key -> value, key ->
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key) if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)
@@ -21,8 +21,7 @@ import com.intellij.util.SmartFMap
object SMAPParser { object SMAPParser {
@JvmStatic @JvmStatic
/*null smap means that there is no any debug info in file (e.g. sourceName)*/ /*null smap means that there is no any debug info in file (e.g. sourceName)*/ fun parseOrCreateDefault(mappingInfo: String?, source: String?, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
public fun parseOrCreateDefault(mappingInfo: String?, source: String?, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
if (mappingInfo == null || mappingInfo.isEmpty()) { if (mappingInfo == null || mappingInfo.isEmpty()) {
val fm: FileMapping val fm: FileMapping
if (source == null || source.isEmpty()) { if (source == null || source.isEmpty()) {
@@ -40,8 +39,7 @@ object SMAPParser {
return parse(mappingInfo) return parse(mappingInfo)
} }
@JvmStatic @JvmStatic fun parse(mappingInfo: String): SMAP {
public fun parse(mappingInfo: String): SMAP {
val fileMappings = linkedMapOf<Int, FileMapping>() 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
@@ -26,7 +26,7 @@ enum class TryCatchPosition {
INNER INNER
} }
public class SplitPair<T: Interval>(val patchedPart: T, val newPart: T) class SplitPair<T: Interval>(val patchedPart: T, val newPart: T)
class SimpleInterval(override val startLabel: LabelNode, override val endLabel: LabelNode ) : Interval class SimpleInterval(override val startLabel: LabelNode, override val endLabel: LabelNode ) : Interval
@@ -35,7 +35,7 @@ interface Interval {
val endLabel: LabelNode val endLabel: LabelNode
/*note that some intervals are mutable */ /*note that some intervals are mutable */
public fun isEmpty(): Boolean = startLabel == endLabel fun isEmpty(): Boolean = startLabel == endLabel
} }
@@ -27,14 +27,14 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
public val FunctionDescriptor.sourceFilePath: String val FunctionDescriptor.sourceFilePath: String
get() { get() {
val source = source as PsiSourceElement val source = source as PsiSourceElement
val containingFile = source.psi?.containingFile val containingFile = source.psi?.containingFile
return containingFile?.virtualFile?.canonicalPath!! return containingFile?.virtualFile?.canonicalPath!!
} }
public fun FunctionDescriptor.getClassFilePath(typeMapper: JetTypeMapper, cache: IncrementalCache): String { fun FunctionDescriptor.getClassFilePath(typeMapper: JetTypeMapper, cache: IncrementalCache): String {
val container = containingDeclaration as? DeclarationDescriptorWithSource val container = containingDeclaration as? DeclarationDescriptorWithSource
val source = container?.source val source = container?.source
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class ArrayGet : IntrinsicMethod() { class ArrayGet : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) { createIntrinsicCallable(method) {
val type = correctElementType(calcReceiverType()) val type = correctElementType(calcReceiverType())
@@ -20,10 +20,10 @@ import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class ArrayIterator : IntrinsicMethod() { class ArrayIterator : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) { createUnaryIntrinsicCallable(method) {
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}" val methodSignature = "(${method.owner.descriptor})${returnType.descriptor}"
val intrinsicOwner = val intrinsicOwner =
if (AsmUtil.isPrimitive(method.owner.elementType)) if (AsmUtil.isPrimitive(method.owner.elementType))
"kotlin/jvm/internal/ArrayIteratorsKt" "kotlin/jvm/internal/ArrayIteratorsKt"
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class ArraySet : IntrinsicMethod() { class ArraySet : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = correctElementType(method.dispatchReceiverType) val type = correctElementType(method.dispatchReceiverType)
return object : IntrinsicCallable( return object : IntrinsicCallable(
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
public class ArraySize : IntrinsicPropertyGetter() { class ArraySize : IntrinsicPropertyGetter() {
override fun generate( override fun generate(
resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue
) = StackValue.operation(returnType) { ) = StackValue.operation(returnType) {
@@ -25,7 +25,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes.ISHR
import org.jetbrains.org.objectweb.asm.Opcodes.IUSHR import org.jetbrains.org.objectweb.asm.Opcodes.IUSHR
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
public class BinaryOp(private val opcode: Int) : IntrinsicMethod() { class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
private fun shift(): Boolean = private fun shift(): Boolean =
opcode == ISHL || opcode == ISHR || opcode == IUSHR opcode == ISHL || opcode == ISHR || opcode == IUSHR
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
public class Clone : IntrinsicMethod() { class Clone : IntrinsicMethod() {
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable = override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable =
createUnaryIntrinsicCallable(method, OBJECT_TYPE) { createUnaryIntrinsicCallable(method, OBJECT_TYPE) {
val opcode = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL val opcode = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class CompareTo : IntrinsicMethod() { class CompareTo : IntrinsicMethod() {
private fun genInvoke(type: Type?, v: InstructionAdapter) { private fun genInvoke(type: Type?, v: InstructionAdapter) {
when (type) { when (type) {
Type.INT_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false) Type.INT_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false)
@@ -31,7 +31,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class Concat : IntrinsicMethod() { class Concat : IntrinsicMethod() {
fun generateImpl( fun generateImpl(
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
v: InstructionAdapter, v: InstructionAdapter,
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
public class Equals : IntrinsicMethod() { class Equals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createBinaryIntrinsicCallable( createBinaryIntrinsicCallable(
method.returnType, method.returnType,
@@ -22,7 +22,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class HashCode : IntrinsicMethod() { class HashCode : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable( object : IntrinsicCallable(
Type.INT_TYPE, Type.INT_TYPE,
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
public class IdentityEquals : IntrinsicMethod() { class IdentityEquals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) { object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments( override fun invokeMethodWithArguments(
@@ -34,17 +34,17 @@ public class IdentityEquals : IntrinsicMethod() {
receiver: StackValue, receiver: StackValue,
codegen: ExpressionCodegen codegen: ExpressionCodegen
): StackValue { ): StackValue {
val element = resolvedCall.getCall().getCallElement() val element = resolvedCall.call.callElement
val left: StackValue val left: StackValue
val right: StackValue val right: StackValue
if (element is KtCallExpression) { if (element is KtCallExpression) {
left = StackValue.receiver(resolvedCall, receiver, codegen, this) left = StackValue.receiver(resolvedCall, receiver, codegen, this)
right = codegen.gen(resolvedCall.getValueArgumentsByIndex()!!.single().getArguments().single().getArgumentExpression()) right = codegen.gen(resolvedCall.valueArgumentsByIndex!!.single().arguments.single().getArgumentExpression())
} }
else { else {
element as KtBinaryExpression element as KtBinaryExpression
left = codegen.gen(element.getLeft()) left = codegen.gen(element.left)
right = codegen.gen(element.getRight()) right = codegen.gen(element.right)
} }
return StackValue.cmp(KtTokens.EQEQEQ, OBJECT_TYPE, left, right) return StackValue.cmp(KtTokens.EQEQEQ, OBJECT_TYPE, left, right)
} }
@@ -22,11 +22,11 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.KtPrefixExpression import org.jetbrains.kotlin.psi.KtPrefixExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
public class Increment(private val myDelta: Int) : IntrinsicMethod() { class Increment(private val myDelta: Int) : IntrinsicMethod() {
override fun toCallable(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable = override fun toCallable(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable =
createIntrinsicCallable(method) { createIntrinsicCallable(method) {
val jetExpression = resolvedCall.getCall().getCalleeExpression() val jetExpression = resolvedCall.call.calleeExpression
assert(jetExpression !is KtPrefixExpression) { "There should be postfix increment ${jetExpression!!.getText()}" } assert(jetExpression !is KtPrefixExpression) { "There should be postfix increment ${jetExpression!!.text}" }
genIncrement(returnType, myDelta, it) genIncrement(returnType, myDelta, it)
} }
} }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public open class IntrinsicCallable( open class IntrinsicCallable(
override val returnType: Type, override val returnType: Type,
override val valueParameterTypes: List<Type>, override val valueParameterTypes: List<Type>,
override val dispatchReceiverType: Type?, override val dispatchReceiverType: Type?,
@@ -45,7 +45,7 @@ public open class IntrinsicCallable(
invokeIntrinsic(v) invokeIntrinsic(v)
} }
public open fun invokeIntrinsic(v: InstructionAdapter) { open fun invokeIntrinsic(v: InstructionAdapter) {
invoke(v) invoke(v)
} }
@@ -60,7 +60,7 @@ public open class IntrinsicCallable(
override val owner: Type override val owner: Type
get() = throw UnsupportedOperationException() get() = throw UnsupportedOperationException()
public fun calcReceiverType(): Type = fun calcReceiverType(): Type =
extensionReceiverType ?: dispatchReceiverType!! extensionReceiverType ?: dispatchReceiverType!!
} }
@@ -80,7 +80,7 @@ fun createBinaryIntrinsicCallable(
} }
} }
public fun createUnaryIntrinsicCallable( fun createUnaryIntrinsicCallable(
callable: CallableMethod, callable: CallableMethod,
newReturnType: Type? = null, newReturnType: Type? = null,
needPrimitiveCheck: Boolean = false, needPrimitiveCheck: Boolean = false,
@@ -103,7 +103,7 @@ public fun createUnaryIntrinsicCallable(
return intrinsic return intrinsic
} }
public fun createIntrinsicCallable( fun createIntrinsicCallable(
callable: CallableMethod, callable: CallableMethod,
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit
): IntrinsicCallable { ): IntrinsicCallable {
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
public abstract class IntrinsicPropertyGetter : IntrinsicMethod() { abstract class IntrinsicPropertyGetter : IntrinsicMethod() {
public abstract fun generate( abstract fun generate(
resolvedCall: ResolvedCall<*>?, resolvedCall: ResolvedCall<*>?,
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
returnType: Type, returnType: Type,
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
public class Inv : IntrinsicMethod() { class Inv : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = numberFunctionOperandType(method.returnType) val type = numberFunctionOperandType(method.returnType)
return createUnaryIntrinsicCallable(method, newThisType = type) { return createUnaryIntrinsicCallable(method, newThisType = type) {
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class IteratorNext : IntrinsicMethod() { class IteratorNext : IntrinsicMethod() {
private fun getIteratorName(returnType: Type): String { private fun getIteratorName(returnType: Type): String {
return when (returnType) { return when (returnType) {
Type.CHAR_TYPE -> "Char" Type.CHAR_TYPE -> "Char"
@@ -47,7 +47,7 @@ public class IteratorNext : IntrinsicMethod() {
v.invokevirtual( v.invokevirtual(
BUILT_INS_PACKAGE_FQ_NAME.asString() + "/" + name + "Iterator", BUILT_INS_PACKAGE_FQ_NAME.asString() + "/" + name + "Iterator",
"next$name", "next$name",
"()" + returnType.getDescriptor(), "()" + returnType.descriptor,
false false
) )
} }
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class JavaClassArray : IntrinsicMethod() { class JavaClassArray : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) { createIntrinsicCallable(method) {
//do nothing all generated as vararg //do nothing all generated as vararg
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class JavaClassFunction : IntrinsicMethod() { class JavaClassFunction : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType() val javaClass = resolvedCall.resultingDescriptor.returnType!!.arguments.first().type
return object : IntrinsicCallable(getType(Class::class.java), listOf(), null, null) { return object : IntrinsicCallable(getType(Class::class.java), listOf(), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.OperationKind.JAVA_CLASS) codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
@@ -28,8 +28,8 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class JavaClassProperty : IntrinsicPropertyGetter() { class JavaClassProperty : IntrinsicPropertyGetter() {
public override fun generate( override fun generate(
resolvedCall: ResolvedCall<*>?, resolvedCall: ResolvedCall<*>?,
codegen: ExpressionCodegen, codegen: ExpressionCodegen,
returnType: Type, returnType: Type,
@@ -47,7 +47,7 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
receiver.put(type, v) receiver.put(type, v)
AsmUtil.pop(v, type) AsmUtil.pop(v, type)
} }
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;") v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
} }
else { else {
receiver.put(type, v) receiver.put(type, v)
@@ -58,11 +58,11 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
} }
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val classType = codegen.getState().typeMapper.mapType(resolvedCall.getCall().getDispatchReceiver()!!.getType()) val classType = codegen.getState().typeMapper.mapType(resolvedCall.call.dispatchReceiver!!.type)
return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) { return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
if (isPrimitive(classType)) { if (isPrimitive(classType)) {
v.getstatic(boxType(classType).getInternalName(), "TYPE", "Ljava/lang/Class;") v.getstatic(boxType(classType).internalName, "TYPE", "Ljava/lang/Class;")
} }
else { else {
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class KClassJavaProperty : IntrinsicPropertyGetter() { class KClassJavaProperty : IntrinsicPropertyGetter() {
override fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? { override fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? {
val extensionReceiver = resolvedCall!!.extensionReceiver as ReceiverValue val extensionReceiver = resolvedCall!!.extensionReceiver as ReceiverValue
val type = extensionReceiver.type.arguments.single().type val type = extensionReceiver.type.arguments.single().type
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class NewArray : IntrinsicMethod() { class NewArray : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val jetType = resolvedCall.getResultingDescriptor().getReturnType()!! val jetType = resolvedCall.resultingDescriptor.returnType!!
val type = codegen.getState().typeMapper.mapType(jetType) val type = codegen.getState().typeMapper.mapType(jetType)
return object : IntrinsicCallable(type, listOf(Type.INT_TYPE), null, null) { return object : IntrinsicCallable(type, listOf(Type.INT_TYPE), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.KtPrefixExpression import org.jetbrains.kotlin.psi.KtPrefixExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
public class Not : IntrinsicMethod() { class Not : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) { object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments( override fun invokeMethodWithArguments(
@@ -31,10 +31,10 @@ public class Not : IntrinsicMethod() {
receiver: StackValue, receiver: StackValue,
codegen: ExpressionCodegen codegen: ExpressionCodegen
): StackValue { ): StackValue {
val element = resolvedCall.getCall().getCallElement() val element = resolvedCall.call.callElement
val stackValue = val stackValue =
if (element is KtPrefixExpression) { if (element is KtPrefixExpression) {
codegen.gen(element.getBaseExpression()) codegen.gen(element.baseExpression)
} }
else { else {
StackValue.receiver(resolvedCall, receiver, codegen, this) StackValue.receiver(resolvedCall, receiver, codegen, this)
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
public class NumberCast : IntrinsicMethod() { class NumberCast : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) { createUnaryIntrinsicCallable(method) {
StackValue.coerce(calcReceiverType(), returnType, it) StackValue.coerce(calcReceiverType(), returnType, it)
@@ -23,7 +23,7 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Type.* import org.jetbrains.org.objectweb.asm.Type.*
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class RangeTo : IntrinsicMethod() { class RangeTo : IntrinsicMethod() {
private fun nameToPrimitive(name: String): Type = private fun nameToPrimitive(name: String): Type =
when (name) { when (name) {
"Double" -> DOUBLE_TYPE "Double" -> DOUBLE_TYPE
@@ -37,7 +37,7 @@ public class RangeTo : IntrinsicMethod() {
} }
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val argType = nameToPrimitive(method.returnType.getInternalName().substringAfter("kotlin/").substringBefore("Range")) val argType = nameToPrimitive(method.returnType.internalName.substringAfter("kotlin/").substringBefore("Range"))
return object : IntrinsicCallable( return object : IntrinsicCallable(
method.returnType, method.returnType,
method.valueParameterTypes.map { argType }, method.valueParameterTypes.map { argType },
@@ -60,7 +60,7 @@ public class RangeTo : IntrinsicMethod() {
} }
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
v.invokespecial(returnType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, argType, argType), false) v.invokespecial(returnType.internalName, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, argType, argType), false)
} }
} }
} }
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class StringGetChar : IntrinsicMethod() { class StringGetChar : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) { createIntrinsicCallable(method) {
it.invokevirtual("java/lang/String", "charAt", "(I)C", false) it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class StringPlus : IntrinsicMethod() { class StringPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) { createIntrinsicCallable(method) {
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus",
@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class ToString : IntrinsicMethod() { class ToString : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType) val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType)
return createUnaryIntrinsicCallable(method, newThisType = type) { return createUnaryIntrinsicCallable(method, newThisType = type) {
it.invokestatic("java/lang/String", "valueOf", "(${type.getDescriptor()})Ljava/lang/String;", false) it.invokestatic("java/lang/String", "valueOf", "(${type.descriptor})Ljava/lang/String;", false)
} }
} }
} }
@@ -25,8 +25,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.* import org.jetbrains.org.objectweb.asm.tree.*
import kotlin.text.Regex import kotlin.text.Regex
public object TypeIntrinsics { object TypeIntrinsics {
public @JvmStatic fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type) { @JvmStatic fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type) {
val functionTypeArity = getFunctionTypeArity(jetType) val functionTypeArity = getFunctionTypeArity(jetType)
if (functionTypeArity >= 0) { if (functionTypeArity >= 0) {
v.iconst(functionTypeArity) v.iconst(functionTypeArity)
@@ -57,7 +57,7 @@ public object TypeIntrinsics {
LdcInsnNode(Integer(value)) LdcInsnNode(Integer(value))
} }
public @JvmStatic fun instanceOf(instanceofInsn: TypeInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type) { @JvmStatic fun instanceOf(instanceofInsn: TypeInsnNode, instructions: InsnList, jetType: KotlinType, asmType: Type) {
val functionTypeArity = getFunctionTypeArity(jetType) val functionTypeArity = getFunctionTypeArity(jetType)
if (functionTypeArity >= 0) { if (functionTypeArity >= 0) {
instructions.insertBefore(instanceofInsn, iconstNode(functionTypeArity)) instructions.insertBefore(instanceofInsn, iconstNode(functionTypeArity))
@@ -78,8 +78,7 @@ public object TypeIntrinsics {
instanceofInsn.desc = asmType.internalName instanceofInsn.desc = asmType.internalName
} }
@JvmStatic @JvmStatic fun checkcast(
public fun checkcast(
v: InstructionAdapter, v: InstructionAdapter,
kotlinType: KotlinType, asmType: Type, kotlinType: KotlinType, asmType: Type,
// This parameter is just for sake of optimization: // This parameter is just for sake of optimization:
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryMinus : IntrinsicMethod() { class UnaryMinus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) { createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
it.neg(returnType) it.neg(returnType)
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryPlus : IntrinsicMethod() { class UnaryPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable = override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) { createUnaryIntrinsicCallable(method) {
//nothing //nothing
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
public class DeadCodeEliminationMethodTransformer : MethodTransformer() { class DeadCodeEliminationMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) { override fun transform(internalClassName: String, methodNode: MethodNode) {
val frames = MethodTransformer.analyze(internalClassName, methodNode, OptimizationBasicInterpreter()) val frames = MethodTransformer.analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
val insnList = methodNode.instructions val insnList = methodNode.instructions
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.tree.* import org.jetbrains.org.objectweb.asm.tree.*
public class LabelNormalizationMethodTransformer : MethodTransformer() { class LabelNormalizationMethodTransformer : MethodTransformer() {
public override fun transform(internalClassName: String, methodNode: MethodNode) { override fun transform(internalClassName: String, methodNode: MethodNode) {
TransformerForMethod(methodNode).transform() TransformerForMethod(methodNode).transform()
} }
@@ -29,7 +29,7 @@ public class LabelNormalizationMethodTransformer : MethodTransformer() {
val instructions = methodNode.instructions val instructions = methodNode.instructions
val newLabelNodes = hashMapOf<Label, LabelNode>() val newLabelNodes = hashMapOf<Label, LabelNode>()
public fun transform() { fun transform() {
if (rewriteLabelInstructions()) { if (rewriteLabelInstructions()) {
rewriteNonLabelInstructions() rewriteNonLabelInstructions()
rewriteTryCatchBlocks() rewriteTryCatchBlocks()
@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransfor
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
public class MandatoryMethodTransformer : MethodTransformer() { class MandatoryMethodTransformer : MethodTransformer() {
private val labelNormalization = LabelNormalizationMethodTransformer() private val labelNormalization = LabelNormalizationMethodTransformer()
private val fixStack = FixStackMethodTransformer() private val fixStack = FixStackMethodTransformer()
public override fun transform(internalClassName: String, methodNode: MethodNode) { override fun transform(internalClassName: String, methodNode: MethodNode) {
labelNormalization.transform(internalClassName, methodNode) labelNormalization.transform(internalClassName, methodNode)
fixStack.transform(internalClassName, methodNode) fixStack.transform(internalClassName, methodNode)
} }
@@ -24,7 +24,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
public class RedundantGotoMethodTransformer : MethodTransformer() { class RedundantGotoMethodTransformer : MethodTransformer() {
/** /**
* Removes redundant GOTO's, i.e. to subsequent labels * Removes redundant GOTO's, i.e. to subsequent labels
*/ */
@@ -35,7 +35,7 @@ public class RedundantGotoMethodTransformer : MethodTransformer() {
val currentLabels = hashSetOf<LabelNode>() val currentLabels = hashSetOf<LabelNode>()
for (insn in insns) { for (insn in insns) {
if (insn.isMeaningful) { if (insn.isMeaningful) {
if (insn.getOpcode() == Opcodes.GOTO && (insn as JumpInsnNode).label in currentLabels) { if (insn.opcode == Opcodes.GOTO && (insn as JumpInsnNode).label in currentLabels) {
insnsToRemove.add(insn) insnsToRemove.add(insn)
} }
else { else {
@@ -23,7 +23,7 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
public class NullabilityInterpreter(insns: InsnList) : BoxingInterpreter(insns) { class NullabilityInterpreter(insns: InsnList) : BoxingInterpreter(insns) {
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue) = makeNotNullIfNeeded(insn, super.unaryOperation(insn, value)) override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue) = makeNotNullIfNeeded(insn, super.unaryOperation(insn, value))
override fun newOperation(insn: AbstractInsnNode) = makeNotNullIfNeeded(insn, super.newOperation(insn)) override fun newOperation(insn: AbstractInsnNode) = makeNotNullIfNeeded(insn, super.newOperation(insn))
@@ -35,7 +35,7 @@ public class NullabilityInterpreter(insns: InsnList) : BoxingInterpreter(insns)
} }
private fun makeNotNullIfNeeded(insn: AbstractInsnNode, value: BasicValue?): BasicValue? = private fun makeNotNullIfNeeded(insn: AbstractInsnNode, value: BasicValue?): BasicValue? =
when (insn.getOpcode()) { when (insn.opcode) {
Opcodes.ANEWARRAY, Opcodes.NEWARRAY, Opcodes.LDC, Opcodes.NEW -> NotNullBasicValue(value) Opcodes.ANEWARRAY, Opcodes.NEWARRAY, Opcodes.LDC, Opcodes.NEW -> NotNullBasicValue(value)
else -> value else -> value
} }
@@ -25,15 +25,15 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.Value import org.jetbrains.org.objectweb.asm.tree.analysis.Value
import java.util.* import java.util.*
public open class MethodAnalyzer<V : Value>( open class MethodAnalyzer<V : Value>(
public val owner: String, val owner: String,
public val method: MethodNode, val method: MethodNode,
protected val interpreter: Interpreter<V> protected val interpreter: Interpreter<V>
) { ) {
public val instructions: InsnList = method.instructions val instructions: InsnList = method.instructions
public val nInsns: Int = instructions.size() val nInsns: Int = instructions.size()
public val frames: Array<Frame<V>?> = arrayOfNulls(nInsns) val frames: Array<Frame<V>?> = arrayOfNulls(nInsns)
private val handlers: Array<MutableList<TryCatchBlockNode>?> = arrayOfNulls(nInsns) private val handlers: Array<MutableList<TryCatchBlockNode>?> = arrayOfNulls(nInsns)
private val queued: BooleanArray = BooleanArray(nInsns) private val queued: BooleanArray = BooleanArray(nInsns)
@@ -45,7 +45,7 @@ public open class MethodAnalyzer<V : Value>(
protected open fun newFrame(nLocals: Int, nStack: Int): Frame<V> = Frame(nLocals, nStack) protected open fun newFrame(nLocals: Int, nStack: Int): Frame<V> = Frame(nLocals, nStack)
protected open fun newFrame(src: Frame<out V>): Frame<V> { protected open fun newFrame(src: Frame<out V>): Frame<V> {
val frame = newFrame(src.getLocals(), src.getMaxStackSize()) val frame = newFrame(src.locals, src.maxStackSize)
frame.init(src) frame.init(src)
return frame return frame
} }
@@ -57,7 +57,7 @@ public open class MethodAnalyzer<V : Value>(
protected open fun visitControlFlowExceptionEdge(insn: Int, tcb: TryCatchBlockNode): Boolean = protected open fun visitControlFlowExceptionEdge(insn: Int, tcb: TryCatchBlockNode): Boolean =
visitControlFlowExceptionEdge(insn, instructions.indexOf(tcb.handler)) visitControlFlowExceptionEdge(insn, instructions.indexOf(tcb.handler))
public fun analyze(): Array<Frame<V>?> { fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return frames if (nInsns == 0) return frames
checkAssertions() checkAssertions()
@@ -75,8 +75,8 @@ public open class MethodAnalyzer<V : Value>(
val insnNode = method.instructions[insn] val insnNode = method.instructions[insn]
try { try {
val insnOpcode = insnNode.getOpcode() val insnOpcode = insnNode.opcode
val insnType = insnNode.getType() val insnType = insnNode.type
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) { if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
visitNopInsn(f, insn) visitNopInsn(f, insn)
@@ -121,11 +121,11 @@ public open class MethodAnalyzer<V : Value>(
return frames return frames
} }
public fun getFrame(insn: AbstractInsnNode): Frame<V>? = fun getFrame(insn: AbstractInsnNode): Frame<V>? =
frames[instructions.indexOf(insn)] frames[instructions.indexOf(insn)]
private fun checkAssertions() { private fun checkAssertions() {
if (instructions.toArray().any { it.getOpcode() == Opcodes.JSR || it.getOpcode() == Opcodes.RET }) if (instructions.toArray().any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET })
throw AssertionError("Subroutines are deprecated since Java 6") throw AssertionError("Subroutines are deprecated since Java 6")
} }
@@ -179,7 +179,7 @@ public open class MethodAnalyzer<V : Value>(
} }
for (arg in args) { for (arg in args) {
current.setLocal(local++, interpreter.newValue(arg)) current.setLocal(local++, interpreter.newValue(arg))
if (arg.getSize() == 2) { if (arg.size == 2) {
current.setLocal(local++, interpreter.newValue(null)) current.setLocal(local++, interpreter.newValue(null))
} }
} }
@@ -21,20 +21,20 @@ import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
val AbstractInsnNode.isMeaningful: Boolean get() = val AbstractInsnNode.isMeaningful: Boolean get() =
when (this.getType()) { when (this.type) {
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME -> false AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME -> false
else -> true else -> true
} }
public class InsnSequence(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Sequence<AbstractInsnNode> { class InsnSequence(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Sequence<AbstractInsnNode> {
public constructor(insnList: InsnList) : this(insnList.getFirst(), null) constructor(insnList: InsnList) : this(insnList.first, null)
override fun iterator(): Iterator<AbstractInsnNode> { override fun iterator(): Iterator<AbstractInsnNode> {
return object : Iterator<AbstractInsnNode> { return object : Iterator<AbstractInsnNode> {
var current: AbstractInsnNode? = from var current: AbstractInsnNode? = from
override fun next(): AbstractInsnNode { override fun next(): AbstractInsnNode {
val result = current val result = current
current = current!!.getNext() current = current!!.next
return result!! return result!!
} }
override fun hasNext() = current != to override fun hasNext() = current != to
@@ -58,11 +58,11 @@ fun MethodNode.prepareForEmitting() {
// We should remove linenumbers after last meaningful instruction // We should remove linenumbers after last meaningful instruction
// because they point to index of non-existing instruction and it leads to VerifyError // because they point to index of non-existing instruction and it leads to VerifyError
var current = instructions.getLast() var current = instructions.last
while (!current.isMeaningful) { while (!current.isMeaningful) {
val prev = current.getPrevious() val prev = current.previous
if (current.getType() == AbstractInsnNode.LINE) { if (current.type == AbstractInsnNode.LINE) {
instructions.remove(current) instructions.remove(current)
} }
@@ -70,7 +70,7 @@ fun MethodNode.prepareForEmitting() {
} }
} }
abstract class BasicValueWrapper(val wrappedValue: BasicValue?) : BasicValue(wrappedValue?.getType()) { abstract class BasicValueWrapper(val wrappedValue: BasicValue?) : BasicValue(wrappedValue?.type) {
val basicValue: BasicValue? get() = (wrappedValue as? BasicValueWrapper)?.basicValue ?: wrappedValue val basicValue: BasicValue? get() = (wrappedValue as? BasicValueWrapper)?.basicValue ?: wrappedValue
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@@ -79,23 +79,23 @@ abstract class BasicValueWrapper(val wrappedValue: BasicValue?) : BasicValue(wra
} }
inline fun AbstractInsnNode.findNextOrNull(predicate: (AbstractInsnNode) -> Boolean): AbstractInsnNode? { inline fun AbstractInsnNode.findNextOrNull(predicate: (AbstractInsnNode) -> Boolean): AbstractInsnNode? {
var finger = this.getNext() var finger = this.next
while (finger != null && !predicate(finger)) { while (finger != null && !predicate(finger)) {
finger = finger.getNext() finger = finger.next
} }
return finger return finger
} }
inline fun AbstractInsnNode.findPreviousOrNull(predicate: (AbstractInsnNode) -> Boolean): AbstractInsnNode? { inline fun AbstractInsnNode.findPreviousOrNull(predicate: (AbstractInsnNode) -> Boolean): AbstractInsnNode? {
var finger = this.getPrevious() var finger = this.previous
while (finger != null && !predicate(finger)) { while (finger != null && !predicate(finger)) {
finger = finger.getPrevious() finger = finger.previous
} }
return finger return finger
} }
fun AbstractInsnNode.hasOpcode(): Boolean = fun AbstractInsnNode.hasOpcode(): Boolean =
getOpcode() >= 0 opcode >= 0
// See InstructionAdapter // See InstructionAdapter
// //
@@ -40,31 +40,31 @@ internal class FixStackAnalyzer(
val savedStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>() val savedStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>()
var maxExtraStackSize = 0; private set var maxExtraStackSize = 0; private set
protected override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean { override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean {
val insnNode = instructions[insn] val insnNode = instructions[insn]
return !(insnNode is JumpInsnNode && context.breakContinueGotoNodes.contains(insnNode)) return !(insnNode is JumpInsnNode && context.breakContinueGotoNodes.contains(insnNode))
} }
protected override fun newFrame(nLocals: Int, nStack: Int): Frame<BasicValue> = override fun newFrame(nLocals: Int, nStack: Int): Frame<BasicValue> =
FixStackFrame(nLocals, nStack) FixStackFrame(nLocals, nStack)
private fun indexOf(node: AbstractInsnNode) = method.instructions.indexOf(node) private fun indexOf(node: AbstractInsnNode) = method.instructions.indexOf(node)
public inner class FixStackFrame(nLocals: Int, nStack: Int) : Frame<BasicValue>(nLocals, nStack) { inner class FixStackFrame(nLocals: Int, nStack: Int) : Frame<BasicValue>(nLocals, nStack) {
val extraStack = Stack<BasicValue>() val extraStack = Stack<BasicValue>()
public override fun init(src: Frame<out BasicValue>): Frame<BasicValue> { override fun init(src: Frame<out BasicValue>): Frame<BasicValue> {
extraStack.clear() extraStack.clear()
extraStack.addAll((src as FixStackFrame).extraStack) extraStack.addAll((src as FixStackFrame).extraStack)
return super.init(src) return super.init(src)
} }
public override fun clearStack() { override fun clearStack() {
extraStack.clear() extraStack.clear()
super.clearStack() super.clearStack()
} }
public override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<BasicValue>) { override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<BasicValue>) {
when { when {
PseudoInsn.SAVE_STACK_BEFORE_TRY.isa(insn) -> PseudoInsn.SAVE_STACK_BEFORE_TRY.isa(insn) ->
executeSaveStackBeforeTry(insn) executeSaveStackBeforeTry(insn)
@@ -83,15 +83,15 @@ internal class FixStackAnalyzer(
super.execute(insn, interpreter) super.execute(insn, interpreter)
} }
public fun getStackContent(): List<BasicValue> { fun getStackContent(): List<BasicValue> {
val savedStack = arrayListOf<BasicValue>() val savedStack = arrayListOf<BasicValue>()
IntRange(0, super.getStackSize() - 1).mapTo(savedStack) { super.getStack(it) } IntRange(0, super.getStackSize() - 1).mapTo(savedStack) { super.getStack(it) }
savedStack.addAll(extraStack) savedStack.addAll(extraStack)
return savedStack return savedStack
} }
public override fun push(value: BasicValue) { override fun push(value: BasicValue) {
if (super.getStackSize() < getMaxStackSize()) { if (super.getStackSize() < maxStackSize) {
super.push(value) super.push(value)
} }
else { else {
@@ -100,11 +100,11 @@ internal class FixStackAnalyzer(
} }
} }
public fun pushAll(values: Collection<BasicValue>) { fun pushAll(values: Collection<BasicValue>) {
values.forEach { push(it) } values.forEach { push(it) }
} }
public override fun pop(): BasicValue { override fun pop(): BasicValue {
if (extraStack.isNotEmpty()) { if (extraStack.isNotEmpty()) {
return extraStack.pop() return extraStack.pop()
} }
@@ -113,12 +113,12 @@ internal class FixStackAnalyzer(
} }
} }
public override fun getStack(i: Int): BasicValue { override fun getStack(i: Int): BasicValue {
if (i < super.getMaxStackSize()) { if (i < super.getMaxStackSize()) {
return super.getStack(i) return super.getStack(i)
} }
else { else {
return extraStack[i - getMaxStackSize()] return extraStack[i - maxStackSize]
} }
} }
} }
@@ -135,7 +135,7 @@ internal class FixStackAnalyzer(
private fun FixStackFrame.executeAfterInlineCallMarker(insn: AbstractInsnNode) { private fun FixStackFrame.executeAfterInlineCallMarker(insn: AbstractInsnNode) {
val beforeInlineMarker = context.openingInlineMethodMarker[insn] val beforeInlineMarker = context.openingInlineMethodMarker[insn]
if (getStackSize() > 0) { if (stackSize > 0) {
val returnValue = pop() val returnValue = pop()
clearStack() clearStack()
val savedValues = savedStacks[beforeInlineMarker] val savedValues = savedStacks[beforeInlineMarker]
@@ -77,23 +77,23 @@ internal class FixStackContext(val methodNode: MethodNode) {
} }
private fun visitFixStackBeforeJump(insnNode: AbstractInsnNode) { private fun visitFixStackBeforeJump(insnNode: AbstractInsnNode) {
val next = insnNode.getNext() val next = insnNode.next
assert(next.getOpcode() == Opcodes.GOTO) { "${indexOf(insnNode)}: should be followed by GOTO" } assert(next.opcode == Opcodes.GOTO) { "${indexOf(insnNode)}: should be followed by GOTO" }
breakContinueGotoNodes.add(next as JumpInsnNode) breakContinueGotoNodes.add(next as JumpInsnNode)
} }
private fun visitFakeAlwaysTrueIfeq(insnNode: AbstractInsnNode) { private fun visitFakeAlwaysTrueIfeq(insnNode: AbstractInsnNode) {
assert(insnNode.getNext().getOpcode() == Opcodes.IFEQ) { "${indexOf(insnNode)}: should be followed by IFEQ" } assert(insnNode.next.opcode == Opcodes.IFEQ) { "${indexOf(insnNode)}: should be followed by IFEQ" }
fakeAlwaysTrueIfeqMarkers.add(insnNode) fakeAlwaysTrueIfeqMarkers.add(insnNode)
} }
private fun visitFakeAlwaysFalseIfeq(insnNode: AbstractInsnNode) { private fun visitFakeAlwaysFalseIfeq(insnNode: AbstractInsnNode) {
assert(insnNode.getNext().getOpcode() == Opcodes.IFEQ) { "${indexOf(insnNode)}: should be followed by IFEQ" } assert(insnNode.next.opcode == Opcodes.IFEQ) { "${indexOf(insnNode)}: should be followed by IFEQ" }
fakeAlwaysFalseIfeqMarkers.add(insnNode) fakeAlwaysFalseIfeqMarkers.add(insnNode)
} }
private fun visitSaveStackBeforeTry(insnNode: AbstractInsnNode) { private fun visitSaveStackBeforeTry(insnNode: AbstractInsnNode) {
val tryStartLabel = insnNode.getNext() val tryStartLabel = insnNode.next
assert(tryStartLabel is LabelNode) { "${indexOf(insnNode)}: save should be followed by a label" } assert(tryStartLabel is LabelNode) { "${indexOf(insnNode)}: save should be followed by a label" }
saveStackNodesForTryStartLabel[tryStartLabel as LabelNode] = insnNode saveStackNodesForTryStartLabel[tryStartLabel as LabelNode] = insnNode
} }
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.parsePseudoInsnOrNull
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
public class FixStackMethodTransformer : MethodTransformer() { class FixStackMethodTransformer : MethodTransformer() {
public override fun transform(internalClassName: String, methodNode: MethodNode) { override fun transform(internalClassName: String, methodNode: MethodNode) {
val context = FixStackContext(methodNode) val context = FixStackContext(methodNode)
if (!context.hasAnyMarkers()) return if (!context.hasAnyMarkers()) return
@@ -73,19 +73,19 @@ public class FixStackMethodTransformer : MethodTransformer() {
val labelIndex = methodNode.instructions.indexOf(gotoNode.label) val labelIndex = methodNode.instructions.indexOf(gotoNode.label)
val DEAD_CODE = -1 // Stack size is always non-negative val DEAD_CODE = -1 // Stack size is always non-negative
val actualStackSize = analyzer.frames[gotoIndex]?.getStackSize() ?: DEAD_CODE val actualStackSize = analyzer.frames[gotoIndex]?.stackSize ?: DEAD_CODE
val expectedStackSize = analyzer.frames[labelIndex]?.getStackSize() ?: DEAD_CODE val expectedStackSize = analyzer.frames[labelIndex]?.stackSize ?: DEAD_CODE
if (actualStackSize != DEAD_CODE && expectedStackSize != DEAD_CODE) { if (actualStackSize != DEAD_CODE && expectedStackSize != DEAD_CODE) {
assert(expectedStackSize <= actualStackSize) { "Label at $labelIndex, jump at $gotoIndex: stack underflow: $expectedStackSize > $actualStackSize" } assert(expectedStackSize <= actualStackSize) { "Label at $labelIndex, jump at $gotoIndex: stack underflow: $expectedStackSize > $actualStackSize" }
val frame = analyzer.frames[gotoIndex]!! val frame = analyzer.frames[gotoIndex]!!
actions.add({ replaceMarkerWithPops(methodNode, gotoNode.getPrevious(), expectedStackSize, frame) }) actions.add({ replaceMarkerWithPops(methodNode, gotoNode.previous, expectedStackSize, frame) })
} }
else if (actualStackSize != DEAD_CODE && expectedStackSize == DEAD_CODE) { else if (actualStackSize != DEAD_CODE && expectedStackSize == DEAD_CODE) {
throw AssertionError("Live jump $gotoIndex to dead label $labelIndex") throw AssertionError("Live jump $gotoIndex to dead label $labelIndex")
} }
else { else {
val marker = gotoNode.getPrevious() val marker = gotoNode.previous
actions.add({ methodNode.instructions.remove(marker) }) actions.add({ methodNode.instructions.remove(marker) })
} }
} }
@@ -153,8 +153,8 @@ public class FixStackMethodTransformer : MethodTransformer() {
val savedStackDescriptor = localVariablesManager.getBeforeInlineDescriptor(inlineMarker) val savedStackDescriptor = localVariablesManager.getBeforeInlineDescriptor(inlineMarker)
val afterInlineFrame = analyzer.getFrame(inlineMarker) as FixStackAnalyzer.FixStackFrame? val afterInlineFrame = analyzer.getFrame(inlineMarker) as FixStackAnalyzer.FixStackFrame?
if (afterInlineFrame != null && savedStackDescriptor.isNotEmpty()) { if (afterInlineFrame != null && savedStackDescriptor.isNotEmpty()) {
assert(afterInlineFrame.getStackSize() <= 1) { "Inline method should not leave more than 1 value on stack" } assert(afterInlineFrame.stackSize <= 1) { "Inline method should not leave more than 1 value on stack" }
if (afterInlineFrame.getStackSize() == 1) { if (afterInlineFrame.stackSize == 1) {
val afterInlineStackValues = afterInlineFrame.getStackContent() val afterInlineStackValues = afterInlineFrame.getStackContent()
val returnValue = afterInlineStackValues.last() val returnValue = afterInlineStackValues.last()
val returnValueLocalVarIndex = localVariablesManager.createReturnValueVariable(returnValue) val returnValueLocalVarIndex = localVariablesManager.createReturnValueVariable(returnValue)
@@ -91,7 +91,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
fun createReturnValueVariable(returnValue: BasicValue): Int { fun createReturnValueVariable(returnValue: BasicValue): Int {
val returnValueIndex = getFirstUnusedLocalVariableIndex() val returnValueIndex = getFirstUnusedLocalVariableIndex()
updateMaxLocals(returnValueIndex + returnValue.getSize()) updateMaxLocals(returnValueIndex + returnValue.size)
return returnValueIndex return returnValueIndex
} }
} }
@@ -26,13 +26,13 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.Value import org.jetbrains.org.objectweb.asm.tree.analysis.Value
public inline fun InsnList.forEachPseudoInsn(block: (PseudoInsn, AbstractInsnNode) -> Unit) { inline fun InsnList.forEachPseudoInsn(block: (PseudoInsn, AbstractInsnNode) -> Unit) {
InsnSequence(this).forEach { insn -> InsnSequence(this).forEach { insn ->
parsePseudoInsnOrNull(insn)?.let { block(it, insn) } parsePseudoInsnOrNull(insn)?.let { block(it, insn) }
} }
} }
public inline fun InsnList.forEachInlineMarker(block: (String, MethodInsnNode) -> Unit) { inline fun InsnList.forEachInlineMarker(block: (String, MethodInsnNode) -> Unit) {
InsnSequence(this).forEach { insn -> InsnSequence(this).forEach { insn ->
if (InlineCodegenUtil.isInlineMarker(insn)) { if (InlineCodegenUtil.isInlineMarker(insn)) {
val methodInsnNode = insn as MethodInsnNode val methodInsnNode = insn as MethodInsnNode
@@ -41,15 +41,15 @@ public inline fun InsnList.forEachInlineMarker(block: (String, MethodInsnNode) -
} }
} }
public fun <V : Value> Frame<V>.top(): V? { fun <V : Value> Frame<V>.top(): V? {
val stackSize = getStackSize() val stackSize = stackSize
if (stackSize == 0) if (stackSize == 0)
return null return null
else else
return getStack(stackSize - 1) return getStack(stackSize - 1)
} }
public fun MethodNode.updateMaxLocals(newMaxLocals: Int) { fun MethodNode.updateMaxLocals(newMaxLocals: Int) {
maxLocals = Math.max(maxLocals, newMaxLocals) maxLocals = Math.max(maxLocals, newMaxLocals)
} }
@@ -57,10 +57,10 @@ class SavedStackDescriptor(
val savedValues: List<BasicValue>, val savedValues: List<BasicValue>,
val firstLocalVarIndex: Int val firstLocalVarIndex: Int
) { ) {
val savedValuesSize = savedValues.fold(0, { size, value -> size + value.getSize() }) val savedValuesSize = savedValues.fold(0, { size, value -> size + value.size })
val firstUnusedLocalVarIndex = firstLocalVarIndex + savedValuesSize val firstUnusedLocalVarIndex = firstLocalVarIndex + savedValuesSize
public override fun toString(): String = override fun toString(): String =
"@$firstLocalVarIndex: [$savedValues]" "@$firstLocalVarIndex: [$savedValues]"
fun isNotEmpty(): Boolean = savedValues.isNotEmpty() fun isNotEmpty(): Boolean = savedValues.isNotEmpty()
@@ -93,9 +93,9 @@ fun restoreStackWithReturnValue(
returnValueLocalVarIndex: Int returnValueLocalVarIndex: Int
) { ) {
with(methodNode.instructions) { with(methodNode.instructions) {
insertBefore(nodeToReplace, VarInsnNode(returnValue.getType().getOpcode(Opcodes.ISTORE), returnValueLocalVarIndex)) insertBefore(nodeToReplace, VarInsnNode(returnValue.type.getOpcode(Opcodes.ISTORE), returnValueLocalVarIndex))
generateLoadInstructions(methodNode, nodeToReplace, savedStackDescriptor) generateLoadInstructions(methodNode, nodeToReplace, savedStackDescriptor)
insertBefore(nodeToReplace, VarInsnNode(returnValue.getType().getOpcode(Opcodes.ILOAD), returnValueLocalVarIndex)) insertBefore(nodeToReplace, VarInsnNode(returnValue.type.getOpcode(Opcodes.ILOAD), returnValueLocalVarIndex))
remove(nodeToReplace) remove(nodeToReplace)
} }
} }
@@ -104,22 +104,22 @@ fun generateLoadInstructions(methodNode: MethodNode, location: AbstractInsnNode,
var localVarIndex = savedStackDescriptor.firstLocalVarIndex var localVarIndex = savedStackDescriptor.firstLocalVarIndex
for (value in savedStackDescriptor.savedValues) { for (value in savedStackDescriptor.savedValues) {
methodNode.instructions.insertBefore(location, methodNode.instructions.insertBefore(location,
VarInsnNode(value.getType().getOpcode(Opcodes.ILOAD), localVarIndex)) VarInsnNode(value.type.getOpcode(Opcodes.ILOAD), localVarIndex))
localVarIndex += value.getSize() localVarIndex += value.size
} }
} }
fun generateStoreInstructions(methodNode: MethodNode, location: AbstractInsnNode, savedStackDescriptor: SavedStackDescriptor) { fun generateStoreInstructions(methodNode: MethodNode, location: AbstractInsnNode, savedStackDescriptor: SavedStackDescriptor) {
var localVarIndex = savedStackDescriptor.firstUnusedLocalVarIndex var localVarIndex = savedStackDescriptor.firstUnusedLocalVarIndex
for (value in savedStackDescriptor.savedValues.asReversed()) { for (value in savedStackDescriptor.savedValues.asReversed()) {
localVarIndex -= value.getSize() localVarIndex -= value.size
methodNode.instructions.insertBefore(location, methodNode.instructions.insertBefore(location,
VarInsnNode(value.getType().getOpcode(Opcodes.ISTORE), localVarIndex)) VarInsnNode(value.type.getOpcode(Opcodes.ISTORE), localVarIndex))
} }
} }
fun getPopInstruction(top: BasicValue) = fun getPopInstruction(top: BasicValue) =
InsnNode(when (top.getSize()) { InsnNode(when (top.size) {
1 -> Opcodes.POP 1 -> Opcodes.POP
2 -> Opcodes.POP2 2 -> Opcodes.POP2
else -> throw AssertionError("Unexpected value type size") else -> throw AssertionError("Unexpected value type size")
@@ -127,14 +127,14 @@ fun getPopInstruction(top: BasicValue) =
fun removeAlwaysFalseIfeq(methodNode: MethodNode, node: AbstractInsnNode) { fun removeAlwaysFalseIfeq(methodNode: MethodNode, node: AbstractInsnNode) {
with (methodNode.instructions) { with (methodNode.instructions) {
remove(node.getNext()) remove(node.next)
remove(node) remove(node)
} }
} }
fun replaceAlwaysTrueIfeqWithGoto(methodNode: MethodNode, node: AbstractInsnNode) { fun replaceAlwaysTrueIfeqWithGoto(methodNode: MethodNode, node: AbstractInsnNode) {
with (methodNode.instructions) { with (methodNode.instructions) {
val next = node.getNext() as JumpInsnNode val next = node.next as JumpInsnNode
insertBefore(node, JumpInsnNode(Opcodes.GOTO, next.label)) insertBefore(node, JumpInsnNode(Opcodes.GOTO, next.label))
remove(node) remove(node)
remove(next) remove(next)
@@ -143,7 +143,7 @@ fun replaceAlwaysTrueIfeqWithGoto(methodNode: MethodNode, node: AbstractInsnNode
fun replaceMarkerWithPops(methodNode: MethodNode, node: AbstractInsnNode, expectedStackSize: Int, frame: Frame<BasicValue>) { fun replaceMarkerWithPops(methodNode: MethodNode, node: AbstractInsnNode, expectedStackSize: Int, frame: Frame<BasicValue>) {
with (methodNode.instructions) { with (methodNode.instructions) {
while (frame.getStackSize() > expectedStackSize) { while (frame.stackSize > expectedStackSize) {
val top = frame.pop() val top = frame.pop()
insertBefore(node, getPopInstruction(top)) insertBefore(node, getPopInstruction(top))
} }
@@ -23,9 +23,9 @@ import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
public val PSEUDO_INSN_CALL_OWNER: String = "kotlin/jvm/internal/\$PseudoInsn" val PSEUDO_INSN_CALL_OWNER: String = "kotlin/jvm/internal/\$PseudoInsn"
public enum class PseudoInsn(val signature: String = "()V") { enum class PseudoInsn(val signature: String = "()V") {
FIX_STACK_BEFORE_JUMP(), FIX_STACK_BEFORE_JUMP(),
FAKE_ALWAYS_TRUE_IFEQ("()I"), FAKE_ALWAYS_TRUE_IFEQ("()I"),
FAKE_ALWAYS_FALSE_IFEQ("()I"), FAKE_ALWAYS_FALSE_IFEQ("()I"),
@@ -33,36 +33,36 @@ public enum class PseudoInsn(val signature: String = "()V") {
RESTORE_STACK_IN_TRY_CATCH() RESTORE_STACK_IN_TRY_CATCH()
; ;
public fun emit(iv: InstructionAdapter) { fun emit(iv: InstructionAdapter) {
iv.invokestatic(PSEUDO_INSN_CALL_OWNER, toString(), signature, false) iv.invokestatic(PSEUDO_INSN_CALL_OWNER, toString(), signature, false)
} }
public fun createInsnNode(): MethodInsnNode = fun createInsnNode(): MethodInsnNode =
MethodInsnNode(Opcodes.INVOKESTATIC, PSEUDO_INSN_CALL_OWNER, toString(), signature, false) MethodInsnNode(Opcodes.INVOKESTATIC, PSEUDO_INSN_CALL_OWNER, toString(), signature, false)
public fun isa(node: AbstractInsnNode): Boolean = fun isa(node: AbstractInsnNode): Boolean =
this == parsePseudoInsnOrNull(node) this == parsePseudoInsnOrNull(node)
} }
public fun isPseudoInsn(insn: AbstractInsnNode): Boolean = fun isPseudoInsn(insn: AbstractInsnNode): Boolean =
insn is MethodInsnNode && insn.getOpcode() == Opcodes.INVOKESTATIC && insn.owner == PSEUDO_INSN_CALL_OWNER insn is MethodInsnNode && insn.getOpcode() == Opcodes.INVOKESTATIC && insn.owner == PSEUDO_INSN_CALL_OWNER
public fun parsePseudoInsnOrNull(insn: AbstractInsnNode): PseudoInsn? = fun parsePseudoInsnOrNull(insn: AbstractInsnNode): PseudoInsn? =
if (isPseudoInsn(insn)) if (isPseudoInsn(insn))
PseudoInsn.valueOf((insn as MethodInsnNode).name) PseudoInsn.valueOf((insn as MethodInsnNode).name)
else null else null
public fun InstructionAdapter.fixStackAndJump(label: Label) { fun InstructionAdapter.fixStackAndJump(label: Label) {
PseudoInsn.FIX_STACK_BEFORE_JUMP.emit(this) PseudoInsn.FIX_STACK_BEFORE_JUMP.emit(this)
this.goTo(label) this.goTo(label)
} }
public fun InstructionAdapter.fakeAlwaysTrueIfeq(label: Label) { fun InstructionAdapter.fakeAlwaysTrueIfeq(label: Label) {
PseudoInsn.FAKE_ALWAYS_TRUE_IFEQ.emit(this) PseudoInsn.FAKE_ALWAYS_TRUE_IFEQ.emit(this)
this.ifeq(label) this.ifeq(label)
} }
public fun InstructionAdapter.fakeAlwaysFalseIfeq(label: Label) { fun InstructionAdapter.fakeAlwaysFalseIfeq(label: Label) {
PseudoInsn.FAKE_ALWAYS_FALSE_IFEQ.emit(this) PseudoInsn.FAKE_ALWAYS_FALSE_IFEQ.emit(this)
this.ifeq(label) this.ifeq(label)
} }
@@ -31,7 +31,7 @@ import java.util.*
// TODO: optimize by reordering records to minimize storage of 'range' fields // TODO: optimize by reordering records to minimize storage of 'range' fields
class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable { class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable {
public val strings = ArrayList<String>() val strings = ArrayList<String>()
private val records = ArrayList<Record.Builder>() private val records = ArrayList<Record.Builder>()
private val map = HashMap<String, Int>() private val map = HashMap<String, Int>()
private val localNames = HashSet<Int>() private val localNames = HashSet<Int>()
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper
public class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper { class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper {
// We use empty BindingContext, because it is only used by JetTypeMapper for purposes irrelevant to the needs of this class // We use empty BindingContext, because it is only used by JetTypeMapper for purposes irrelevant to the needs of this class
private val typeMapper: JetTypeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null, JvmAbi.DEFAULT_MODULE_NAME) private val typeMapper: JetTypeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null, JvmAbi.DEFAULT_MODULE_NAME)
@@ -120,17 +120,17 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
var ownNonFakeCount = 0 var ownNonFakeCount = 0
for (origin in origins) { for (origin in origins) {
val member = origin.descriptor as? CallableMemberDescriptor? val member = origin.descriptor as? CallableMemberDescriptor?
if (member != null && member.containingDeclaration == classOrigin.descriptor && member.getKind() != FAKE_OVERRIDE) { if (member != null && member.containingDeclaration == classOrigin.descriptor && member.kind != FAKE_OVERRIDE) {
ownNonFakeCount++ ownNonFakeCount++
// If there's more than one real element, the clashing signature is already reported. // If there's more than one real element, the clashing signature is already reported.
// Only clashes between fake overrides are interesting here // Only clashes between fake overrides are interesting here
if (ownNonFakeCount > 1) continue@signatures if (ownNonFakeCount > 1) continue@signatures
if (member.getKind() != DELEGATION) { if (member.kind != DELEGATION) {
// Delegates don't have declarations in the code // Delegates don't have declarations in the code
memberElement = origin.element ?: DescriptorToSourceUtils.descriptorToDeclaration(member) memberElement = origin.element ?: DescriptorToSourceUtils.descriptorToDeclaration(member)
if (memberElement == null && member is PropertyAccessorDescriptor) { if (memberElement == null && member is PropertyAccessorDescriptor) {
memberElement = DescriptorToSourceUtils.descriptorToDeclaration(member.getCorrespondingProperty()) memberElement = DescriptorToSourceUtils.descriptorToDeclaration(member.correspondingProperty)
} }
} }
} }
@@ -154,18 +154,18 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
fun processMember(member: DeclarationDescriptor?) { fun processMember(member: DeclarationDescriptor?) {
// a member of super is not visible: no override // a member of super is not visible: no override
if (member is DeclarationDescriptorWithVisibility && member.getVisibility() == Visibilities.INVISIBLE_FAKE) return if (member is DeclarationDescriptorWithVisibility && member.visibility == Visibilities.INVISIBLE_FAKE) return
// if a signature clashes with a SAM-adapter or something like that, there's no harm // if a signature clashes with a SAM-adapter or something like that, there's no harm
if (member is CallableMemberDescriptor && isOrOverridesSamAdapter(member)) return if (member is CallableMemberDescriptor && isOrOverridesSamAdapter(member)) return
if (member is PropertyDescriptor) { if (member is PropertyDescriptor) {
processMember(member.getGetter()) processMember(member.getter)
processMember(member.getSetter()) processMember(member.setter)
} }
else if (member is FunctionDescriptor) { else if (member is FunctionDescriptor) {
val methodSignature = typeMapper.mapSignature(member) val methodSignature = typeMapper.mapSignature(member)
val rawSignature = RawSignature( val rawSignature = RawSignature(
methodSignature.getAsmMethod().getName()!!, methodSignature.getAsmMethod().getDescriptor()!!, MemberKind.METHOD) methodSignature.asmMethod.name!!, methodSignature.asmMethod.descriptor!!, MemberKind.METHOD)
groupedBySignature.putValue(rawSignature, OtherOrigin(member)) groupedBySignature.putValue(rawSignature, OtherOrigin(member))
} }
} }
@@ -185,7 +185,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean { private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
if (descriptor is SamAdapterDescriptor<*>) return true if (descriptor is SamAdapterDescriptor<*>) return true
return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE return descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
&& descriptor.getOverriddenDescriptors().all { isOrOverridesSamAdapter(it) } && descriptor.overriddenDescriptors.all { isOrOverridesSamAdapter(it) }
} }
} }
@@ -44,40 +44,39 @@ import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import java.io.File import java.io.File
public class GenerationState @JvmOverloads constructor( class GenerationState @JvmOverloads constructor(
public val project: Project, val project: Project,
builderFactory: ClassBuilderFactory, builderFactory: ClassBuilderFactory,
public val module: ModuleDescriptor, val module: ModuleDescriptor,
bindingContext: BindingContext, bindingContext: BindingContext,
public val files: List<KtFile>, val files: List<KtFile>,
disableCallAssertions: Boolean = true, disableCallAssertions: Boolean = true,
disableParamAssertions: Boolean = true, disableParamAssertions: Boolean = true,
public val generateDeclaredClassFilter: GenerationState.GenerateClassFilter = GenerationState.GenerateClassFilter.GENERATE_ALL, val generateDeclaredClassFilter: GenerationState.GenerateClassFilter = GenerationState.GenerateClassFilter.GENERATE_ALL,
disableInline: Boolean = false, disableInline: Boolean = false,
disableOptimization: Boolean = false, disableOptimization: Boolean = false,
public val useTypeTableInSerializer: Boolean = false, val useTypeTableInSerializer: Boolean = false,
public val packagesWithObsoleteParts: Collection<FqName> = emptySet(), val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
public val obsoleteMultifileClasses: Collection<FqName> = emptySet(), val obsoleteMultifileClasses: Collection<FqName> = emptySet(),
// for PackageCodegen in incremental compilation mode // for PackageCodegen in incremental compilation mode
public val targetId: TargetId? = null, val targetId: TargetId? = null,
moduleName: String? = null, moduleName: String? = null,
// 'outDirectory' is a hack to correctly determine if a compiled class is from the same module as the callee during // 'outDirectory' is a hack to correctly determine if a compiled class is from the same module as the callee during
// partial compilation. Module chunks are treated as a single module. // partial compilation. Module chunks are treated as a single module.
// TODO: get rid of it with the proper module infrastructure // TODO: get rid of it with the proper module infrastructure
public val outDirectory: File? = null, val outDirectory: File? = null,
public val incrementalCompilationComponents: IncrementalCompilationComponents? = null, val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
public val generateOpenMultifileClasses: Boolean = false, val generateOpenMultifileClasses: Boolean = false,
public val progress: Progress = Progress.DEAF val progress: Progress = Progress.DEAF
) { ) {
public abstract class GenerateClassFilter { abstract class GenerateClassFilter {
public abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
public abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean
public abstract fun shouldGeneratePackagePart(jetFile: KtFile): Boolean abstract fun shouldGeneratePackagePart(jetFile: KtFile): Boolean
public abstract fun shouldGenerateScript(script: KtScript): Boolean abstract fun shouldGenerateScript(script: KtScript): Boolean
companion object { companion object {
@JvmField @JvmField val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
public val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = true override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = true
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean = true override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean = true
@@ -89,7 +88,7 @@ public class GenerationState @JvmOverloads constructor(
} }
} }
public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider() val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider()
private fun getIncrementalCacheForThisTarget() = private fun getIncrementalCacheForThisTarget() =
if (incrementalCompilationComponents != null && targetId != null) if (incrementalCompilationComponents != null && targetId != null)
@@ -100,47 +99,47 @@ public class GenerationState @JvmOverloads constructor(
private val interceptedBuilderFactory: ClassBuilderFactory private val interceptedBuilderFactory: ClassBuilderFactory
private var used = false private var used = false
public val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace
public val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics { val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics {
duplicateSignatureFactory.reportDiagnostics() duplicateSignatureFactory.reportDiagnostics()
extraJvmDiagnosticsTrace.bindingContext.diagnostics extraJvmDiagnosticsTrace.bindingContext.diagnostics
} }
public val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module) val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode() val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
public val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState") val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")
public val bindingContext: BindingContext = bindingTrace.getBindingContext() val bindingContext: BindingContext = bindingTrace.bindingContext
public val typeMapper: JetTypeMapper = JetTypeMapper(this.bindingContext, classBuilderMode, fileClassesProvider, getIncrementalCacheForThisTarget(), this.moduleName) val typeMapper: JetTypeMapper = JetTypeMapper(this.bindingContext, classBuilderMode, fileClassesProvider, getIncrementalCacheForThisTarget(), this.moduleName)
public val intrinsics: IntrinsicMethods = IntrinsicMethods() val intrinsics: IntrinsicMethods = IntrinsicMethods()
public val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this) val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
public val inlineCycleReporter: InlineCycleReporter = InlineCycleReporter(diagnostics) val inlineCycleReporter: InlineCycleReporter = InlineCycleReporter(diagnostics)
public val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this) val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
public val reflectionTypes: ReflectionTypes = ReflectionTypes(module) val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes() val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
public val factory: ClassFileFactory val factory: ClassFileFactory
private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics
public val replSpecific = ForRepl() val replSpecific = ForRepl()
//TODO: should be refactored out //TODO: should be refactored out
public class ForRepl { class ForRepl {
public var earlierScriptsForReplInterpreter: List<ScriptDescriptor>? = null var earlierScriptsForReplInterpreter: List<ScriptDescriptor>? = null
public var scriptResultFieldName: String? = null var scriptResultFieldName: String? = null
public val shouldGenerateScriptResultValue: Boolean get() = scriptResultFieldName != null val shouldGenerateScriptResultValue: Boolean get() = scriptResultFieldName != null
public var hasResult: Boolean = false var hasResult: Boolean = false
} }
public val isCallAssertionsEnabled: Boolean = !disableCallAssertions val isCallAssertionsEnabled: Boolean = !disableCallAssertions
@JvmName("isCallAssertionsEnabled") get @JvmName("isCallAssertionsEnabled") get
public val isParamAssertionsEnabled: Boolean = !disableParamAssertions val isParamAssertionsEnabled: Boolean = !disableParamAssertions
@JvmName("isParamAssertionsEnabled") get @JvmName("isParamAssertionsEnabled") get
public val isInlineEnabled: Boolean = !disableInline val isInlineEnabled: Boolean = !disableInline
@JvmName("isInlineEnabled") get @JvmName("isInlineEnabled") get
public val rootContext: CodegenContext<*> = RootContext(this) val rootContext: CodegenContext<*> = RootContext(this)
init { init {
val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization) val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization)
@@ -162,7 +161,7 @@ public class GenerationState @JvmOverloads constructor(
this.factory = ClassFileFactory(this, interceptedBuilderFactory) this.factory = ClassFileFactory(this, interceptedBuilderFactory)
} }
public fun beforeCompile() { fun beforeCompile() {
markUsed() markUsed()
CodegenBinding.initTrace(this) CodegenBinding.initTrace(this)
@@ -174,7 +173,7 @@ public class GenerationState @JvmOverloads constructor(
used = true used = true
} }
public fun destroy() { fun destroy() {
interceptedBuilderFactory.close() interceptedBuilderFactory.close()
} }
} }
@@ -56,7 +56,7 @@ private fun KotlinType.canHaveSubtypesIgnoringNullability(): Boolean {
return false return false
} }
public fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance): Variance { fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance): Variance {
if (parameterVariance === Variance.INVARIANT) { if (parameterVariance === Variance.INVARIANT) {
return projectionKind return projectionKind
} }
@@ -48,11 +48,11 @@ import java.io.ByteArrayOutputStream
import java.io.DataOutputStream import java.io.DataOutputStream
import java.io.File import java.io.File
public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) { class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
private var totalSize = 0 private var totalSize = 0
private var totalFiles = 0 private var totalFiles = 0
public fun serialize( fun serialize(
destDir: File, destDir: File,
srcDirs: List<File>, srcDirs: List<File>,
extraClassPath: List<File>, extraClassPath: List<File>,
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
public class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) { class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
override fun shouldUseTypeTable(): Boolean = true override fun shouldUseTypeTable(): Boolean = true
override fun serializePackage(packageFragments: Collection<PackageFragmentDescriptor>, proto: ProtoBuf.Package.Builder) { override fun serializePackage(packageFragments: Collection<PackageFragmentDescriptor>, proto: ProtoBuf.Package.Builder) {
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.cli.common package org.jetbrains.kotlin.cli.common
public val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = "kotlin.environment.keepalive" val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = "kotlin.environment.keepalive"
fun String?.toBooleanLenient(): Boolean? = when (this?.toLowerCase()) { fun String?.toBooleanLenient(): Boolean? = when (this?.toLowerCase()) {
@@ -16,21 +16,19 @@
package org.jetbrains.kotlin.cli.common.messages package org.jetbrains.kotlin.cli.common.messages
public data class CompilerMessageLocation private constructor( data class CompilerMessageLocation private constructor(
public val path: String?, val path: String?,
public val line: Int, val line: Int,
public val column: Int, val column: Int,
public val lineContent: String? val lineContent: String?
) { ) {
override fun toString(): String = override fun toString(): String =
path + (if (line != -1 || column != -1) " ($line:$column)" else "") path + (if (line != -1 || column != -1) " ($line:$column)" else "")
companion object { companion object {
@JvmField @JvmField val NO_LOCATION: CompilerMessageLocation = CompilerMessageLocation(null, -1, -1, null)
public val NO_LOCATION: CompilerMessageLocation = CompilerMessageLocation(null, -1, -1, null)
@JvmStatic @JvmStatic fun create(
public fun create(
path: String?, path: String?,
line: Int, line: Int,
column: Int, column: Int,
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.modules.JavaRootPath import org.jetbrains.kotlin.modules.JavaRootPath
import java.util.* import java.util.*
public class ModuleBuilder( class ModuleBuilder(
private val name: String, private val name: String,
private val outputDir: String, private val outputDir: String,
private val type: String private val type: String
@@ -30,19 +30,19 @@ public class ModuleBuilder(
private val javaSourceRoots = ArrayList<JavaRootPath>() private val javaSourceRoots = ArrayList<JavaRootPath>()
private val friendDirs = ArrayList<String>() private val friendDirs = ArrayList<String>()
public fun addSourceFiles(pattern: String) { fun addSourceFiles(pattern: String) {
sourceFiles.add(pattern) sourceFiles.add(pattern)
} }
public fun addClasspathEntry(name: String) { fun addClasspathEntry(name: String) {
classpathRoots.add(name) classpathRoots.add(name)
} }
public fun addJavaSourceRoot(rootPath: JavaRootPath) { fun addJavaSourceRoot(rootPath: JavaRootPath) {
javaSourceRoots.add(rootPath) javaSourceRoots.add(rootPath)
} }
public fun addFriendDir(friendDir: String) { fun addFriendDir(friendDir: String) {
friendDirs.add(friendDir) friendDirs.add(friendDir)
} }
@@ -20,7 +20,7 @@ import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.util.* import java.util.*
public object Main { object Main {
private val KOTLIN_HOME: File private val KOTLIN_HOME: File
init { init {
@@ -99,8 +99,7 @@ public object Main {
runner.run(classpath, arguments) runner.run(classpath, arguments)
} }
@JvmStatic @JvmStatic fun main(args: Array<String>) {
public fun main(args: Array<String>) {
try { try {
run(args) run(args)
} }
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
/** /**
* This class behaviour is the same as [MessageCollector.report] in [AnalyzerWithCompilerReport.reportDiagnostic]. * This class behaviour is the same as [MessageCollector.report] in [AnalyzerWithCompilerReport.reportDiagnostic].
*/ */
public class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter
public interface MessageCollectorBasedReporter : DiagnosticMessageReporter { interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
val messageCollector: MessageCollector val messageCollector: MessageCollector
@@ -19,6 +19,6 @@ package org.jetbrains.kotlin.cli.common.messages
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
public interface DiagnosticMessageReporter { interface DiagnosticMessageReporter {
fun report(diagnostic: Diagnostic, file: PsiFile, render: String) fun report(diagnostic: Diagnostic, file: PsiFile, render: String)
} }
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import java.io.File import java.io.File
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
public fun OutputFileCollection.writeAll(outputDir: File, report: (sources: List<File>, output: File) -> Unit) { fun OutputFileCollection.writeAll(outputDir: File, report: (sources: List<File>, output: File) -> Unit) {
for (file in asList()) { for (file in asList()) {
val sources = file.sourceFiles val sources = file.sourceFiles
val output = File(outputDir, file.relativePath) val output = File(outputDir, file.relativePath)
@@ -35,11 +35,11 @@ public fun OutputFileCollection.writeAll(outputDir: File, report: (sources: List
private val REPORT_NOTHING = { sources: List<File>, output: File -> } private val REPORT_NOTHING = { sources: List<File>, output: File -> }
public fun OutputFileCollection.writeAllTo(outputDir: File) { fun OutputFileCollection.writeAllTo(outputDir: File) {
writeAll(outputDir, REPORT_NOTHING) writeAll(outputDir, REPORT_NOTHING)
} }
public fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector) { fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector) {
writeAll(outputDir) { sources, output -> writeAll(outputDir) { sources, output ->
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output), CompilerMessageLocation.NO_LOCATION) messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output), CompilerMessageLocation.NO_LOCATION)
} }
@@ -45,7 +45,7 @@ import java.io.File
import java.lang.management.ManagementFactory import java.lang.management.ManagementFactory
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() { open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
override fun doExecute(arguments: K2JVMCompilerArguments, services: Services, messageCollector: MessageCollector, rootDisposable: Disposable): ExitCode { override fun doExecute(arguments: K2JVMCompilerArguments, services: Services, messageCollector: MessageCollector, rootDisposable: Disposable): ExitCode {
val messageSeverityCollector = MessageSeverityCollector(messageCollector) val messageSeverityCollector = MessageSeverityCollector(messageCollector)
@@ -54,7 +54,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
else else
PathUtil.getKotlinPathsForCompiler() PathUtil.getKotlinPathsForCompiler()
messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Using Kotlin home directory " + paths.getHomePath(), CompilerMessageLocation.NO_LOCATION) messageSeverityCollector.report(CompilerMessageSeverity.LOGGING, "Using Kotlin home directory " + paths.homePath, CompilerMessageLocation.NO_LOCATION)
PerformanceCounter.setTimeCounterEnabled(arguments.reportPerf); PerformanceCounter.setTimeCounterEnabled(arguments.reportPerf);
val configuration = CompilerConfiguration() val configuration = CompilerConfiguration()
@@ -108,7 +108,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
for (arg in arguments.freeArgs) { for (arg in arguments.freeArgs) {
configuration.addKotlinSourceRoot(arg) configuration.addKotlinSourceRoot(arg)
val file = File(arg) val file = File(arg)
if (file.isDirectory()) { if (file.isDirectory) {
configuration.addJavaSourceRoot(file) configuration.addJavaSourceRoot(file)
} }
} }
@@ -159,14 +159,14 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
messageSeverityCollector.report(CompilerMessageSeverity.WARNING, "The '-d' option with a directory destination is ignored because '-module' is specified", CompilerMessageLocation.NO_LOCATION) messageSeverityCollector.report(CompilerMessageSeverity.WARNING, "The '-d' option with a directory destination is ignored because '-module' is specified", CompilerMessageLocation.NO_LOCATION)
} }
val directory = File(arguments.module).getAbsoluteFile().getParentFile() val directory = File(arguments.module).absoluteFile.parentFile
val compilerConfiguration = KotlinToJVMBytecodeCompiler.createCompilerConfiguration(configuration, moduleScript.getModules(), directory) val compilerConfiguration = KotlinToJVMBytecodeCompiler.createCompilerConfiguration(configuration, moduleScript.modules, directory)
environment = createCoreEnvironment(rootDisposable, compilerConfiguration) environment = createCoreEnvironment(rootDisposable, compilerConfiguration)
if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR if (messageSeverityCollector.anyReported(CompilerMessageSeverity.ERROR)) return COMPILATION_ERROR
KotlinToJVMBytecodeCompiler.compileModules(environment, configuration, moduleScript.getModules(), directory, jar, friendPaths, arguments.includeRuntime) KotlinToJVMBytecodeCompiler.compileModules(environment, configuration, moduleScript.modules, directory, jar, friendPaths, arguments.includeRuntime)
} }
else if (arguments.script) { else if (arguments.script) {
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size) val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size)
@@ -200,7 +200,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
return OK return OK
} }
catch (e: CompilationException) { catch (e: CompilationException) {
messageSeverityCollector.report(CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.getElement())) messageSeverityCollector.report(CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.element))
return INTERNAL_ERROR return INTERNAL_ERROR
} }
@@ -235,18 +235,17 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
private var elapsedJITTime = 0L private var elapsedJITTime = 0L
private var shouldReportPerf = true private var shouldReportPerf = true
public fun resetInitStartTime() { fun resetInitStartTime() {
if (initStartNanos == 0L) { if (initStartNanos == 0L) {
initStartNanos = System.nanoTime() initStartNanos = System.nanoTime()
} }
} }
@JvmStatic @JvmStatic fun main(args: Array<String>) {
public fun main(args: Array<String>) {
CLICompiler.doMain(K2JVMCompiler(), args) CLICompiler.doMain(K2JVMCompiler(), args)
} }
public fun reportPerf(configuration: CompilerConfiguration, message: String) { fun reportPerf(configuration: CompilerConfiguration, message: String) {
if (!shouldReportPerf) return if (!shouldReportPerf) return
val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!! val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!!
@@ -255,17 +254,17 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
fun reportGCTime(configuration: CompilerConfiguration) { fun reportGCTime(configuration: CompilerConfiguration) {
ManagementFactory.getGarbageCollectorMXBeans().forEach { ManagementFactory.getGarbageCollectorMXBeans().forEach {
val currentTime = it.getCollectionTime() val currentTime = it.collectionTime
val elapsedTime = elapsedGCTime.getOrElse(it.getName()) { 0 } val elapsedTime = elapsedGCTime.getOrElse(it.name) { 0 }
val time = currentTime - elapsedTime val time = currentTime - elapsedTime
reportPerf(configuration, "GC time for ${it.getName()} is $time ms") reportPerf(configuration, "GC time for ${it.name} is $time ms")
elapsedGCTime[it.getName()] = currentTime elapsedGCTime[it.name] = currentTime
} }
} }
fun reportCompilationTime(configuration: CompilerConfiguration) { fun reportCompilationTime(configuration: CompilerConfiguration) {
val bean = ManagementFactory.getCompilationMXBean() ?: return val bean = ManagementFactory.getCompilationMXBean() ?: return
val currentTime = bean.getTotalCompilationTime() val currentTime = bean.totalCompilationTime
reportPerf(configuration, "JIT time is ${currentTime - elapsedJITTime} ms") reportPerf(configuration, "JIT time is ${currentTime - elapsedJITTime} ms")
elapsedJITTime = currentTime elapsedJITTime = currentTime
} }
@@ -284,7 +283,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
classpath.addAll(arguments.classpath.split(File.pathSeparatorChar).map { File(it) }) classpath.addAll(arguments.classpath.split(File.pathSeparatorChar).map { File(it) })
} }
if (!arguments.noStdlib) { if (!arguments.noStdlib) {
classpath.add(paths.getRuntimePath()) classpath.add(paths.runtimePath)
} }
return classpath return classpath
} }
@@ -26,7 +26,7 @@ import java.net.URLClassLoader
import java.util.* import java.util.*
public object PluginCliParser { object PluginCliParser {
@JvmStatic @JvmStatic
fun loadPlugins(arguments: CommonCompilerArguments, configuration: CompilerConfiguration) { fun loadPlugins(arguments: CommonCompilerArguments, configuration: CompilerConfiguration) {
@@ -35,7 +35,7 @@ public object PluginCliParser {
?.map { File(it).toURI().toURL() } ?.map { File(it).toURI().toURL() }
?.toTypedArray() ?.toTypedArray()
?: arrayOf<URL>(), ?: arrayOf<URL>(),
javaClass.getClassLoader() javaClass.classLoader
) )
val componentRegistrars = ServiceLoader.load(ComponentRegistrar::class.java, classLoader).toArrayList() val componentRegistrars = ServiceLoader.load(ComponentRegistrar::class.java, classLoader).toArrayList()
@@ -93,7 +93,7 @@ public object PluginCliParser {
} }
} }
private class PluginURLClassLoader(urls: Array<URL>, parent: ClassLoader) : ClassLoader(Thread.currentThread().getContextClassLoader()) { private class PluginURLClassLoader(urls: Array<URL>, parent: ClassLoader) : ClassLoader(Thread.currentThread().contextClassLoader) {
private val childClassLoader: SelfThenParentURLClassLoader = SelfThenParentURLClassLoader(urls, parent) private val childClassLoader: SelfThenParentURLClassLoader = SelfThenParentURLClassLoader(urls, parent)
@Synchronized @Synchronized
@@ -62,7 +62,7 @@ import kotlin.properties.Delegates
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses * To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
*/ */
public class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSupport(), CodeAnalyzerInitializer { class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSupport(), CodeAnalyzerInitializer {
private val psiManager = PsiManager.getInstance(project) private val psiManager = PsiManager.getInstance(project)
private var bindingContext: BindingContext by Delegates.notNull() private var bindingContext: BindingContext by Delegates.notNull()
private var module: ModuleDescriptor by Delegates.notNull() private var module: ModuleDescriptor by Delegates.notNull()
@@ -172,7 +172,7 @@ public class CliLightClassGenerationSupport(project: Project) : LightClassGenera
return NoScopeRecordCliBindingTrace() return NoScopeRecordCliBindingTrace()
} }
public class NoScopeRecordCliBindingTrace : CliBindingTrace() { class NoScopeRecordCliBindingTrace : CliBindingTrace() {
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) { override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
if (slice === BindingContext.LEXICAL_SCOPE) { if (slice === BindingContext.LEXICAL_SCOPE) {
// In the compiler there's no need to keep scopes // In the compiler there's no need to keep scopes
@@ -186,14 +186,14 @@ public class CliLightClassGenerationSupport(project: Project) : LightClassGenera
} }
} }
public open class CliBindingTrace @TestOnly constructor() : BindingTraceContext() { open class CliBindingTrace @TestOnly constructor() : BindingTraceContext() {
private var kotlinCodeAnalyzer: KotlinCodeAnalyzer? = null private var kotlinCodeAnalyzer: KotlinCodeAnalyzer? = null
override fun toString(): String { override fun toString(): String {
return CliBindingTrace::class.java.name return CliBindingTrace::class.java.name
} }
public fun setKotlinCodeAnalyzer(kotlinCodeAnalyzer: KotlinCodeAnalyzer) { fun setKotlinCodeAnalyzer(kotlinCodeAnalyzer: KotlinCodeAnalyzer) {
this.kotlinCodeAnalyzer = kotlinCodeAnalyzer this.kotlinCodeAnalyzer = kotlinCodeAnalyzer
} }
@@ -20,13 +20,13 @@ import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClassFinder import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClassFinder
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
public class JvmCliVirtualFileFinder(private val index: JvmDependenciesIndex) : VirtualFileKotlinClassFinder() { class JvmCliVirtualFileFinder(private val index: JvmDependenciesIndex) : VirtualFileKotlinClassFinder() {
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? { override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? {
val classFileName = classId.getRelativeClassName().asString().replace('.', '$') val classFileName = classId.relativeClassName.asString().replace('.', '$')
return index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, rootType -> return index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, rootType ->
dir.findChild("$classFileName.class")?.let { dir.findChild("$classFileName.class")?.let {
if (it.isValid()) it else null if (it.isValid) it else null
} }
} }
} }

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