Minor. Reformat
This commit is contained in:
@@ -37,14 +37,14 @@ interface InnerClassConsumer {
|
|||||||
if (defaultImpls) {
|
if (defaultImpls) {
|
||||||
if (DescriptorUtils.isLocal(descriptor)) return null
|
if (DescriptorUtils.isLocal(descriptor)) return null
|
||||||
val classDescriptorImpl = ClassDescriptorImpl(
|
val classDescriptorImpl = ClassDescriptorImpl(
|
||||||
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
descriptor, Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
|
||||||
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE,
|
Modality.FINAL, ClassKind.CLASS, Collections.emptyList(), SourceElement.NO_SOURCE,
|
||||||
/* isExternal = */ false, LockBasedStorageManager.NO_LOCKS)
|
/* isExternal = */ false, LockBasedStorageManager.NO_LOCKS
|
||||||
|
)
|
||||||
|
|
||||||
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
classDescriptorImpl.initialize(MemberScope.Empty, emptySet(), null)
|
||||||
return classDescriptorImpl
|
return classDescriptorImpl
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return if (DescriptorUtils.isTopLevelDeclaration(descriptor)) null else descriptor
|
return if (DescriptorUtils.isTopLevelDeclaration(descriptor)) null else descriptor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-17
@@ -19,19 +19,19 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
class InlineCodegenForDefaultBody(
|
class InlineCodegenForDefaultBody(
|
||||||
function: FunctionDescriptor,
|
function: FunctionDescriptor,
|
||||||
codegen: ExpressionCodegen,
|
codegen: ExpressionCodegen,
|
||||||
val state: GenerationState,
|
val state: GenerationState,
|
||||||
private val sourceCompilerForInline: SourceCompilerForInline
|
private val sourceCompilerForInline: SourceCompilerForInline
|
||||||
) : CallGenerator {
|
) : CallGenerator {
|
||||||
|
|
||||||
private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper
|
private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper
|
||||||
|
|
||||||
private val functionDescriptor =
|
private val functionDescriptor =
|
||||||
if (InlineUtil.isArrayConstructorWithLambda(function))
|
if (InlineUtil.isArrayConstructorWithLambda(function))
|
||||||
FictitiousArrayConstructor.create(function as ConstructorDescriptor)
|
FictitiousArrayConstructor.create(function as ConstructorDescriptor)
|
||||||
else
|
else
|
||||||
function.original
|
function.original
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -45,7 +45,7 @@ class InlineCodegenForDefaultBody(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
assert(InlineUtil.isInline(function)) {
|
assert(InlineUtil.isInline(function)) {
|
||||||
"InlineCodegen can inline only inline functions and array constructors: " + function
|
"InlineCodegen can inline only inline functions and array constructors: $function"
|
||||||
}
|
}
|
||||||
sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor)
|
sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor)
|
||||||
jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompilerForInline.contextKind)
|
jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompilerForInline.contextKind)
|
||||||
@@ -55,18 +55,21 @@ class InlineCodegenForDefaultBody(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||||
val nodeAndSmap = InlineCodegen.createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, null, state, sourceCompilerForInline)
|
val nodeAndSmap =
|
||||||
|
InlineCodegen.createInlineMethodNode(functionDescriptor, jvmSignature, callDefault, null, state, sourceCompilerForInline)
|
||||||
val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper)
|
val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper)
|
||||||
|
|
||||||
val node = nodeAndSmap.node
|
val node = nodeAndSmap.node
|
||||||
val transformedMethod = MethodNode(
|
val transformedMethod = MethodNode(
|
||||||
node.access,
|
node.access,
|
||||||
node.name,
|
node.name,
|
||||||
node.desc,
|
node.desc,
|
||||||
node.signature,
|
node.signature,
|
||||||
node.exceptions.toTypedArray())
|
node.exceptions.toTypedArray()
|
||||||
|
)
|
||||||
|
|
||||||
val argsSize = (Type.getArgumentsAndReturnSizes(jvmSignature.asmMethod.descriptor) ushr 2) - if (callableMethod.isStaticCall()) 1 else 0
|
val argsSize =
|
||||||
|
(Type.getArgumentsAndReturnSizes(jvmSignature.asmMethod.descriptor) ushr 2) - if (callableMethod.isStaticCall()) 1 else 0
|
||||||
node.accept(object : InlineAdapter(transformedMethod, 0, childSourceMapper) {
|
node.accept(object : InlineAdapter(transformedMethod, 0, childSourceMapper) {
|
||||||
override fun visitLocalVariable(name: String, desc: String, signature: String?, start: Label, end: Label, index: Int) {
|
override fun visitLocalVariable(name: String, desc: String, signature: String?, start: Label, end: Label, index: Int) {
|
||||||
val startLabel = if (index < argsSize) methodStartLabel else start
|
val startLabel = if (index < argsSize) methodStartLabel else start
|
||||||
@@ -77,7 +80,12 @@ class InlineCodegenForDefaultBody(
|
|||||||
transformedMethod.accept(MethodBodyVisitor(codegen.visitor))
|
transformedMethod.accept(MethodBodyVisitor(codegen.visitor))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun genValueAndPut(valueParameterDescriptor: ValueParameterDescriptor, argumentExpression: KtExpression, parameterType: Type, parameterIndex: Int) {
|
override fun genValueAndPut(
|
||||||
|
valueParameterDescriptor: ValueParameterDescriptor,
|
||||||
|
argumentExpression: KtExpression,
|
||||||
|
parameterType: Type,
|
||||||
|
parameterIndex: Int
|
||||||
|
) {
|
||||||
throw UnsupportedOperationException("Shouldn't be called")
|
throw UnsupportedOperationException("Shouldn't be called")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : LabelOwner {
|
|||||||
val builder = ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, invokeMethod.descriptor, this)
|
val builder = ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, invokeMethod.descriptor, this)
|
||||||
|
|
||||||
for (info in capturedVars) {
|
for (info in capturedVars) {
|
||||||
val field = remapper.findField(FieldInsnNode(0, info.containingLambdaName, info.fieldName, "")) ?:
|
val field = remapper.findField(FieldInsnNode(0, info.containingLambdaName, info.fieldName, ""))
|
||||||
error("Captured field not found: " + info.containingLambdaName + "." + info.fieldName)
|
?: error("Captured field not found: " + info.containingLambdaName + "." + info.fieldName)
|
||||||
builder.addCapturedParam(field, info.fieldName)
|
builder.addCapturedParam(field, info.fieldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,11 +74,11 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : LabelOwner {
|
|||||||
|
|
||||||
|
|
||||||
class DefaultLambda(
|
class DefaultLambda(
|
||||||
override val lambdaClassType: Type,
|
override val lambdaClassType: Type,
|
||||||
private val capturedArgs: Array<Type>,
|
private val capturedArgs: Array<Type>,
|
||||||
val parameterDescriptor: ValueParameterDescriptor,
|
val parameterDescriptor: ValueParameterDescriptor,
|
||||||
val offset: Int,
|
val offset: Int,
|
||||||
val needReification: Boolean
|
val needReification: Boolean
|
||||||
) : LambdaInfo(parameterDescriptor.isCrossinline) {
|
) : LambdaInfo(parameterDescriptor.isCrossinline) {
|
||||||
|
|
||||||
override var isBoundCallableReference by Delegates.notNull<Boolean>()
|
override var isBoundCallableReference by Delegates.notNull<Boolean>()
|
||||||
@@ -103,8 +103,15 @@ class DefaultLambda(
|
|||||||
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
||||||
var isPropertyReference = false
|
var isPropertyReference = false
|
||||||
var isFunctionReference = false
|
var isFunctionReference = false
|
||||||
classReader.accept(object: ClassVisitor(API){
|
classReader.accept(object : ClassVisitor(API) {
|
||||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<out String>?) {
|
override fun visit(
|
||||||
|
version: Int,
|
||||||
|
access: Int,
|
||||||
|
name: String,
|
||||||
|
signature: String?,
|
||||||
|
superName: String?,
|
||||||
|
interfaces: Array<out String>?
|
||||||
|
) {
|
||||||
isPropertyReference = superName?.startsWith("kotlin/jvm/internal/PropertyReference") ?: false
|
isPropertyReference = superName?.startsWith("kotlin/jvm/internal/PropertyReference") ?: false
|
||||||
isFunctionReference = "kotlin/jvm/internal/FunctionReference" == superName
|
isFunctionReference = "kotlin/jvm/internal/FunctionReference" == superName
|
||||||
|
|
||||||
@@ -114,19 +121,20 @@ class DefaultLambda(
|
|||||||
|
|
||||||
invokeMethodDescriptor =
|
invokeMethodDescriptor =
|
||||||
parameterDescriptor.type.memberScope
|
parameterDescriptor.type.memberScope
|
||||||
.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND)
|
.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND)
|
||||||
.single()
|
.single()
|
||||||
.let {
|
.let {
|
||||||
//property reference generates erased 'get' method
|
//property reference generates erased 'get' method
|
||||||
if (isPropertyReference) it.original else it
|
if (isPropertyReference) it.original else it
|
||||||
}
|
}
|
||||||
|
|
||||||
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
|
||||||
val constructor = getMethodNode(
|
val constructor = getMethodNode(
|
||||||
classReader.b,
|
classReader.b,
|
||||||
"<init>",
|
"<init>",
|
||||||
descriptor,
|
descriptor,
|
||||||
lambdaClassType)?.node
|
lambdaClassType
|
||||||
|
)?.node
|
||||||
|
|
||||||
assert(constructor != null || capturedArgs.isEmpty()) {
|
assert(constructor != null || capturedArgs.isEmpty()) {
|
||||||
"Can't find non-default constructor <init>$descriptor for default lambda $lambdaClassType"
|
"Can't find non-default constructor <init>$descriptor for default lambda $lambdaClassType"
|
||||||
@@ -139,23 +147,23 @@ class DefaultLambda(
|
|||||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it.boxReceiverForBoundReference()))
|
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it.boxReceiverForBoundReference()))
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
else
|
else
|
||||||
constructor?.findCapturedFieldAssignmentInstructions()?.map {
|
constructor?.findCapturedFieldAssignmentInstructions()?.map { fieldNode ->
|
||||||
fieldNode ->
|
|
||||||
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc))
|
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc))
|
||||||
}?.toList() ?: emptyList()
|
}?.toList() ?: emptyList()
|
||||||
|
|
||||||
isBoundCallableReference = (isFunctionReference || isPropertyReference) && capturedVars.isNotEmpty()
|
isBoundCallableReference = (isFunctionReference || isPropertyReference) && capturedVars.isNotEmpty()
|
||||||
|
|
||||||
invokeMethod = Method(
|
invokeMethod = Method(
|
||||||
(if (isPropertyReference) OperatorNameConventions.GET else OperatorNameConventions.INVOKE).asString(),
|
(if (isPropertyReference) OperatorNameConventions.GET else OperatorNameConventions.INVOKE).asString(),
|
||||||
sourceCompiler.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor
|
sourceCompiler.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor
|
||||||
)
|
)
|
||||||
|
|
||||||
node = getMethodNode(
|
node = getMethodNode(
|
||||||
classReader.b,
|
classReader.b,
|
||||||
invokeMethod.name,
|
invokeMethod.name,
|
||||||
invokeMethod.descriptor,
|
invokeMethod.descriptor,
|
||||||
lambdaClassType) ?: error("Can't find method '${invokeMethod.name}${invokeMethod.descriptor}' in '${classReader.className}'")
|
lambdaClassType
|
||||||
|
) ?: error("Can't find method '${invokeMethod.name}${invokeMethod.descriptor}' in '${classReader.className}'")
|
||||||
|
|
||||||
if (needReification) {
|
if (needReification) {
|
||||||
//nested classes could also require reification
|
//nested classes could also require reification
|
||||||
@@ -166,19 +174,19 @@ class DefaultLambda(
|
|||||||
|
|
||||||
fun Type.boxReceiverForBoundReference() = AsmUtil.boxType(this)
|
fun Type.boxReceiverForBoundReference() = AsmUtil.boxType(this)
|
||||||
|
|
||||||
abstract class ExpressionLambda(protected val typeMapper: KotlinTypeMapper, isCrossInline: Boolean): LambdaInfo(isCrossInline) {
|
abstract class ExpressionLambda(protected val typeMapper: KotlinTypeMapper, isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
||||||
|
|
||||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||||
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
|
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
|
||||||
val asmMethod = jvmMethodSignature.asmMethod
|
val asmMethod = jvmMethodSignature.asmMethod
|
||||||
val methodNode = MethodNode(
|
val methodNode = MethodNode(
|
||||||
API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, OwnerKind.IMPLEMENTATION, sourceCompiler.state),
|
API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, OwnerKind.IMPLEMENTATION, sourceCompiler.state),
|
||||||
asmMethod.name, asmMethod.descriptor, null, null
|
asmMethod.name, asmMethod.descriptor, null, null
|
||||||
)
|
)
|
||||||
|
|
||||||
node = wrapWithMaxLocalCalc(methodNode).let { adapter ->
|
node = wrapWithMaxLocalCalc(methodNode).let { adapter ->
|
||||||
val smap = sourceCompiler.generateLambdaBody(
|
val smap = sourceCompiler.generateLambdaBody(
|
||||||
adapter, jvmMethodSignature, this
|
adapter, jvmMethodSignature, this
|
||||||
)
|
)
|
||||||
adapter.visitMaxs(-1, -1)
|
adapter.visitMaxs(-1, -1)
|
||||||
SMAPAndMethodNode(methodNode, smap)
|
SMAPAndMethodNode(methodNode, smap)
|
||||||
@@ -187,10 +195,10 @@ abstract class ExpressionLambda(protected val typeMapper: KotlinTypeMapper, isCr
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PsiExpressionLambda(
|
class PsiExpressionLambda(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
typeMapper: KotlinTypeMapper,
|
typeMapper: KotlinTypeMapper,
|
||||||
isCrossInline: Boolean,
|
isCrossInline: Boolean,
|
||||||
override val isBoundCallableReference: Boolean
|
override val isBoundCallableReference: Boolean
|
||||||
) : ExpressionLambda(typeMapper, isCrossInline) {
|
) : ExpressionLambda(typeMapper, isCrossInline) {
|
||||||
|
|
||||||
override val lambdaClassType: Type
|
override val lambdaClassType: Type
|
||||||
@@ -211,21 +219,21 @@ class PsiExpressionLambda(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
val bindingContext = typeMapper.bindingContext
|
val bindingContext = typeMapper.bindingContext
|
||||||
val function = bindingContext.get<PsiElement, SimpleFunctionDescriptor>(BindingContext.FUNCTION, functionWithBodyOrCallableReference)
|
val function =
|
||||||
|
bindingContext.get<PsiElement, SimpleFunctionDescriptor>(BindingContext.FUNCTION, functionWithBodyOrCallableReference)
|
||||||
if (function == null && expression is KtCallableReferenceExpression) {
|
if (function == null && expression is KtCallableReferenceExpression) {
|
||||||
val variableDescriptor =
|
val variableDescriptor =
|
||||||
bindingContext.get(BindingContext.VARIABLE, functionWithBodyOrCallableReference) as? VariableDescriptorWithAccessors ?:
|
bindingContext.get(BindingContext.VARIABLE, functionWithBodyOrCallableReference) as? VariableDescriptorWithAccessors
|
||||||
throw AssertionError("""Reference expression not resolved to variable descriptor with accessors: ${expression.getText()}""")
|
?: throw AssertionError("""Reference expression not resolved to variable descriptor with accessors: ${expression.getText()}""")
|
||||||
classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor)
|
classDescriptor = CodegenBinding.anonymousClassForCallable(bindingContext, variableDescriptor)
|
||||||
lambdaClassType = typeMapper.mapClass(classDescriptor)
|
lambdaClassType = typeMapper.mapClass(classDescriptor)
|
||||||
val getFunction = PropertyReferenceCodegen.findGetFunction(variableDescriptor)
|
val getFunction = PropertyReferenceCodegen.findGetFunction(variableDescriptor)
|
||||||
invokeMethodDescriptor = PropertyReferenceCodegen.createFakeOpenDescriptor(getFunction, classDescriptor)
|
invokeMethodDescriptor = PropertyReferenceCodegen.createFakeOpenDescriptor(getFunction, classDescriptor)
|
||||||
val resolvedCall = expression.callableReference.getResolvedCallWithAssert(bindingContext)
|
val resolvedCall = expression.callableReference.getResolvedCallWithAssert(bindingContext)
|
||||||
propertyReferenceInfo = PropertyReferenceInfo(
|
propertyReferenceInfo = PropertyReferenceInfo(
|
||||||
resolvedCall.resultingDescriptor as VariableDescriptor, getFunction
|
resolvedCall.resultingDescriptor as VariableDescriptor, getFunction
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
propertyReferenceInfo = null
|
propertyReferenceInfo = null
|
||||||
invokeMethodDescriptor = function ?: throw AssertionError("Function is not resolved to descriptor: " + expression.text)
|
invokeMethodDescriptor = function ?: throw AssertionError("Function is not resolved to descriptor: " + expression.text)
|
||||||
classDescriptor = anonymousClassForCallable(bindingContext, invokeMethodDescriptor)
|
classDescriptor = anonymousClassForCallable(bindingContext, invokeMethodDescriptor)
|
||||||
@@ -246,9 +254,9 @@ class PsiExpressionLambda(
|
|||||||
if (closure.captureThis != null) {
|
if (closure.captureThis != null) {
|
||||||
val type = typeMapper.mapType(closure.captureThis!!)
|
val type = typeMapper.mapType(closure.captureThis!!)
|
||||||
val descriptor = EnclosedValueDescriptor(
|
val descriptor = EnclosedValueDescriptor(
|
||||||
AsmUtil.CAPTURED_THIS_FIELD, null,
|
AsmUtil.CAPTURED_THIS_FIELD, null,
|
||||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
||||||
type
|
type
|
||||||
)
|
)
|
||||||
add(getCapturedParamInfo(descriptor))
|
add(getCapturedParamInfo(descriptor))
|
||||||
}
|
}
|
||||||
@@ -258,15 +266,14 @@ class PsiExpressionLambda(
|
|||||||
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
||||||
}
|
}
|
||||||
val descriptor = EnclosedValueDescriptor(
|
val descriptor = EnclosedValueDescriptor(
|
||||||
AsmUtil.CAPTURED_RECEIVER_FIELD, null,
|
AsmUtil.CAPTURED_RECEIVER_FIELD, null,
|
||||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0),
|
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0),
|
||||||
type
|
type
|
||||||
)
|
)
|
||||||
add(getCapturedParamInfo(descriptor))
|
add(getCapturedParamInfo(descriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
closure.captureVariables.values.forEach {
|
closure.captureVariables.values.forEach { descriptor ->
|
||||||
descriptor ->
|
|
||||||
add(getCapturedParamInfo(descriptor))
|
add(getCapturedParamInfo(descriptor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
|
|||||||
|
|
||||||
protected fun createRemappingClassBuilderViaFactory(inliningContext: InliningContext): ClassBuilder {
|
protected fun createRemappingClassBuilderViaFactory(inliningContext: InliningContext): ClassBuilder {
|
||||||
val classBuilder = state.factory.newVisitor(
|
val classBuilder = state.factory.newVisitor(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN,
|
JvmDeclarationOrigin.NO_ORIGIN,
|
||||||
Type.getObjectType(transformationInfo.newClassName),
|
Type.getObjectType(transformationInfo.newClassName),
|
||||||
inliningContext.root.sourceCompilerForInline.callsiteFile!!
|
inliningContext.root.sourceCompilerForInline.callsiteFile!!
|
||||||
)
|
)
|
||||||
|
|
||||||
return RemappingClassBuilder(
|
return RemappingClassBuilder(
|
||||||
classBuilder,
|
classBuilder,
|
||||||
AsmTypeRemapper(inliningContext.typeRemapper, transformationResult)
|
AsmTypeRemapper(inliningContext.typeRemapper, transformationResult)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,8 +52,8 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WhenMappingTransformer(
|
class WhenMappingTransformer(
|
||||||
whenObjectRegenerationInfo: WhenMappingTransformationInfo,
|
whenObjectRegenerationInfo: WhenMappingTransformationInfo,
|
||||||
private val inliningContext: InliningContext
|
private val inliningContext: InliningContext
|
||||||
) : ObjectTransformer<WhenMappingTransformationInfo>(whenObjectRegenerationInfo, inliningContext.state) {
|
) : ObjectTransformer<WhenMappingTransformationInfo>(whenObjectRegenerationInfo, inliningContext.state) {
|
||||||
|
|
||||||
override fun doTransform(parentRemapper: FieldRemapper): InlineResult {
|
override fun doTransform(parentRemapper: FieldRemapper): InlineResult {
|
||||||
@@ -72,14 +72,13 @@ class WhenMappingTransformer(
|
|||||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
||||||
return if (name == fieldNode.name) {
|
return if (name == fieldNode.name) {
|
||||||
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
|
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitMethod(
|
override fun visitMethod(
|
||||||
access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?
|
access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?
|
||||||
): MethodVisitor? {
|
): MethodVisitor? {
|
||||||
return MethodNode(access, name, desc, signature, exceptions).apply {
|
return MethodNode(access, name, desc, signature, exceptions).apply {
|
||||||
methodNodes.add(this)
|
methodNodes.add(this)
|
||||||
@@ -91,12 +90,12 @@ class WhenMappingTransformer(
|
|||||||
"When mapping ${fieldNode.owner} class should contain only one method but: " + methodNodes.joinToString { it.name }
|
"When mapping ${fieldNode.owner} class should contain only one method but: " + methodNodes.joinToString { it.name }
|
||||||
}
|
}
|
||||||
val clinit = methodNodes.first()
|
val clinit = methodNodes.first()
|
||||||
assert(clinit.name == "<clinit>", { "When mapping should contains only <clinit> method, but contains '${clinit.name}'" })
|
assert(clinit.name == "<clinit>") { "When mapping should contains only <clinit> method, but contains '${clinit.name}'" }
|
||||||
|
|
||||||
val transformedClinit = cutOtherMappings(clinit)
|
val transformedClinit = cutOtherMappings(clinit)
|
||||||
val result = classBuilder.newMethod(
|
val result = classBuilder.newMethod(
|
||||||
JvmDeclarationOrigin.NO_ORIGIN, transformedClinit.access, transformedClinit.name, transformedClinit.desc,
|
JvmDeclarationOrigin.NO_ORIGIN, transformedClinit.access, transformedClinit.name, transformedClinit.desc,
|
||||||
transformedClinit.signature, transformedClinit.exceptions.toTypedArray()
|
transformedClinit.signature, transformedClinit.exceptions.toTypedArray()
|
||||||
)
|
)
|
||||||
transformedClinit.accept(result)
|
transformedClinit.accept(result)
|
||||||
classBuilder.done()
|
classBuilder.done()
|
||||||
@@ -106,7 +105,7 @@ class WhenMappingTransformer(
|
|||||||
|
|
||||||
private fun cutOtherMappings(node: MethodNode): MethodNode {
|
private fun cutOtherMappings(node: MethodNode): MethodNode {
|
||||||
val myArrayAccess = InsnSequence(node.instructions).first {
|
val myArrayAccess = InsnSequence(node.instructions).first {
|
||||||
it is FieldInsnNode && it.name.equals(transformationInfo.fieldNode.name)
|
it is FieldInsnNode && it.name == transformationInfo.fieldNode.name
|
||||||
}
|
}
|
||||||
|
|
||||||
val myValuesAccess = generateSequence(myArrayAccess) { it.previous }.first {
|
val myValuesAccess = generateSequence(myArrayAccess) { it.previous }.first {
|
||||||
@@ -125,8 +124,8 @@ class WhenMappingTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isValues(node: AbstractInsnNode) =
|
private fun isValues(node: AbstractInsnNode) =
|
||||||
node is MethodInsnNode &&
|
node is MethodInsnNode &&
|
||||||
node.opcode == Opcodes.INVOKESTATIC &&
|
node.opcode == Opcodes.INVOKESTATIC &&
|
||||||
node.name == "values" &&
|
node.name == "values" &&
|
||||||
node.desc == "()[" + Type.getObjectType(node.owner).descriptor
|
node.desc == "()[" + Type.getObjectType(node.owner).descriptor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ val KOTLIN_DEBUG_STRATA_NAME = "KotlinDebug"
|
|||||||
|
|
||||||
//TODO join parameter
|
//TODO join parameter
|
||||||
class SMAPBuilder(
|
class SMAPBuilder(
|
||||||
val source: String,
|
val source: String,
|
||||||
val path: String,
|
val path: String,
|
||||||
private val fileMappings: List<FileMapping>
|
private val fileMappings: List<FileMapping>
|
||||||
) {
|
) {
|
||||||
private val header = "SMAP\n$source\nKotlin"
|
private val header = "SMAP\n$source\nKotlin"
|
||||||
|
|
||||||
@@ -58,9 +58,11 @@ class SMAPBuilder(
|
|||||||
val combinedMapping = FileMapping(source, path)
|
val combinedMapping = FileMapping(source, path)
|
||||||
realMappings.forEach { fileMapping ->
|
realMappings.forEach { fileMapping ->
|
||||||
fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { (_, dest, range, callSiteMarker) ->
|
fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { (_, dest, range, callSiteMarker) ->
|
||||||
combinedMapping.addRangeMapping(RangeMapping(
|
combinedMapping.addRangeMapping(
|
||||||
|
RangeMapping(
|
||||||
callSiteMarker!!.lineNumber, dest, range
|
callSiteMarker!!.lineNumber, dest, range
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ class SMAPBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class NestedSourceMapper(
|
open class NestedSourceMapper(
|
||||||
override val parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
|
override val parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
|
||||||
) : DefaultSourceMapper(sourceInfo) {
|
) : DefaultSourceMapper(sourceInfo) {
|
||||||
|
|
||||||
private val visitedLines = TIntIntHashMap()
|
private val visitedLines = TIntIntHashMap()
|
||||||
@@ -100,11 +102,10 @@ open class NestedSourceMapper(
|
|||||||
|
|
||||||
return if (mappedLineNumber > 0) {
|
return if (mappedLineNumber > 0) {
|
||||||
mappedLineNumber
|
mappedLineNumber
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val rangeForMapping =
|
val rangeForMapping =
|
||||||
(if (lastVisitedRange?.contains(lineNumber) ?: false) lastVisitedRange!! else findMappingIfExists(lineNumber))
|
(if (lastVisitedRange?.contains(lineNumber) ?: false) lastVisitedRange!! else findMappingIfExists(lineNumber))
|
||||||
?: error("Can't find range to map line $lineNumber in ${sourceInfo.source}: ${sourceInfo.pathOrCleanFQN}")
|
?: error("Can't find range to map line $lineNumber in ${sourceInfo.source}: ${sourceInfo.pathOrCleanFQN}")
|
||||||
val sourceLineNumber = rangeForMapping.mapDestToSource(lineNumber)
|
val sourceLineNumber = rangeForMapping.mapDestToSource(lineNumber)
|
||||||
val newLineNumber = parent.mapLineNumber(sourceLineNumber, rangeForMapping.parent!!.name, rangeForMapping.parent!!.path)
|
val newLineNumber = parent.mapLineNumber(sourceLineNumber, rangeForMapping.parent!!.name, rangeForMapping.parent!!.path)
|
||||||
if (newLineNumber > 0) {
|
if (newLineNumber > 0) {
|
||||||
@@ -116,8 +117,7 @@ open class NestedSourceMapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findMappingIfExists(lineNumber: Int): RangeMapping? {
|
private fun findMappingIfExists(lineNumber: Int): RangeMapping? {
|
||||||
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator {
|
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator { value, key ->
|
||||||
value, key ->
|
|
||||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||||
})
|
})
|
||||||
return if (index < 0) null else ranges[index]
|
return if (index < 0) null else ranges[index]
|
||||||
@@ -125,7 +125,7 @@ open class NestedSourceMapper(
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class InlineLambdaSourceMapper(
|
open class InlineLambdaSourceMapper(
|
||||||
parent: SourceMapper, smap: SMAPAndMethodNode
|
parent: SourceMapper, smap: SMAPAndMethodNode
|
||||||
) : NestedSourceMapper(parent, smap.sortedRanges, smap.classSMAP.sourceInfo) {
|
) : NestedSourceMapper(parent, smap.sortedRanges, smap.classSMAP.sourceInfo) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -208,14 +208,14 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
|
|||||||
|
|
||||||
constructor(sourceInfo: SourceInfo, fileMappings: List<FileMapping>) : this(sourceInfo) {
|
constructor(sourceInfo: SourceInfo, fileMappings: List<FileMapping>) : this(sourceInfo) {
|
||||||
fileMappings.asSequence().drop(1)
|
fileMappings.asSequence().drop(1)
|
||||||
//default one mapped through sourceInfo
|
//default one mapped through sourceInfo
|
||||||
.forEach { fileMapping ->
|
.forEach { fileMapping ->
|
||||||
val newFileMapping = getOrRegisterNewSource(fileMapping.name, fileMapping.path)
|
val newFileMapping = getOrRegisterNewSource(fileMapping.name, fileMapping.path)
|
||||||
fileMapping.lineMappings.forEach {
|
fileMapping.lineMappings.forEach {
|
||||||
newFileMapping.mapNewInterval(it.source, it.dest, it.range)
|
newFileMapping.mapNewInterval(it.source, it.dest, it.range)
|
||||||
maxUsedValue = Math.max(it.maxDest, maxUsedValue)
|
maxUsedValue = Math.max(it.maxDest, maxUsedValue)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createKey(name: String, path: String) = "$name#$path"
|
private fun createKey(name: String, path: String) = "$name#$path"
|
||||||
@@ -282,11 +282,11 @@ class RawFileMapping(val name: String, val path: String) {
|
|||||||
private var lastMappedWithNewIndex = -1000
|
private var lastMappedWithNewIndex = -1000
|
||||||
|
|
||||||
fun toFileMapping() =
|
fun toFileMapping() =
|
||||||
FileMapping(name, path).apply {
|
FileMapping(name, path).apply {
|
||||||
for (range in rangeMappings) {
|
for (range in rangeMappings) {
|
||||||
addRangeMapping(range)
|
addRangeMapping(range)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun initRange(start: Int, end: Int) {
|
fun initRange(start: Int, end: Int) {
|
||||||
assert(rangeMappings.isEmpty()) { "initRange should only be called for empty mapping" }
|
assert(rangeMappings.isEmpty()) { "initRange should only be called for empty mapping" }
|
||||||
@@ -301,8 +301,7 @@ class RawFileMapping(val name: String, val path: String) {
|
|||||||
rangeMapping = rangeMappings.last()
|
rangeMapping = rangeMappings.last()
|
||||||
rangeMapping.range += source - lastMappedWithNewIndex
|
rangeMapping.range += source - lastMappedWithNewIndex
|
||||||
dest = rangeMapping.mapSourceToDest(source)
|
dest = rangeMapping.mapSourceToDest(source)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dest = currentIndex + 1
|
dest = currentIndex + 1
|
||||||
rangeMapping = RangeMapping(source, dest, callSiteMarker = callSiteMarker)
|
rangeMapping = RangeMapping(source, dest, callSiteMarker = callSiteMarker)
|
||||||
rangeMappings.add(rangeMapping)
|
rangeMappings.add(rangeMapping)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
override val lookupLocation = KotlinLookupLocation(callElement)
|
override val lookupLocation = KotlinLookupLocation(callElement)
|
||||||
|
|
||||||
|
|
||||||
override val callElementText by lazy {
|
override val callElementText: String by lazy {
|
||||||
callElement.text
|
callElement.text
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
mappings: List<FileMapping>
|
mappings: List<FileMapping>
|
||||||
): SMAP {
|
): SMAP {
|
||||||
val containingFile = declaration.containingFile
|
val containingFile = declaration.containingFile
|
||||||
CodegenUtil.getLineNumberForElement(containingFile, true) ?: error("Couldn't extract line count in " + containingFile)
|
CodegenUtil.getLineNumberForElement(containingFile, true) ?: error("Couldn't extract line count in $containingFile")
|
||||||
|
|
||||||
return SMAP(mappings)
|
return SMAP(mappings)
|
||||||
}
|
}
|
||||||
@@ -261,7 +261,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor)
|
val element = DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor)
|
||||||
|
|
||||||
if (!(element is KtNamedFunction || element is KtPropertyAccessor)) {
|
if (!(element is KtNamedFunction || element is KtPropertyAccessor)) {
|
||||||
throw IllegalStateException("Couldn't find declaration for function " + callableDescriptor)
|
throw IllegalStateException("Couldn't find declaration for function $callableDescriptor")
|
||||||
}
|
}
|
||||||
val inliningFunction = element as KtDeclarationWithBody?
|
val inliningFunction = element as KtDeclarationWithBody?
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
|
|
||||||
//for maxLocals calculation
|
//for maxLocals calculation
|
||||||
val maxCalcAdapter = wrapWithMaxLocalCalc(node)
|
val maxCalcAdapter = wrapWithMaxLocalCalc(node)
|
||||||
val parentContext = context.parentContext ?: error("Context has no parent: " + context)
|
val parentContext = context.parentContext ?: error("Context has no parent: $context")
|
||||||
val methodContext = parentContext.intoFunction(callableDescriptor)
|
val methodContext = parentContext.intoFunction(callableDescriptor)
|
||||||
|
|
||||||
val smap = if (callDefault) {
|
val smap = if (callDefault) {
|
||||||
@@ -286,7 +286,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
if (element !is KtNamedFunction) {
|
if (element !is KtNamedFunction) {
|
||||||
throw IllegalStateException("Property accessors with default parameters not supported " + callableDescriptor)
|
throw IllegalStateException("Property accessors with default parameters not supported $callableDescriptor")
|
||||||
}
|
}
|
||||||
FunctionCodegen.generateDefaultImplBody(
|
FunctionCodegen.generateDefaultImplBody(
|
||||||
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||||
@@ -416,7 +416,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
return PackageContext(descriptor, state.rootContext, null, sourceFile)
|
return PackageContext(descriptor, state.rootContext, null, sourceFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
val container = descriptor.containingDeclaration ?: error("No container for descriptor: " + descriptor)
|
val container = descriptor.containingDeclaration ?: error("No container for descriptor: $descriptor")
|
||||||
val parent = getContext(
|
val parent = getContext(
|
||||||
container,
|
container,
|
||||||
descriptor,
|
descriptor,
|
||||||
@@ -454,7 +454,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
parent.intoFunction(descriptor)
|
parent.intoFunction(descriptor)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException("Couldn't build context for " + descriptor)
|
throw IllegalStateException("Couldn't build context for $descriptor")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,10 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
|||||||
//This method was moved to separate class cause of LightClass generation problem: KT-18419
|
//This method was moved to separate class cause of LightClass generation problem: KT-18419
|
||||||
//Move it back to inlineCodegenUtil after fix
|
//Move it back to inlineCodegenUtil after fix
|
||||||
fun initDefaultSourceMappingIfNeeded(
|
fun initDefaultSourceMappingIfNeeded(
|
||||||
context: CodegenContext<*>, codegen: MemberCodegen<*>, state: GenerationState
|
context: CodegenContext<*>, codegen: MemberCodegen<*>, state: GenerationState
|
||||||
) {
|
) {
|
||||||
if (state.isInlineDisabled) return
|
if (state.isInlineDisabled) return
|
||||||
|
|
||||||
|
|
||||||
var parentContext: CodegenContext<*>? = context.parentContext
|
var parentContext: CodegenContext<*>? = context.parentContext
|
||||||
while (parentContext != null) {
|
while (parentContext != null) {
|
||||||
if (parentContext.isInlineMethodContext) {
|
if (parentContext.isInlineMethodContext) {
|
||||||
|
|||||||
+28
-18
@@ -35,52 +35,62 @@ enum class JvmDeclarationOriginKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JvmDeclarationOrigin(
|
class JvmDeclarationOrigin(
|
||||||
val originKind: JvmDeclarationOriginKind,
|
val originKind: JvmDeclarationOriginKind,
|
||||||
val element: PsiElement?,
|
val element: PsiElement?,
|
||||||
val descriptor: DeclarationDescriptor?
|
val descriptor: DeclarationDescriptor?
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField val NO_ORIGIN: JvmDeclarationOrigin = JvmDeclarationOrigin(OTHER, null, null)
|
@JvmField
|
||||||
|
val NO_ORIGIN: JvmDeclarationOrigin = JvmDeclarationOrigin(OTHER, null, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun OtherOrigin(element: PsiElement?, descriptor: DeclarationDescriptor? = null) =
|
fun OtherOrigin(element: PsiElement?, descriptor: DeclarationDescriptor? = null) =
|
||||||
if (element == null && descriptor == null)
|
if (element == null && descriptor == null)
|
||||||
JvmDeclarationOrigin.NO_ORIGIN
|
JvmDeclarationOrigin.NO_ORIGIN
|
||||||
else
|
else
|
||||||
JvmDeclarationOrigin(OTHER, element, descriptor)
|
JvmDeclarationOrigin(OTHER, element, descriptor)
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun OtherOriginFromPure(element: KtPureElement?, descriptor: DeclarationDescriptor? = null) =
|
fun OtherOriginFromPure(element: KtPureElement?, descriptor: DeclarationDescriptor? = null) =
|
||||||
OtherOrigin(element?.psiOrParent, descriptor)
|
OtherOrigin(element?.psiOrParent, descriptor)
|
||||||
|
|
||||||
fun OtherOrigin(descriptor: DeclarationDescriptor) = JvmDeclarationOrigin(OTHER, null, descriptor)
|
fun OtherOrigin(descriptor: DeclarationDescriptor) = JvmDeclarationOrigin(OTHER, null, descriptor)
|
||||||
|
|
||||||
fun Bridge(descriptor: DeclarationDescriptor, element: PsiElement? = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)): JvmDeclarationOrigin =
|
fun Bridge(
|
||||||
JvmDeclarationOrigin(BRIDGE, element, descriptor)
|
descriptor: DeclarationDescriptor,
|
||||||
|
element: PsiElement? = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
|
||||||
|
): JvmDeclarationOrigin =
|
||||||
|
JvmDeclarationOrigin(BRIDGE, element, descriptor)
|
||||||
|
|
||||||
fun PackagePart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(PACKAGE_PART, file, descriptor)
|
fun PackagePart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
|
||||||
|
JvmDeclarationOrigin(PACKAGE_PART, file, descriptor)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param representativeFile one of the files representing this multifile class (will be used for diagnostics)
|
* @param representativeFile one of the files representing this multifile class (will be used for diagnostics)
|
||||||
*/
|
*/
|
||||||
fun MultifileClass(representativeFile: KtFile?, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
|
fun MultifileClass(representativeFile: KtFile?, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
|
||||||
JvmDeclarationOrigin(MULTIFILE_CLASS, representativeFile, descriptor)
|
JvmDeclarationOrigin(MULTIFILE_CLASS, representativeFile, descriptor)
|
||||||
|
|
||||||
fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
|
fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
|
||||||
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor)
|
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor)
|
||||||
|
|
||||||
fun DefaultImpls(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)
|
fun DefaultImpls(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin =
|
||||||
|
JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)
|
||||||
|
|
||||||
fun Delegation(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(DELEGATION, element, descriptor)
|
fun Delegation(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin =
|
||||||
|
JvmDeclarationOrigin(DELEGATION, element, descriptor)
|
||||||
|
|
||||||
fun SamDelegation(descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SAM_DELEGATION, null, descriptor)
|
fun SamDelegation(descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SAM_DELEGATION, null, descriptor)
|
||||||
|
|
||||||
fun Synthetic(element: PsiElement?, descriptor: CallableMemberDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SYNTHETIC, element, descriptor)
|
fun Synthetic(element: PsiElement?, descriptor: CallableMemberDescriptor): JvmDeclarationOrigin =
|
||||||
|
JvmDeclarationOrigin(SYNTHETIC, element, descriptor)
|
||||||
|
|
||||||
val CollectionStub = JvmDeclarationOrigin(COLLECTION_STUB, null, null)
|
val CollectionStub = JvmDeclarationOrigin(COLLECTION_STUB, null, null)
|
||||||
|
|
||||||
fun AugmentedBuiltInApi(descriptor: CallableDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(AUGMENTED_BUILTIN_API, null, descriptor)
|
fun AugmentedBuiltInApi(descriptor: CallableDescriptor): JvmDeclarationOrigin =
|
||||||
|
JvmDeclarationOrigin(AUGMENTED_BUILTIN_API, null, descriptor)
|
||||||
|
|
||||||
fun ErasedInlineClassOrigin(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin =
|
fun ErasedInlineClassOrigin(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin =
|
||||||
JvmDeclarationOrigin(ERASED_INLINE_CLASS, element, descriptor)
|
JvmDeclarationOrigin(ERASED_INLINE_CLASS, element, descriptor)
|
||||||
|
|||||||
+37
-33
@@ -25,9 +25,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private class IrEmptyVarargExpression(
|
private class IrEmptyVarargExpression(
|
||||||
override val type: KotlinType,
|
override val type: KotlinType,
|
||||||
override val startOffset: Int,
|
override val startOffset: Int,
|
||||||
override val endOffset: Int
|
override val endOffset: Int
|
||||||
) : IrExpression {
|
) : IrExpression {
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||||
TODO("not implemented")
|
TODO("not implemented")
|
||||||
@@ -43,10 +43,10 @@ private class IrEmptyVarargExpression(
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class IrIntrinsicFunction(
|
open class IrIntrinsicFunction(
|
||||||
val expression: IrMemberAccessExpression,
|
val expression: IrMemberAccessExpression,
|
||||||
val signature: JvmMethodSignature,
|
val signature: JvmMethodSignature,
|
||||||
val context: JvmBackendContext,
|
val context: JvmBackendContext,
|
||||||
val argsTypes: List<Type> = expression.argTypes(context)
|
val argsTypes: List<Type> = expression.argTypes(context)
|
||||||
) : Callable {
|
) : Callable {
|
||||||
override val owner: Type
|
override val owner: Type
|
||||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
@@ -84,12 +84,11 @@ open class IrIntrinsicFunction(
|
|||||||
|
|
||||||
open fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue {
|
open fun invoke(v: InstructionAdapter, codegen: ExpressionCodegen, data: BlockInfo): StackValue {
|
||||||
val args = listOfNotNull(expression.dispatchReceiver, expression.extensionReceiver) +
|
val args = listOfNotNull(expression.dispatchReceiver, expression.extensionReceiver) +
|
||||||
expression.descriptor.valueParameters.mapIndexed { i, descriptor ->
|
expression.descriptor.valueParameters.mapIndexed { i, descriptor ->
|
||||||
expression.getValueArgument(i) ?:
|
expression.getValueArgument(i) ?: if (descriptor.isVararg)
|
||||||
if (descriptor.isVararg)
|
IrEmptyVarargExpression(descriptor.type, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||||
IrEmptyVarargExpression(descriptor.type, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
else error("Unknown parameter: $descriptor in $expression")
|
||||||
else error("Unknown parameter: $descriptor in $expression")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
args.forEachIndexed { i, irExpression ->
|
args.forEachIndexed { i, irExpression ->
|
||||||
if (irExpression is IrEmptyVarargExpression) {
|
if (irExpression is IrEmptyVarargExpression) {
|
||||||
@@ -98,8 +97,7 @@ open class IrIntrinsicFunction(
|
|||||||
it.aconst(0)
|
it.aconst(0)
|
||||||
it.newarray(AsmUtil.correctElementType(parameterType))
|
it.newarray(AsmUtil.correctElementType(parameterType))
|
||||||
}.put(parameterType, codegen.mv)
|
}.put(parameterType, codegen.mv)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
genArg(irExpression, codegen, i, data)
|
genArg(irExpression, codegen, i, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,33 +109,39 @@ open class IrIntrinsicFunction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(expression: IrMemberAccessExpression,
|
fun create(
|
||||||
signature: JvmMethodSignature,
|
expression: IrMemberAccessExpression,
|
||||||
context: JvmBackendContext,
|
signature: JvmMethodSignature,
|
||||||
argsTypes: List<Type> = expression.argTypes(context),
|
context: JvmBackendContext,
|
||||||
invokeInstuction: IrIntrinsicFunction.(InstructionAdapter) -> Unit): IrIntrinsicFunction {
|
argsTypes: List<Type> = expression.argTypes(context),
|
||||||
|
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Unit
|
||||||
|
): IrIntrinsicFunction {
|
||||||
return object : IrIntrinsicFunction(expression, signature, context, argsTypes) {
|
return object : IrIntrinsicFunction(expression, signature, context, argsTypes) {
|
||||||
|
|
||||||
override fun genInvokeInstruction(v: InstructionAdapter) = invokeInstuction(v)
|
override fun genInvokeInstruction(v: InstructionAdapter) = invokeInstruction(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createWithResult(expression: IrMemberAccessExpression,
|
fun createWithResult(
|
||||||
signature: JvmMethodSignature,
|
expression: IrMemberAccessExpression,
|
||||||
context: JvmBackendContext,
|
signature: JvmMethodSignature,
|
||||||
argsTypes: List<Type> = expression.argTypes(context),
|
context: JvmBackendContext,
|
||||||
invokeInstuction: IrIntrinsicFunction.(InstructionAdapter) -> Type): IrIntrinsicFunction {
|
argsTypes: List<Type> = expression.argTypes(context),
|
||||||
|
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Type
|
||||||
|
): IrIntrinsicFunction {
|
||||||
return object : IrIntrinsicFunction(expression, signature, context, argsTypes) {
|
return object : IrIntrinsicFunction(expression, signature, context, argsTypes) {
|
||||||
|
|
||||||
override fun genInvokeInstructionWithResult(v: InstructionAdapter) = invokeInstuction(v)
|
override fun genInvokeInstructionWithResult(v: InstructionAdapter) = invokeInstruction(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(expression: IrMemberAccessExpression,
|
fun create(
|
||||||
signature: JvmMethodSignature,
|
expression: IrMemberAccessExpression,
|
||||||
context: JvmBackendContext,
|
signature: JvmMethodSignature,
|
||||||
type: Type,
|
context: JvmBackendContext,
|
||||||
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Unit): IrIntrinsicFunction {
|
type: Type,
|
||||||
|
invokeInstruction: IrIntrinsicFunction.(InstructionAdapter) -> Unit
|
||||||
|
): IrIntrinsicFunction {
|
||||||
return create(expression, signature, context, listOf(type), invokeInstruction)
|
return create(expression, signature, context, listOf(type), invokeInstruction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +157,7 @@ fun IrMemberAccessExpression.argTypes(context: JvmBackendContext): ArrayList<Typ
|
|||||||
|
|
||||||
fun IrMemberAccessExpression.receiverAndArgs(): List<IrExpression> {
|
fun IrMemberAccessExpression.receiverAndArgs(): List<IrExpression> {
|
||||||
return (arrayListOf(this.dispatchReceiver, this.extensionReceiver) +
|
return (arrayListOf(this.dispatchReceiver, this.extensionReceiver) +
|
||||||
descriptor.valueParameters.mapIndexed { i, _ ->getValueArgument(i)}).filterNotNull()
|
descriptor.valueParameters.mapIndexed { i, _ -> getValueArgument(i) }).filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<IrExpression>.asmTypes(context: JvmBackendContext): List<Type> {
|
fun List<IrExpression>.asmTypes(context: JvmBackendContext): List<Type> {
|
||||||
|
|||||||
Reference in New Issue
Block a user