From 51d494a271c67f0cd7b61a23a5faeaebd06b2ad9 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 12 Jun 2017 10:10:12 +0200 Subject: [PATCH] Convert InlineCodegenUtil to Kotlin --- .../kotlin/codegen/AbstractClassBuilder.java | 5 +- .../kotlin/codegen/ClosureCodegen.java | 4 +- .../kotlin/codegen/ExpressionCodegen.java | 18 +- .../codegen/ImplementationBodyCodegen.java | 4 +- .../kotlin/codegen/MemberCodegen.java | 8 +- .../codegen/TransformationMethodVisitor.java | 8 +- .../CoroutineTransformerMethodVisitor.kt | 4 +- .../inline/AnonymousObjectTransformer.kt | 21 +- .../inline/CoveringTryCatchNodeProcessor.kt | 2 +- .../codegen/inline/DeferredMethodVisitor.kt | 2 +- .../kotlin/codegen/inline/FieldRemapper.kt | 4 +- .../kotlin/codegen/inline/InlineAdapter.java | 8 +- .../kotlin/codegen/inline/InlineCodegen.kt | 31 +- .../codegen/inline/InlineCodegenUtil.kt | 1076 ++++++++--------- .../inline/InternalFinallyBlockInliner.java | 17 +- .../kotlin/codegen/inline/LambdaInfo.kt | 12 +- .../kotlin/codegen/inline/LocalVarRemapper.kt | 2 +- .../codegen/inline/MethodBodyVisitor.java | 4 +- .../kotlin/codegen/inline/MethodInliner.kt | 29 +- .../codegen/inline/MethodInlinerUtil.kt | 2 +- .../codegen/inline/ObjectTransformer.kt | 4 +- .../inline/RegeneratedLambdaFieldRemapper.kt | 4 +- .../codegen/inline/ReifiedTypeInliner.kt | 8 +- .../kotlin/codegen/inline/RemapVisitor.java | 4 +- .../codegen/inline/TryBlockClustering.kt | 1 - .../codegen/inline/defaultMethodUtil.kt | 2 - .../RedundantBoxingMethodTransformer.kt | 7 +- .../optimization/common/MethodAnalyzer.kt | 6 +- .../common/OptimizationBasicInterpreter.java | 8 +- .../codegen/optimization/common/Util.kt | 4 +- .../optimization/fixStack/FixStackAnalyzer.kt | 10 +- .../optimization/fixStack/FixStackContext.kt | 7 +- .../fixStack/FixStackMethodTransformer.kt | 10 +- .../jetbrains/kotlin/codegen/SMAPTestUtil.kt | 4 +- .../CompileKotlinAgainstCustomBinariesTest.kt | 4 +- .../kotlin/idea/debugger/KotlinStackFrame.kt | 4 +- .../debugger/NoStrataPositionManagerHelper.kt | 4 +- .../idea/debugger/evaluate/FrameVisitor.kt | 7 +- .../kotlin/idea/debugger/smapUtil.kt | 4 +- 39 files changed, 664 insertions(+), 699 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AbstractClassBuilder.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AbstractClassBuilder.java index 18894119676..24f69d9e568 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AbstractClassBuilder.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AbstractClassBuilder.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.inline.FileMapping; -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil; import org.jetbrains.kotlin.codegen.inline.SMAPBuilder; import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; @@ -29,6 +28,8 @@ import org.jetbrains.org.objectweb.asm.*; import java.util.ArrayList; import java.util.List; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP; + public abstract class AbstractClassBuilder implements ClassBuilder { protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM5) {}; protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM5) {}; @@ -105,7 +106,7 @@ public abstract class AbstractClassBuilder implements ClassBuilder { @Override public void done() { - if (!fileMappings.isEmpty() && InlineCodegenUtil.GENERATE_SMAP) { + if (!fileMappings.isEmpty() && GENERATE_SMAP) { FileMapping origin = fileMappings.get(0); assert sourceName == null || origin.getName().equals(sourceName) : "Error " + origin.getName() + " != " + sourceName; getVisitor().visitSource(origin.getName(), new SMAPBuilder(origin.getName(), origin.getPath(), fileMappings).build()); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index be1dd432955..8f53fd51545 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; import org.jetbrains.kotlin.codegen.context.ClosureContext; import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor; import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt; -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil; import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter; @@ -60,6 +59,7 @@ import java.util.List; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*; import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN; @@ -158,7 +158,7 @@ public class ClosureCodegen extends MemberCodegen { superInterfaceAsmTypes ); - InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state); + initDefaultSourceMappingIfNeeded(context, this, state); v.visitSource(element.getContainingFile().getName(), null); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 233edb105a4..0089381a2ad 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -107,7 +107,7 @@ import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; -import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*; import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall; import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure; @@ -1414,14 +1414,14 @@ public class ExpressionCodegen extends KtVisitor impleme Label finallyStart = new Label(); v.mark(finallyStart); finallyBlockStackElement.addGapLabel(finallyStart); - if (InlineCodegenUtil.isFinallyMarkerRequired(context)) { - InlineCodegenUtil.generateFinallyMarker(v, finallyDepth, true); + if (isFinallyMarkerRequired(context)) { + generateFinallyMarker(v, finallyDepth, true); } //noinspection ConstantConditions gen(jetTryExpression.getFinallyBlock().getFinalExpression(), Type.VOID_TYPE); - if (InlineCodegenUtil.isFinallyMarkerRequired(context)) { - InlineCodegenUtil.generateFinallyMarker(v, finallyDepth, false); + if (isFinallyMarkerRequired(context)) { + generateFinallyMarker(v, finallyDepth, false); } } @@ -1464,7 +1464,7 @@ public class ExpressionCodegen extends KtVisitor impleme generateFinallyBlocksIfNeeded(returnType, afterReturnLabel); if (isNonLocalReturn) { - InlineCodegenUtil.generateGlobalReturnFlag(v, nonLocalReturn.labelName); + generateGlobalReturnFlag(v, nonLocalReturn.labelName); v.visitInsn(returnType.getOpcode(Opcodes.IRETURN)); } else { @@ -1502,7 +1502,7 @@ public class ExpressionCodegen extends KtVisitor impleme FunctionDescriptor containingFunction = BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst(); //FIRST_FUN_LABEL to prevent clashing with existing labels - return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL); + return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), FIRST_FUN_LABEL); } else { //local return null; @@ -4217,8 +4217,8 @@ The "returned" value of try expression with no finally is either the last expres public NameGenerator getInlineNameGenerator() { NameGenerator nameGenerator = getParentCodegen().getInlineNameGenerator(); Name name = context.getContextDescriptor().getName(); - String inlinedName = name.isSpecial() ? InlineCodegenUtil.SPECIAL_TRANSFORMATION_NAME : name.asString(); - return nameGenerator.subGenerator(inlinedName + InlineCodegenUtil.INLINE_CALL_TRANSFORMATION_SUFFIX); + String inlinedName = name.isSpecial() ? SPECIAL_TRANSFORMATION_NAME : name.asString(); + return nameGenerator.subGenerator(inlinedName + INLINE_CALL_TRANSFORMATION_SUFFIX); } public Type getReturnType() { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 59094b20909..97be52a709e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -31,7 +31,6 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.MutableClosure; import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension; -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter; import org.jetbrains.kotlin.codegen.state.GenerationState; @@ -79,6 +78,7 @@ import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isGenericToArray; import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isNonGenericToArray; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded; import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall; import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull; import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration; @@ -217,7 +217,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.visitSource(myClass.getContainingKtFile().getName(), null); - InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state); + initDefaultSourceMappingIfNeeded(context, this, state); writeEnclosingMethod(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 4c1d7902afd..0dc64fea9f4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -25,7 +25,10 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple; import org.jetbrains.kotlin.codegen.context.*; -import org.jetbrains.kotlin.codegen.inline.*; +import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper; +import org.jetbrains.kotlin.codegen.inline.NameGenerator; +import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages; +import org.jetbrains.kotlin.codegen.inline.SourceMapper; import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; @@ -71,6 +74,7 @@ import java.util.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getInlineName; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED; import static org.jetbrains.kotlin.resolve.BindingContext.*; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; @@ -437,7 +441,7 @@ public abstract class MemberCodegen(5); - this.mv = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode); + this.mv = wrapWithMaxLocalCalc(methodNode); } @Override @@ -83,7 +85,7 @@ public abstract class TransformationMethodVisitor extends MethodVisitor { delegate.visitEnd(); } catch (Throwable t) { - throw new CompilationException("Couldn't transform method node: " + InlineCodegenUtil.getNodeText(methodNode), t, null); + throw new CompilationException("Couldn't transform method node: " + getNodeText(methodNode), t, null); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 1ee64591800..a19306caa8e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -21,8 +21,8 @@ import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.TransformationMethodVisitor -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil import org.jetbrains.kotlin.codegen.inline.MaxStackFrameSizeAndLocalsCalculator +import org.jetbrains.kotlin.codegen.inline.isInlineMarker import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer import org.jetbrains.kotlin.codegen.optimization.common.* import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer @@ -681,7 +681,7 @@ private fun findSafelyReachableReturns(methodNode: MethodNode): Array?> } if (!insn.isMeaningful || insn.opcode in SAFE_OPCODES || insn.isInvisibleInDebugVarInsn(methodNode) || - InlineCodegenUtil.isInlineMarker(insn)) { + isInlineMarker(insn)) { setOf() } else null diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt index 24ff74959fd..2063654220d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.ClassBuilder import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_IMPL_ASM_TYPE -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.isThis0 import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN import org.jetbrains.org.objectweb.asm.* @@ -49,7 +48,7 @@ class AnonymousObjectTransformer( val classBuilder = createRemappingClassBuilderViaFactory(inliningContext) val methodsToTransform = ArrayList() - createClassReader().accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) { + createClassReader().accept(object : ClassVisitor(API, classBuilder.visitor) { override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array) { classBuilder.defineClass(null, version, access, name, signature, superName, interfaces) if (COROUTINE_IMPL_ASM_TYPE.internalName == superName) { @@ -79,7 +78,7 @@ class AnonymousObjectTransformer( override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? { addUniqueField(name) - if (InlineCodegenUtil.isCapturedFieldName(name)) { + if (isCapturedFieldName(name)) { return null } else { @@ -103,7 +102,7 @@ class AnonymousObjectTransformer( //seems we can't do any clever mapping cause we don't know any about original class name sourceMapper = IdenticalSourceMapper } - if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) { + if (sourceInfo != null && !GENERATE_SMAP) { classBuilder.visitSource(sourceInfo!!, debugInfo) } } @@ -139,7 +138,7 @@ class AnonymousObjectTransformer( } deferringMethods.forEach { method -> - InlineCodegenUtil.removeFinallyMarkers(method.intermediate) + removeFinallyMarkers(method.intermediate) method.visitEnd() } @@ -286,7 +285,7 @@ class AnonymousObjectTransformer( val intermediateMethodNode = MethodNode(constructor!!.access, "", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY) inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor!!, constructorInlineBuilder, true) - InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode) + removeFinallyMarkers(intermediateMethodNode) val first = intermediateMethodNode.instructions.first val oldStartLabel = if (first is LabelNode) first.label else null @@ -429,8 +428,8 @@ class AnonymousObjectTransformer( val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?: throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}") val ownerType = Type.getObjectType(parent.originalLambdaInternalName) - val desc = CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType) - val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.`THIS$0`/*outer lambda/object*/, false) + val desc = CapturedParamDesc(ownerType, THIS, ownerType) + val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, THIS_0/*outer lambda/object*/, false) val composed = StackValue.LOCAL_0 recapturedParamInfo.remapValue = composed allRecapturedParameters.add(desc) @@ -458,16 +457,16 @@ class AnonymousObjectTransformer( } private fun getNewFieldName(oldName: String, originalField: Boolean): String { - if (InlineCodegenUtil.`THIS$0` == oldName) { + if (THIS_0 == oldName) { if (!originalField) { return oldName } else { //rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site - return addUniqueField(oldName + InlineCodegenUtil.INLINE_FUN_THIS_0_SUFFIX) + return addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX) } } - return addUniqueField(oldName + InlineCodegenUtil.INLINE_TRANSFORMATION_SUFFIX) + return addUniqueField(oldName + INLINE_TRANSFORMATION_SUFFIX) } private fun addUniqueField(name: String): String { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/CoveringTryCatchNodeProcessor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/CoveringTryCatchNodeProcessor.kt index 16a0ccef4fa..7bcc88e3793 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/CoveringTryCatchNodeProcessor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/CoveringTryCatchNodeProcessor.kt @@ -38,7 +38,7 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) { open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) { if (curInstr is VarInsnNode || curInstr is IincInsnNode) { - val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.opcode) + val argSize = getLoadStoreArgSize(curInstr.opcode) val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var` nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt index f2dba7275a1..3c34356cfd8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/DeferredMethodVisitor.kt @@ -22,7 +22,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode class DeferredMethodVisitor( val intermediate: MethodNode, val resultNode: () -> MethodVisitor -) : MethodVisitor(InlineCodegenUtil.API, intermediate) { +) : MethodVisitor(API, intermediate) { override fun visitEnd() { super.visitEnd() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt index 52f706cf6f7..9a911f4d0af 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/FieldRemapper.kt @@ -35,7 +35,7 @@ open class FieldRemapper( protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean { return fieldOwner == originalLambdaInternalName && //don't process general field of anonymous objects - InlineCodegenUtil.isCapturedFieldName(fieldName) + isCapturedFieldName(fieldName) } fun foldFieldAccessChainIfNeeded(capturedFieldAccess: List, node: MethodNode): AbstractInsnNode? = @@ -68,7 +68,7 @@ open class FieldRemapper( val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode if (canProcess(insnNode.owner, insnNode.name, true)) { - insnNode.name = InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode) + insnNode.name = CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode) insnNode.opcode = Opcodes.GETSTATIC node.remove(InsnSequence(capturedFieldAccess[0], insnNode)) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineAdapter.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineAdapter.java index ec1cd1cbb40..2a0a3e02162 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineAdapter.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineAdapter.java @@ -25,7 +25,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import java.util.ArrayList; import java.util.List; -import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getLoadStoreArgSize; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getLoadStoreArgSize; public class InlineAdapter extends InstructionAdapter { private final SourceMapper sourceMapper; @@ -36,7 +38,7 @@ public class InlineAdapter extends InstructionAdapter { private int nextLocalIndexBeforeInline = -1; public InlineAdapter(@NotNull MethodVisitor mv, int localsSize, @NotNull SourceMapper sourceMapper) { - super(InlineCodegenUtil.API, mv); + super(API, mv); this.nextLocalIndex = localsSize; this.sourceMapper = sourceMapper; } @@ -86,7 +88,7 @@ public class InlineAdapter extends InstructionAdapter { @Override public void visitLineNumber(int line, @NotNull Label start) { - if (InlineCodegenUtil.GENERATE_SMAP) { + if (GENERATE_SMAP) { line = sourceMapper.mapLineNumber(line); } //skip not mapped lines diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt index ade3f2a5e9c..cca47fa795b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive import org.jetbrains.kotlin.codegen.context.* import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineOrReturn import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineOrReturnInJvm -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.* import org.jetbrains.kotlin.codegen.intrinsics.bytecode import org.jetbrains.kotlin.codegen.intrinsics.classId import org.jetbrains.kotlin.codegen.state.GenerationState @@ -168,7 +167,7 @@ class InlineCodegen( "Couldn't inline method call '" + functionDescriptor.name + "' into\n" + DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" + (element?.text ?: "") + - if (generateNodeText) "\nCause: " + InlineCodegenUtil.getNodeText(node) else "", + if (generateNodeText) "\nCause: " + getNodeText(node) else "", e, callElement ) } @@ -230,7 +229,7 @@ class InlineCodegen( val remapper = LocalVarRemapper(parameters, initialFrameSize) - val adapter = InlineCodegenUtil.createEmptyMethodNode() + val adapter = createEmptyMethodNode() //hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain adapter.visitInsn(Opcodes.NOP) @@ -245,8 +244,8 @@ class InlineCodegen( adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index ) removeStaticInitializationTrigger(adapter) - if (!InlineCodegenUtil.isFinallyMarkerRequired(codegen.getContext())) { - InlineCodegenUtil.removeFinallyMarkers(adapter) + if (!isFinallyMarkerRequired(codegen.getContext())) { + removeFinallyMarkers(adapter) } adapter.accept(MethodBodyVisitor(codegen.v)) @@ -539,7 +538,7 @@ class InlineCodegen( var curInstr: AbstractInsnNode? = intoNode.instructions.first while (curInstr != null) { processor.processInstruction(curInstr, true) - if (InlineCodegenUtil.isFinallyStart(curInstr)) { + if (isFinallyStart(curInstr)) { //TODO depth index calc could be more precise curFinallyDepth = getConstant(curInstr.previous) } @@ -548,7 +547,7 @@ class InlineCodegen( if (extension != null) { val start = Label() - val finallyNode = InlineCodegenUtil.createEmptyMethodNode() + val finallyNode = createEmptyMethodNode() finallyNode.visitLabel(start) val finallyCodegen = ExpressionCodegen(finallyNode, codegen.frameMap, codegen.returnType, @@ -569,7 +568,7 @@ class InlineCodegen( finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, extension.finallyIntervalEnd.label) //Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method - InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr) + insertNodeBefore(finallyNode, intoNode, curInstr) val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd) processor.tryBlocksMetaInfo.splitCurrentIntervals(splitBy, true) @@ -620,12 +619,12 @@ class InlineCodegen( callDefault: Boolean, resolvedCall: ResolvedCall<*>? ): SMAPAndMethodNode { - if (InlineCodegenUtil.isSpecialEnumMethod(functionDescriptor)) { + if (isSpecialEnumMethod(functionDescriptor)) { assert(resolvedCall != null) { "Resolved call for $functionDescriptor should be not null" } val arguments = resolvedCall!!.typeArguments assert(arguments.size == 1) { "Resolved call for $functionDescriptor should have 1 type argument" } - val node = InlineCodegenUtil.createSpecialEnumMethodBody( + val node = createSpecialEnumMethodBody( codegen, functionDescriptor.name.asString(), arguments.keys.iterator().next().defaultType, @@ -689,7 +688,7 @@ class InlineCodegen( if (isBuiltInArrayIntrinsic(callableDescriptor)) { val classId = classId val bytes = state.inlineCache.classBytes.getOrPut(classId) { bytecode } - return InlineCodegenUtil.getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString()) + return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString()) } assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor } @@ -699,7 +698,7 @@ class InlineCodegen( val containerId = containingClasses.implClassId val bytes = state.inlineCache.classBytes.getOrPut(containerId) { - val file = InlineCodegenUtil.findVirtualFile(state, containerId) ?: throw IllegalStateException("Couldn't find declaration file for " + containerId) + val file = findVirtualFile(state, containerId) ?: throw IllegalStateException("Couldn't find declaration file for " + containerId) try { file.contentsToByteArray() } @@ -708,7 +707,7 @@ class InlineCodegen( } } - return InlineCodegenUtil.getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString()) + return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString()) } private fun doCreateMethodNodeFromSource( @@ -728,14 +727,14 @@ class InlineCodegen( val inliningFunction = element as KtDeclarationWithBody? val node = MethodNode( - InlineCodegenUtil.API, + API, getMethodAsmFlags(callableDescriptor, context.contextKind, state) or if (callDefault) Opcodes.ACC_STATIC else 0, asmMethod.name, asmMethod.descriptor, null, null ) //for maxLocals calculation - val maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node) + val maxCalcAdapter = wrapWithMaxLocalCalc(node) val parentContext = context.parentContext ?: error("Context has no parent: " + context) val methodContext = parentContext.intoFunction(callableDescriptor) @@ -919,7 +918,7 @@ class InlineCodegen( if (!descriptor.name.isSpecial) { result.add(descriptor.name.asString()) } - result.add(InlineCodegenUtil.FIRST_FUN_LABEL) + result.add(FIRST_FUN_LABEL) } return result } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.kt index 88636dda40e..002ff1b6cc5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.kt @@ -14,580 +14,534 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.inline; +package org.jetbrains.kotlin.codegen.inline -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import kotlin.text.StringsKt; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.backend.common.output.OutputFile; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.codegen.AsmUtil; -import org.jetbrains.kotlin.codegen.ExpressionCodegen; -import org.jetbrains.kotlin.codegen.MemberCodegen; -import org.jetbrains.kotlin.codegen.binding.CodegenBinding; -import org.jetbrains.kotlin.codegen.context.CodegenContext; -import org.jetbrains.kotlin.codegen.context.CodegenContextUtil; -import org.jetbrains.kotlin.codegen.context.InlineLambdaContext; -import org.jetbrains.kotlin.codegen.context.MethodContext; -import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt; -import org.jetbrains.kotlin.codegen.state.GenerationState; -import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; -import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping; -import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.fileClasses.FileClasses; -import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider; -import org.jetbrains.kotlin.load.java.JvmAbi; -import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder; -import org.jetbrains.kotlin.name.ClassId; -import org.jetbrains.kotlin.name.FqName; -import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.psi.KtFile; -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; -import org.jetbrains.kotlin.resolve.jvm.AsmTypes; -import org.jetbrains.kotlin.resolve.jvm.JvmClassName; -import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.util.OperatorNameConventions; -import org.jetbrains.org.objectweb.asm.*; -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; -import org.jetbrains.org.objectweb.asm.tree.*; -import org.jetbrains.org.objectweb.asm.util.Printer; -import org.jetbrains.org.objectweb.asm.util.Textifier; -import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor; +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.MemberCodegen +import org.jetbrains.kotlin.codegen.binding.CodegenBinding +import org.jetbrains.kotlin.codegen.context.CodegenContext +import org.jetbrains.kotlin.codegen.context.CodegenContextUtil +import org.jetbrains.kotlin.codegen.context.InlineLambdaContext +import org.jetbrains.kotlin.codegen.context.MethodContext +import org.jetbrains.kotlin.codegen.intrinsics.* +import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper +import org.jetbrains.kotlin.codegen.`when`.WhenByEnumsMapping +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.fileClasses.* +import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.jvm.AsmTypes +import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.org.objectweb.asm.* +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter +import org.jetbrains.org.objectweb.asm.tree.* +import org.jetbrains.org.objectweb.asm.util.Printer +import org.jetbrains.org.objectweb.asm.util.Textifier +import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.List; -import java.util.ListIterator; +import java.io.IOException +import java.io.PrintWriter +import java.io.StringWriter -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.ENUM_TYPE; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_CLASS_TYPE; +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.ENUM_TYPE +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_CLASS_TYPE -public class InlineCodegenUtil { - public static final boolean GENERATE_SMAP = true; - public static final int API = Opcodes.ASM5; - private static final String CAPTURED_FIELD_PREFIX = "$"; - private static final String NON_CAPTURED_FIELD_PREFIX = "$$"; - public static final String THIS$0 = "this$0"; - public static final String THIS = "this"; - private static final String RECEIVER$0 = "receiver$0"; - private static final String NON_LOCAL_RETURN = "$$$$$NON_LOCAL_RETURN$$$$$"; - public static final String FIRST_FUN_LABEL = "$$$$$ROOT$$$$$"; - public static final String NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function"; - private static final String INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker"; - private static final String INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall"; - private static final String INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall"; - private static final String INLINE_MARKER_FINALLY_START = "finallyStart"; - private static final String INLINE_MARKER_FINALLY_END = "finallyEnd"; - public static final String SPECIAL_TRANSFORMATION_NAME = "$special"; - public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined"; - public static final String INLINE_CALL_TRANSFORMATION_SUFFIX = "$" + INLINE_TRANSFORMATION_SUFFIX; - public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun"; - public static final String INLINE_FUN_VAR_SUFFIX = "$iv"; +const val GENERATE_SMAP = true +const val API = Opcodes.ASM5 +const val THIS = "this" +const val THIS_0 = "this$0" +const val FIRST_FUN_LABEL = "$$$$\$ROOT$$$$$" +const val NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function" +const val SPECIAL_TRANSFORMATION_NAME = "\$special" +const val INLINE_TRANSFORMATION_SUFFIX = "\$inlined" +const val INLINE_CALL_TRANSFORMATION_SUFFIX = "$" + INLINE_TRANSFORMATION_SUFFIX +const val INLINE_FUN_THIS_0_SUFFIX = "\$inline_fun" +const val INLINE_FUN_VAR_SUFFIX = "\$iv" +const val DEFAULT_LAMBDA_FAKE_CALL = "$$\$DEFAULT_LAMBDA_FAKE_CALL$$$" - public static final String DEFAULT_LAMBDA_FAKE_CALL = "$$$DEFAULT_LAMBDA_FAKE_CALL$$$"; - public static final String CAPTURED_FIELD_FOLD_PREFIX = "$$$"; - - @Nullable - public static SMAPAndMethodNode getMethodNode( - byte[] classData, - @NotNull String methodName, - @NotNull String methodDescriptor, - @NotNull String classInternalName - ) { - ClassReader cr = new ClassReader(classData); - MethodNode[] node = new MethodNode[1]; - String[] debugInfo = new String[2]; - int[] lines = new int[2]; - lines[0] = Integer.MAX_VALUE; - lines[1] = Integer.MIN_VALUE; - //noinspection PointlessBitwiseExpression - cr.accept(new ClassVisitor(API) { +const val CAPTURED_FIELD_FOLD_PREFIX = "$$$" +private const val `RECEIVER$0` = "receiver$0" +private const val NON_LOCAL_RETURN = "$$$$\$NON_LOCAL_RETURN$$$$$" +private const val CAPTURED_FIELD_PREFIX = "$" +private const val NON_CAPTURED_FIELD_PREFIX = "$$" +private const val INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker" +private const val INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall" +private const val INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall" +private const val INLINE_MARKER_FINALLY_START = "finallyStart" - @Override - public void visitSource(String source, String debug) { - super.visitSource(source, debug); - debugInfo[0] = source; - debugInfo[1] = debug; - } +private const val INLINE_MARKER_FINALLY_END = "finallyEnd" - @Override - public MethodVisitor visitMethod( - int access, - @NotNull String name, - @NotNull String desc, - String signature, - String[] exceptions - ) { - if (methodName.equals(name) && methodDescriptor.equals(desc)) { - node[0] = new MethodNode(API, access, name, desc, signature, exceptions) { - @Override - public void visitLineNumber(int line, @NotNull Label start) { - super.visitLineNumber(line, start); - lines[0] = Math.min(lines[0], line); - lines[1] = Math.max(lines[1], line); - } - }; - return node[0]; +fun getMethodNode( + classData: ByteArray, + methodName: String, + methodDescriptor: String, + classInternalName: String +): SMAPAndMethodNode? { + val cr = ClassReader(classData) + var node: MethodNode? = null + val debugInfo = arrayOfNulls(2) + val lines = IntArray(2) + lines[0] = Integer.MAX_VALUE + lines[1] = Integer.MIN_VALUE + + cr.accept(object : ClassVisitor(API) { + + override fun visitSource(source: String?, debug: String?) { + super.visitSource(source, debug) + debugInfo[0] = source + debugInfo[1] = debug + } + + override fun visitMethod( + access: Int, + name: String, + desc: String, + signature: String?, + exceptions: Array? + ): MethodVisitor? { + if (methodName == name && methodDescriptor == desc) { + node = object : MethodNode(API, access, name, desc, signature, exceptions) { + override fun visitLineNumber(line: Int, start: Label) { + super.visitLineNumber(line, start) + lines[0] = Math.min(lines[0], line) + lines[1] = Math.max(lines[1], line) + } } - return null; + return node } - }, ClassReader.SKIP_FRAMES | (GENERATE_SMAP ? 0 : ClassReader.SKIP_DEBUG)); - - if (node[0] == null) { - return null; + return null } + }, ClassReader.SKIP_FRAMES or if (GENERATE_SMAP) 0 else ClassReader.SKIP_DEBUG) - if (IntrinsicArrayConstructorsKt.getClassId().asString().equals(classInternalName)) { - // Don't load source map for intrinsic array constructors - debugInfo[0] = null; + if (node == null) { + return null + } + + if (classId.asString() == classInternalName) { + // Don't load source map for intrinsic array constructors + debugInfo[0] = null + } + + val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classInternalName, lines[0], lines[1]) + return SMAPAndMethodNode(node!!, smap) +} + +fun initDefaultSourceMappingIfNeeded( + context: CodegenContext<*>, codegen: MemberCodegen<*>, state: GenerationState +) { + if (state.isInlineDisabled) return + + var parentContext: CodegenContext<*>? = context.parentContext + while (parentContext != null) { + if (parentContext.isInlineMethodContext) { + //just init default one to one mapping + codegen.orCreateSourceMapper + break } - - SMAP smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classInternalName, lines[0], lines[1]); - return new SMAPAndMethodNode(node[0], smap); - } - - public static void initDefaultSourceMappingIfNeeded( - @NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state - ) { - if (state.isInlineDisabled()) return; - - CodegenContext parentContext = context.getParentContext(); - while (parentContext != null) { - if (parentContext.isInlineMethodContext()) { - //just init default one to one mapping - codegen.getOrCreateSourceMapper(); - break; - } - parentContext = parentContext.getParentContext(); - } - } - - @Nullable - public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) { - return VirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId); - } - - @Nullable - public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) { - FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName(); - String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName); - //TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file - // we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE - return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars))); - } - - @NotNull - public static String getInlineName( - @NotNull CodegenContext codegenContext, - @NotNull KotlinTypeMapper typeMapper, - @NotNull JvmFileClassesProvider fileClassesManager - ) { - return getInlineName(codegenContext, codegenContext.getContextDescriptor(), typeMapper, fileClassesManager); - } - - @NotNull - private static String getInlineName( - @NotNull CodegenContext codegenContext, - @NotNull DeclarationDescriptor currentDescriptor, - @NotNull KotlinTypeMapper typeMapper, - @NotNull JvmFileClassesProvider fileClassesProvider - ) { - if (currentDescriptor instanceof PackageFragmentDescriptor) { - PsiFile file = DescriptorToSourceUtils.getContainingFile(codegenContext.getContextDescriptor()); - - Type implementationOwnerType; - if (file == null) { - implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(codegenContext); - } - else { - implementationOwnerType = FileClasses.getFileClassType(fileClassesProvider, (KtFile) file); - } - - if (implementationOwnerType == null) { - DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor(); - //noinspection ConstantConditions - throw new RuntimeException( - "Couldn't find declaration for " + - contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() + - "; context: " + codegenContext - ); - } - - return implementationOwnerType.getInternalName(); - } - else if (currentDescriptor instanceof ClassifierDescriptor) { - Type type = typeMapper.mapType((ClassifierDescriptor) currentDescriptor); - return type.getInternalName(); - } - else if (currentDescriptor instanceof FunctionDescriptor) { - ClassDescriptor descriptor = - typeMapper.getBindingContext().get(CodegenBinding.CLASS_FOR_CALLABLE, (FunctionDescriptor) currentDescriptor); - if (descriptor != null) { - return typeMapper.mapType(descriptor).getInternalName(); - } - } - - //TODO: add suffix for special case - String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString(); - - //noinspection ConstantConditions - return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper, fileClassesProvider) + "$" + suffix; - } - - public static boolean isInvokeOnLambda(@NotNull String owner, @NotNull String name) { - return OperatorNameConventions.INVOKE.asString().equals(name) && - owner.startsWith(NUMBERED_FUNCTION_PREFIX) && - isInteger(owner.substring(NUMBERED_FUNCTION_PREFIX.length())); - } - - public static boolean isAnonymousConstructorCall(@NotNull String internalName, @NotNull String methodName) { - return "".equals(methodName) && isAnonymousClass(internalName); - } - - public static boolean isWhenMappingAccess(@NotNull String internalName, @NotNull String fieldName) { - return fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) && - internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX); - } - - public static boolean isAnonymousSingletonLoad(@NotNull String internalName, @NotNull String fieldName) { - return JvmAbi.INSTANCE_FIELD.equals(fieldName) && isAnonymousClass(internalName); - } - - public static boolean isAnonymousClass(@NotNull String internalName) { - String shortName = getLastNamePart(internalName); - int index = shortName.lastIndexOf("$"); - - if (index < 0) { - return false; - } - - String suffix = shortName.substring(index + 1); - return isInteger(suffix); - } - - @NotNull - private static String getLastNamePart(@NotNull String internalName) { - int index = internalName.lastIndexOf("/"); - return index < 0 ? internalName : internalName.substring(index + 1); - } - - @NotNull - public static MethodVisitor wrapWithMaxLocalCalc(@NotNull MethodNode methodNode) { - return new MaxStackFrameSizeAndLocalsCalculator(API, methodNode.access, methodNode.desc, methodNode); - } - - private static boolean isInteger(@NotNull String string) { - if (string.isEmpty()) { - return false; - } - - for (int i = 0; i < string.length(); i++) { - if (!Character.isDigit(string.charAt(i))) { - return false; - } - } - - return true; - } - - public static boolean isCapturedFieldName(@NotNull String fieldName) { - // TODO: improve this heuristic - return fieldName.startsWith(CAPTURED_FIELD_PREFIX) && - !fieldName.startsWith(NON_CAPTURED_FIELD_PREFIX) || - THIS$0.equals(fieldName) || - RECEIVER$0.equals(fieldName); - } - - public static boolean isReturnOpcode(int opcode) { - return opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN; - } - - //marked return could be either non-local or local in case of labeled lambda self-returns - public static boolean isMarkedReturn(@NotNull AbstractInsnNode returnIns) { - return getMarkedReturnLabelOrNull(returnIns) != null; - } - - @Nullable - public static String getMarkedReturnLabelOrNull(@NotNull AbstractInsnNode returnInsn) { - if (!isReturnOpcode(returnInsn.getOpcode())) { - return null; - } - AbstractInsnNode previous = returnInsn.getPrevious(); - if (previous instanceof MethodInsnNode) { - MethodInsnNode marker = (MethodInsnNode) previous; - if (NON_LOCAL_RETURN.equals(marker.owner)) { - return marker.name; - } - } - return null; - } - - public static void generateGlobalReturnFlag(@NotNull InstructionAdapter iv, @NotNull String labelName) { - iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false); - } - - @NotNull - public static Type getReturnType(int opcode) { - switch (opcode) { - case Opcodes.RETURN: - return Type.VOID_TYPE; - case Opcodes.IRETURN: - return Type.INT_TYPE; - case Opcodes.DRETURN: - return Type.DOUBLE_TYPE; - case Opcodes.FRETURN: - return Type.FLOAT_TYPE; - case Opcodes.LRETURN: - return Type.LONG_TYPE; - default: - return AsmTypes.OBJECT_TYPE; - } - } - - public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) { - ListIterator iterator = from.instructions.iterator(); - while (iterator.hasNext()) { - AbstractInsnNode next = iterator.next(); - to.instructions.insertBefore(beforeNode, next); - } - } - - @NotNull - public static MethodNode createEmptyMethodNode() { - return new MethodNode(API, 0, "fake", "()V", null, null); - } - - @NotNull - public static LabelNode firstLabelInChain(@NotNull LabelNode node) { - LabelNode curNode = node; - while (curNode.getPrevious() instanceof LabelNode) { - curNode = (LabelNode) curNode.getPrevious(); - } - return curNode; - } - - @NotNull - public static String getNodeText(@Nullable MethodNode node) { - Textifier textifier = new Textifier(); - if (node == null) { - return "Not generated"; - } - node.accept(new TraceMethodVisitor(textifier)); - StringWriter sw = new StringWriter(); - textifier.print(new PrintWriter(sw)); - sw.flush(); - return node.name + " " + node.desc + ":\n" + sw.getBuffer().toString(); - } - - @NotNull - public static String getInsnText(@Nullable AbstractInsnNode node) { - if (node == null) return ""; - Textifier textifier = new Textifier(); - node.accept(new TraceMethodVisitor(textifier)); - StringWriter sw = new StringWriter(); - textifier.print(new PrintWriter(sw)); - sw.flush(); - return sw.toString().trim(); - } - - @NotNull - public static String getInsnOpcodeText(@Nullable AbstractInsnNode node) { - return node == null ? "null" : Printer.OPCODES[node.getOpcode()]; - } - - @NotNull - /* package */ static ClassReader buildClassReaderByInternalName(@NotNull GenerationState state, @NotNull String internalName) { - //try to find just compiled classes then in dependencies - try { - OutputFile outputFile = state.getFactory().get(internalName + ".class"); - if (outputFile != null) { - return new ClassReader(outputFile.asByteArray()); - } - VirtualFile file = findVirtualFileImprecise(state, internalName); - if (file != null) { - return new ClassReader(file.contentsToByteArray()); - } - throw new RuntimeException("Couldn't find virtual file for " + internalName); - } - catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static void generateFinallyMarker(@NotNull InstructionAdapter v, int depth, boolean start) { - v.iconst(depth); - v.invokestatic(INLINE_MARKER_CLASS_NAME, start ? INLINE_MARKER_FINALLY_START : INLINE_MARKER_FINALLY_END, "(I)V", false); - } - - public static boolean isFinallyEnd(@NotNull AbstractInsnNode node) { - return isFinallyMarker(node, INLINE_MARKER_FINALLY_END); - } - - public static boolean isFinallyStart(@NotNull AbstractInsnNode node) { - return isFinallyMarker(node, INLINE_MARKER_FINALLY_START); - } - - public static boolean isFinallyMarker(@Nullable AbstractInsnNode node) { - return node != null && (isFinallyStart(node) || isFinallyEnd(node)); - } - - private static boolean isFinallyMarker(@NotNull AbstractInsnNode node, String name) { - if (!(node instanceof MethodInsnNode)) return false; - MethodInsnNode method = (MethodInsnNode) node; - return INLINE_MARKER_CLASS_NAME.equals(method.owner) && name.equals(method.name); - } - - public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) { - return context.isInlineMethodContext() || context instanceof InlineLambdaContext; - } - - public static int getConstant(@NotNull AbstractInsnNode ins) { - int opcode = ins.getOpcode(); - if (opcode >= Opcodes.ICONST_0 && opcode <= Opcodes.ICONST_5) { - return opcode - Opcodes.ICONST_0; - } - else if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) { - return ((IntInsnNode) ins).operand; - } - else { - LdcInsnNode index = (LdcInsnNode) ins; - return (Integer) index.cst; - } - } - - public static void removeFinallyMarkers(@NotNull MethodNode intoNode) { - InsnList instructions = intoNode.instructions; - AbstractInsnNode curInstr = instructions.getFirst(); - while (curInstr != null) { - if (isFinallyMarker(curInstr)) { - AbstractInsnNode marker = curInstr; - //just to assert - getConstant(marker.getPrevious()); - curInstr = curInstr.getNext(); - instructions.remove(marker.getPrevious()); - instructions.remove(marker); - continue; - } - curInstr = curInstr.getNext(); - } - } - - public static void addInlineMarker(@NotNull InstructionAdapter v, boolean isStartNotEnd) { - v.visitMethodInsn( - Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME, - isStartNotEnd ? INLINE_MARKER_BEFORE_METHOD_NAME : INLINE_MARKER_AFTER_METHOD_NAME, - "()V", false - ); - } - - public static boolean isInlineMarker(@NotNull AbstractInsnNode insn) { - return isInlineMarker(insn, null); - } - - private static boolean isInlineMarker(@NotNull AbstractInsnNode insn, @Nullable String name) { - if (!(insn instanceof MethodInsnNode)) { - return false; - } - - MethodInsnNode methodInsnNode = (MethodInsnNode) insn; - return insn.getOpcode() == Opcodes.INVOKESTATIC && - methodInsnNode.owner.equals(INLINE_MARKER_CLASS_NAME) && - (name != null ? methodInsnNode.name.equals(name) - : methodInsnNode.name.equals(INLINE_MARKER_BEFORE_METHOD_NAME) || - methodInsnNode.name.equals(INLINE_MARKER_AFTER_METHOD_NAME)); - } - - public static boolean isBeforeInlineMarker(@NotNull AbstractInsnNode insn) { - return isInlineMarker(insn, INLINE_MARKER_BEFORE_METHOD_NAME); - } - - public static boolean isAfterInlineMarker(@NotNull AbstractInsnNode insn) { - return isInlineMarker(insn, INLINE_MARKER_AFTER_METHOD_NAME); - } - - public static int getLoadStoreArgSize(int opcode) { - return opcode == Opcodes.DSTORE || opcode == Opcodes.LSTORE || opcode == Opcodes.DLOAD || opcode == Opcodes.LLOAD ? 2 : 1; - } - - public static boolean isStoreInstruction(int opcode) { - return opcode >= Opcodes.ISTORE && opcode <= Opcodes.ASTORE; - } - - public static int calcMarkerShift(@NotNull Parameters parameters, @NotNull MethodNode node) { - int markerShiftTemp = getIndexAfterLastMarker(node); - return markerShiftTemp - parameters.getRealParametersSizeOnStack() + parameters.getArgsSizeOnStack(); - } - - private static int getIndexAfterLastMarker(@NotNull MethodNode node) { - int result = -1; - for (LocalVariableNode variable : node.localVariables) { - if (isFakeLocalVariableForInline(variable.name)) { - result = Math.max(result, variable.index + 1); - } - } - return result; - } - - public static boolean isFakeLocalVariableForInline(@NotNull String name) { - return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || - name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT); - } - - public static boolean isThis0(@NotNull String name) { - return THIS$0.equals(name); - } - - public static boolean isSpecialEnumMethod(@NotNull FunctionDescriptor functionDescriptor) { - DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); - if (!(containingDeclaration instanceof PackageFragmentDescriptor)) { - return false; - } - if (!((PackageFragmentDescriptor) containingDeclaration).getFqName().equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)) { - return false; - } - if (functionDescriptor.getTypeParameters().size() != 1) { - return false; - } - String name = functionDescriptor.getName().asString(); - List parameters = functionDescriptor.getValueParameters(); - return "enumValues".equals(name) && parameters.size() == 0 || - "enumValueOf".equals(name) && parameters.size() == 1 && KotlinBuiltIns.isString(parameters.get(0).getType()); - } - - public static MethodNode createSpecialEnumMethodBody( - @NotNull ExpressionCodegen codegen, - @NotNull String name, - @NotNull KotlinType type, - @NotNull KotlinTypeMapper typeMapper - ) { - boolean isValueOf = "enumValueOf".equals(name); - Type invokeType = typeMapper.mapType(type); - String desc = getSpecialEnumFunDescriptor(invokeType, isValueOf); - MethodNode node = new MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null); - codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, new InstructionAdapter(node)); - if (isValueOf) { - node.visitInsn(Opcodes.ACONST_NULL); - node.visitVarInsn(Opcodes.ALOAD, 0); - - node.visitMethodInsn(Opcodes.INVOKESTATIC, ENUM_TYPE.getInternalName(), "valueOf", - Type.getMethodDescriptor(ENUM_TYPE, JAVA_CLASS_TYPE, AsmTypes.JAVA_STRING_TYPE), false); - } - else { - node.visitInsn(Opcodes.ICONST_0); - node.visitTypeInsn(Opcodes.ANEWARRAY, ENUM_TYPE.getInternalName()); - } - node.visitInsn(Opcodes.ARETURN); - node.visitMaxs(isValueOf ? 3 : 2, isValueOf ? 1 : 0); - return node; - } - - @NotNull - public static String getSpecialEnumFunDescriptor(@NotNull Type type, boolean isValueOf) { - return isValueOf ? Type.getMethodDescriptor(type, AsmTypes.JAVA_STRING_TYPE) : Type.getMethodDescriptor(AsmUtil.getArrayType(type)); + parentContext = parentContext.parentContext } } +fun findVirtualFile(state: GenerationState, classId: ClassId): VirtualFile? { + return VirtualFileFinder.getInstance(state.project).findVirtualFileWithHeader(classId) +} + +fun findVirtualFileImprecise(state: GenerationState, internalClassName: String): VirtualFile? { + val packageFqName = JvmClassName.byInternalName(internalClassName).packageFqName + val classNameWithDollars = internalClassName.substringAfterLast("/", internalClassName) + //TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file + // we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE + return findVirtualFile(state, ClassId(packageFqName, Name.identifier(classNameWithDollars))) +} + +fun getInlineName( + codegenContext: CodegenContext<*>, + typeMapper: KotlinTypeMapper, + fileClassesManager: JvmFileClassesProvider +): String { + return getInlineName(codegenContext, codegenContext.contextDescriptor, typeMapper, fileClassesManager) +} + +private fun getInlineName( + codegenContext: CodegenContext<*>, + currentDescriptor: DeclarationDescriptor, + typeMapper: KotlinTypeMapper, + fileClassesProvider: JvmFileClassesProvider +): String { + if (currentDescriptor is PackageFragmentDescriptor) { + val file = DescriptorToSourceUtils.getContainingFile(codegenContext.contextDescriptor) + + val implementationOwnerType: Type? = + if (file == null) { + CodegenContextUtil.getImplementationOwnerClassType(codegenContext) + } + else fileClassesProvider.getFileClassType(file) + + if (implementationOwnerType == null) { + val contextDescriptor = codegenContext.contextDescriptor + throw RuntimeException( + "Couldn't find declaration for " + + contextDescriptor.containingDeclaration!!.name + "." + contextDescriptor.name + + "; context: " + codegenContext + ) + } + + return implementationOwnerType.internalName + } + else if (currentDescriptor is ClassifierDescriptor) { + return typeMapper.mapType(currentDescriptor).internalName + } + else if (currentDescriptor is FunctionDescriptor) { + val descriptor = typeMapper.bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, currentDescriptor) + if (descriptor != null) { + return typeMapper.mapType(descriptor).internalName + } + } + + //TODO: add suffix for special case + val suffix = if (currentDescriptor.name.isSpecial) "" else currentDescriptor.name.asString() + + + return getInlineName(codegenContext, currentDescriptor.containingDeclaration!!, typeMapper, fileClassesProvider) + "$" + suffix +} + +fun isInvokeOnLambda(owner: String, name: String): Boolean { + return OperatorNameConventions.INVOKE.asString() == name && + owner.startsWith(NUMBERED_FUNCTION_PREFIX) && + isInteger(owner.substring(NUMBERED_FUNCTION_PREFIX.length)) +} + +fun isAnonymousConstructorCall(internalName: String, methodName: String): Boolean { + return "" == methodName && isAnonymousClass(internalName) +} + +fun isWhenMappingAccess(internalName: String, fieldName: String): Boolean { + return fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) && internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX) +} + +fun isAnonymousSingletonLoad(internalName: String, fieldName: String): Boolean { + return JvmAbi.INSTANCE_FIELD == fieldName && isAnonymousClass(internalName) +} + +fun isAnonymousClass(internalName: String): Boolean { + val shortName = getLastNamePart(internalName) + val index = shortName.lastIndexOf("$") + + if (index < 0) { + return false + } + + val suffix = shortName.substring(index + 1) + return isInteger(suffix) +} + +private fun getLastNamePart(internalName: String): String { + val index = internalName.lastIndexOf("/") + return if (index < 0) internalName else internalName.substring(index + 1) +} + +fun wrapWithMaxLocalCalc(methodNode: MethodNode): MethodVisitor { + return MaxStackFrameSizeAndLocalsCalculator(API, methodNode.access, methodNode.desc, methodNode) +} + +private fun isInteger(string: String): Boolean { + if (string.isEmpty()) { + return false + } + + for (i in 0..string.length - 1) { + if (!Character.isDigit(string[i])) { + return false + } + } + + return true +} + +fun isCapturedFieldName(fieldName: String): Boolean { + // TODO: improve this heuristic + return fieldName.startsWith(CAPTURED_FIELD_PREFIX) && !fieldName.startsWith(NON_CAPTURED_FIELD_PREFIX) || + THIS_0 == fieldName || + `RECEIVER$0` == fieldName +} + +fun isReturnOpcode(opcode: Int): Boolean { + return opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN +} + +//marked return could be either non-local or local in case of labeled lambda self-returns +fun isMarkedReturn(returnIns: AbstractInsnNode): Boolean { + return getMarkedReturnLabelOrNull(returnIns) != null +} + +fun getMarkedReturnLabelOrNull(returnInsn: AbstractInsnNode): String? { + if (!isReturnOpcode(returnInsn.opcode)) { + return null + } + val previous = returnInsn.previous + if (previous is MethodInsnNode) { + val marker = previous + if (NON_LOCAL_RETURN == marker.owner) { + return marker.name + } + } + return null +} + +fun generateGlobalReturnFlag(iv: InstructionAdapter, labelName: String) { + iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false) +} + +fun getReturnType(opcode: Int): Type { + when (opcode) { + Opcodes.RETURN -> return Type.VOID_TYPE + Opcodes.IRETURN -> return Type.INT_TYPE + Opcodes.DRETURN -> return Type.DOUBLE_TYPE + Opcodes.FRETURN -> return Type.FLOAT_TYPE + Opcodes.LRETURN -> return Type.LONG_TYPE + else -> return AsmTypes.OBJECT_TYPE + } +} + +fun insertNodeBefore(from: MethodNode, to: MethodNode, beforeNode: AbstractInsnNode) { + val iterator = from.instructions.iterator() + while (iterator.hasNext()) { + val next = iterator.next() + to.instructions.insertBefore(beforeNode, next) + } +} + +fun createEmptyMethodNode(): MethodNode { + return MethodNode(API, 0, "fake", "()V", null, null) +} + +fun firstLabelInChain(node: LabelNode): LabelNode { + var curNode = node + while (curNode.previous is LabelNode) { + curNode = curNode.previous as LabelNode + } + return curNode +} + +fun getNodeText(node: MethodNode?): String { + val textifier = Textifier() + if (node == null) { + return "Not generated" + } + node.accept(TraceMethodVisitor(textifier)) + val sw = StringWriter() + textifier.print(PrintWriter(sw)) + sw.flush() + return node.name + " " + node.desc + ":\n" + sw.buffer.toString() +} + +fun getInsnText(node: AbstractInsnNode?): String { + if (node == null) return "" + val textifier = Textifier() + node.accept(TraceMethodVisitor(textifier)) + val sw = StringWriter() + textifier.print(PrintWriter(sw)) + sw.flush() + return sw.toString().trim { it <= ' ' } +} + +fun getInsnOpcodeText(node: AbstractInsnNode?): String { + return if (node == null) "null" else Printer.OPCODES[node.opcode] +} + +internal /* package */ fun buildClassReaderByInternalName(state: GenerationState, internalName: String): ClassReader { + //try to find just compiled classes then in dependencies + try { + val outputFile = state.factory.get(internalName + ".class") + if (outputFile != null) { + return ClassReader(outputFile.asByteArray()) + } + val file = findVirtualFileImprecise(state, internalName) + if (file != null) { + return ClassReader(file.contentsToByteArray()) + } + throw RuntimeException("Couldn't find virtual file for " + internalName) + } + catch (e: IOException) { + throw RuntimeException(e) + } + +} + +fun generateFinallyMarker(v: InstructionAdapter, depth: Int, start: Boolean) { + v.iconst(depth) + v.invokestatic(INLINE_MARKER_CLASS_NAME, if (start) INLINE_MARKER_FINALLY_START else INLINE_MARKER_FINALLY_END, "(I)V", false) +} + +fun isFinallyEnd(node: AbstractInsnNode): Boolean { + return isFinallyMarker(node, INLINE_MARKER_FINALLY_END) +} + +fun isFinallyStart(node: AbstractInsnNode): Boolean { + return isFinallyMarker(node, INLINE_MARKER_FINALLY_START) +} + +fun isFinallyMarker(node: AbstractInsnNode?): Boolean { + return node != null && (isFinallyStart(node) || isFinallyEnd(node)) +} + +private fun isFinallyMarker(node: AbstractInsnNode, name: String): Boolean { + if (node !is MethodInsnNode) return false + val method = node + return INLINE_MARKER_CLASS_NAME == method.owner && name == method.name +} + +fun isFinallyMarkerRequired(context: MethodContext): Boolean { + return context.isInlineMethodContext || context is InlineLambdaContext +} + +fun getConstant(ins: AbstractInsnNode): Int { + val opcode = ins.opcode + if (opcode >= Opcodes.ICONST_0 && opcode <= Opcodes.ICONST_5) { + return opcode - Opcodes.ICONST_0 + } + else if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) { + return (ins as IntInsnNode).operand + } + else { + val index = ins as LdcInsnNode + return index.cst as Int + } +} + +fun removeFinallyMarkers(intoNode: MethodNode) { + val instructions = intoNode.instructions + var curInstr: AbstractInsnNode? = instructions.first + while (curInstr != null) { + if (isFinallyMarker(curInstr)) { + val marker = curInstr + //just to assert + getConstant(marker.previous) + curInstr = curInstr.next + instructions.remove(marker.previous) + instructions.remove(marker) + continue + } + curInstr = curInstr.next + } +} + +fun addInlineMarker(v: InstructionAdapter, isStartNotEnd: Boolean) { + v.visitMethodInsn( + Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME, + if (isStartNotEnd) INLINE_MARKER_BEFORE_METHOD_NAME else INLINE_MARKER_AFTER_METHOD_NAME, + "()V", false + ) +} + +fun isInlineMarker(insn: AbstractInsnNode): Boolean { + return isInlineMarker(insn, null) +} + +private fun isInlineMarker(insn: AbstractInsnNode, name: String?): Boolean { + if (insn !is MethodInsnNode) { + return false + } + + val methodInsnNode = insn + return insn.getOpcode() == Opcodes.INVOKESTATIC && + methodInsnNode.owner == INLINE_MARKER_CLASS_NAME && + if (name != null) + methodInsnNode.name == name + else + methodInsnNode.name == INLINE_MARKER_BEFORE_METHOD_NAME || methodInsnNode.name == INLINE_MARKER_AFTER_METHOD_NAME +} + +fun isBeforeInlineMarker(insn: AbstractInsnNode): Boolean { + return isInlineMarker(insn, INLINE_MARKER_BEFORE_METHOD_NAME) +} + +fun isAfterInlineMarker(insn: AbstractInsnNode): Boolean { + return isInlineMarker(insn, INLINE_MARKER_AFTER_METHOD_NAME) +} + +fun getLoadStoreArgSize(opcode: Int): Int { + return if (opcode == Opcodes.DSTORE || opcode == Opcodes.LSTORE || opcode == Opcodes.DLOAD || opcode == Opcodes.LLOAD) 2 else 1 +} + +fun isStoreInstruction(opcode: Int): Boolean { + return opcode >= Opcodes.ISTORE && opcode <= Opcodes.ASTORE +} + +fun calcMarkerShift(parameters: Parameters, node: MethodNode): Int { + val markerShiftTemp = getIndexAfterLastMarker(node) + return markerShiftTemp - parameters.realParametersSizeOnStack + parameters.argsSizeOnStack +} + +private fun getIndexAfterLastMarker(node: MethodNode): Int { + var result = -1 + for (variable in node.localVariables) { + if (isFakeLocalVariableForInline(variable.name)) { + result = Math.max(result, variable.index + 1) + } + } + return result +} + +fun isFakeLocalVariableForInline(name: String): Boolean { + return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT) +} + +fun isThis0(name: String): Boolean { + return THIS_0 == name +} + +fun isSpecialEnumMethod(functionDescriptor: FunctionDescriptor): Boolean { + val containingDeclaration = functionDescriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false + if (containingDeclaration.fqName != KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME) { + return false + } + if (functionDescriptor.typeParameters.size != 1) { + return false + } + val name = functionDescriptor.name.asString() + val parameters = functionDescriptor.valueParameters + return "enumValues" == name && parameters.size == 0 || "enumValueOf" == name && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type) +} + +fun createSpecialEnumMethodBody( + codegen: ExpressionCodegen, + name: String, + type: KotlinType, + typeMapper: KotlinTypeMapper +): MethodNode { + val isValueOf = "enumValueOf" == name + val invokeType = typeMapper.mapType(type) + val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf) + val node = MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null) + codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node)) + if (isValueOf) { + node.visitInsn(Opcodes.ACONST_NULL) + node.visitVarInsn(Opcodes.ALOAD, 0) + + node.visitMethodInsn(Opcodes.INVOKESTATIC, ENUM_TYPE.internalName, "valueOf", + Type.getMethodDescriptor(ENUM_TYPE, JAVA_CLASS_TYPE, AsmTypes.JAVA_STRING_TYPE), false) + } + else { + node.visitInsn(Opcodes.ICONST_0) + node.visitTypeInsn(Opcodes.ANEWARRAY, ENUM_TYPE.internalName) + } + node.visitInsn(Opcodes.ARETURN) + node.visitMaxs(if (isValueOf) 3 else 2, if (isValueOf) 1 else 0) + return node +} + +fun getSpecialEnumFunDescriptor(type: Type, isValueOf: Boolean): String { + return if (isValueOf) Type.getMethodDescriptor(type, AsmTypes.JAVA_STRING_TYPE) else Type.getMethodDescriptor(AsmUtil.getArrayType(type)) +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InternalFinallyBlockInliner.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InternalFinallyBlockInliner.java index b0db81082bf..b1233fb88c1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InternalFinallyBlockInliner.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InternalFinallyBlockInliner.java @@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.ReadOnly; import org.jetbrains.annotations.TestOnly; -import org.jetbrains.kotlin.codegen.optimization.common.UtilKt; import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.Opcodes; import org.jetbrains.org.objectweb.asm.Type; @@ -34,7 +33,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.*; -import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*; import static org.jetbrains.kotlin.codegen.inline.MethodInlinerUtilKt.getNextMeaningful; public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { @@ -106,7 +105,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { private int initAndGetVarIndexForNonLocalReturnValue() { MaxLocalsCalculator tempCalcNode = new MaxLocalsCalculator( - InlineCodegenUtil.API, + API, inlineFun.access, inlineFun.desc, null ); inlineFun.accept(tempCalcNode); @@ -126,8 +125,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { processInstruction(curIns, false); //At this point only global return is possible, local one already substituted with: goto endLabel - if (!InlineCodegenUtil.isReturnOpcode(curIns.getOpcode()) || - !InlineCodegenUtil.isMarkedReturn(curIns)) { + if (!isReturnOpcode(curIns.getOpcode()) || + !isMarkedReturn(curIns)) { curIns = curIns.getPrevious(); continue; } @@ -147,7 +146,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { AbstractInsnNode nextPrev = instrInsertFinallyBefore.getPrevious(); assert markedReturn.getNext() instanceof LabelNode : "Label should be occurred after non-local return"; LabelNode newFinallyEnd = (LabelNode) markedReturn.getNext(); - Type nonLocalReturnType = InlineCodegenUtil.getReturnType(markedReturn.getOpcode()); + Type nonLocalReturnType = getReturnType(markedReturn.getOpcode()); //Generally there could be several tryCatch blocks (group) on one code interval (same start and end labels, but maybe different handlers) - // all of them refer to one try/*catches*/finally or try/catches. @@ -216,7 +215,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { finallyBlockCopy.visitLabel(insertedBlockEnd); //Copying finally body before non-local return instruction - InlineCodegenUtil.insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore); + insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore); updateExceptionTable(clusterBlocks, newFinallyStart, newFinallyEnd, tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info); @@ -251,7 +250,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { int depthShift ) { if (isInsOrJumpInsideFinally) { - if (InlineCodegenUtil.isFinallyMarker(currentIns.getNext())) { + if (isFinallyMarker(currentIns.getNext())) { Integer constant = getConstant(currentIns); finallyBlockCopy.visitLdcInsn(constant + depthShift); } else { @@ -455,7 +454,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor { AbstractInsnNode current = meaningful.getNext(); while (endFinallyChainExclusive != current) { current = current.getNext(); - if (InlineCodegenUtil.isFinallyEnd(current)) { + if (isFinallyEnd(current)) { Integer currentDepth = getConstant(current.getPrevious()); if (currentDepth.equals(finallyDepth)) { endFinallyChainExclusive = current.getNext(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt index 0a94c7cda45..117bbf6bef4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LambdaInfo.kt @@ -106,10 +106,10 @@ class DefaultLambda( override fun isMyLabel(name: String): Boolean = false override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) { - val classReader = InlineCodegenUtil.buildClassReaderByInternalName(codegen.state, lambdaClassType.internalName) + val classReader = buildClassReaderByInternalName(codegen.state, lambdaClassType.internalName) var isPropertyReference = false var isFunctionReference = false - classReader.accept(object: ClassVisitor(InlineCodegenUtil.API){ + classReader.accept(object: ClassVisitor(API){ override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array?) { isPropertyReference = superName?.startsWith("kotlin/jvm/internal/PropertyReference") ?: false isFunctionReference = "kotlin/jvm/internal/FunctionReference" == superName @@ -128,7 +128,7 @@ class DefaultLambda( } val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs) - val constructor = InlineCodegenUtil.getMethodNode( + val constructor = getMethodNode( classReader.b, "", descriptor, @@ -156,7 +156,7 @@ class DefaultLambda( codegen.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor ) - node = InlineCodegenUtil.getMethodNode( + node = getMethodNode( classReader.b, invokeMethod.name, invokeMethod.descriptor, @@ -271,11 +271,11 @@ class ExpressionLambda( val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor) val asmMethod = jvmMethodSignature.asmMethod val methodNode = MethodNode( - InlineCodegenUtil.API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, context.contextKind, codegen.state), + API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, context.contextKind, codegen.state), asmMethod.name, asmMethod.descriptor, null, null ) - node = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode).let { adapter -> + node = wrapWithMaxLocalCalc(methodNode).let { adapter -> val smap = InlineCodegen.generateMethodBody( adapter, invokeMethodDescriptor, context, functionWithBodyOrCallableReference, jvmMethodSignature, codegen, this ) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LocalVarRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LocalVarRemapper.kt index 92c82094094..847ccf6a4d8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LocalVarRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/LocalVarRemapper.kt @@ -103,7 +103,7 @@ class LocalVarRemapper(private val params: Parameters, private val additionalShi val remapInfo = remap(`var`) val value = remapInfo.value if (value is StackValue.Local) { - val isStore = InlineCodegenUtil.isStoreInstruction(opcode) + val isStore = isStoreInstruction(opcode) if (remapInfo.parameterInfo != null) { //All remapped value parameters can't be rewritten except case of default ones. //On remapping default parameter to actual value there is only one instruction that writes to it according to mask value diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodBodyVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodBodyVisitor.java index c9c11bcf753..2bd09333894 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodBodyVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodBodyVisitor.java @@ -23,10 +23,12 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.TypePath; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API; + public class MethodBodyVisitor extends InstructionAdapter { public MethodBodyVisitor(MethodVisitor mv) { - super(InlineCodegenUtil.API, mv); + super(API, mv); } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt index 4e1f320fff8..28f34955345 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.codegen.ClosureCodegen import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.* import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence @@ -87,7 +86,7 @@ class MethodInliner( transformedNode.instructions.resetLabels() val resultNode = MethodNode( - InlineCodegenUtil.API, transformedNode.access, transformedNode.name, transformedNode.desc, + API, transformedNode.access, transformedNode.name, transformedNode.desc, transformedNode.signature, transformedNode.exceptions?.toTypedArray() ) val visitor = RemapVisitor(resultNode, remapper, nodeRemapper) @@ -130,7 +129,7 @@ class MethodInliner( AsmTypeRemapper(remapper, result) ) - val markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node) + val markerShift = calcMarkerShift(parameters, node) val lambdaInliner = object : InlineAdapter(remappingMethodAdapter, parameters.argsSizeOnStack, sourceMapper) { private var transformationInfo: TransformationInfo? = null @@ -312,11 +311,11 @@ class MethodInliner( val realParametersSize = parameters.realParametersSizeOnStack val transformedNode = object : MethodNode( - InlineCodegenUtil.API, node.access, node.name, + API, node.access, node.name, Type.getMethodDescriptor(Type.getReturnType(node.desc), *(Type.getArgumentTypes(node.desc) + parameters.capturedTypes)), node.signature, node.exceptions?.toTypedArray() ) { - private val GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && inlineOnlySmapSkipper == null + private val GENERATE_DEBUG_INFO = GENERATE_SMAP && inlineOnlySmapSkipper == null private val isInliningLambda = nodeRemapper.isInsideInliningLambda @@ -343,8 +342,8 @@ class MethodInliner( } override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) { - if (InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL == owner) { - val index = name.substringAfter(InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL).toInt() + if (DEFAULT_LAMBDA_FAKE_CALL == owner) { + val index = name.substringAfter(DEFAULT_LAMBDA_FAKE_CALL).toInt() val lambda = getLambdaIfExists(index) as DefaultLambda lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach { (_, captured) -> @@ -362,7 +361,7 @@ class MethodInliner( name: String, desc: String, signature: String?, start: Label, end: Label, index: Int ) { if (isInliningLambda || GENERATE_DEBUG_INFO) { - val varSuffix = if (inliningContext.isRoot && !InlineCodegenUtil.isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else "" + val varSuffix = if (inliningContext.isRoot && !isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else "" val varName = if (!varSuffix.isEmpty() && name == "this") name + "_" else name super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index)) } @@ -400,9 +399,9 @@ class MethodInliner( awaitClassReification = true } else if (cur is MethodInsnNode) { - if (InlineCodegenUtil.isFinallyStart(cur)) { + if (isFinallyStart(cur)) { //TODO deep index calc could be more precise - currentFinallyDeep = InlineCodegenUtil.getConstant(cur.previous) + currentFinallyDeep = getConstant(cur.previous) } val owner = cur.owner @@ -668,7 +667,7 @@ class MethodInliner( insertBeforeInsn: AbstractInsnNode, sourceValueFrame: Frame ) { - assert(InlineCodegenUtil.isReturnOpcode(returnInsn.opcode)) { "return instruction expected" } + assert(isReturnOpcode(returnInsn.opcode)) { "return instruction expected" } assert(returnOpcode < 0 || returnOpcode == returnInsn.opcode) { "Return op should be " + Printer.OPCODES[returnOpcode] + ", got " + Printer.OPCODES[returnInsn.opcode] } returnOpcode = returnInsn.opcode @@ -771,9 +770,9 @@ class MethodInliner( var cur: AbstractInsnNode? = node.instructions.first while (cur != null) { - if (cur is MethodInsnNode && InlineCodegenUtil.isFinallyMarker(cur)) { + if (cur is MethodInsnNode && isFinallyMarker(cur)) { val constant = cur.previous - val curDeep = InlineCodegenUtil.getConstant(constant) + val curDeep = getConstant(constant) node.instructions.insert(constant, LdcInsnNode(curDeep + finallyDeepShift)) node.instructions.remove(constant) } @@ -829,9 +828,9 @@ class MethodInliner( val instructions = node.instructions var insnNode: AbstractInsnNode? = instructions.first while (insnNode != null) { - if (InlineCodegenUtil.isReturnOpcode(insnNode.opcode)) { + if (isReturnOpcode(insnNode.opcode)) { var isLocalReturn = true - val labelName = InlineCodegenUtil.getMarkedReturnLabelOrNull(insnNode) + val labelName = getMarkedReturnLabelOrNull(insnNode) if (labelName != null) { isLocalReturn = labelOwner.isMyLabel(labelName) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt index 4af07843a9e..1281ff84396 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt @@ -121,7 +121,7 @@ fun MethodNode.findCapturedFieldAssignmentInstructions(): Sequence(@JvmField val trans } fun createClassReader(): ClassReader { - return InlineCodegenUtil.buildClassReaderByInternalName(state, transformationInfo.oldClassName) + return buildClassReaderByInternalName(state, transformationInfo.oldClassName) } } @@ -64,7 +64,7 @@ class WhenMappingTransformer( /*MAPPING File could contains mappings for several enum classes, we should filter one*/ val methodNodes = arrayListOf() val fieldNode = transformationInfo.fieldNode - classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) { + classReader.accept(object : ClassVisitor(API, classBuilder.visitor) { override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array) { classBuilder.defineClass(null, version, access, name, signature, superName, interfaces) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt index 4eea63ad374..14c30767942 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RegeneratedLambdaFieldRemapper.kt @@ -17,8 +17,6 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.THIS import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode @@ -67,7 +65,7 @@ class RegeneratedLambdaFieldRemapper( val field = findFieldInSuper(fin) ?: //search in parent findFieldInSuper(FieldInsnNode( - Opcodes.GETSTATIC, originalLambdaInternalName, InlineCodegenUtil.`THIS$0`, + Opcodes.GETSTATIC, originalLambdaInternalName, THIS_0, Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor ))?.also { fromParent = true } ?: throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName") diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt index 82e5d6febd5..7d97370fd22 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -169,7 +169,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) ) = rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode -> if (stubCheckcast !is TypeInsnNode) return false - val newMethodNode = MethodNode(InlineCodegenUtil.API) + val newMethodNode = MethodNode(API) generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe) instructions.insert(insn, newMethodNode.instructions) @@ -189,7 +189,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) ) = rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode -> if (stubInstanceOf !is TypeInsnNode) return false - val newMethodNode = MethodNode(InlineCodegenUtil.API) + val newMethodNode = MethodNode(API) generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType) instructions.insert(insn, newMethodNode.instructions) @@ -231,14 +231,14 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) if (next3 is MethodInsnNode && next3.name == "valueOf") { instructions.remove(next1) next3.owner = parameter.internalName - next3.desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, true) + next3.desc = getSpecialEnumFunDescriptor(parameter, true) return true } } else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) { instructions.remove(next1) instructions.remove(next2) - val desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, false) + val desc = getSpecialEnumFunDescriptor(parameter, false) instructions.insert(insn, MethodInsnNode(Opcodes.INVOKESTATIC, parameter.internalName, "values", desc, false)) return true } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemapVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemapVisitor.java index 7a3a5cde79a..c55ded016fc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemapVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemapVisitor.java @@ -24,6 +24,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.CAPTURED_FIELD_FOLD_PREFIX; + public class RemapVisitor extends MethodBodyVisitor { private final LocalVarRemapper remapper; private final FieldRemapper nodeRemapper; @@ -59,7 +61,7 @@ public class RemapVisitor extends MethodBodyVisitor { @Override public void visitFieldInsn(int opcode, @NotNull String owner, @NotNull String name, @NotNull String desc) { - if (name.startsWith(InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX) && + if (name.startsWith(CAPTURED_FIELD_FOLD_PREFIX) && (nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot())) { FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc); StackValue inline = nodeRemapper.getFieldForInline(fin, null); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TryBlockClustering.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TryBlockClustering.kt index 0d7dace4642..14b00cad736 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TryBlockClustering.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TryBlockClustering.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.codegen.inline -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.firstLabelInChain import org.jetbrains.org.objectweb.asm.tree.LabelNode import org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt index 46326c066a1..25ca818be39 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/defaultMethodUtil.kt @@ -18,8 +18,6 @@ package org.jetbrains.kotlin.codegen.inline import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.OwnerKind -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getConstant import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.isNeedClassReificationMarker import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.optimization.common.asSequence diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.kt index 9989a3365d3..38b5f0a3268 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/RedundantBoxingMethodTransformer.kt @@ -17,7 +17,8 @@ package org.jetbrains.kotlin.codegen.optimization.boxing import com.intellij.openapi.util.Pair -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.getInsnOpcodeText +import org.jetbrains.kotlin.codegen.inline.getInsnText import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue import org.jetbrains.kotlin.codegen.optimization.common.* @@ -324,7 +325,7 @@ class RedundantBoxingMethodTransformer : MethodTransformer() { } private fun throwCannotAdaptInstruction(insn: AbstractInsnNode): Nothing = - throw AssertionError("Cannot adapt instruction: ${InlineCodegenUtil.getInsnText(insn)}") + throw AssertionError("Cannot adapt instruction: ${getInsnText(insn)}") private fun adaptAreEqualIntrinsic( node: MethodNode, @@ -392,7 +393,7 @@ class RedundantBoxingMethodTransformer : MethodTransformer() { next.getOpcode() == Opcodes.IFNE -> insertBefore(insn, JumpInsnNode(ifNotEqualOpcode, nextLabel)) else -> - throw AssertionError("IFEQ or IFNE expected: " + InlineCodegenUtil.getInsnOpcodeText(next)) + throw AssertionError("IFEQ or IFNE expected: " + getInsnOpcodeText(next)) } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/MethodAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/MethodAnalyzer.kt index 5b48e5597cd..c8815fe7064 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/MethodAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/MethodAnalyzer.kt @@ -46,7 +46,7 @@ package org.jetbrains.kotlin.codegen.optimization.common -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.getInsnText import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.tree.* @@ -146,10 +146,10 @@ open class MethodAnalyzer( } catch (e: AnalyzerException) { - throw AnalyzerException(e.node, "Error at instruction #" + insn + " ${InlineCodegenUtil.getInsnText(insnNode)}: " + e.message, e) + throw AnalyzerException(e.node, "Error at instruction #" + insn + " ${getInsnText(insnNode)}: " + e.message, e) } catch (e: Exception) { - throw AnalyzerException(insnNode, "Error at instruction #" + insn + " ${InlineCodegenUtil.getInsnText(insnNode)}: " + e.message, e) + throw AnalyzerException(insnNode, "Error at instruction #" + insn + " ${getInsnText(insnNode)}: " + e.message, e) } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java index 8ca813e02b5..5d9c9abeff6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/OptimizationBasicInterpreter.java @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen.optimization.common; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.AsmUtil; -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil; import org.jetbrains.org.objectweb.asm.Handle; import org.jetbrains.org.objectweb.asm.Opcodes; import org.jetbrains.org.objectweb.asm.Type; @@ -30,6 +29,7 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter; import java.util.List; +import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getInsnOpcodeText; import static org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue.*; public class OptimizationBasicInterpreter extends Interpreter implements Opcodes { @@ -137,7 +137,7 @@ public class OptimizationBasicInterpreter extends Interpreter implem case NEW: return newValue(Type.getObjectType(((TypeInsnNode) insn).desc)); default: - throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn)); + throw new IllegalArgumentException("Unexpected instruction: " + getInsnOpcodeText(insn)); } } @@ -222,7 +222,7 @@ public class OptimizationBasicInterpreter extends Interpreter implem case PUTFIELD: return null; default: - throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn)); + throw new IllegalArgumentException("Unexpected instruction: " + getInsnOpcodeText(insn)); } } @@ -341,7 +341,7 @@ public class OptimizationBasicInterpreter extends Interpreter implem case IFNONNULL: return null; default: - throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn)); + throw new IllegalArgumentException("Unexpected instruction: " + getInsnOpcodeText(insn)); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt index 273961c7319..ed38a82d328 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt @@ -16,7 +16,7 @@ package org.jetbrains.kotlin.codegen.optimization.common -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.getInsnText import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes.* @@ -176,7 +176,7 @@ fun insnListOf(vararg insns: AbstractInsnNode) = InsnList().apply { insns.forEac fun AbstractInsnNode.isStoreOperation(): Boolean = opcode in Opcodes.ISTORE..Opcodes.ASTORE fun AbstractInsnNode.isLoadOperation(): Boolean = opcode in Opcodes.ILOAD..Opcodes.ALOAD -val AbstractInsnNode?.insnText get() = InlineCodegenUtil.getInsnText(this) +val AbstractInsnNode?.insnText get() = getInsnText(this) val AbstractInsnNode?.debugText get() = if (this == null) "" else "${this::class.java.simpleName}: $insnText" diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt index 1d5ea660159..550e228958a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackAnalyzer.kt @@ -17,7 +17,9 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack import com.intellij.util.containers.Stack -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker +import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker +import org.jetbrains.kotlin.codegen.inline.isMarkedReturn import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn @@ -103,11 +105,11 @@ internal class FixStackAnalyzer( executeSaveStackBeforeTry(insn) PseudoInsn.RESTORE_STACK_IN_TRY_CATCH.isa(insn) -> executeRestoreStackInTryCatch(insn) - InlineCodegenUtil.isBeforeInlineMarker(insn) -> + isBeforeInlineMarker(insn) -> executeBeforeInlineCallMarker(insn) - InlineCodegenUtil.isAfterInlineMarker(insn) -> + isAfterInlineMarker(insn) -> executeAfterInlineCallMarker(insn) - InlineCodegenUtil.isMarkedReturn(insn) -> { + isMarkedReturn(insn) -> { // KT-9644: might throw "Incompatible return type" on non-local return, in fact we don't care. if (insn.opcode == Opcodes.RETURN) return } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackContext.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackContext.kt index d7a2620cde6..cb8f1edceed 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackContext.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackContext.kt @@ -18,7 +18,8 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack import com.intellij.util.SmartList import com.intellij.util.containers.Stack -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker +import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn import org.jetbrains.kotlin.codegen.pseudoInsns.parsePseudoInsnOrNull @@ -56,10 +57,10 @@ internal class FixStackContext(val methodNode: MethodNode) { visitFakeAlwaysTrueIfeq(insnNode) pseudoInsn == PseudoInsn.FAKE_ALWAYS_FALSE_IFEQ -> visitFakeAlwaysFalseIfeq(insnNode) - InlineCodegenUtil.isBeforeInlineMarker(insnNode) -> { + isBeforeInlineMarker(insnNode) -> { inlineMarkersStack.push(insnNode) } - InlineCodegenUtil.isAfterInlineMarker(insnNode) -> { + isAfterInlineMarker(insnNode) -> { assert(inlineMarkersStack.isNotEmpty()) { "Mismatching after inline method marker at ${indexOf(insnNode)}" } openingInlineMethodMarker[insnNode] = inlineMarkersStack.pop() } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackMethodTransformer.kt index f9bc09d7bc0..6e522cce862 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/fixStack/FixStackMethodTransformer.kt @@ -16,7 +16,9 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker +import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker +import org.jetbrains.kotlin.codegen.inline.isInlineMarker import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn @@ -33,7 +35,7 @@ class FixStackMethodTransformer : MethodTransformer() { // If inline method markers are inconsistent, remove them now if (!context.consistentInlineMarkers) { InsnSequence(methodNode.instructions).forEach { insnNode -> - if (InlineCodegenUtil.isInlineMarker(insnNode)) + if (isInlineMarker(insnNode)) methodNode.instructions.remove(insnNode) } } @@ -131,9 +133,9 @@ class FixStackMethodTransformer : MethodTransformer() { transformSaveStackMarker(methodNode, actions, analyzer, marker, localVariablesManager) pseudoInsn == PseudoInsn.RESTORE_STACK_IN_TRY_CATCH -> transformRestoreStackMarker(methodNode, actions, marker, localVariablesManager) - InlineCodegenUtil.isBeforeInlineMarker(marker) -> + isBeforeInlineMarker(marker) -> transformBeforeInlineCallMarker(methodNode, actions, analyzer, marker, localVariablesManager) - InlineCodegenUtil.isAfterInlineMarker(marker) -> + isAfterInlineMarker(marker) -> transformAfterInlineCallMarker(methodNode, actions, analyzer, marker, localVariablesManager) } } diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt b/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt index d6bc6c0adb0..c8a0ab48610 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import org.jetbrains.kotlin.backend.common.output.OutputFile -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.GENERATE_SMAP import org.jetbrains.kotlin.codegen.inline.RangeMapping import org.jetbrains.kotlin.codegen.inline.SMAPParser import org.jetbrains.kotlin.codegen.inline.toRange @@ -61,7 +61,7 @@ object SMAPTestUtil { } fun checkSMAP(inputFiles: List, outputFiles: Iterable) { - if (!InlineCodegenUtil.GENERATE_SMAP) return + if (!GENERATE_SMAP) return val sourceData = inputFiles.mapNotNull { extractSmapFromTestDataFile(it) } val compiledSmaps = extractSMAPFromClasses(outputFiles) diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index 9ef244e89fc..042057d804f 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.cli.js.K2JSCompiler import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.GENERATE_SMAP import org.jetbrains.kotlin.config.KotlinCompilerVersion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PackageViewDescriptor @@ -433,7 +433,7 @@ class CompileKotlinAgainstCustomBinariesTest : TestCaseWithTmpdir() { *E """.trimIndent() + "\n" - if (InlineCodegenUtil.GENERATE_SMAP) { + if (GENERATE_SMAP) { assertEquals(expected, debugInfo) } else { diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinStackFrame.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinStackFrame.kt index 40570111ded..15694b479fe 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinStackFrame.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinStackFrame.kt @@ -21,12 +21,12 @@ import com.intellij.debugger.jdi.LocalVariableProxyImpl import com.intellij.debugger.jdi.StackFrameProxyImpl import com.intellij.debugger.ui.impl.watch.MethodsTracker import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.isFakeLocalVariableForInline class KotlinStackFrame(frame: StackFrameProxyImpl) : JavaStackFrame(StackFrameDescriptorImpl(frame, MethodsTracker()), true) { override fun getVisibleVariables(): List? { return super.getVisibleVariables().filter { - !InlineCodegenUtil.isFakeLocalVariableForInline(it.name()) + !isFakeLocalVariableForInline(it.name()) } } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt index b974d799396..68b3c0c5c3e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt @@ -29,7 +29,7 @@ import com.intellij.util.containers.ConcurrentWeakFactoryMap import com.intellij.util.containers.ContainerUtil import com.sun.jdi.Location import com.sun.jdi.ReferenceType -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.API import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches import org.jetbrains.kotlin.idea.refactoring.getLineCount @@ -199,7 +199,7 @@ private fun findClassFileByPath(packageName: String, className: String, outputDi private fun readLineNumberTableMapping(bytes: ByteArray): Map>> { val lineNumberMapping = HashMap>>() - ClassReader(bytes).accept(object : ClassVisitor(InlineCodegenUtil.API) { + ClassReader(bytes).accept(object : ClassVisitor(API) { override fun visitMethod(access: Int, name: String?, desc: String?, signature: String?, exceptions: Array?): MethodVisitor? { if (name == null || desc == null) { return null diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt index 2d85efcc61a..cefc45ca1ad 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/FrameVisitor.kt @@ -26,7 +26,8 @@ import org.jetbrains.eval4j.jdi.asJdiValue import org.jetbrains.eval4j.jdi.asValue import org.jetbrains.eval4j.obj import org.jetbrains.kotlin.codegen.AsmUtil -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil +import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX +import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX import org.jetbrains.kotlin.idea.debugger.isInsideInlineFunctionBody import org.jetbrains.kotlin.idea.debugger.numberOfInlinedFunctions import org.jetbrains.kotlin.idea.util.application.runReadAction @@ -128,12 +129,12 @@ class FrameVisitor(context: EvaluationContextImpl) { } private fun findLocalVariableForInlineArgument(name: String, number: Int, asmType: Type?, checkType: Boolean): Value? { - return findLocalVariable(name + InlineCodegenUtil.INLINE_FUN_VAR_SUFFIX.repeat(number), asmType, checkType) + return findLocalVariable(name + INLINE_FUN_VAR_SUFFIX.repeat(number), asmType, checkType) } private fun isFunctionType(type: Type?): Boolean { return type?.sort == Type.OBJECT && - type.internalName.startsWith(InlineCodegenUtil.NUMBERED_FUNCTION_PREFIX) + type.internalName.startsWith(NUMBERED_FUNCTION_PREFIX) } private fun findLocalVariable(name: String, asmType: Type?, checkType: Boolean): Value? { diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/smapUtil.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/smapUtil.kt index b9c1fc426a8..22c5559b61f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/smapUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/smapUtil.kt @@ -18,8 +18,8 @@ package org.jetbrains.kotlin.idea.debugger import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.codegen.inline.API import org.jetbrains.kotlin.codegen.inline.FileMapping -import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil import org.jetbrains.kotlin.codegen.inline.SMAP import org.jetbrains.kotlin.codegen.inline.SMAPParser import org.jetbrains.kotlin.psi.KtFile @@ -62,7 +62,7 @@ fun mapStacktraceLineToSource(smapData: SmapData, fun readDebugInfo(bytes: ByteArray): SmapData? { val cr = ClassReader(bytes) var debugInfo: String? = null - cr.accept(object : ClassVisitor(InlineCodegenUtil.API) { + cr.accept(object : ClassVisitor(API) { override fun visitSource(source: String?, debug: String?) { debugInfo = debug }