Signature remapping moved to RemappingSignatureAdapter inside TypeRemapper

This commit is contained in:
Michael Bogdanov
2015-12-22 14:20:04 +03:00
parent dd336a5581
commit cb41f1cc2a
8 changed files with 99 additions and 59 deletions
@@ -89,12 +89,6 @@ public class AnonymousObjectTransformer {
@Override @Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) { public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version); 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); super.visit(version, access, name, signature, superName, interfaces);
} }
@@ -350,7 +344,11 @@ public class AnonymousObjectTransformer {
@NotNull @NotNull
private ClassBuilder createClassBuilder() { private ClassBuilder createClassBuilder() {
ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile()); 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 @NotNull
@@ -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]
}
}
}
@@ -86,6 +86,7 @@ public class InlineCodegen extends CallGenerator {
private final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>(); private final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
private final ReifiedTypeInliner reifiedTypeInliner; private final ReifiedTypeInliner reifiedTypeInliner;
@Nullable private final TypeParameterMappings typeParameterMappings;
private LambdaInfo activeLambda; private LambdaInfo activeLambda;
@@ -105,6 +106,7 @@ public class InlineCodegen extends CallGenerator {
this.codegen = codegen; this.codegen = codegen;
this.callElement = callElement; this.callElement = callElement;
this.functionDescriptor = functionDescriptor.getOriginal(); this.functionDescriptor = functionDescriptor.getOriginal();
this.typeParameterMappings = typeParameterMappings;
reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings); reifiedTypeInliner = new ReifiedTypeInliner(typeParameterMappings);
@@ -267,7 +269,8 @@ public class InlineCodegen extends CallGenerator {
.subGenerator(functionDescriptor.getName().asString()), .subGenerator(functionDescriptor.getName().asString()),
codegen.getContext(), codegen.getContext(),
callElement, callElement,
codegen.getParentCodegen().getClassName(), reifiedTypeInliner); codegen.getParentCodegen().getClassName(), reifiedTypeInliner,
typeParameterMappings);
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule, MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
"Method inlining " + callElement.getText(), "Method inlining " + callElement.getText(),
@@ -154,8 +154,12 @@ public class MethodInliner {
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator(); final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping); final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode, RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
remapper); resultNode.access,
resultNode.desc,
resultNode,
new AsmTypeRemapper(remapper, inliningContext.getRoot().typeParameterMappings, result)
);
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node); final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) { InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
@@ -27,8 +27,6 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.signature.SignatureReader
import org.jetbrains.org.objectweb.asm.signature.SignatureWriter
import org.jetbrains.org.objectweb.asm.tree.* import org.jetbrains.org.objectweb.asm.tree.*
private class ParameterNameAndNullability(val name: String, val nullable: Boolean) private class ParameterNameAndNullability(val name: String, val nullable: Boolean)
@@ -94,44 +92,6 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
return result 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 * @return new type parameter identifier if this marker should be reified further
* or null if it shouldn't * or null if it shouldn't
@@ -52,7 +52,10 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
@Nullable String signature, @Nullable String signature,
@Nullable Object value @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 @Override
@@ -65,9 +68,11 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
@Nullable String signature, @Nullable String signature,
@Nullable String[] exceptions @Nullable String[] exceptions
) { ) {
return new RemappingMethodAdapter(access, desc, return new RemappingMethodAdapter(
builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), signature, exceptions), access, desc,
remapper); builder.newMethod(origin, access, name, remapper.mapMethodDesc(desc), remapper.mapSignature(signature, false), exceptions),
remapper
);
} }
@Override @Override
@@ -81,5 +86,4 @@ public class RemappingClassBuilder extends DelegatingClassBuilder {
public ClassVisitor getVisitor() { public ClassVisitor getVisitor() {
return new RemappingClassAdapter(builder.getVisitor(), remapper); return new RemappingClassAdapter(builder.getVisitor(), remapper);
} }
} }
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen.inline; package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.psi.KtElement;
@@ -26,6 +27,7 @@ import java.util.Map;
public class RootInliningContext extends InliningContext { public class RootInliningContext extends InliningContext {
public final CodegenContext startContext; public final CodegenContext startContext;
private final String classNameToInline; private final String classNameToInline;
public final TypeParameterMappings typeParameterMappings;
public final KtElement callElement; public final KtElement callElement;
public RootInliningContext( public RootInliningContext(
@@ -35,12 +37,14 @@ public class RootInliningContext extends InliningContext {
@NotNull CodegenContext startContext, @NotNull CodegenContext startContext,
@NotNull KtElement callElement, @NotNull KtElement callElement,
@NotNull String classNameToInline, @NotNull String classNameToInline,
@NotNull ReifiedTypeInliner inliner @NotNull ReifiedTypeInliner inliner,
@Nullable TypeParameterMappings typeParameterMappings
) { ) {
super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false); super(null, map, state, nameGenerator, TypeRemapper.createEmpty(), inliner, false, false);
this.callElement = callElement; this.callElement = callElement;
this.startContext = startContext; this.startContext = startContext;
this.classNameToInline = classNameToInline; this.classNameToInline = classNameToInline;
this.typeParameterMappings = typeParameterMappings;
} }
@Override @Override
@@ -17,12 +17,11 @@
package org.jetbrains.kotlin.codegen.inline; package org.jetbrains.kotlin.codegen.inline;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.commons.Remapper;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class TypeRemapper extends Remapper { public class TypeRemapper {
//typeMapping field could be changed outside through method processing //typeMapping field could be changed outside through method processing
private final Map<String, String> typeMapping; private final Map<String, String> typeMapping;
@@ -60,7 +59,6 @@ public class TypeRemapper extends Remapper {
return typeMapping.containsKey(type); return typeMapping.containsKey(type);
} }
@Override
public String map(String type) { public String map(String type) {
String newType = typeMapping.get(type); String newType = typeMapping.get(type);
if (newType != null) { if (newType != null) {