diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java index 5e52ca69f12..395dc9597c5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java @@ -89,12 +89,6 @@ public class AnonymousObjectTransformer { @Override public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) { InlineCodegenUtil.assertVersionNotGreaterThanJava6(version); - - if (signature != null) { - ReifiedTypeInliner.SignatureReificationResult signatureResult = inliningContext.reifedTypeInliner.reifySignature(signature); - signature = signatureResult.getNewSignature(); - transformationResult.getReifiedTypeParametersUsages().mergeAll(signatureResult.getTypeParametersUsages()); - } super.visit(version, access, name, signature, superName, interfaces); } @@ -350,7 +344,11 @@ public class AnonymousObjectTransformer { @NotNull private ClassBuilder createClassBuilder() { ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile()); - return new RemappingClassBuilder(classBuilder, inliningContext.typeRemapper); + + return new RemappingClassBuilder( + classBuilder, + new AsmTypeRemapper(inliningContext.typeRemapper, inliningContext.getRoot().typeParameterMappings, transformationResult) + ); } @NotNull diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AsmTypeRemapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AsmTypeRemapper.kt new file mode 100644 index 00000000000..2b454812a3f --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AsmTypeRemapper.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.codegen.inline + +import org.jetbrains.org.objectweb.asm.commons.Remapper +import org.jetbrains.org.objectweb.asm.commons.RemappingSignatureAdapter +import org.jetbrains.org.objectweb.asm.signature.SignatureReader +import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor + +class AsmTypeRemapper(val typeRemapper: TypeRemapper, val mappings: TypeParameterMappings?, val result: InlineResult) : Remapper() { + + override fun map(type: String): String { + return typeRemapper.map(type) + } + + + override fun createRemappingSignatureAdapter(v: SignatureVisitor?): SignatureVisitor { + if (mappings == null) { + //don't remap default generation + return super.createRemappingSignatureAdapter(v); + } + + return object : RemappingSignatureAdapter(v, this) { + + override fun visitTypeVariable(name: String) { + val mapping = getMappingByName(name) ?: + return super.visitTypeVariable(name) + + if (mapping.newName != null) { + if (mapping.isReified) { + result.reifiedTypeParametersUsages.addUsedReifiedParameter(mapping.newName) + } + return super.visitTypeVariable(mapping.newName) + } + // else TypeVariable is replaced by concrete type + SignatureReader(mapping.signature).accept(this) + } + + override fun visitFormalTypeParameter(name: String) { + val mapping: TypeParameterMapping = getMappingByName(name) ?: + return super.visitFormalTypeParameter(name) + if (mapping.newName != null ) { + if (mapping.isReified) { + result.reifiedTypeParametersUsages.addUsedReifiedParameter(mapping.newName) + } + super.visitFormalTypeParameter(mapping.newName) + } + } + + private fun getMappingByName(name: String): TypeParameterMapping? = mappings[name] + } + } + + +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index 21a84e21b3c..a3edccd9b30 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -86,6 +86,7 @@ public class InlineCodegen extends CallGenerator { private final Map expressionMap = new HashMap(); private final ReifiedTypeInliner reifiedTypeInliner; + @Nullable private final TypeParameterMappings typeParameterMappings; private LambdaInfo activeLambda; @@ -105,6 +106,7 @@ public class InlineCodegen extends CallGenerator { this.codegen = codegen; this.callElement = callElement; this.functionDescriptor = functionDescriptor.getOriginal(); + this.typeParameterMappings = typeParameterMappings; reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings); @@ -267,7 +269,8 @@ public class InlineCodegen extends CallGenerator { .subGenerator(functionDescriptor.getName().asString()), codegen.getContext(), callElement, - codegen.getParentCodegen().getClassName(), reifiedTypeInliner); + codegen.getParentCodegen().getClassName(), reifiedTypeInliner, + typeParameterMappings); MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule, "Method inlining " + callElement.getText(), diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java index 8606a0cffea..c5e137dd082 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java @@ -154,8 +154,12 @@ public class MethodInliner { final Iterator iterator = anonymousObjectGenerations.iterator(); final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping); - RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode, - remapper); + RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter( + resultNode.access, + resultNode.desc, + resultNode, + new AsmTypeRemapper(remapper, inliningContext.getRoot().typeParameterMappings, result) + ); final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node); InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) { 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 f77d9e86361..707170c716b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -27,8 +27,6 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -import org.jetbrains.org.objectweb.asm.signature.SignatureReader -import org.jetbrains.org.objectweb.asm.signature.SignatureWriter import org.jetbrains.org.objectweb.asm.tree.* private class ParameterNameAndNullability(val name: String, val nullable: Boolean) @@ -94,44 +92,6 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) return result } - - fun reifySignature(oldSignature: String): SignatureReificationResult { - if (!hasReifiedParameters) return SignatureReificationResult(oldSignature, ReifiedTypeParametersUsages()) - - - val signatureRemapper = object : SignatureWriter() { - var typeParamsToReify = ReifiedTypeParametersUsages() - override fun visitTypeVariable(name: String?) { - val mapping = getMappingByName(name) ?: - return super.visitTypeVariable(name) - if (mapping.newName != null) { - typeParamsToReify.addUsedReifiedParameter(mapping.newName) - return super.visitTypeVariable(mapping.newName) - } - - // else TypeVariable is replaced by concrete type - SignatureReader(mapping.signature).accept(this) - } - - override fun visitFormalTypeParameter(name: String?) { - val mapping = getMappingByName(name) ?: - return super.visitFormalTypeParameter(name) - if (mapping.newName != null) { - typeParamsToReify.addUsedReifiedParameter(mapping.newName) - super.visitFormalTypeParameter(mapping.newName) - } - } - - private fun getMappingByName(name: String?) = parametersMapping!![name!!] - } - - SignatureReader(oldSignature).accept(signatureRemapper) - - return SignatureReificationResult(signatureRemapper.toString(), signatureRemapper.typeParamsToReify) - } - - data class SignatureReificationResult(val newSignature: String, val typeParametersUsages: ReifiedTypeParametersUsages) - /** * @return new type parameter identifier if this marker should be reified further * or null if it shouldn't diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemappingClassBuilder.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemappingClassBuilder.java index fc97cb4159e..27925b6872c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemappingClassBuilder.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RemappingClassBuilder.java @@ -52,7 +52,10 @@ public class RemappingClassBuilder extends DelegatingClassBuilder { @Nullable String signature, @Nullable Object value ) { - return new RemappingFieldAdapter(builder.newField(origin, access, name, remapper.mapDesc(desc), signature, value), remapper); + return new RemappingFieldAdapter( + builder.newField(origin, access, name, remapper.mapDesc(desc), remapper.mapSignature(signature, true), value), + remapper + ); } @Override @@ -65,9 +68,11 @@ public class RemappingClassBuilder extends DelegatingClassBuilder { @Nullable String signature, @Nullable String[] exceptions ) { - return new RemappingMethodAdapter(access, desc, - builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), signature, exceptions), - remapper); + return new RemappingMethodAdapter( + access, desc, + builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), remapper.mapSignature(signature, false), exceptions), + remapper + ); } @Override @@ -81,5 +86,4 @@ public class RemappingClassBuilder extends DelegatingClassBuilder { public ClassVisitor getVisitor() { return new RemappingClassAdapter(builder.getVisitor(), remapper); } - } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java index 22940a9ea2d..62eccaee7f2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.codegen.inline; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.psi.KtElement; @@ -26,6 +27,7 @@ import java.util.Map; public class RootInliningContext extends InliningContext { public final CodegenContext startContext; private final String classNameToInline; + public final TypeParameterMappings typeParameterMappings; public final KtElement callElement; public RootInliningContext( @@ -35,12 +37,14 @@ public class RootInliningContext extends InliningContext { @NotNull CodegenContext startContext, @NotNull KtElement callElement, @NotNull String classNameToInline, - @NotNull ReifiedTypeInliner inliner + @NotNull ReifiedTypeInliner inliner, + @Nullable TypeParameterMappings typeParameterMappings ) { super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false); this.callElement = callElement; this.startContext = startContext; this.classNameToInline = classNameToInline; + this.typeParameterMappings = typeParameterMappings; } @Override diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TypeRemapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TypeRemapper.java index ea3923c18f7..4a7e0de3005 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TypeRemapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/TypeRemapper.java @@ -17,12 +17,11 @@ package org.jetbrains.kotlin.codegen.inline; import org.jetbrains.annotations.NotNull; -import org.jetbrains.org.objectweb.asm.commons.Remapper; import java.util.HashMap; import java.util.Map; -public class TypeRemapper extends Remapper { +public class TypeRemapper { //typeMapping field could be changed outside through method processing private final Map typeMapping; @@ -60,7 +59,6 @@ public class TypeRemapper extends Remapper { return typeMapping.containsKey(type); } - @Override public String map(String type) { String newType = typeMapping.get(type); if (newType != null) {