Introduced base class for AnonymousObjectGeneration
This commit is contained in:
+10
-5
@@ -24,7 +24,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AnonymousObjectGeneration {
|
||||
public class AnonymousObjectRegenerationInfo extends RegenerationInfo {
|
||||
|
||||
private final String ownerInternalName;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class AnonymousObjectGeneration {
|
||||
private final boolean alreadyRegenerated;
|
||||
private final boolean isStaticOrigin;
|
||||
|
||||
AnonymousObjectGeneration(
|
||||
AnonymousObjectRegenerationInfo(
|
||||
@NotNull String ownerInternalName,
|
||||
boolean needReification,
|
||||
@NotNull Map<Integer, LambdaInfo> lambdasToInline,
|
||||
@@ -63,7 +63,7 @@ public class AnonymousObjectGeneration {
|
||||
this.isStaticOrigin = isStaticOrigin;
|
||||
}
|
||||
|
||||
public AnonymousObjectGeneration(
|
||||
public AnonymousObjectRegenerationInfo(
|
||||
@NotNull String ownerInternalName, boolean needReification,
|
||||
boolean alreadyRegenerated,
|
||||
boolean isStaticOrigin
|
||||
@@ -74,10 +74,13 @@ public class AnonymousObjectGeneration {
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getOldClassName() {
|
||||
return ownerInternalName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRegenerate(boolean isSameModule) {
|
||||
return !alreadyRegenerated && (
|
||||
!lambdasToInline.isEmpty() || !isSameModule || capturedOuterRegenerated || needReification
|
||||
@@ -88,8 +91,10 @@ public class AnonymousObjectGeneration {
|
||||
return lambdasToInline;
|
||||
}
|
||||
|
||||
public Type getNewLambdaType() {
|
||||
return newLambdaType;
|
||||
@NotNull
|
||||
@Override
|
||||
public String getNewClassName() {
|
||||
return newLambdaType.getInternalName();
|
||||
}
|
||||
|
||||
public void setNewLambdaType(Type newLambdaType) {
|
||||
+28
-43
@@ -34,14 +34,12 @@ import java.util.*;
|
||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.isThis0;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||
|
||||
public class AnonymousObjectTransformer {
|
||||
public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjectRegenerationInfo> {
|
||||
|
||||
protected final GenerationState state;
|
||||
|
||||
protected final KotlinTypeMapper typeMapper;
|
||||
|
||||
private final InlineResult transformationResult;
|
||||
|
||||
private MethodNode constructor;
|
||||
|
||||
private String sourceInfo;
|
||||
@@ -56,36 +54,33 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
private final Type newLambdaType;
|
||||
|
||||
private final ClassReader reader;
|
||||
|
||||
private final boolean isSameModule;
|
||||
|
||||
private final Map<String, List<String>> fieldNames = new HashMap<String, List<String>>();
|
||||
|
||||
public AnonymousObjectTransformer(
|
||||
@NotNull String objectInternalName,
|
||||
@NotNull AnonymousObjectRegenerationInfo regenerationInfo,
|
||||
@NotNull InliningContext inliningContext,
|
||||
boolean isSameModule,
|
||||
@NotNull Type newLambdaType
|
||||
) {
|
||||
super(regenerationInfo, inliningContext.state);
|
||||
this.isSameModule = isSameModule;
|
||||
this.state = inliningContext.state;
|
||||
this.typeMapper = state.getTypeMapper();
|
||||
this.inliningContext = inliningContext;
|
||||
this.oldObjectType = Type.getObjectType(objectInternalName);
|
||||
this.oldObjectType = Type.getObjectType(regenerationInfo.getOldClassName());
|
||||
this.newLambdaType = newLambdaType;
|
||||
|
||||
reader = InlineCodegenUtil.buildClassReaderByInternalName(state, objectInternalName);
|
||||
transformationResult = InlineResult.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public InlineResult doTransform(@NotNull AnonymousObjectGeneration anonymousObjectGen, @NotNull FieldRemapper parentRemapper) {
|
||||
public InlineResult doTransform(@NotNull AnonymousObjectRegenerationInfo regenerationInfo, @NotNull FieldRemapper parentRemapper) {
|
||||
final List<InnerClassNode> innerClassNodes = new ArrayList<InnerClassNode>();
|
||||
ClassBuilder classBuilder = createClassBuilder();
|
||||
ClassBuilder classBuilder = createRemappingClassBuilderViaFactory(inliningContext);
|
||||
final List<MethodNode> methodsToTransform = new ArrayList<MethodNode>();
|
||||
|
||||
reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
|
||||
createClassReader().accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version, name);
|
||||
@@ -160,13 +155,13 @@ public class AnonymousObjectTransformer {
|
||||
ParametersBuilder constructorParamBuilder = ParametersBuilder.newBuilder();
|
||||
List<CapturedParamInfo> additionalFakeParams =
|
||||
extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder,
|
||||
anonymousObjectGen, parentRemapper);
|
||||
regenerationInfo, parentRemapper);
|
||||
List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();
|
||||
|
||||
for (MethodNode next : methodsToTransform) {
|
||||
MethodVisitor deferringVisitor = newMethod(classBuilder, next);
|
||||
InlineResult funResult =
|
||||
inlineMethodAndUpdateGlobalResult(anonymousObjectGen, parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false);
|
||||
inlineMethodAndUpdateGlobalResult(regenerationInfo, parentRemapper, deferringVisitor, next, allCapturedParamBuilder, false);
|
||||
|
||||
Type returnType = Type.getReturnType(next.desc);
|
||||
if (!AsmUtil.isPrimitive(returnType)) {
|
||||
@@ -183,7 +178,7 @@ public class AnonymousObjectTransformer {
|
||||
method.visitEnd();
|
||||
}
|
||||
|
||||
generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, anonymousObjectGen, parentRemapper, additionalFakeParams);
|
||||
generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, regenerationInfo, parentRemapper, additionalFakeParams);
|
||||
|
||||
SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder);
|
||||
|
||||
@@ -196,7 +191,7 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
classBuilder.done();
|
||||
|
||||
anonymousObjectGen.setNewLambdaType(newLambdaType);
|
||||
regenerationInfo.setNewLambdaType(newLambdaType);
|
||||
return transformationResult;
|
||||
}
|
||||
|
||||
@@ -207,14 +202,14 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
@NotNull
|
||||
private InlineResult inlineMethodAndUpdateGlobalResult(
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGen,
|
||||
@NotNull AnonymousObjectRegenerationInfo regenerationInfo,
|
||||
@NotNull FieldRemapper parentRemapper,
|
||||
@NotNull MethodVisitor deferringVisitor,
|
||||
@NotNull MethodNode next,
|
||||
@NotNull ParametersBuilder allCapturedParamBuilder,
|
||||
boolean isConstructor
|
||||
) {
|
||||
InlineResult funResult = inlineMethod(anonymousObjectGen, parentRemapper, deferringVisitor, next, allCapturedParamBuilder, isConstructor);
|
||||
InlineResult funResult = inlineMethod(regenerationInfo, parentRemapper, deferringVisitor, next, allCapturedParamBuilder, isConstructor);
|
||||
transformationResult.addAllClassesToRemove(funResult);
|
||||
transformationResult.getReifiedTypeParametersUsages().mergeAll(funResult.getReifiedTypeParametersUsages());
|
||||
return funResult;
|
||||
@@ -222,7 +217,7 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
@NotNull
|
||||
private InlineResult inlineMethod(
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGen,
|
||||
@NotNull AnonymousObjectRegenerationInfo regenerationInfo,
|
||||
@NotNull FieldRemapper parentRemapper,
|
||||
@NotNull MethodVisitor deferringVisitor,
|
||||
@NotNull MethodNode sourceNode,
|
||||
@@ -234,7 +229,7 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
RegeneratedLambdaFieldRemapper remapper =
|
||||
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
||||
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
||||
parameters, regenerationInfo.getCapturedLambdasToInline(),
|
||||
parentRemapper, isConstructor);
|
||||
|
||||
MethodInliner inliner =
|
||||
@@ -244,12 +239,12 @@ public class AnonymousObjectTransformer {
|
||||
inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper,
|
||||
isSameModule,
|
||||
"Transformer for " + anonymousObjectGen.getOldClassName(),
|
||||
"Transformer for " + regenerationInfo.getOldClassName(),
|
||||
sourceMapper,
|
||||
new InlineCallSiteInfo(
|
||||
anonymousObjectGen.getOldClassName(),
|
||||
regenerationInfo.getOldClassName(),
|
||||
sourceNode.name,
|
||||
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc),
|
||||
isConstructor ? regenerationInfo.getNewConstructorDescriptor() : sourceNode.desc),
|
||||
null
|
||||
);
|
||||
|
||||
@@ -263,7 +258,7 @@ public class AnonymousObjectTransformer {
|
||||
@NotNull ClassBuilder classBuilder,
|
||||
@NotNull ParametersBuilder allCapturedBuilder,
|
||||
@NotNull ParametersBuilder constructorInlineBuilder,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGen,
|
||||
@NotNull AnonymousObjectRegenerationInfo regenerationInfo,
|
||||
@NotNull FieldRemapper parentRemapper,
|
||||
@NotNull List<CapturedParamInfo> constructorAdditionalFakeParams
|
||||
) {
|
||||
@@ -291,7 +286,7 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()]));
|
||||
//TODO for inline method make public class
|
||||
anonymousObjectGen.setNewConstructorDescriptor(constructorDescriptor);
|
||||
regenerationInfo.setNewConstructorDescriptor(constructorDescriptor);
|
||||
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN,
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
"<init>", constructorDescriptor,
|
||||
@@ -329,7 +324,7 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
inlineMethodAndUpdateGlobalResult(anonymousObjectGen, parentRemapper, capturedFieldInitializer, constructor, constructorInlineBuilder, true);
|
||||
inlineMethodAndUpdateGlobalResult(regenerationInfo, parentRemapper, capturedFieldInitializer, constructor, constructorInlineBuilder, true);
|
||||
constructorVisitor.visitEnd();
|
||||
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
|
||||
}
|
||||
@@ -346,16 +341,6 @@ public class AnonymousObjectTransformer {
|
||||
return builder.buildParameters();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassBuilder createClassBuilder() {
|
||||
ClassBuilder classBuilder = state.getFactory().newVisitor(NO_ORIGIN, newLambdaType, inliningContext.getRoot().callElement.getContainingFile());
|
||||
|
||||
return new RemappingClassBuilder(
|
||||
classBuilder,
|
||||
new AsmTypeRemapper(inliningContext.typeRemapper, inliningContext.getRoot().typeParameterMappings == null, transformationResult)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DeferredMethodVisitor newMethod(@NotNull final ClassBuilder builder, @NotNull final MethodNode original) {
|
||||
return new DeferredMethodVisitor(
|
||||
@@ -383,20 +368,20 @@ public class AnonymousObjectTransformer {
|
||||
@NotNull MethodNode constructor,
|
||||
@NotNull ParametersBuilder capturedParamBuilder,
|
||||
@NotNull ParametersBuilder constructorParamBuilder,
|
||||
@NotNull final AnonymousObjectGeneration anonymousObjectGen,
|
||||
@NotNull final AnonymousObjectRegenerationInfo regenerationInfo,
|
||||
@NotNull FieldRemapper parentFieldRemapper
|
||||
) {
|
||||
|
||||
CapturedParamOwner owner = new CapturedParamOwner() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return Type.getObjectType(anonymousObjectGen.getOldClassName());
|
||||
return Type.getObjectType(regenerationInfo.getOldClassName());
|
||||
}
|
||||
};
|
||||
|
||||
Set<LambdaInfo> capturedLambdas = new LinkedHashSet<LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamInfo> constructorAdditionalFakeParams = new ArrayList<CapturedParamInfo>();
|
||||
Map<Integer, LambdaInfo> indexToLambda = anonymousObjectGen.getLambdasToInline();
|
||||
Map<Integer, LambdaInfo> indexToLambda = regenerationInfo.getLambdasToInline();
|
||||
Set<Integer> capturedParams = new HashSet<Integer>();
|
||||
|
||||
//load captured parameters and patch instruction list (NB: there is also could be object fields)
|
||||
@@ -439,7 +424,7 @@ public class AnonymousObjectTransformer {
|
||||
}
|
||||
|
||||
constructorParamBuilder.addThis(oldObjectType, false);
|
||||
String constructorDesc = anonymousObjectGen.getConstructorDesc();
|
||||
String constructorDesc = regenerationInfo.getConstructorDesc();
|
||||
|
||||
if (constructorDesc == null) {
|
||||
// in case of anonymous object with empty closure
|
||||
@@ -514,8 +499,8 @@ public class AnonymousObjectTransformer {
|
||||
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName()).setRemapValue(composed);
|
||||
}
|
||||
|
||||
anonymousObjectGen.setAllRecapturedParameters(allRecapturedParameters);
|
||||
anonymousObjectGen.setCapturedLambdasToInline(capturedLambdasToInline);
|
||||
regenerationInfo.setAllRecapturedParameters(allRecapturedParameters);
|
||||
regenerationInfo.setCapturedLambdasToInline(capturedLambdasToInline);
|
||||
|
||||
return constructorAdditionalFakeParams;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MethodInliner {
|
||||
private final List<InvokeCall> invokeCalls = new ArrayList<InvokeCall>();
|
||||
|
||||
//keeps order
|
||||
private final List<AnonymousObjectGeneration> anonymousObjectGenerations = new ArrayList<AnonymousObjectGeneration>();
|
||||
private final List<AnonymousObjectRegenerationInfo> anonymousObjectRegenerations = new ArrayList<AnonymousObjectRegenerationInfo>();
|
||||
//current state
|
||||
private final Map<String, String> currentTypeMapping = new HashMap<String, String>();
|
||||
|
||||
@@ -160,7 +160,7 @@ public class MethodInliner {
|
||||
|
||||
final MethodNode resultNode = new MethodNode(node.access, node.name, node.desc, node.signature, null);
|
||||
|
||||
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
|
||||
final Iterator<AnonymousObjectRegenerationInfo> iterator = anonymousObjectRegenerations.iterator();
|
||||
|
||||
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
|
||||
final RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
|
||||
@@ -173,8 +173,8 @@ public class MethodInliner {
|
||||
final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node);
|
||||
InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) {
|
||||
|
||||
private AnonymousObjectGeneration anonymousObjectGen;
|
||||
private void handleAnonymousObjectGeneration() {
|
||||
private AnonymousObjectRegenerationInfo anonymousObjectGen;
|
||||
private void handleAnonymousObjectRegeneration() {
|
||||
anonymousObjectGen = iterator.next();
|
||||
|
||||
if (anonymousObjectGen.shouldRegenerate(isSameModule)) {
|
||||
@@ -183,7 +183,7 @@ public class MethodInliner {
|
||||
String newClassName = inliningContext.nameGenerator.genLambdaClassName();
|
||||
remapper.addMapping(oldClassName, newClassName);
|
||||
AnonymousObjectTransformer transformer =
|
||||
new AnonymousObjectTransformer(oldClassName,
|
||||
new AnonymousObjectTransformer((AnonymousObjectRegenerationInfo) anonymousObjectGen,
|
||||
inliningContext
|
||||
.subInlineWithClassRegeneration(
|
||||
inliningContext.nameGenerator,
|
||||
@@ -213,7 +213,7 @@ public class MethodInliner {
|
||||
@Override
|
||||
public void anew(@NotNull Type type) {
|
||||
if (isAnonymousConstructorCall(type.getInternalName(), "<init>")) {
|
||||
handleAnonymousObjectGeneration();
|
||||
handleAnonymousObjectRegeneration();
|
||||
}
|
||||
|
||||
//in case of regenerated anonymousObjectGen type would be remapped to new one via remappingMethodAdapter
|
||||
@@ -278,7 +278,7 @@ public class MethodInliner {
|
||||
visitFieldInsn(Opcodes.GETSTATIC, capturedParamDesc.getContainingLambdaName(),
|
||||
"$$$" + capturedParamDesc.getFieldName(), capturedParamDesc.getType().getDescriptor());
|
||||
}
|
||||
String newInternalName = anonymousObjectGen.getNewLambdaType().getInternalName();
|
||||
String newInternalName = anonymousObjectGen.getNewClassName();
|
||||
super.visitMethodInsn(opcode, newInternalName, name, anonymousObjectGen.getNewConstructorDescriptor(), itf);
|
||||
|
||||
//TODO: add new inner class also for other contexts
|
||||
@@ -302,7 +302,7 @@ public class MethodInliner {
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, @NotNull String owner, @NotNull String name, @NotNull String desc) {
|
||||
if (opcode == Opcodes.GETSTATIC && isAnonymousSingletonLoad(owner, name)) {
|
||||
handleAnonymousObjectGeneration();
|
||||
handleAnonymousObjectRegeneration();
|
||||
}
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
@@ -488,7 +488,7 @@ public class MethodInliner {
|
||||
offset += i == 0 ? 1 : argTypes[i - 1].getSize();
|
||||
}
|
||||
|
||||
anonymousObjectGenerations.add(
|
||||
anonymousObjectRegenerations.add(
|
||||
buildConstructorInvocation(
|
||||
owner, desc, lambdaMapping, awaitClassReification
|
||||
)
|
||||
@@ -500,8 +500,8 @@ public class MethodInliner {
|
||||
FieldInsnNode fieldInsnNode = (FieldInsnNode) cur;
|
||||
String owner = fieldInsnNode.owner;
|
||||
if (isAnonymousSingletonLoad(owner, fieldInsnNode.name)) {
|
||||
anonymousObjectGenerations.add(
|
||||
new AnonymousObjectGeneration(
|
||||
anonymousObjectRegenerations.add(
|
||||
new AnonymousObjectRegenerationInfo(
|
||||
owner, awaitClassReification, isAlreadyRegenerated(owner), true
|
||||
)
|
||||
);
|
||||
@@ -551,13 +551,13 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private AnonymousObjectGeneration buildConstructorInvocation(
|
||||
private AnonymousObjectRegenerationInfo buildConstructorInvocation(
|
||||
@NotNull String anonymousType,
|
||||
@NotNull String desc,
|
||||
@NotNull Map<Integer, LambdaInfo> lambdaMapping,
|
||||
boolean needReification
|
||||
) {
|
||||
return new AnonymousObjectGeneration(
|
||||
return new AnonymousObjectRegenerationInfo(
|
||||
anonymousType, needReification, lambdaMapping,
|
||||
inliningContext.classRegeneration,
|
||||
isAlreadyRegenerated(anonymousType),
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
abstract class ObjectTransformer<T : RegenerationInfo>(val regenerationInfo: T, val state: GenerationState) {
|
||||
|
||||
abstract fun doTransform(info: T, parentRemapper: FieldRemapper): InlineResult
|
||||
|
||||
@JvmField
|
||||
val transformationResult = InlineResult.create()
|
||||
|
||||
protected fun createRemappingClassBuilderViaFactory(inliningContext: InliningContext): ClassBuilder {
|
||||
val classBuilder = state.factory.newVisitor(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
Type.getObjectType(regenerationInfo.getNewClassName()),
|
||||
inliningContext.root.callElement.containingFile
|
||||
)
|
||||
|
||||
return RemappingClassBuilder(
|
||||
classBuilder,
|
||||
AsmTypeRemapper(inliningContext.typeRemapper, inliningContext.root.typeParameterMappings == null, transformationResult))
|
||||
}
|
||||
|
||||
|
||||
fun createClassReader(): ClassReader {
|
||||
return InlineCodegenUtil.buildClassReaderByInternalName(state, regenerationInfo.getOldClassName())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WhenMappingTransformer(
|
||||
whenObjectRegenerationInfo: WhenMappingRegenerationInfo,
|
||||
state: GenerationState,
|
||||
val inliningContext: InliningContext
|
||||
) : ObjectTransformer<WhenMappingRegenerationInfo>(whenObjectRegenerationInfo, state) {
|
||||
|
||||
override fun doTransform(info: WhenMappingRegenerationInfo, parentRemapper: FieldRemapper): InlineResult {
|
||||
val classReader = createClassReader()
|
||||
//TODO add additional check that it's when mapping
|
||||
|
||||
val classBuilder = createRemappingClassBuilderViaFactory(inliningContext)
|
||||
classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
|
||||
override fun visit(version: Int, access: Int, name: String, signature: String, superName: String, interfaces: Array<String>) {
|
||||
InlineCodegenUtil.assertVersionNotGreaterThanJava6(version, name)
|
||||
super.visit(version, access, name, signature, superName, interfaces)
|
||||
}
|
||||
}, ClassReader.SKIP_FRAMES)
|
||||
|
||||
return transformationResult
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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
|
||||
|
||||
abstract class RegenerationInfo() {
|
||||
|
||||
abstract fun getOldClassName(): String
|
||||
abstract fun getNewClassName(): String
|
||||
|
||||
abstract fun shouldRegenerate(sameModule: Boolean): Boolean
|
||||
|
||||
}
|
||||
|
||||
class WhenMappingRegenerationInfo(val oldName: String, val nameGenerator: NameGenerator) : RegenerationInfo() {
|
||||
|
||||
override fun shouldRegenerate(sameModule: Boolean): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun getOldClassName(): String {
|
||||
return oldName
|
||||
}
|
||||
|
||||
override fun getNewClassName(): String {
|
||||
return nameGenerator.genLambdaClassName() + oldName
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user