compiler: cleanup 'public', property access syntax
This commit is contained in:
@@ -27,15 +27,14 @@ import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
import java.util.Comparator
|
||||
|
||||
public object CodegenUtilKt {
|
||||
object CodegenUtilKt {
|
||||
|
||||
// class Foo : Bar by baz
|
||||
// descriptor = Foo
|
||||
// toInterface = Bar
|
||||
// delegateExpressionType = typeof(baz)
|
||||
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||
@JvmStatic
|
||||
public fun getDelegates(
|
||||
@JvmStatic fun getDelegates(
|
||||
descriptor: ClassDescriptor,
|
||||
toInterface: ClassDescriptor,
|
||||
delegateExpressionType: KotlinType? = null
|
||||
|
||||
+10
-10
@@ -19,22 +19,22 @@ package org.jetbrains.kotlin.backend.common.bridges
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import java.util.HashSet
|
||||
|
||||
public interface FunctionHandle {
|
||||
public val isDeclaration: Boolean
|
||||
public val isAbstract: Boolean
|
||||
interface FunctionHandle {
|
||||
val isDeclaration: Boolean
|
||||
val isAbstract: Boolean
|
||||
|
||||
public fun getOverridden(): Iterable<FunctionHandle>
|
||||
fun getOverridden(): Iterable<FunctionHandle>
|
||||
}
|
||||
|
||||
public data class Bridge<Signature>(
|
||||
public val from: Signature,
|
||||
public val to: Signature
|
||||
data class Bridge<Signature>(
|
||||
val from: Signature,
|
||||
val to: Signature
|
||||
) {
|
||||
override fun toString() = "$from -> $to"
|
||||
}
|
||||
|
||||
|
||||
public fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
function: Function,
|
||||
signature: (Function) -> Signature
|
||||
): Set<Bridge<Signature>> {
|
||||
@@ -69,7 +69,7 @@ public fun <Function : FunctionHandle, Signature> generateBridges(
|
||||
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>() {
|
||||
override fun afterChildren(current: Function) {
|
||||
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.
|
||||
* 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" })
|
||||
|
||||
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.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
|
||||
public fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
fun <Signature> generateBridgesForFunctionDescriptor(
|
||||
descriptor: FunctionDescriptor,
|
||||
signature: (FunctionDescriptor) -> 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
|
||||
* 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 {
|
||||
private val overridden = descriptor.getOverriddenDescriptors().map { DescriptorBasedFunctionHandle(it.getOriginal()) }
|
||||
data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
|
||||
private val overridden = descriptor.overriddenDescriptors.map { DescriptorBasedFunctionHandle(it.original) }
|
||||
|
||||
override val isDeclaration: Boolean =
|
||||
descriptor.getKind().isReal() ||
|
||||
descriptor.kind.isReal ||
|
||||
findTraitImplementation(descriptor) != null
|
||||
|
||||
override val isAbstract: Boolean =
|
||||
descriptor.getModality() == Modality.ABSTRACT ||
|
||||
DescriptorUtils.isInterface(descriptor.getContainingDeclaration())
|
||||
descriptor.modality == Modality.ABSTRACT ||
|
||||
DescriptorUtils.isInterface(descriptor.containingDeclaration)
|
||||
|
||||
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
|
||||
* 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? {
|
||||
if (descriptor.getKind().isReal()) return null
|
||||
fun findTraitImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? {
|
||||
if (descriptor.kind.isReal) return null
|
||||
if (isOrOverridesSynthesized(descriptor)) return null
|
||||
|
||||
val implementation = findImplementationFromInterface(descriptor) ?: 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
|
||||
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
|
||||
* 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 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.
|
||||
* The returned function should be called from TImpl-bridges generated for the given fake override.
|
||||
*/
|
||||
public fun firstSuperMethodFromKotlin(
|
||||
fun firstSuperMethodFromKotlin(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
implementation: CallableMemberDescriptor
|
||||
): CallableMemberDescriptor? {
|
||||
return descriptor.getOverriddenDescriptors().firstOrNull { overridden ->
|
||||
overridden.getModality() != Modality.ABSTRACT &&
|
||||
return descriptor.overriddenDescriptors.firstOrNull { overridden ->
|
||||
overridden.modality != Modality.ABSTRACT &&
|
||||
(overridden == implementation || OverrideResolver.overrides(overridden, implementation))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,24 +18,24 @@ package org.jetbrains.kotlin.backend.common.output
|
||||
|
||||
import java.io.File
|
||||
|
||||
public interface OutputFileCollection {
|
||||
public fun get(relativePath: String): OutputFile?
|
||||
public fun asList(): List<OutputFile>
|
||||
interface OutputFileCollection {
|
||||
fun get(relativePath: String): 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 asList(): List<OutputFile> = outputFiles
|
||||
}
|
||||
|
||||
public interface OutputFile {
|
||||
public val relativePath: String
|
||||
public val sourceFiles: List<File>
|
||||
public fun asByteArray(): ByteArray
|
||||
public fun asText(): String
|
||||
interface OutputFile {
|
||||
val relativePath: String
|
||||
val sourceFiles: List<File>
|
||||
fun asByteArray(): ByteArray
|
||||
fun asText(): String
|
||||
}
|
||||
|
||||
public class SimpleOutputFile(
|
||||
class SimpleOutputFile(
|
||||
override val sourceFiles: List<File>,
|
||||
override val relativePath: String,
|
||||
private val content: String
|
||||
@@ -46,7 +46,7 @@ public class SimpleOutputFile(
|
||||
override fun toString() = "$relativePath (compiled from $sourceFiles)"
|
||||
}
|
||||
|
||||
public class SimpleOutputBinaryFile(
|
||||
class SimpleOutputBinaryFile(
|
||||
override val sourceFiles: List<File>,
|
||||
override val relativePath: String,
|
||||
private val content: ByteArray
|
||||
|
||||
+7
-7
@@ -24,18 +24,18 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import java.util.*
|
||||
|
||||
open public class AbstractAccessorForFunctionDescriptor(
|
||||
open class AbstractAccessorForFunctionDescriptor(
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
name: Name
|
||||
) : SimpleFunctionDescriptorImpl(containingDeclaration, null, Annotations.EMPTY,
|
||||
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(
|
||||
this, it.getAnnotations(), it.isReified(),
|
||||
it.getVariance(), it.getName(),
|
||||
it.getIndex(), SourceElement.NO_SOURCE)
|
||||
for (upperBound in it.getUpperBounds()) {
|
||||
this, it.annotations, it.isReified,
|
||||
it.variance, it.name,
|
||||
it.index, SourceElement.NO_SOURCE)
|
||||
for (upperBound in it.upperBounds) {
|
||||
copy.addUpperBound(upperBound)
|
||||
}
|
||||
copy.setInitialized()
|
||||
@@ -43,5 +43,5 @@ open public class AbstractAccessorForFunctionDescriptor(
|
||||
}
|
||||
|
||||
protected fun copyValueParameters(descriptor: FunctionDescriptor): List<ValueParameterDescriptor> =
|
||||
descriptor.getValueParameters().map { it.copy(this, it.getName()) }
|
||||
descriptor.valueParameters.map { it.copy(this, it.name) }
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
public class AccessorForConstructorDescriptor(
|
||||
class AccessorForConstructorDescriptor(
|
||||
private val calleeDescriptor: ConstructorDescriptor,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
private val superCallTarget: ClassDescriptor?
|
||||
|
||||
@@ -147,8 +147,8 @@ open class BranchedValue(
|
||||
}, IFEQ)
|
||||
}
|
||||
|
||||
public fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
|
||||
if (operandType.getSort() == Type.OBJECT)
|
||||
fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
|
||||
if (operandType.sort == Type.OBJECT)
|
||||
ObjectCompare(opToken, operandType, left, right)
|
||||
else
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public interface Callable {
|
||||
public val owner: Type
|
||||
interface Callable {
|
||||
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) {
|
||||
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.util.Printer
|
||||
|
||||
public class CallableMethod(
|
||||
class CallableMethod(
|
||||
override val owner: Type,
|
||||
private val defaultImplOwner: Type?,
|
||||
private val defaultMethodDesc: String,
|
||||
@@ -37,48 +37,48 @@ public class CallableMethod(
|
||||
override val extensionReceiverType: Type?,
|
||||
override val generateCalleeType: Type?
|
||||
) : Callable {
|
||||
public fun getValueParameters(): List<JvmMethodParameterSignature> =
|
||||
signature.getValueParameters()
|
||||
fun getValueParameters(): List<JvmMethodParameterSignature> =
|
||||
signature.valueParameters
|
||||
|
||||
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 =
|
||||
signature.getAsmMethod()
|
||||
fun getAsmMethod(): Method =
|
||||
signature.asmMethod
|
||||
|
||||
override val parameterTypes: Array<Type>
|
||||
get() = getAsmMethod().getArgumentTypes()
|
||||
get() = getAsmMethod().argumentTypes
|
||||
|
||||
|
||||
public override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor())
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
v.visitMethodInsn(invokeOpcode, owner.internalName, getAsmMethod().name, getAsmMethod().descriptor)
|
||||
}
|
||||
|
||||
public fun genInvokeDefaultInstruction(v: InstructionAdapter) {
|
||||
fun genInvokeDefaultInstruction(v: InstructionAdapter) {
|
||||
if (defaultImplOwner == null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
val method = getAsmMethod()
|
||||
|
||||
if ("<init>".equals(method.getName())) {
|
||||
if ("<init>".equals(method.name)) {
|
||||
v.aconst(null)
|
||||
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", defaultMethodDesc, false)
|
||||
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.internalName, "<init>", defaultMethodDesc, false)
|
||||
}
|
||||
else {
|
||||
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(),
|
||||
method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
|
||||
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.internalName,
|
||||
method.name + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, defaultMethodDesc, false)
|
||||
|
||||
StackValue.coerce(Type.getReturnType(defaultMethodDesc), Type.getReturnType(signature.asmMethod.descriptor), v)
|
||||
}
|
||||
}
|
||||
|
||||
override val returnType: Type
|
||||
get() = signature.getReturnType()
|
||||
get() = signature.returnType
|
||||
|
||||
override fun isStaticCall(): Boolean =
|
||||
invokeOpcode == INVOKESTATIC
|
||||
|
||||
override fun toString(): String =
|
||||
"${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature"
|
||||
"${Printer.OPCODES[invokeOpcode]} ${owner.internalName}.$signature"
|
||||
}
|
||||
|
||||
+1
-1
@@ -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.MethodVisitor
|
||||
|
||||
public abstract class ClassNameCollectionClassBuilderFactory(
|
||||
abstract class ClassNameCollectionClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
public class CodegenFileClassesProvider : JvmFileClassesProvider {
|
||||
override public fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
|
||||
class CodegenFileClassesProvider : JvmFileClassesProvider {
|
||||
override fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
|
||||
JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
||||
}
|
||||
+27
-27
@@ -65,14 +65,14 @@ class CollectionStubMethodGenerator(
|
||||
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
|
||||
// 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,
|
||||
// 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
|
||||
// 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 mutableCollectionType = newType(mutableClass, readOnlyCollectionType.getArguments())
|
||||
val mutableCollectionType = newType(mutableClass, readOnlyCollectionType.arguments)
|
||||
|
||||
child.addSupertype(parentType)
|
||||
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
|
||||
// or save its descriptor to generate all the needed bridges
|
||||
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
|
||||
// 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
|
||||
val signature = method.signature()
|
||||
@@ -160,18 +160,18 @@ class CollectionStubMethodGenerator(
|
||||
|
||||
val collectionClasses = with(descriptor.builtIns) {
|
||||
listOf(
|
||||
pair(getCollection(), getMutableCollection()),
|
||||
pair(getSet(), getMutableSet()),
|
||||
pair(getList(), getMutableList()),
|
||||
pair(getMap(), getMutableMap()),
|
||||
pair(getMapEntry(), getMutableMapEntry()),
|
||||
pair(getIterable(), getMutableIterable()),
|
||||
pair(getIterator(), getMutableIterator()),
|
||||
pair(getListIterator(), getMutableListIterator())
|
||||
pair(collection, mutableCollection),
|
||||
pair(set, mutableSet),
|
||||
pair(list, mutableList),
|
||||
pair(map, mutableMap),
|
||||
pair(mapEntry, mutableMapEntry),
|
||||
pair(iterable, mutableIterable),
|
||||
pair(iterator, mutableIterator),
|
||||
pair(listIterator, mutableListIterator)
|
||||
)
|
||||
}
|
||||
|
||||
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.getDefaultType()).classes().toHashSet()
|
||||
val allSuperClasses = TypeUtils.getAllSupertypes(descriptor.defaultType).classes().toHashSet()
|
||||
|
||||
val ourSuperCollectionClasses = collectionClasses.filter { pair ->
|
||||
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.
|
||||
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 }
|
||||
}
|
||||
|
||||
private fun Collection<KotlinType>.classes(): Collection<ClassDescriptor> =
|
||||
this.map { it.getConstructor().getDeclarationDescriptor() as ClassDescriptor }
|
||||
this.map { it.constructor.declarationDescriptor as ClassDescriptor }
|
||||
|
||||
private fun findFakeOverridesForMethodsFromMutableCollection(
|
||||
klass: ClassDescriptor,
|
||||
@@ -212,7 +212,7 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
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.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
|
||||
@@ -222,11 +222,11 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun createSyntheticSubclass(): Pair<MutableClassDescriptor, List<TypeParameterDescriptor>> {
|
||||
val child = MutableClassDescriptor(descriptor.getContainingDeclaration(), ClassKind.CLASS, false,
|
||||
Name.special("<synthetic inheritor of ${descriptor.getName()}>"), descriptor.getSource())
|
||||
child.setModality(Modality.FINAL)
|
||||
child.setVisibility(Visibilities.PUBLIC)
|
||||
val typeParameters = descriptor.getTypeConstructor().getParameters()
|
||||
val child = MutableClassDescriptor(descriptor.containingDeclaration, ClassKind.CLASS, false,
|
||||
Name.special("<synthetic inheritor of ${descriptor.name}>"), descriptor.source)
|
||||
child.modality = Modality.FINAL
|
||||
child.visibility = Visibilities.PUBLIC
|
||||
val typeParameters = descriptor.typeConstructor.parameters
|
||||
val newTypeParameters = ArrayList<TypeParameterDescriptor>(typeParameters.size)
|
||||
DescriptorSubstitutor.substituteTypeParameters(typeParameters, TypeSubstitution.EMPTY, child, newTypeParameters)
|
||||
child.setTypeParameterDescriptors(typeParameters)
|
||||
@@ -234,7 +234,7 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -246,13 +246,13 @@ class CollectionStubMethodGenerator(
|
||||
private fun generateMethodStub(signature: JvmMethodSignature, synthetic: Boolean) {
|
||||
// TODO: investigate if it makes sense to generate abstract stubs in traits
|
||||
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
|
||||
|
||||
val asmMethod = signature.getAsmMethod()
|
||||
val genericSignature = if (synthetic) null else signature.getGenericsSignature()
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.getName(), asmMethod.getDescriptor(), genericSignature, null)
|
||||
if (descriptor.getKind() != ClassKind.INTERFACE) {
|
||||
val asmMethod = signature.asmMethod
|
||||
val genericSignature = if (synthetic) null else signature.genericsSignature
|
||||
val mv = v.newMethod(JvmDeclarationOrigin.NO_ORIGIN, access, asmMethod.name, asmMethod.descriptor, genericSignature, null)
|
||||
if (descriptor.kind != ClassKind.INTERFACE) {
|
||||
mv.visitCode()
|
||||
AsmUtil.genThrow(InstructionAdapter(mv), "java/lang/UnsupportedOperationException", "Mutating immutable collection")
|
||||
FunctionCodegen.endVisit(mv, "built-in stub for $signature", null)
|
||||
|
||||
@@ -50,7 +50,7 @@ class DefaultCallMask(val size: Int) {
|
||||
return masks
|
||||
}
|
||||
|
||||
public fun generateOnStackIfNeeded(callGenerator: CallGenerator): Boolean {
|
||||
fun generateOnStackIfNeeded(callGenerator: CallGenerator): Boolean {
|
||||
val toInts = toInts()
|
||||
for (mask in toInts) {
|
||||
callGenerator.putValueIfNeeded(null, Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE))
|
||||
|
||||
+22
-22
@@ -33,7 +33,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
* Generates Java overloads for functions and constructors that have the default
|
||||
* 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,
|
||||
* 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 isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
|
||||
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 mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
|
||||
signature.getAsmMethod().getName(),
|
||||
signature.getAsmMethod().getDescriptor(),
|
||||
signature.getGenericsSignature(),
|
||||
signature.asmMethod.name,
|
||||
signature.asmMethod.descriptor,
|
||||
signature.genericsSignature,
|
||||
FunctionCodegen.getThrownExceptions(functionDescriptor, typeMapper))
|
||||
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.getReturnType())
|
||||
AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(functionDescriptor, signature.returnType)
|
||||
|
||||
remainingParameters.withIndex().forEach {
|
||||
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) {
|
||||
@@ -148,14 +148,14 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
v.load(thisIndex, methodOwner) // Load this on stack
|
||||
}
|
||||
else {
|
||||
val delegateOwner = delegateFunctionDescriptor.getContainingDeclaration()
|
||||
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject()) {
|
||||
val delegateOwner = delegateFunctionDescriptor.containingDeclaration
|
||||
if (delegateOwner is ClassDescriptor && delegateOwner.isCompanionObject) {
|
||||
val singletonValue = StackValue.singleton(delegateOwner, typeMapper)
|
||||
singletonValue.put(singletonValue.type, v);
|
||||
}
|
||||
}
|
||||
|
||||
val receiver = functionDescriptor.getExtensionReceiverParameter()
|
||||
val receiver = functionDescriptor.extensionReceiverParameter
|
||||
if (receiver != null) {
|
||||
val receiverType = typeMapper.mapType(receiver)
|
||||
val receiverIndex = frameMap.enter(receiver, receiverType)
|
||||
@@ -167,8 +167,8 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
|
||||
var mask = 0
|
||||
val masks = arrayListOf<Int>()
|
||||
for (parameterDescriptor in functionDescriptor.getValueParameters()) {
|
||||
val paramType = typeMapper.mapType(parameterDescriptor.getType())
|
||||
for (parameterDescriptor in functionDescriptor.valueParameters) {
|
||||
val paramType = typeMapper.mapType(parameterDescriptor.type)
|
||||
if (parameterDescriptor in remainingParameters) {
|
||||
val index = frameMap.getIndex(parameterDescriptor)
|
||||
StackValue.local(index, paramType).put(paramType, v)
|
||||
@@ -195,39 +195,39 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
|
||||
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
v.invokespecial(methodOwner.getInternalName(), defaultMethod.getName(), defaultMethod.getDescriptor(), false)
|
||||
v.invokespecial(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
private fun getRemainingParameters(functionDescriptor: FunctionDescriptor,
|
||||
substituteCount: Int): List<ValueParameterDescriptor> {
|
||||
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 {
|
||||
val classDescriptor = constructorDescriptor.getContainingDeclaration()
|
||||
if (classDescriptor.getKind() != ClassKind.CLASS) return false
|
||||
val classDescriptor = constructorDescriptor.containingDeclaration
|
||||
if (classDescriptor.kind != ClassKind.CLASS) return false
|
||||
|
||||
if (classOrObject.isLocal()) 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
|
||||
|
||||
if (constructorDescriptor.getValueParameters().isEmpty()) return false
|
||||
if (constructorDescriptor.valueParameters.isEmpty()) 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) =
|
||||
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.MethodVisitor
|
||||
|
||||
public abstract class DelegatingClassBuilderFactory(
|
||||
abstract class DelegatingClassBuilderFactory(
|
||||
protected val delegate: ClassBuilderFactory
|
||||
|
||||
) : ClassBuilderFactory by delegate {
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
public override fun asText(builder: ClassBuilder?): String? {
|
||||
override fun asText(builder: ClassBuilder?): String? {
|
||||
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.resolve.calls.model.ResolvedCall
|
||||
|
||||
public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
|
||||
val processingFunctions = linkedMapOf<PsiElement, CallableDescriptor>()
|
||||
|
||||
public fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
|
||||
fun enterIntoInlining(call: ResolvedCall<*>?): Boolean {
|
||||
//null call for default method inlining
|
||||
if (call != null) {
|
||||
val callElement = call.getCall().getCallElement()
|
||||
val callElement = call.call.callElement
|
||||
if (processingFunctions.contains(callElement)) {
|
||||
val cycle = processingFunctions.asSequence().dropWhile { it.key != callElement }
|
||||
cycle.forEach {
|
||||
@@ -38,14 +38,14 @@ public class InlineCycleReporter(val diagnostics: DiagnosticSink) {
|
||||
}
|
||||
return false
|
||||
}
|
||||
processingFunctions.put(callElement, call.getResultingDescriptor().getOriginal())
|
||||
processingFunctions.put(callElement, call.resultingDescriptor.original)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public fun exitFromInliningOf(call: ResolvedCall<*>?) {
|
||||
fun exitFromInliningOf(call: ResolvedCall<*>?) {
|
||||
if (call != null) {
|
||||
val callElement = call.getCall().getCallElement()
|
||||
val callElement = call.call.callElement
|
||||
processingFunctions.remove(callElement)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import java.util.*
|
||||
|
||||
public class InterfaceImplBodyCodegen(
|
||||
class InterfaceImplBodyCodegen(
|
||||
aClass: KtClassOrObject,
|
||||
context: ClassContext,
|
||||
v: ClassBuilder,
|
||||
@@ -54,7 +54,7 @@ public class InterfaceImplBodyCodegen(
|
||||
typeMapper.mapDefaultImpls(descriptor).internalName,
|
||||
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
|
||||
)
|
||||
v.visitSource(myClass.getContainingFile().getName(), null)
|
||||
v.visitSource(myClass.containingFile.name, null)
|
||||
}
|
||||
|
||||
override fun classForInnerClassRecord(): ClassDescriptor? {
|
||||
@@ -69,12 +69,12 @@ public class InterfaceImplBodyCodegen(
|
||||
}
|
||||
|
||||
override fun generateSyntheticParts() {
|
||||
for (memberDescriptor in descriptor.getDefaultType().getMemberScope().getContributedDescriptors()) {
|
||||
for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
|
||||
if (memberDescriptor !is CallableMemberDescriptor) continue
|
||||
|
||||
if (memberDescriptor.getKind().isReal()) continue
|
||||
if (memberDescriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) continue
|
||||
if (memberDescriptor.getModality() == Modality.ABSTRACT) continue
|
||||
if (memberDescriptor.kind.isReal) continue
|
||||
if (memberDescriptor.visibility == Visibilities.INVISIBLE_FAKE) continue
|
||||
if (memberDescriptor.modality == Modality.ABSTRACT) continue
|
||||
|
||||
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
|
||||
|
||||
@@ -82,7 +82,7 @@ public class InterfaceImplBodyCodegen(
|
||||
if (implementation is JavaMethodDescriptor) continue
|
||||
|
||||
// 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)
|
||||
|
||||
if (memberDescriptor is FunctionDescriptor) {
|
||||
@@ -90,13 +90,13 @@ public class InterfaceImplBodyCodegen(
|
||||
}
|
||||
else if (memberDescriptor is PropertyDescriptor) {
|
||||
implementation as PropertyDescriptor
|
||||
val getter = (copy as PropertyDescriptor).getGetter()
|
||||
val implGetter = implementation.getGetter()
|
||||
val getter = (copy as PropertyDescriptor).getter
|
||||
val implGetter = implementation.getter
|
||||
if (getter != null && implGetter != null) {
|
||||
generateDelegationToSuperTraitImpl(getter, implGetter)
|
||||
}
|
||||
val setter = copy.getSetter()
|
||||
val implSetter = implementation.getSetter()
|
||||
val setter = copy.setter
|
||||
val implSetter = implementation.setter
|
||||
if (setter != null && implSetter != null) {
|
||||
generateDelegationToSuperTraitImpl(setter, implSetter)
|
||||
}
|
||||
@@ -120,7 +120,7 @@ public class InterfaceImplBodyCodegen(
|
||||
val iv = codegen.v
|
||||
|
||||
val method = typeMapper.mapToCallableMethod(delegateTo, true)
|
||||
val myParameters = signature.getValueParameters()
|
||||
val myParameters = signature.valueParameters
|
||||
val calleeParameters = method.getValueParameters()
|
||||
|
||||
if (myParameters.size != calleeParameters.size) {
|
||||
@@ -135,14 +135,14 @@ public class InterfaceImplBodyCodegen(
|
||||
var k = 0
|
||||
val it = calleeParameters.iterator()
|
||||
for (parameter in myParameters) {
|
||||
val type = parameter.getAsmType()
|
||||
StackValue.local(k, type).put(it.next().getAsmType(), iv)
|
||||
k += type.getSize()
|
||||
val type = parameter.asmType
|
||||
StackValue.local(k, type).put(it.next().asmType, iv)
|
||||
k += type.size
|
||||
}
|
||||
|
||||
method.genInvokeInstruction(iv)
|
||||
StackValue.coerce(method.returnType, signature.getReturnType(), iv)
|
||||
iv.areturn(signature.getReturnType())
|
||||
StackValue.coerce(method.returnType, signature.returnType, iv)
|
||||
iv.areturn(signature.returnType)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -79,15 +79,14 @@ class JvmStaticGenerator(
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
public fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
|
||||
@JvmStatic fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
|
||||
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor
|
||||
val copies = CodegenUtil.copyFunctions(
|
||||
memberDescriptor,
|
||||
memberDescriptor,
|
||||
descriptor.getContainingDeclaration().getContainingDeclaration(),
|
||||
descriptor.getModality(),
|
||||
descriptor.getVisibility(),
|
||||
descriptor.containingDeclaration.containingDeclaration,
|
||||
descriptor.modality,
|
||||
descriptor.visibility,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
false
|
||||
)
|
||||
|
||||
@@ -54,9 +54,9 @@ import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.util.*
|
||||
|
||||
public class MultifileClassCodegen(
|
||||
class MultifileClassCodegen(
|
||||
private val state: GenerationState,
|
||||
public val files: Collection<KtFile>,
|
||||
val files: Collection<KtFile>,
|
||||
private val facadeFqName: FqName
|
||||
) {
|
||||
private val facadeClassType = AsmUtil.asmTypeByFqNameWithoutInnerClasses(facadeFqName)
|
||||
@@ -74,7 +74,7 @@ public class MultifileClassCodegen(
|
||||
private fun getDeserializedCallables(compiledPackageFragment: PackageFragmentDescriptor) =
|
||||
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 {
|
||||
val originFile = files.firstOrNull()
|
||||
@@ -103,7 +103,7 @@ public class MultifileClassCodegen(
|
||||
classBuilder
|
||||
}
|
||||
|
||||
public fun generate(errorHandler: CompilationErrorHandler) {
|
||||
fun generate(errorHandler: CompilationErrorHandler) {
|
||||
val generateCallableMemberTasks = HashMap<CallableMemberDescriptor, () -> Unit>()
|
||||
val partFqNames = arrayListOf<FqName>()
|
||||
|
||||
@@ -152,7 +152,7 @@ public class MultifileClassCodegen(
|
||||
writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames)
|
||||
}
|
||||
|
||||
public fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
|
||||
fun generateClassOrObject(classOrObject: KtClassOrObject, packagePartContext: FieldOwnerContext<PackageFragmentDescriptor>) {
|
||||
MemberCodegen.genClassOrObject(packagePartContext, classOrObject, state, null)
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ public class MultifileClassCodegen(
|
||||
override fun generateKotlinAnnotation() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
public fun done() {
|
||||
fun done() {
|
||||
classBuilder.done()
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import java.util.*
|
||||
|
||||
public class MultifileClassPartCodegen(
|
||||
class MultifileClassPartCodegen(
|
||||
v: ClassBuilder,
|
||||
file: KtFile,
|
||||
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.Method
|
||||
|
||||
public class PropertyReferenceCodegen(
|
||||
class PropertyReferenceCodegen(
|
||||
state: GenerationState,
|
||||
parentCodegen: MemberCodegen<*>,
|
||||
context: ClassContext,
|
||||
@@ -68,22 +68,22 @@ public class PropertyReferenceCodegen(
|
||||
element,
|
||||
V1_6,
|
||||
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor),
|
||||
asmType.getInternalName(),
|
||||
asmType.internalName,
|
||||
null,
|
||||
superAsmType.getInternalName(),
|
||||
superAsmType.internalName,
|
||||
emptyArray()
|
||||
)
|
||||
|
||||
v.visitSource(element.getContainingFile().getName(), null)
|
||||
v.visitSource(element.containingFile.name, null)
|
||||
}
|
||||
|
||||
// TODO: ImplementationBodyCodegen.markLineNumberForSyntheticFunction?
|
||||
override fun generateBody() {
|
||||
generateConstInstance(asmType, wrapperMethod.getReturnType())
|
||||
generateConstInstance(asmType, wrapperMethod.returnType)
|
||||
|
||||
generateMethod("property reference init", 0, method("<init>", Type.VOID_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)) {
|
||||
@@ -91,7 +91,7 @@ public class PropertyReferenceCodegen(
|
||||
}
|
||||
|
||||
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)) {
|
||||
@@ -108,11 +108,11 @@ public class PropertyReferenceCodegen(
|
||||
// return type and value parameter types. However, it's created only to be able to use
|
||||
// ExpressionCodegen#intermediateValueForProperty, which is poorly coupled with everything else.
|
||||
val fakeDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(method.getName()), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
classDescriptor, Annotations.EMPTY, Name.identifier(method.name), CallableMemberDescriptor.Kind.DECLARATION,
|
||||
SourceElement.NO_SOURCE
|
||||
)
|
||||
fakeDescriptor.initialize(null, classDescriptor.getThisAsReceiverParameter(), emptyList(), emptyList(),
|
||||
classDescriptor.builtIns.getAnyType(), Modality.OPEN, Visibilities.PUBLIC)
|
||||
fakeDescriptor.initialize(null, classDescriptor.thisAsReceiverParameter, emptyList(), emptyList(),
|
||||
classDescriptor.builtIns.anyType, Modality.OPEN, Visibilities.PUBLIC)
|
||||
|
||||
val fakeCodegen = ExpressionCodegen(
|
||||
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) {
|
||||
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) {
|
||||
val iv = InstructionAdapter(mv)
|
||||
iv.visitCode()
|
||||
iv.generate()
|
||||
iv.areturn(method.getReturnType())
|
||||
iv.areturn(method.returnType)
|
||||
FunctionCodegen.endVisit(mv, debugString, element)
|
||||
}
|
||||
}
|
||||
@@ -162,9 +162,9 @@ public class PropertyReferenceCodegen(
|
||||
writeKotlinSyntheticClassAnnotation(v, state)
|
||||
}
|
||||
|
||||
public fun putInstanceOnStack(): StackValue =
|
||||
StackValue.operation(wrapperMethod.getReturnType()) { iv ->
|
||||
iv.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, wrapperMethod.getReturnType().getDescriptor())
|
||||
fun putInstanceOnStack(): StackValue =
|
||||
StackValue.operation(wrapperMethod.returnType) { iv ->
|
||||
iv.getstatic(asmType.internalName, JvmAbi.INSTANCE_FIELD, wrapperMethod.returnType.descriptor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+1
-1
@@ -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.MethodVisitor
|
||||
|
||||
public abstract class SignatureCollectingClassBuilderFactory(
|
||||
abstract class SignatureCollectingClassBuilderFactory(
|
||||
delegate: ClassBuilderFactory
|
||||
) : DelegatingClassBuilderFactory(delegate) {
|
||||
|
||||
|
||||
@@ -22,19 +22,19 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
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 {
|
||||
fun createInfo(element: KtElement?, internalClassName: String): SourceInfo {
|
||||
assert(element != null) { "Couldn't create source mapper for null element " + internalClassName }
|
||||
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.getContainingFile(), true)
|
||||
assert(lineNumbers != null) { "Couldn't extract line count in " + element.getContainingFile() }
|
||||
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.containingFile, true)
|
||||
assert(lineNumbers != null) { "Couldn't extract line count in " + element.containingFile }
|
||||
|
||||
//TODO hack condition for package parts cleaning
|
||||
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
|
||||
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 leaveTasks: (StackValue) -> Unit
|
||||
) : StackValue(stackValue.type) {
|
||||
|
||||
+5
-5
@@ -22,15 +22,15 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
public interface WrappedAnnotated : Annotated {
|
||||
public val originalAnnotated: Annotated
|
||||
interface WrappedAnnotated : 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
|
||||
}
|
||||
|
||||
public class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
|
||||
class AnnotatedWithOnlyTargetedAnnotations(private val original: Annotated) : Annotated {
|
||||
private val annotations: Annotations = UseSiteTargetedAnnotations(original.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 {
|
||||
@JvmStatic
|
||||
public fun <Signature> generateBridgesForBuiltinSpecial(
|
||||
@JvmStatic fun <Signature> generateBridgesForBuiltinSpecial(
|
||||
function: FunctionDescriptor,
|
||||
signatureByDescriptor: (FunctionDescriptor) -> Signature
|
||||
): Set<BridgeForBuiltinSpecial<Signature>> {
|
||||
@@ -93,8 +92,7 @@ object BuiltinSpecialBridgesUtil {
|
||||
return bridges
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
|
||||
@JvmStatic fun <Signature> FunctionDescriptor.shouldHaveTypeSafeBarrier(
|
||||
signatureByDescriptor: (FunctionDescriptor) -> Signature
|
||||
): Boolean {
|
||||
if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false
|
||||
@@ -143,7 +141,7 @@ private fun <Signature> needGenerateSpecialBridge(
|
||||
&& signatureByDescriptor(it) == overriddenBuiltinSignature }
|
||||
}
|
||||
|
||||
public fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
|
||||
fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
|
||||
element: KtElement,
|
||||
bindingContext: BindingContext
|
||||
): 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)") }
|
||||
|
||||
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
|
||||
|
||||
public object CodegenContextUtil {
|
||||
@JvmStatic
|
||||
public fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
|
||||
object CodegenContextUtil {
|
||||
@JvmStatic fun getImplementationOwnerClassType(owner: CodegenContext<*>): Type? =
|
||||
when (owner) {
|
||||
is MultifileClassFacadeContext -> owner.filePartType
|
||||
is DelegatingToPartContext -> owner.implementationOwnerClassType
|
||||
else -> null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
|
||||
@JvmStatic fun isImplClassOwner(owner: CodegenContext<*>): Boolean =
|
||||
owner !is MultifileClassFacadeContext
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,11 +21,11 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
public interface ClassBuilderInterceptorExtension {
|
||||
interface ClassBuilderInterceptorExtension {
|
||||
companion object : ProjectExtensionDescriptor<ClassBuilderInterceptorExtension>(
|
||||
"org.jetbrains.kotlin.classBuilderFactoryInterceptorExtension", ClassBuilderInterceptorExtension::class.java)
|
||||
|
||||
public fun interceptClassBuilderFactory(
|
||||
fun interceptClassBuilderFactory(
|
||||
interceptedFactory: ClassBuilderFactory,
|
||||
bindingContext: BindingContext,
|
||||
diagnostics: DiagnosticSink
|
||||
|
||||
+7
-7
@@ -26,28 +26,28 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
|
||||
public interface ExpressionCodegenExtension {
|
||||
interface ExpressionCodegenExtension {
|
||||
companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>(
|
||||
"org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java)
|
||||
|
||||
public class Context(
|
||||
public val typeMapper: JetTypeMapper,
|
||||
public val v: InstructionAdapter
|
||||
class Context(
|
||||
val typeMapper: JetTypeMapper,
|
||||
val v: InstructionAdapter
|
||||
)
|
||||
|
||||
/**
|
||||
* Used for generating custom byte code for the property value obtain. This function has lazy semantics.
|
||||
* 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.
|
||||
* 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,
|
||||
state: GenerationState,
|
||||
classOrObject: KtClassOrObject,
|
||||
|
||||
+15
-15
@@ -25,26 +25,26 @@ import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import java.util.Comparator
|
||||
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
|
||||
|
||||
public fun getStartNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
|
||||
fun getStartNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
|
||||
return tryBlocksMetaInfo.intervalStarts.get(label)
|
||||
}
|
||||
|
||||
public fun getEndNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
|
||||
fun getEndNodes(label: LabelNode): List<TryCatchBlockNodeInfo> {
|
||||
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) {
|
||||
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`
|
||||
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 ->
|
||||
var result = instructionIndex(t1.handler) - instructionIndex(t2.handler)
|
||||
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()
|
||||
for (info in localVarsMetaInfo.getMeaningfulIntervals()) {
|
||||
node.localVariables.add(info.node)
|
||||
@@ -165,16 +165,16 @@ private fun Interval.isMeaningless(): Boolean {
|
||||
val start = this.startLabel
|
||||
var end: AbstractInsnNode = this.endLabel
|
||||
while (end != start && !end.isMeaningful) {
|
||||
end = end.getPrevious()
|
||||
end = end.previous
|
||||
}
|
||||
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() }
|
||||
}
|
||||
|
||||
public class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) {
|
||||
class DefaultProcessor(val node: MethodNode, parameterSize: Int) : CoveringTryCatchNodeProcessor(parameterSize) {
|
||||
|
||||
init {
|
||||
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
|
||||
get() = node.start
|
||||
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.tree.MethodNode
|
||||
|
||||
public class DeferredMethodVisitor(
|
||||
class DeferredMethodVisitor(
|
||||
val intermediate: MethodNode,
|
||||
val resultNode: () -> MethodVisitor
|
||||
) : 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 paramToDeclByteCodeIndex: HashMap<ParameterInfo, Int> = hashMapOf()
|
||||
|
||||
public val realArgsSizeOnStack = real.sumBy { it.type.size }
|
||||
public val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
|
||||
val realArgsSizeOnStack = real.sumBy { it.type.size }
|
||||
val capturedArgsSizeOnStack = captured.sumBy { it.type.size }
|
||||
|
||||
public val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack
|
||||
val argsSizeOnStack = realArgsSizeOnStack + capturedArgsSizeOnStack
|
||||
|
||||
init {
|
||||
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)
|
||||
|
||||
public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
|
||||
class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParameterMappings?) {
|
||||
|
||||
enum class OperationKind {
|
||||
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS;
|
||||
@@ -43,25 +43,21 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
public val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||
@JvmField
|
||||
public val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||
@JvmField val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||
@JvmField val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||
|
||||
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
|
||||
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
|
||||
@JvmStatic fun isNeedClassReificationMarker(insn: AbstractInsnNode): Boolean =
|
||||
isReifiedMarker(insn) { s -> s == NEED_CLASS_REIFICATION_MARKER_METHOD_NAME }
|
||||
|
||||
@JvmStatic
|
||||
public fun putNeedClassReificationMarker(v: MethodVisitor) {
|
||||
@JvmStatic fun putNeedClassReificationMarker(v: MethodVisitor) {
|
||||
v.visitMethodInsn(
|
||||
Opcodes.INVOKESTATIC,
|
||||
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
|
||||
* 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()
|
||||
val instructions = node.instructions
|
||||
maxStackSize = 0
|
||||
@@ -95,7 +91,7 @@ public class ReifiedTypeInliner(private val parametersMapping: ReifiedTypeParame
|
||||
return result
|
||||
}
|
||||
|
||||
public fun reifySignature(oldSignature: String): SignatureReificationResult {
|
||||
fun reifySignature(oldSignature: String): SignatureReificationResult {
|
||||
if (parametersMapping == null) return SignatureReificationResult(oldSignature, ReifiedTypeParametersUsages())
|
||||
|
||||
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 {
|
||||
if (insn.getNext()?.getOpcode() != expectedNextOpcode) return false
|
||||
(insn.getNext() as TypeInsnNode).desc = parameter.getInternalName()
|
||||
if (insn.next?.opcode != expectedNextOpcode) return false
|
||||
(insn.next as TypeInsnNode).desc = parameter.internalName
|
||||
return true
|
||||
}
|
||||
|
||||
private fun processJavaClass(insn: MethodInsnNode, parameter: Type): Boolean {
|
||||
val next = insn.getNext()
|
||||
val next = insn.next
|
||||
if (next !is LdcInsnNode) return false
|
||||
next.cst = parameter
|
||||
return true
|
||||
@@ -255,14 +251,14 @@ private val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind? get(
|
||||
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||
}
|
||||
|
||||
public class ReifiedTypeParameterMappings() {
|
||||
class ReifiedTypeParameterMappings() {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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?
|
||||
)
|
||||
|
||||
public class ReifiedTypeParametersUsages {
|
||||
class ReifiedTypeParametersUsages {
|
||||
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)
|
||||
}
|
||||
|
||||
public fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) {
|
||||
fun propagateChildUsagesWithinContext(child: ReifiedTypeParametersUsages, context: MethodContext) {
|
||||
if (!child.wereUsedReifiedParameters()) return
|
||||
// used for propagating reified TP usages from children member codegen to parent's
|
||||
// mark enclosing object-literal/lambda as needed reification iff
|
||||
@@ -298,7 +294,7 @@ public class ReifiedTypeParametersUsages {
|
||||
}.forEach { usedTypeParameters.add(it) }
|
||||
}
|
||||
|
||||
public fun mergeAll(other: ReifiedTypeParametersUsages) {
|
||||
fun mergeAll(other: ReifiedTypeParametersUsages) {
|
||||
if (!other.wereUsedReifiedParameters()) return
|
||||
usedTypeParameters.addAll(other.usedTypeParameters)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import java.util.*
|
||||
|
||||
//TODO join parameter
|
||||
public class SMAPBuilder(val source: String,
|
||||
class SMAPBuilder(val source: String,
|
||||
val path: String,
|
||||
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) {
|
||||
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) {
|
||||
super.visitSource(name, path)
|
||||
@@ -162,7 +162,7 @@ interface SourceMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public object IdenticalSourceMapper : SourceMapper {
|
||||
object IdenticalSourceMapper : SourceMapper {
|
||||
override val resultMappings: List<FileMapping>
|
||||
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
|
||||
|
||||
@@ -273,7 +273,7 @@ class RawFileMapping(val name: String, val path: String) {
|
||||
}
|
||||
|
||||
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) {
|
||||
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>()
|
||||
|
||||
var id = -1;
|
||||
@@ -329,7 +329,7 @@ open public class FileMapping(val name: String, val path: String) {
|
||||
lineMapping.parent = this
|
||||
}
|
||||
|
||||
public object SKIP : FileMapping("no-source-info", "no-source-info") {
|
||||
object SKIP : FileMapping("no-source-info", "no-source-info") {
|
||||
init {
|
||||
addRangeMapping(RangeMapping.SKIP)
|
||||
}
|
||||
@@ -337,7 +337,7 @@ open public class FileMapping(val name: String, val path: String) {
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
@@ -366,6 +366,6 @@ data public class RangeMapping(val source: Int, val dest: Int, var range: Int =
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
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)) {
|
||||
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 {
|
||||
|
||||
@JvmStatic
|
||||
/*null smap means that there is no any debug info in file (e.g. sourceName)*/
|
||||
public fun parseOrCreateDefault(mappingInfo: String?, source: String?, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
|
||||
/*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 {
|
||||
if (mappingInfo == null || mappingInfo.isEmpty()) {
|
||||
val fm: FileMapping
|
||||
if (source == null || source.isEmpty()) {
|
||||
@@ -40,8 +39,7 @@ object SMAPParser {
|
||||
return parse(mappingInfo)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun parse(mappingInfo: String): SMAP {
|
||||
@JvmStatic fun parse(mappingInfo: String): SMAP {
|
||||
val fileMappings = linkedMapOf<Int, FileMapping>()
|
||||
|
||||
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length
|
||||
|
||||
@@ -26,7 +26,7 @@ enum class TryCatchPosition {
|
||||
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
|
||||
|
||||
@@ -35,7 +35,7 @@ interface Interval {
|
||||
val endLabel: LabelNode
|
||||
|
||||
/*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.DeserializedSimpleFunctionDescriptor
|
||||
|
||||
public val FunctionDescriptor.sourceFilePath: String
|
||||
val FunctionDescriptor.sourceFilePath: String
|
||||
get() {
|
||||
val source = source as PsiSourceElement
|
||||
val containingFile = source.psi?.containingFile
|
||||
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 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.CallableMethod
|
||||
|
||||
public class ArrayGet : IntrinsicMethod() {
|
||||
class ArrayGet : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
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.CallableMethod
|
||||
|
||||
public class ArrayIterator : IntrinsicMethod() {
|
||||
class ArrayIterator : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createUnaryIntrinsicCallable(method) {
|
||||
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}"
|
||||
val methodSignature = "(${method.owner.descriptor})${returnType.descriptor}"
|
||||
val intrinsicOwner =
|
||||
if (AsmUtil.isPrimitive(method.owner.elementType))
|
||||
"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.commons.InstructionAdapter
|
||||
|
||||
public class ArraySet : IntrinsicMethod() {
|
||||
class ArraySet : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable {
|
||||
val type = correctElementType(method.dispatchReceiverType)
|
||||
return object : IntrinsicCallable(
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
public class ArraySize : IntrinsicPropertyGetter() {
|
||||
class ArraySize : IntrinsicPropertyGetter() {
|
||||
override fun generate(
|
||||
resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue
|
||||
) = 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.Type
|
||||
|
||||
public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
||||
class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
||||
private fun shift(): Boolean =
|
||||
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.org.objectweb.asm.Opcodes
|
||||
|
||||
public class Clone : IntrinsicMethod() {
|
||||
class Clone : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable =
|
||||
createUnaryIntrinsicCallable(method, OBJECT_TYPE) {
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class CompareTo : IntrinsicMethod() {
|
||||
class CompareTo : IntrinsicMethod() {
|
||||
private fun genInvoke(type: Type?, v: InstructionAdapter) {
|
||||
when (type) {
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class Concat : IntrinsicMethod() {
|
||||
class Concat : IntrinsicMethod() {
|
||||
fun generateImpl(
|
||||
codegen: ExpressionCodegen,
|
||||
v: InstructionAdapter,
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
|
||||
public class Equals : IntrinsicMethod() {
|
||||
class Equals : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createBinaryIntrinsicCallable(
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class HashCode : IntrinsicMethod() {
|
||||
class HashCode : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
object : IntrinsicCallable(
|
||||
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.jvm.AsmTypes.OBJECT_TYPE
|
||||
|
||||
public class IdentityEquals : IntrinsicMethod() {
|
||||
class IdentityEquals : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
object : IntrinsicCallable(method) {
|
||||
override fun invokeMethodWithArguments(
|
||||
@@ -34,17 +34,17 @@ public class IdentityEquals : IntrinsicMethod() {
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
val element = resolvedCall.getCall().getCallElement()
|
||||
val element = resolvedCall.call.callElement
|
||||
val left: StackValue
|
||||
val right: StackValue
|
||||
if (element is KtCallExpression) {
|
||||
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 {
|
||||
element as KtBinaryExpression
|
||||
left = codegen.gen(element.getLeft())
|
||||
right = codegen.gen(element.getRight())
|
||||
left = codegen.gen(element.left)
|
||||
right = codegen.gen(element.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.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 =
|
||||
createIntrinsicCallable(method) {
|
||||
val jetExpression = resolvedCall.getCall().getCalleeExpression()
|
||||
assert(jetExpression !is KtPrefixExpression) { "There should be postfix increment ${jetExpression!!.getText()}" }
|
||||
val jetExpression = resolvedCall.call.calleeExpression
|
||||
assert(jetExpression !is KtPrefixExpression) { "There should be postfix increment ${jetExpression!!.text}" }
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public open class IntrinsicCallable(
|
||||
open class IntrinsicCallable(
|
||||
override val returnType: Type,
|
||||
override val valueParameterTypes: List<Type>,
|
||||
override val dispatchReceiverType: Type?,
|
||||
@@ -45,7 +45,7 @@ public open class IntrinsicCallable(
|
||||
invokeIntrinsic(v)
|
||||
}
|
||||
|
||||
public open fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
open fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
invoke(v)
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public open class IntrinsicCallable(
|
||||
override val owner: Type
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
public fun calcReceiverType(): Type =
|
||||
fun calcReceiverType(): Type =
|
||||
extensionReceiverType ?: dispatchReceiverType!!
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ fun createBinaryIntrinsicCallable(
|
||||
}
|
||||
}
|
||||
|
||||
public fun createUnaryIntrinsicCallable(
|
||||
fun createUnaryIntrinsicCallable(
|
||||
callable: CallableMethod,
|
||||
newReturnType: Type? = null,
|
||||
needPrimitiveCheck: Boolean = false,
|
||||
@@ -103,7 +103,7 @@ public fun createUnaryIntrinsicCallable(
|
||||
return intrinsic
|
||||
}
|
||||
|
||||
public fun createIntrinsicCallable(
|
||||
fun createIntrinsicCallable(
|
||||
callable: CallableMethod,
|
||||
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit
|
||||
): IntrinsicCallable {
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
public abstract class IntrinsicPropertyGetter : IntrinsicMethod() {
|
||||
public abstract fun generate(
|
||||
abstract class IntrinsicPropertyGetter : IntrinsicMethod() {
|
||||
abstract fun generate(
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
codegen: ExpressionCodegen,
|
||||
returnType: Type,
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
public class Inv : IntrinsicMethod() {
|
||||
class Inv : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable {
|
||||
val type = numberFunctionOperandType(method.returnType)
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class IteratorNext : IntrinsicMethod() {
|
||||
class IteratorNext : IntrinsicMethod() {
|
||||
private fun getIteratorName(returnType: Type): String {
|
||||
return when (returnType) {
|
||||
Type.CHAR_TYPE -> "Char"
|
||||
@@ -47,7 +47,7 @@ public class IteratorNext : IntrinsicMethod() {
|
||||
v.invokevirtual(
|
||||
BUILT_INS_PACKAGE_FQ_NAME.asString() + "/" + name + "Iterator",
|
||||
"next$name",
|
||||
"()" + returnType.getDescriptor(),
|
||||
"()" + returnType.descriptor,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
|
||||
public class JavaClassArray : IntrinsicMethod() {
|
||||
class JavaClassArray : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
//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.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
public class JavaClassFunction : IntrinsicMethod() {
|
||||
class JavaClassFunction : IntrinsicMethod() {
|
||||
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) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
public override fun generate(
|
||||
class JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
override fun generate(
|
||||
resolvedCall: ResolvedCall<*>?,
|
||||
codegen: ExpressionCodegen,
|
||||
returnType: Type,
|
||||
@@ -47,7 +47,7 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
receiver.put(type, v)
|
||||
AsmUtil.pop(v, type)
|
||||
}
|
||||
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;")
|
||||
v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
else {
|
||||
receiver.put(type, v)
|
||||
@@ -58,11 +58,11 @@ public class JavaClassProperty : IntrinsicPropertyGetter() {
|
||||
}
|
||||
|
||||
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) {
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
if (isPrimitive(classType)) {
|
||||
v.getstatic(boxType(classType).getInternalName(), "TYPE", "Ljava/lang/Class;")
|
||||
v.getstatic(boxType(classType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
else {
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class KClassJavaProperty : IntrinsicPropertyGetter() {
|
||||
class KClassJavaProperty : IntrinsicPropertyGetter() {
|
||||
override fun generate(resolvedCall: ResolvedCall<*>?, codegen: ExpressionCodegen, returnType: Type, receiver: StackValue): StackValue? {
|
||||
val extensionReceiver = resolvedCall!!.extensionReceiver as ReceiverValue
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class NewArray : IntrinsicMethod() {
|
||||
class NewArray : IntrinsicMethod() {
|
||||
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)
|
||||
return object : IntrinsicCallable(type, listOf(Type.INT_TYPE), null, null) {
|
||||
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.resolve.calls.model.ResolvedCall
|
||||
|
||||
public class Not : IntrinsicMethod() {
|
||||
class Not : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
object : IntrinsicCallable(method) {
|
||||
override fun invokeMethodWithArguments(
|
||||
@@ -31,10 +31,10 @@ public class Not : IntrinsicMethod() {
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
val element = resolvedCall.getCall().getCallElement()
|
||||
val element = resolvedCall.call.callElement
|
||||
val stackValue =
|
||||
if (element is KtPrefixExpression) {
|
||||
codegen.gen(element.getBaseExpression())
|
||||
codegen.gen(element.baseExpression)
|
||||
}
|
||||
else {
|
||||
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.StackValue
|
||||
|
||||
public class NumberCast : IntrinsicMethod() {
|
||||
class NumberCast : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createUnaryIntrinsicCallable(method) {
|
||||
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.commons.InstructionAdapter
|
||||
|
||||
public class RangeTo : IntrinsicMethod() {
|
||||
class RangeTo : IntrinsicMethod() {
|
||||
private fun nameToPrimitive(name: String): Type =
|
||||
when (name) {
|
||||
"Double" -> DOUBLE_TYPE
|
||||
@@ -37,7 +37,7 @@ public class RangeTo : IntrinsicMethod() {
|
||||
}
|
||||
|
||||
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(
|
||||
method.returnType,
|
||||
method.valueParameterTypes.map { argType },
|
||||
@@ -60,7 +60,7 @@ public class RangeTo : IntrinsicMethod() {
|
||||
}
|
||||
|
||||
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.CallableMethod
|
||||
|
||||
public class StringGetChar : IntrinsicMethod() {
|
||||
class StringGetChar : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
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.CallableMethod
|
||||
|
||||
public class StringPlus : IntrinsicMethod() {
|
||||
class StringPlus : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
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.CallableMethod
|
||||
|
||||
public class ToString : IntrinsicMethod() {
|
||||
class ToString : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable {
|
||||
val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType)
|
||||
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 kotlin.text.Regex
|
||||
|
||||
public object TypeIntrinsics {
|
||||
public @JvmStatic fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type) {
|
||||
object TypeIntrinsics {
|
||||
@JvmStatic fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type) {
|
||||
val functionTypeArity = getFunctionTypeArity(jetType)
|
||||
if (functionTypeArity >= 0) {
|
||||
v.iconst(functionTypeArity)
|
||||
@@ -57,7 +57,7 @@ public object TypeIntrinsics {
|
||||
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)
|
||||
if (functionTypeArity >= 0) {
|
||||
instructions.insertBefore(instanceofInsn, iconstNode(functionTypeArity))
|
||||
@@ -78,8 +78,7 @@ public object TypeIntrinsics {
|
||||
instanceofInsn.desc = asmType.internalName
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun checkcast(
|
||||
@JvmStatic fun checkcast(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType, asmType: Type,
|
||||
// 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.CallableMethod
|
||||
|
||||
public class UnaryMinus : IntrinsicMethod() {
|
||||
class UnaryMinus : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
|
||||
it.neg(returnType)
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
|
||||
public class UnaryPlus : IntrinsicMethod() {
|
||||
class UnaryPlus : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createUnaryIntrinsicCallable(method) {
|
||||
//nothing
|
||||
|
||||
+1
-1
@@ -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.isMeaningful
|
||||
|
||||
public class DeadCodeEliminationMethodTransformer : MethodTransformer() {
|
||||
class DeadCodeEliminationMethodTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
val frames = MethodTransformer.analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
|
||||
val insnList = methodNode.instructions
|
||||
|
||||
+3
-3
@@ -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.tree.*
|
||||
|
||||
public class LabelNormalizationMethodTransformer : MethodTransformer() {
|
||||
public override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
class LabelNormalizationMethodTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
TransformerForMethod(methodNode).transform()
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class LabelNormalizationMethodTransformer : MethodTransformer() {
|
||||
val instructions = methodNode.instructions
|
||||
val newLabelNodes = hashMapOf<Label, LabelNode>()
|
||||
|
||||
public fun transform() {
|
||||
fun transform() {
|
||||
if (rewriteLabelInstructions()) {
|
||||
rewriteNonLabelInstructions()
|
||||
rewriteTryCatchBlocks()
|
||||
|
||||
+2
-2
@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransfor
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
public class MandatoryMethodTransformer : MethodTransformer() {
|
||||
class MandatoryMethodTransformer : MethodTransformer() {
|
||||
private val labelNormalization = LabelNormalizationMethodTransformer()
|
||||
private val fixStack = FixStackMethodTransformer()
|
||||
|
||||
public override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
labelNormalization.transform(internalClassName, methodNode)
|
||||
fixStack.transform(internalClassName, methodNode)
|
||||
}
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
|
||||
public class RedundantGotoMethodTransformer : MethodTransformer() {
|
||||
class RedundantGotoMethodTransformer : MethodTransformer() {
|
||||
/**
|
||||
* Removes redundant GOTO's, i.e. to subsequent labels
|
||||
*/
|
||||
@@ -35,7 +35,7 @@ public class RedundantGotoMethodTransformer : MethodTransformer() {
|
||||
val currentLabels = hashSetOf<LabelNode>()
|
||||
for (insn in insns) {
|
||||
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)
|
||||
}
|
||||
else {
|
||||
|
||||
+2
-2
@@ -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.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 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? =
|
||||
when (insn.getOpcode()) {
|
||||
when (insn.opcode) {
|
||||
Opcodes.ANEWARRAY, Opcodes.NEWARRAY, Opcodes.LDC, Opcodes.NEW -> NotNullBasicValue(value)
|
||||
else -> value
|
||||
}
|
||||
|
||||
+13
-13
@@ -25,15 +25,15 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
|
||||
import java.util.*
|
||||
|
||||
public open class MethodAnalyzer<V : Value>(
|
||||
public val owner: String,
|
||||
public val method: MethodNode,
|
||||
open class MethodAnalyzer<V : Value>(
|
||||
val owner: String,
|
||||
val method: MethodNode,
|
||||
protected val interpreter: Interpreter<V>
|
||||
) {
|
||||
public val instructions: InsnList = method.instructions
|
||||
public val nInsns: Int = instructions.size()
|
||||
val instructions: InsnList = method.instructions
|
||||
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 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(src: Frame<out V>): Frame<V> {
|
||||
val frame = newFrame(src.getLocals(), src.getMaxStackSize())
|
||||
val frame = newFrame(src.locals, src.maxStackSize)
|
||||
frame.init(src)
|
||||
return frame
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public open class MethodAnalyzer<V : Value>(
|
||||
protected open fun visitControlFlowExceptionEdge(insn: Int, tcb: TryCatchBlockNode): Boolean =
|
||||
visitControlFlowExceptionEdge(insn, instructions.indexOf(tcb.handler))
|
||||
|
||||
public fun analyze(): Array<Frame<V>?> {
|
||||
fun analyze(): Array<Frame<V>?> {
|
||||
if (nInsns == 0) return frames
|
||||
|
||||
checkAssertions()
|
||||
@@ -75,8 +75,8 @@ public open class MethodAnalyzer<V : Value>(
|
||||
|
||||
val insnNode = method.instructions[insn]
|
||||
try {
|
||||
val insnOpcode = insnNode.getOpcode()
|
||||
val insnType = insnNode.getType()
|
||||
val insnOpcode = insnNode.opcode
|
||||
val insnType = insnNode.type
|
||||
|
||||
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
|
||||
visitNopInsn(f, insn)
|
||||
@@ -121,11 +121,11 @@ public open class MethodAnalyzer<V : Value>(
|
||||
return frames
|
||||
}
|
||||
|
||||
public fun getFrame(insn: AbstractInsnNode): Frame<V>? =
|
||||
fun getFrame(insn: AbstractInsnNode): Frame<V>? =
|
||||
frames[instructions.indexOf(insn)]
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public open class MethodAnalyzer<V : Value>(
|
||||
}
|
||||
for (arg in args) {
|
||||
current.setLocal(local++, interpreter.newValue(arg))
|
||||
if (arg.getSize() == 2) {
|
||||
if (arg.size == 2) {
|
||||
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
|
||||
|
||||
val AbstractInsnNode.isMeaningful: Boolean get() =
|
||||
when (this.getType()) {
|
||||
when (this.type) {
|
||||
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
public class InsnSequence(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Sequence<AbstractInsnNode> {
|
||||
public constructor(insnList: InsnList) : this(insnList.getFirst(), null)
|
||||
class InsnSequence(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Sequence<AbstractInsnNode> {
|
||||
constructor(insnList: InsnList) : this(insnList.first, null)
|
||||
|
||||
override fun iterator(): Iterator<AbstractInsnNode> {
|
||||
return object : Iterator<AbstractInsnNode> {
|
||||
var current: AbstractInsnNode? = from
|
||||
override fun next(): AbstractInsnNode {
|
||||
val result = current
|
||||
current = current!!.getNext()
|
||||
current = current!!.next
|
||||
return result!!
|
||||
}
|
||||
override fun hasNext() = current != to
|
||||
@@ -58,11 +58,11 @@ fun MethodNode.prepareForEmitting() {
|
||||
|
||||
// We should remove linenumbers after last meaningful instruction
|
||||
// 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) {
|
||||
val prev = current.getPrevious()
|
||||
val prev = current.previous
|
||||
|
||||
if (current.getType() == AbstractInsnNode.LINE) {
|
||||
if (current.type == AbstractInsnNode.LINE) {
|
||||
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
|
||||
|
||||
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? {
|
||||
var finger = this.getNext()
|
||||
var finger = this.next
|
||||
while (finger != null && !predicate(finger)) {
|
||||
finger = finger.getNext()
|
||||
finger = finger.next
|
||||
}
|
||||
return finger
|
||||
}
|
||||
|
||||
inline fun AbstractInsnNode.findPreviousOrNull(predicate: (AbstractInsnNode) -> Boolean): AbstractInsnNode? {
|
||||
var finger = this.getPrevious()
|
||||
var finger = this.previous
|
||||
while (finger != null && !predicate(finger)) {
|
||||
finger = finger.getPrevious()
|
||||
finger = finger.previous
|
||||
}
|
||||
return finger
|
||||
}
|
||||
|
||||
fun AbstractInsnNode.hasOpcode(): Boolean =
|
||||
getOpcode() >= 0
|
||||
opcode >= 0
|
||||
|
||||
// See InstructionAdapter
|
||||
//
|
||||
|
||||
+14
-14
@@ -40,31 +40,31 @@ internal class FixStackAnalyzer(
|
||||
val savedStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>()
|
||||
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]
|
||||
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)
|
||||
|
||||
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>()
|
||||
|
||||
public override fun init(src: Frame<out BasicValue>): Frame<BasicValue> {
|
||||
override fun init(src: Frame<out BasicValue>): Frame<BasicValue> {
|
||||
extraStack.clear()
|
||||
extraStack.addAll((src as FixStackFrame).extraStack)
|
||||
return super.init(src)
|
||||
}
|
||||
|
||||
public override fun clearStack() {
|
||||
override fun clearStack() {
|
||||
extraStack.clear()
|
||||
super.clearStack()
|
||||
}
|
||||
|
||||
public override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<BasicValue>) {
|
||||
override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<BasicValue>) {
|
||||
when {
|
||||
PseudoInsn.SAVE_STACK_BEFORE_TRY.isa(insn) ->
|
||||
executeSaveStackBeforeTry(insn)
|
||||
@@ -83,15 +83,15 @@ internal class FixStackAnalyzer(
|
||||
super.execute(insn, interpreter)
|
||||
}
|
||||
|
||||
public fun getStackContent(): List<BasicValue> {
|
||||
fun getStackContent(): List<BasicValue> {
|
||||
val savedStack = arrayListOf<BasicValue>()
|
||||
IntRange(0, super.getStackSize() - 1).mapTo(savedStack) { super.getStack(it) }
|
||||
savedStack.addAll(extraStack)
|
||||
return savedStack
|
||||
}
|
||||
|
||||
public override fun push(value: BasicValue) {
|
||||
if (super.getStackSize() < getMaxStackSize()) {
|
||||
override fun push(value: BasicValue) {
|
||||
if (super.getStackSize() < maxStackSize) {
|
||||
super.push(value)
|
||||
}
|
||||
else {
|
||||
@@ -100,11 +100,11 @@ internal class FixStackAnalyzer(
|
||||
}
|
||||
}
|
||||
|
||||
public fun pushAll(values: Collection<BasicValue>) {
|
||||
fun pushAll(values: Collection<BasicValue>) {
|
||||
values.forEach { push(it) }
|
||||
}
|
||||
|
||||
public override fun pop(): BasicValue {
|
||||
override fun pop(): BasicValue {
|
||||
if (extraStack.isNotEmpty()) {
|
||||
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()) {
|
||||
return super.getStack(i)
|
||||
}
|
||||
else {
|
||||
return extraStack[i - getMaxStackSize()]
|
||||
return extraStack[i - maxStackSize]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ internal class FixStackAnalyzer(
|
||||
|
||||
private fun FixStackFrame.executeAfterInlineCallMarker(insn: AbstractInsnNode) {
|
||||
val beforeInlineMarker = context.openingInlineMethodMarker[insn]
|
||||
if (getStackSize() > 0) {
|
||||
if (stackSize > 0) {
|
||||
val returnValue = pop()
|
||||
clearStack()
|
||||
val savedValues = savedStacks[beforeInlineMarker]
|
||||
|
||||
+5
-5
@@ -77,23 +77,23 @@ internal class FixStackContext(val methodNode: MethodNode) {
|
||||
}
|
||||
|
||||
private fun visitFixStackBeforeJump(insnNode: AbstractInsnNode) {
|
||||
val next = insnNode.getNext()
|
||||
assert(next.getOpcode() == Opcodes.GOTO) { "${indexOf(insnNode)}: should be followed by GOTO" }
|
||||
val next = insnNode.next
|
||||
assert(next.opcode == Opcodes.GOTO) { "${indexOf(insnNode)}: should be followed by GOTO" }
|
||||
breakContinueGotoNodes.add(next as JumpInsnNode)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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" }
|
||||
saveStackNodesForTryStartLabel[tryStartLabel as LabelNode] = insnNode
|
||||
}
|
||||
|
||||
+8
-8
@@ -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.MethodNode
|
||||
|
||||
public class FixStackMethodTransformer : MethodTransformer() {
|
||||
public override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
class FixStackMethodTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
val context = FixStackContext(methodNode)
|
||||
|
||||
if (!context.hasAnyMarkers()) return
|
||||
@@ -73,19 +73,19 @@ public class FixStackMethodTransformer : MethodTransformer() {
|
||||
val labelIndex = methodNode.instructions.indexOf(gotoNode.label)
|
||||
|
||||
val DEAD_CODE = -1 // Stack size is always non-negative
|
||||
val actualStackSize = analyzer.frames[gotoIndex]?.getStackSize() ?: DEAD_CODE
|
||||
val expectedStackSize = analyzer.frames[labelIndex]?.getStackSize() ?: DEAD_CODE
|
||||
val actualStackSize = analyzer.frames[gotoIndex]?.stackSize ?: DEAD_CODE
|
||||
val expectedStackSize = analyzer.frames[labelIndex]?.stackSize ?: DEAD_CODE
|
||||
|
||||
if (actualStackSize != DEAD_CODE && expectedStackSize != DEAD_CODE) {
|
||||
assert(expectedStackSize <= actualStackSize) { "Label at $labelIndex, jump at $gotoIndex: stack underflow: $expectedStackSize > $actualStackSize" }
|
||||
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) {
|
||||
throw AssertionError("Live jump $gotoIndex to dead label $labelIndex")
|
||||
}
|
||||
else {
|
||||
val marker = gotoNode.getPrevious()
|
||||
val marker = gotoNode.previous
|
||||
actions.add({ methodNode.instructions.remove(marker) })
|
||||
}
|
||||
}
|
||||
@@ -153,8 +153,8 @@ public class FixStackMethodTransformer : MethodTransformer() {
|
||||
val savedStackDescriptor = localVariablesManager.getBeforeInlineDescriptor(inlineMarker)
|
||||
val afterInlineFrame = analyzer.getFrame(inlineMarker) as FixStackAnalyzer.FixStackFrame?
|
||||
if (afterInlineFrame != null && savedStackDescriptor.isNotEmpty()) {
|
||||
assert(afterInlineFrame.getStackSize() <= 1) { "Inline method should not leave more than 1 value on stack" }
|
||||
if (afterInlineFrame.getStackSize() == 1) {
|
||||
assert(afterInlineFrame.stackSize <= 1) { "Inline method should not leave more than 1 value on stack" }
|
||||
if (afterInlineFrame.stackSize == 1) {
|
||||
val afterInlineStackValues = afterInlineFrame.getStackContent()
|
||||
val returnValue = afterInlineStackValues.last()
|
||||
val returnValueLocalVarIndex = localVariablesManager.createReturnValueVariable(returnValue)
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
|
||||
|
||||
fun createReturnValueVariable(returnValue: BasicValue): Int {
|
||||
val returnValueIndex = getFirstUnusedLocalVariableIndex()
|
||||
updateMaxLocals(returnValueIndex + returnValue.getSize())
|
||||
updateMaxLocals(returnValueIndex + returnValue.size)
|
||||
return returnValueIndex
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -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.Value
|
||||
|
||||
public inline fun InsnList.forEachPseudoInsn(block: (PseudoInsn, AbstractInsnNode) -> Unit) {
|
||||
inline fun InsnList.forEachPseudoInsn(block: (PseudoInsn, AbstractInsnNode) -> Unit) {
|
||||
InsnSequence(this).forEach { 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 ->
|
||||
if (InlineCodegenUtil.isInlineMarker(insn)) {
|
||||
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? {
|
||||
val stackSize = getStackSize()
|
||||
fun <V : Value> Frame<V>.top(): V? {
|
||||
val stackSize = stackSize
|
||||
if (stackSize == 0)
|
||||
return null
|
||||
else
|
||||
return getStack(stackSize - 1)
|
||||
}
|
||||
|
||||
public fun MethodNode.updateMaxLocals(newMaxLocals: Int) {
|
||||
fun MethodNode.updateMaxLocals(newMaxLocals: Int) {
|
||||
maxLocals = Math.max(maxLocals, newMaxLocals)
|
||||
}
|
||||
|
||||
@@ -57,10 +57,10 @@ class SavedStackDescriptor(
|
||||
val savedValues: List<BasicValue>,
|
||||
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
|
||||
|
||||
public override fun toString(): String =
|
||||
override fun toString(): String =
|
||||
"@$firstLocalVarIndex: [$savedValues]"
|
||||
|
||||
fun isNotEmpty(): Boolean = savedValues.isNotEmpty()
|
||||
@@ -93,9 +93,9 @@ fun restoreStackWithReturnValue(
|
||||
returnValueLocalVarIndex: Int
|
||||
) {
|
||||
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)
|
||||
insertBefore(nodeToReplace, VarInsnNode(returnValue.getType().getOpcode(Opcodes.ILOAD), returnValueLocalVarIndex))
|
||||
insertBefore(nodeToReplace, VarInsnNode(returnValue.type.getOpcode(Opcodes.ILOAD), returnValueLocalVarIndex))
|
||||
remove(nodeToReplace)
|
||||
}
|
||||
}
|
||||
@@ -104,22 +104,22 @@ fun generateLoadInstructions(methodNode: MethodNode, location: AbstractInsnNode,
|
||||
var localVarIndex = savedStackDescriptor.firstLocalVarIndex
|
||||
for (value in savedStackDescriptor.savedValues) {
|
||||
methodNode.instructions.insertBefore(location,
|
||||
VarInsnNode(value.getType().getOpcode(Opcodes.ILOAD), localVarIndex))
|
||||
localVarIndex += value.getSize()
|
||||
VarInsnNode(value.type.getOpcode(Opcodes.ILOAD), localVarIndex))
|
||||
localVarIndex += value.size
|
||||
}
|
||||
}
|
||||
|
||||
fun generateStoreInstructions(methodNode: MethodNode, location: AbstractInsnNode, savedStackDescriptor: SavedStackDescriptor) {
|
||||
var localVarIndex = savedStackDescriptor.firstUnusedLocalVarIndex
|
||||
for (value in savedStackDescriptor.savedValues.asReversed()) {
|
||||
localVarIndex -= value.getSize()
|
||||
localVarIndex -= value.size
|
||||
methodNode.instructions.insertBefore(location,
|
||||
VarInsnNode(value.getType().getOpcode(Opcodes.ISTORE), localVarIndex))
|
||||
VarInsnNode(value.type.getOpcode(Opcodes.ISTORE), localVarIndex))
|
||||
}
|
||||
}
|
||||
|
||||
fun getPopInstruction(top: BasicValue) =
|
||||
InsnNode(when (top.getSize()) {
|
||||
InsnNode(when (top.size) {
|
||||
1 -> Opcodes.POP
|
||||
2 -> Opcodes.POP2
|
||||
else -> throw AssertionError("Unexpected value type size")
|
||||
@@ -127,14 +127,14 @@ fun getPopInstruction(top: BasicValue) =
|
||||
|
||||
fun removeAlwaysFalseIfeq(methodNode: MethodNode, node: AbstractInsnNode) {
|
||||
with (methodNode.instructions) {
|
||||
remove(node.getNext())
|
||||
remove(node.next)
|
||||
remove(node)
|
||||
}
|
||||
}
|
||||
|
||||
fun replaceAlwaysTrueIfeqWithGoto(methodNode: MethodNode, node: AbstractInsnNode) {
|
||||
with (methodNode.instructions) {
|
||||
val next = node.getNext() as JumpInsnNode
|
||||
val next = node.next as JumpInsnNode
|
||||
insertBefore(node, JumpInsnNode(Opcodes.GOTO, next.label))
|
||||
remove(node)
|
||||
remove(next)
|
||||
@@ -143,7 +143,7 @@ fun replaceAlwaysTrueIfeqWithGoto(methodNode: MethodNode, node: AbstractInsnNode
|
||||
|
||||
fun replaceMarkerWithPops(methodNode: MethodNode, node: AbstractInsnNode, expectedStackSize: Int, frame: Frame<BasicValue>) {
|
||||
with (methodNode.instructions) {
|
||||
while (frame.getStackSize() > expectedStackSize) {
|
||||
while (frame.stackSize > expectedStackSize) {
|
||||
val top = frame.pop()
|
||||
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.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(),
|
||||
FAKE_ALWAYS_TRUE_IFEQ("()I"),
|
||||
FAKE_ALWAYS_FALSE_IFEQ("()I"),
|
||||
@@ -33,36 +33,36 @@ public enum class PseudoInsn(val signature: String = "()V") {
|
||||
RESTORE_STACK_IN_TRY_CATCH()
|
||||
;
|
||||
|
||||
public fun emit(iv: InstructionAdapter) {
|
||||
fun emit(iv: InstructionAdapter) {
|
||||
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)
|
||||
|
||||
public fun isa(node: AbstractInsnNode): Boolean =
|
||||
fun isa(node: AbstractInsnNode): Boolean =
|
||||
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
|
||||
|
||||
public fun parsePseudoInsnOrNull(insn: AbstractInsnNode): PseudoInsn? =
|
||||
fun parsePseudoInsnOrNull(insn: AbstractInsnNode): PseudoInsn? =
|
||||
if (isPseudoInsn(insn))
|
||||
PseudoInsn.valueOf((insn as MethodInsnNode).name)
|
||||
else null
|
||||
|
||||
public fun InstructionAdapter.fixStackAndJump(label: Label) {
|
||||
fun InstructionAdapter.fixStackAndJump(label: Label) {
|
||||
PseudoInsn.FIX_STACK_BEFORE_JUMP.emit(this)
|
||||
this.goTo(label)
|
||||
}
|
||||
|
||||
public fun InstructionAdapter.fakeAlwaysTrueIfeq(label: Label) {
|
||||
fun InstructionAdapter.fakeAlwaysTrueIfeq(label: Label) {
|
||||
PseudoInsn.FAKE_ALWAYS_TRUE_IFEQ.emit(this)
|
||||
this.ifeq(label)
|
||||
}
|
||||
|
||||
public fun InstructionAdapter.fakeAlwaysFalseIfeq(label: Label) {
|
||||
fun InstructionAdapter.fakeAlwaysFalseIfeq(label: Label) {
|
||||
PseudoInsn.FAKE_ALWAYS_FALSE_IFEQ.emit(this)
|
||||
this.ifeq(label)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.*
|
||||
|
||||
// TODO: optimize by reordering records to minimize storage of 'range' fields
|
||||
class JvmStringTable(private val typeMapper: JetTypeMapper) : StringTable {
|
||||
public val strings = ArrayList<String>()
|
||||
val strings = ArrayList<String>()
|
||||
private val records = ArrayList<Record.Builder>()
|
||||
private val map = HashMap<String, Int>()
|
||||
private val localNames = HashSet<Int>()
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
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
|
||||
private val typeMapper: JetTypeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null, JvmAbi.DEFAULT_MODULE_NAME)
|
||||
|
||||
|
||||
+9
-9
@@ -120,17 +120,17 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
var ownNonFakeCount = 0
|
||||
for (origin in origins) {
|
||||
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++
|
||||
// If there's more than one real element, the clashing signature is already reported.
|
||||
// Only clashes between fake overrides are interesting here
|
||||
if (ownNonFakeCount > 1) continue@signatures
|
||||
|
||||
if (member.getKind() != DELEGATION) {
|
||||
if (member.kind != DELEGATION) {
|
||||
// Delegates don't have declarations in the code
|
||||
memberElement = origin.element ?: DescriptorToSourceUtils.descriptorToDeclaration(member)
|
||||
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?) {
|
||||
// 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 (member is CallableMemberDescriptor && isOrOverridesSamAdapter(member)) return
|
||||
|
||||
if (member is PropertyDescriptor) {
|
||||
processMember(member.getGetter())
|
||||
processMember(member.getSetter())
|
||||
processMember(member.getter)
|
||||
processMember(member.setter)
|
||||
}
|
||||
else if (member is FunctionDescriptor) {
|
||||
val methodSignature = typeMapper.mapSignature(member)
|
||||
val rawSignature = RawSignature(
|
||||
methodSignature.getAsmMethod().getName()!!, methodSignature.getAsmMethod().getDescriptor()!!, MemberKind.METHOD)
|
||||
methodSignature.asmMethod.name!!, methodSignature.asmMethod.descriptor!!, MemberKind.METHOD)
|
||||
groupedBySignature.putValue(rawSignature, OtherOrigin(member))
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (descriptor is SamAdapterDescriptor<*>) return true
|
||||
|
||||
return descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
&& descriptor.getOverriddenDescriptors().all { isOrOverridesSamAdapter(it) }
|
||||
return descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
&& descriptor.overriddenDescriptors.all { isOrOverridesSamAdapter(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,40 +44,39 @@ import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import java.io.File
|
||||
|
||||
public class GenerationState @JvmOverloads constructor(
|
||||
public val project: Project,
|
||||
class GenerationState @JvmOverloads constructor(
|
||||
val project: Project,
|
||||
builderFactory: ClassBuilderFactory,
|
||||
public val module: ModuleDescriptor,
|
||||
val module: ModuleDescriptor,
|
||||
bindingContext: BindingContext,
|
||||
public val files: List<KtFile>,
|
||||
val files: List<KtFile>,
|
||||
disableCallAssertions: 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,
|
||||
disableOptimization: Boolean = false,
|
||||
public val useTypeTableInSerializer: Boolean = false,
|
||||
public val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
|
||||
public val obsoleteMultifileClasses: Collection<FqName> = emptySet(),
|
||||
val useTypeTableInSerializer: Boolean = false,
|
||||
val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
|
||||
val obsoleteMultifileClasses: Collection<FqName> = emptySet(),
|
||||
// for PackageCodegen in incremental compilation mode
|
||||
public val targetId: TargetId? = null,
|
||||
val targetId: TargetId? = null,
|
||||
moduleName: String? = null,
|
||||
// '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.
|
||||
// TODO: get rid of it with the proper module infrastructure
|
||||
public val outDirectory: File? = null,
|
||||
public val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
|
||||
public val generateOpenMultifileClasses: Boolean = false,
|
||||
public val progress: Progress = Progress.DEAF
|
||||
val outDirectory: File? = null,
|
||||
val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
|
||||
val generateOpenMultifileClasses: Boolean = false,
|
||||
val progress: Progress = Progress.DEAF
|
||||
) {
|
||||
public abstract class GenerateClassFilter {
|
||||
public abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||
public abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||
public abstract fun shouldGeneratePackagePart(jetFile: KtFile): Boolean
|
||||
public abstract fun shouldGenerateScript(script: KtScript): Boolean
|
||||
abstract class GenerateClassFilter {
|
||||
abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||
abstract fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||
abstract fun shouldGeneratePackagePart(jetFile: KtFile): Boolean
|
||||
abstract fun shouldGenerateScript(script: KtScript): Boolean
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
public val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
|
||||
@JvmField val GENERATE_ALL: GenerateClassFilter = object : GenerateClassFilter() {
|
||||
override fun shouldAnnotateClass(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() =
|
||||
if (incrementalCompilationComponents != null && targetId != null)
|
||||
@@ -100,47 +99,47 @@ public class GenerationState @JvmOverloads constructor(
|
||||
private val interceptedBuilderFactory: ClassBuilderFactory
|
||||
private var used = false
|
||||
|
||||
public val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace
|
||||
public val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics {
|
||||
val diagnostics: DiagnosticSink get() = extraJvmDiagnosticsTrace
|
||||
val collectedExtraJvmDiagnostics: Diagnostics = LazyJvmDiagnostics {
|
||||
duplicateSignatureFactory.reportDiagnostics()
|
||||
extraJvmDiagnosticsTrace.bindingContext.diagnostics
|
||||
}
|
||||
|
||||
public val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode()
|
||||
public val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")
|
||||
public val bindingContext: BindingContext = bindingTrace.getBindingContext()
|
||||
public val typeMapper: JetTypeMapper = JetTypeMapper(this.bindingContext, classBuilderMode, fileClassesProvider, getIncrementalCacheForThisTarget(), this.moduleName)
|
||||
public val intrinsics: IntrinsicMethods = IntrinsicMethods()
|
||||
public val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||
public val inlineCycleReporter: InlineCycleReporter = InlineCycleReporter(diagnostics)
|
||||
public val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||
public val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
|
||||
public val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
|
||||
public val factory: ClassFileFactory
|
||||
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
||||
val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")
|
||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||
val typeMapper: JetTypeMapper = JetTypeMapper(this.bindingContext, classBuilderMode, fileClassesProvider, getIncrementalCacheForThisTarget(), this.moduleName)
|
||||
val intrinsics: IntrinsicMethods = IntrinsicMethods()
|
||||
val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||
val inlineCycleReporter: InlineCycleReporter = InlineCycleReporter(diagnostics)
|
||||
val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||
val reflectionTypes: ReflectionTypes = ReflectionTypes(module)
|
||||
val jvmRuntimeTypes: JvmRuntimeTypes = JvmRuntimeTypes()
|
||||
val factory: ClassFileFactory
|
||||
private val duplicateSignatureFactory: BuilderFactoryForDuplicateSignatureDiagnostics
|
||||
|
||||
public val replSpecific = ForRepl()
|
||||
val replSpecific = ForRepl()
|
||||
|
||||
//TODO: should be refactored out
|
||||
public class ForRepl {
|
||||
public var earlierScriptsForReplInterpreter: List<ScriptDescriptor>? = null
|
||||
public var scriptResultFieldName: String? = null
|
||||
public val shouldGenerateScriptResultValue: Boolean get() = scriptResultFieldName != null
|
||||
public var hasResult: Boolean = false
|
||||
class ForRepl {
|
||||
var earlierScriptsForReplInterpreter: List<ScriptDescriptor>? = null
|
||||
var scriptResultFieldName: String? = null
|
||||
val shouldGenerateScriptResultValue: Boolean get() = scriptResultFieldName != null
|
||||
var hasResult: Boolean = false
|
||||
}
|
||||
|
||||
public val isCallAssertionsEnabled: Boolean = !disableCallAssertions
|
||||
val isCallAssertionsEnabled: Boolean = !disableCallAssertions
|
||||
@JvmName("isCallAssertionsEnabled") get
|
||||
|
||||
public val isParamAssertionsEnabled: Boolean = !disableParamAssertions
|
||||
val isParamAssertionsEnabled: Boolean = !disableParamAssertions
|
||||
@JvmName("isParamAssertionsEnabled") get
|
||||
|
||||
public val isInlineEnabled: Boolean = !disableInline
|
||||
val isInlineEnabled: Boolean = !disableInline
|
||||
@JvmName("isInlineEnabled") get
|
||||
|
||||
|
||||
public val rootContext: CodegenContext<*> = RootContext(this)
|
||||
val rootContext: CodegenContext<*> = RootContext(this)
|
||||
|
||||
init {
|
||||
val optimizationClassBuilderFactory = OptimizationClassBuilderFactory(builderFactory, disableOptimization)
|
||||
@@ -162,7 +161,7 @@ public class GenerationState @JvmOverloads constructor(
|
||||
this.factory = ClassFileFactory(this, interceptedBuilderFactory)
|
||||
}
|
||||
|
||||
public fun beforeCompile() {
|
||||
fun beforeCompile() {
|
||||
markUsed()
|
||||
|
||||
CodegenBinding.initTrace(this)
|
||||
@@ -174,7 +173,7 @@ public class GenerationState @JvmOverloads constructor(
|
||||
used = true
|
||||
}
|
||||
|
||||
public fun destroy() {
|
||||
fun destroy() {
|
||||
interceptedBuilderFactory.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ private fun KotlinType.canHaveSubtypesIgnoringNullability(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
public fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance): Variance {
|
||||
fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance): Variance {
|
||||
if (parameterVariance === Variance.INVARIANT) {
|
||||
return projectionKind
|
||||
}
|
||||
|
||||
+2
-2
@@ -48,11 +48,11 @@ import java.io.ByteArrayOutputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
|
||||
public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
|
||||
class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
|
||||
private var totalSize = 0
|
||||
private var totalFiles = 0
|
||||
|
||||
public fun serialize(
|
||||
fun serialize(
|
||||
destDir: File,
|
||||
srcDirs: List<File>,
|
||||
extraClassPath: List<File>,
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
|
||||
public class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
||||
class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
||||
override fun shouldUseTypeTable(): Boolean = true
|
||||
|
||||
override fun serializePackage(packageFragments: Collection<PackageFragmentDescriptor>, proto: ProtoBuf.Package.Builder) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
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()) {
|
||||
|
||||
+7
-9
@@ -16,21 +16,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.messages
|
||||
|
||||
public data class CompilerMessageLocation private constructor(
|
||||
public val path: String?,
|
||||
public val line: Int,
|
||||
public val column: Int,
|
||||
public val lineContent: String?
|
||||
data class CompilerMessageLocation private constructor(
|
||||
val path: String?,
|
||||
val line: Int,
|
||||
val column: Int,
|
||||
val lineContent: String?
|
||||
) {
|
||||
override fun toString(): String =
|
||||
path + (if (line != -1 || column != -1) " ($line:$column)" else "")
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
public val NO_LOCATION: CompilerMessageLocation = CompilerMessageLocation(null, -1, -1, null)
|
||||
@JvmField val NO_LOCATION: CompilerMessageLocation = CompilerMessageLocation(null, -1, -1, null)
|
||||
|
||||
@JvmStatic
|
||||
public fun create(
|
||||
@JvmStatic fun create(
|
||||
path: String?,
|
||||
line: Int,
|
||||
column: Int,
|
||||
|
||||
+5
-5
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.modules.JavaRootPath
|
||||
import java.util.*
|
||||
|
||||
public class ModuleBuilder(
|
||||
class ModuleBuilder(
|
||||
private val name: String,
|
||||
private val outputDir: String,
|
||||
private val type: String
|
||||
@@ -30,19 +30,19 @@ public class ModuleBuilder(
|
||||
private val javaSourceRoots = ArrayList<JavaRootPath>()
|
||||
private val friendDirs = ArrayList<String>()
|
||||
|
||||
public fun addSourceFiles(pattern: String) {
|
||||
fun addSourceFiles(pattern: String) {
|
||||
sourceFiles.add(pattern)
|
||||
}
|
||||
|
||||
public fun addClasspathEntry(name: String) {
|
||||
fun addClasspathEntry(name: String) {
|
||||
classpathRoots.add(name)
|
||||
}
|
||||
|
||||
public fun addJavaSourceRoot(rootPath: JavaRootPath) {
|
||||
fun addJavaSourceRoot(rootPath: JavaRootPath) {
|
||||
javaSourceRoots.add(rootPath)
|
||||
}
|
||||
|
||||
public fun addFriendDir(friendDir: String) {
|
||||
fun addFriendDir(friendDir: String) {
|
||||
friendDirs.add(friendDir)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.*
|
||||
|
||||
public object Main {
|
||||
object Main {
|
||||
private val KOTLIN_HOME: File
|
||||
|
||||
init {
|
||||
@@ -99,8 +99,7 @@ public object Main {
|
||||
runner.run(classpath, arguments)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun main(args: Array<String>) {
|
||||
@JvmStatic fun main(args: Array<String>) {
|
||||
try {
|
||||
run(args)
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
/**
|
||||
* 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
|
||||
|
||||
|
||||
+1
-1
@@ -19,6 +19,6 @@ package org.jetbrains.kotlin.cli.common.messages
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
|
||||
public interface DiagnosticMessageReporter {
|
||||
interface DiagnosticMessageReporter {
|
||||
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 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()) {
|
||||
val sources = file.sourceFiles
|
||||
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 -> }
|
||||
|
||||
public fun OutputFileCollection.writeAllTo(outputDir: File) {
|
||||
fun OutputFileCollection.writeAllTo(outputDir: File) {
|
||||
writeAll(outputDir, REPORT_NOTHING)
|
||||
}
|
||||
|
||||
public fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector) {
|
||||
fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector) {
|
||||
writeAll(outputDir) { sources, output ->
|
||||
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.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 {
|
||||
val messageSeverityCollector = MessageSeverityCollector(messageCollector)
|
||||
@@ -54,7 +54,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
else
|
||||
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);
|
||||
|
||||
val configuration = CompilerConfiguration()
|
||||
@@ -108,7 +108,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
for (arg in arguments.freeArgs) {
|
||||
configuration.addKotlinSourceRoot(arg)
|
||||
val file = File(arg)
|
||||
if (file.isDirectory()) {
|
||||
if (file.isDirectory) {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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) {
|
||||
val scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size)
|
||||
@@ -200,7 +200,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
return OK
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -235,18 +235,17 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
private var elapsedJITTime = 0L
|
||||
private var shouldReportPerf = true
|
||||
|
||||
public fun resetInitStartTime() {
|
||||
fun resetInitStartTime() {
|
||||
if (initStartNanos == 0L) {
|
||||
initStartNanos = System.nanoTime()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun main(args: Array<String>) {
|
||||
@JvmStatic fun main(args: Array<String>) {
|
||||
CLICompiler.doMain(K2JVMCompiler(), args)
|
||||
}
|
||||
|
||||
public fun reportPerf(configuration: CompilerConfiguration, message: String) {
|
||||
fun reportPerf(configuration: CompilerConfiguration, message: String) {
|
||||
if (!shouldReportPerf) return
|
||||
|
||||
val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!!
|
||||
@@ -255,17 +254,17 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
fun reportGCTime(configuration: CompilerConfiguration) {
|
||||
ManagementFactory.getGarbageCollectorMXBeans().forEach {
|
||||
val currentTime = it.getCollectionTime()
|
||||
val elapsedTime = elapsedGCTime.getOrElse(it.getName()) { 0 }
|
||||
val currentTime = it.collectionTime
|
||||
val elapsedTime = elapsedGCTime.getOrElse(it.name) { 0 }
|
||||
val time = currentTime - elapsedTime
|
||||
reportPerf(configuration, "GC time for ${it.getName()} is $time ms")
|
||||
elapsedGCTime[it.getName()] = currentTime
|
||||
reportPerf(configuration, "GC time for ${it.name} is $time ms")
|
||||
elapsedGCTime[it.name] = currentTime
|
||||
}
|
||||
}
|
||||
|
||||
fun reportCompilationTime(configuration: CompilerConfiguration) {
|
||||
val bean = ManagementFactory.getCompilationMXBean() ?: return
|
||||
val currentTime = bean.getTotalCompilationTime()
|
||||
val currentTime = bean.totalCompilationTime
|
||||
reportPerf(configuration, "JIT time is ${currentTime - elapsedJITTime} ms")
|
||||
elapsedJITTime = currentTime
|
||||
}
|
||||
@@ -284,7 +283,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
classpath.addAll(arguments.classpath.split(File.pathSeparatorChar).map { File(it) })
|
||||
}
|
||||
if (!arguments.noStdlib) {
|
||||
classpath.add(paths.getRuntimePath())
|
||||
classpath.add(paths.runtimePath)
|
||||
}
|
||||
return classpath
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
|
||||
|
||||
public object PluginCliParser {
|
||||
object PluginCliParser {
|
||||
|
||||
@JvmStatic
|
||||
fun loadPlugins(arguments: CommonCompilerArguments, configuration: CompilerConfiguration) {
|
||||
@@ -35,7 +35,7 @@ public object PluginCliParser {
|
||||
?.map { File(it).toURI().toURL() }
|
||||
?.toTypedArray()
|
||||
?: arrayOf<URL>(),
|
||||
javaClass.getClassLoader()
|
||||
javaClass.classLoader
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
@Synchronized
|
||||
|
||||
+4
-4
@@ -62,7 +62,7 @@ import kotlin.properties.Delegates
|
||||
|
||||
* 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 var bindingContext: BindingContext by Delegates.notNull()
|
||||
private var module: ModuleDescriptor by Delegates.notNull()
|
||||
@@ -172,7 +172,7 @@ public class CliLightClassGenerationSupport(project: Project) : LightClassGenera
|
||||
return NoScopeRecordCliBindingTrace()
|
||||
}
|
||||
|
||||
public class NoScopeRecordCliBindingTrace : CliBindingTrace() {
|
||||
class NoScopeRecordCliBindingTrace : CliBindingTrace() {
|
||||
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
|
||||
if (slice === BindingContext.LEXICAL_SCOPE) {
|
||||
// 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
|
||||
|
||||
override fun toString(): String {
|
||||
return CliBindingTrace::class.java.name
|
||||
}
|
||||
|
||||
public fun setKotlinCodeAnalyzer(kotlinCodeAnalyzer: KotlinCodeAnalyzer) {
|
||||
fun setKotlinCodeAnalyzer(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.name.ClassId
|
||||
|
||||
public class JvmCliVirtualFileFinder(private val index: JvmDependenciesIndex) : VirtualFileKotlinClassFinder() {
|
||||
class JvmCliVirtualFileFinder(private val index: JvmDependenciesIndex) : VirtualFileKotlinClassFinder() {
|
||||
|
||||
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 ->
|
||||
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
Reference in New Issue
Block a user