Write enclosing method info for transformed objects
This commit is contained in:
+25
-21
@@ -97,21 +97,6 @@ public class AnonymousObjectTransformer {
|
||||
innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(@NotNull String owner, String name, String desc) {
|
||||
InliningContext parent = inliningContext.getParent();
|
||||
assert parent != null : "Context for transformer should have parent one: " + inliningContext;
|
||||
|
||||
//we don't write owner info for lamdbas and SAMs just only for objects
|
||||
if (parent.isRoot() || parent.isInliningLambdaRootContext()) {
|
||||
//TODO: think about writing method info - there is some problem with new constructor desc calculation
|
||||
super.visitOuterClass(inliningContext.getParent().getClassNameToInline(), null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
super.visitOuterClass(owner, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(
|
||||
int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions
|
||||
@@ -202,16 +187,24 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder);
|
||||
|
||||
ClassVisitor visitor = classBuilder.getVisitor();
|
||||
for (InnerClassNode node : innerClassNodes) {
|
||||
classBuilder.getVisitor().visitInnerClass(node.name, node.outerName, node.innerName, node.access);
|
||||
visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access);
|
||||
}
|
||||
|
||||
writeOuterInfo(visitor);
|
||||
|
||||
classBuilder.done();
|
||||
|
||||
anonymousObjectGen.setNewLambdaType(newLambdaType);
|
||||
return transformationResult;
|
||||
}
|
||||
|
||||
private void writeOuterInfo(@NotNull ClassVisitor visitor) {
|
||||
InlineCallSiteInfo info = inliningContext.getCallSiteInfo();
|
||||
visitor.visitOuterClass(info.getOwnerClassName(), info.getFunctionName(), info.getFunctionDesc());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private InlineResult inlineMethodAndUpdateGlobalResult(
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGen,
|
||||
@@ -244,9 +237,20 @@ public class AnonymousObjectTransformer {
|
||||
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
||||
parentRemapper, isConstructor);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
|
||||
sourceMapper);
|
||||
MethodInliner inliner =
|
||||
new MethodInliner(
|
||||
sourceNode,
|
||||
parameters,
|
||||
inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||
remapper,
|
||||
isSameModule,
|
||||
"Transformer for " + anonymousObjectGen.getOwnerInternalName(),
|
||||
sourceMapper,
|
||||
new InlineCallSiteInfo(
|
||||
anonymousObjectGen.getOwnerInternalName(),
|
||||
sourceNode.name,
|
||||
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc)
|
||||
);
|
||||
|
||||
InlineResult result = inliner.doInline(deferringVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE);
|
||||
result.getReifiedTypeParametersUsages().mergeAll(typeParametersToReify);
|
||||
@@ -285,6 +289,8 @@ 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);
|
||||
MethodVisitor constructorVisitor = classBuilder.newMethod(NO_ORIGIN,
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
"<init>", constructorDescriptor,
|
||||
@@ -325,8 +331,6 @@ public class AnonymousObjectTransformer {
|
||||
inlineMethodAndUpdateGlobalResult(anonymousObjectGen, parentRemapper, capturedFieldInitializer, constructor, constructorInlineBuilder, true);
|
||||
constructorVisitor.visitEnd();
|
||||
AsmUtil.genClosureFields(TransformationUtilsKt.toNameTypePair(TransformationUtilsKt.filterSkipped(newFieldsWithSkipped)), classBuilder);
|
||||
//TODO for inline method make public class
|
||||
anonymousObjectGen.setNewConstructorDescriptor(constructorDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?)
|
||||
@@ -269,12 +269,12 @@ public class InlineCodegen extends CallGenerator {
|
||||
.subGenerator(functionDescriptor.getName().asString()),
|
||||
codegen.getContext(),
|
||||
callElement,
|
||||
codegen.getParentCodegen().getClassName(), reifiedTypeInliner,
|
||||
getInlineCallSiteInfo(), reifiedTypeInliner,
|
||||
typeParameterMappings);
|
||||
|
||||
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
|
||||
"Method inlining " + callElement.getText(),
|
||||
createNestedSourceMapper(nodeAndSmap)); //with captured
|
||||
createNestedSourceMapper(nodeAndSmap), info.getCallSiteInfo()); //with captured
|
||||
|
||||
LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);
|
||||
|
||||
@@ -306,6 +306,13 @@ public class InlineCodegen extends CallGenerator {
|
||||
return result;
|
||||
}
|
||||
|
||||
private InlineCallSiteInfo getInlineCallSiteInfo() {
|
||||
MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
|
||||
MethodContext context = codegen.getContext();
|
||||
JvmMethodSignature signature = typeMapper.mapSignature(context.getFunctionDescriptor(), context.getContextKind());
|
||||
return new InlineCallSiteInfo(parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor());
|
||||
}
|
||||
|
||||
private void generateClosuresBodies() {
|
||||
for (LambdaInfo info : expressionMap.values()) {
|
||||
info.setNode(generateLambdaBody(info));
|
||||
|
||||
@@ -73,17 +73,18 @@ public class InliningContext {
|
||||
return subInline(nameGenerator.subGenerator("lambda"), map, true);
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
|
||||
private InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings) {
|
||||
return subInline(generator, additionalTypeMappings, isInliningLambda);
|
||||
}
|
||||
|
||||
public InliningContext subInlineWithClassRegeneration(@NotNull NameGenerator generator,
|
||||
@NotNull Map<String, String> newTypeMappings,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration,
|
||||
@NotNull InlineCallSiteInfo callSiteInfo
|
||||
) {
|
||||
return new RegeneratedClassContext(this, expressionMap, state, generator,
|
||||
TypeRemapper.createFrom(typeRemapper, newTypeMappings),
|
||||
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration);
|
||||
reifedTypeInliner, isInliningLambda, anonymousObjectGeneration, callSiteInfo);
|
||||
}
|
||||
|
||||
public InliningContext subInline(NameGenerator generator, Map<String, String> additionalTypeMappings, boolean isInliningLambda) {
|
||||
@@ -131,8 +132,8 @@ public class InliningContext {
|
||||
return isInliningLambda && !getParent().isInliningLambda;
|
||||
}
|
||||
|
||||
public String getClassNameToInline() {
|
||||
public InlineCallSiteInfo getCallSiteInfo() {
|
||||
assert parent != null : "At least root context should return proper value";
|
||||
return parent.getClassNameToInline();
|
||||
return parent.getCallSiteInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ public class MethodInliner {
|
||||
|
||||
private final SourceMapper sourceMapper;
|
||||
|
||||
private final InlineCallSiteInfo inlineCallSiteInfo;
|
||||
|
||||
private final JetTypeMapper typeMapper;
|
||||
|
||||
private final List<InvokeCall> invokeCalls = new ArrayList<InvokeCall>();
|
||||
@@ -82,7 +84,8 @@ public class MethodInliner {
|
||||
@NotNull FieldRemapper nodeRemapper,
|
||||
boolean isSameModule,
|
||||
@NotNull String errorPrefix,
|
||||
@NotNull SourceMapper sourceMapper
|
||||
@NotNull SourceMapper sourceMapper,
|
||||
@NotNull InlineCallSiteInfo inlineCallSiteInfo
|
||||
) {
|
||||
this.node = node;
|
||||
this.parameters = parameters;
|
||||
@@ -91,6 +94,7 @@ public class MethodInliner {
|
||||
this.isSameModule = isSameModule;
|
||||
this.errorPrefix = errorPrefix;
|
||||
this.sourceMapper = sourceMapper;
|
||||
this.inlineCallSiteInfo = inlineCallSiteInfo;
|
||||
this.typeMapper = inliningContext.state.getTypeMapper();
|
||||
this.result = InlineResult.create();
|
||||
}
|
||||
@@ -145,7 +149,7 @@ public class MethodInliner {
|
||||
return result;
|
||||
}
|
||||
|
||||
private MethodNode doInline(MethodNode node) {
|
||||
private MethodNode doInline(final MethodNode node) {
|
||||
|
||||
final Deque<InvokeCall> currentInvokes = new LinkedList<InvokeCall>(invokeCalls);
|
||||
|
||||
@@ -179,7 +183,8 @@ public class MethodInliner {
|
||||
.subInlineWithClassRegeneration(
|
||||
inliningContext.nameGenerator,
|
||||
currentTypeMapping,
|
||||
anonymousObjectGen),
|
||||
anonymousObjectGen,
|
||||
inlineCallSiteInfo),
|
||||
isSameModule, Type.getObjectType(newClassName)
|
||||
);
|
||||
|
||||
@@ -243,7 +248,7 @@ public class MethodInliner {
|
||||
inliningContext.subInlineLambda(info),
|
||||
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
|
||||
"Lambda inlining " + info.getLambdaClassType().getInternalName(),
|
||||
mapper);
|
||||
mapper, inlineCallSiteInfo);
|
||||
|
||||
LocalVarRemapper remapper = new LocalVarRemapper(lambdaParameters, valueParamShift);
|
||||
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);//TODO add skipped this and receiver
|
||||
@@ -639,7 +644,7 @@ public class MethodInliner {
|
||||
}
|
||||
}
|
||||
|
||||
private void transformFinallyDeepIndex(@NotNull MethodNode node, int finallyDeepShift) {
|
||||
private static void transformFinallyDeepIndex(@NotNull MethodNode node, int finallyDeepShift) {
|
||||
if (finallyDeepShift == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
+6
-4
@@ -24,6 +24,7 @@ import java.util.Map;
|
||||
|
||||
public class RegeneratedClassContext extends InliningContext {
|
||||
private final AnonymousObjectGeneration anonymousObjectGeneration;
|
||||
private InlineCallSiteInfo callSiteInfo;
|
||||
|
||||
public RegeneratedClassContext(
|
||||
@Nullable InliningContext parent,
|
||||
@@ -33,14 +34,15 @@ public class RegeneratedClassContext extends InliningContext {
|
||||
@NotNull TypeRemapper typeRemapper,
|
||||
@NotNull ReifiedTypeInliner reifiedTypeInliner,
|
||||
boolean isInliningLambda,
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration
|
||||
@NotNull AnonymousObjectGeneration anonymousObjectGeneration,
|
||||
@NotNull InlineCallSiteInfo callSiteInfo
|
||||
) {
|
||||
super(parent, map, state, nameGenerator, typeRemapper, reifiedTypeInliner, isInliningLambda, true);
|
||||
this.anonymousObjectGeneration = anonymousObjectGeneration;
|
||||
this.callSiteInfo = callSiteInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassNameToInline() {
|
||||
return anonymousObjectGeneration.getOwnerInternalName();
|
||||
public InlineCallSiteInfo getCallSiteInfo() {
|
||||
return callSiteInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
|
||||
public class RootInliningContext extends InliningContext {
|
||||
public final CodegenContext startContext;
|
||||
private final String classNameToInline;
|
||||
private final InlineCallSiteInfo inlineCallSiteInfo;
|
||||
public final TypeParameterMappings typeParameterMappings;
|
||||
public final KtElement callElement;
|
||||
|
||||
@@ -36,20 +36,19 @@ public class RootInliningContext extends InliningContext {
|
||||
@NotNull NameGenerator nameGenerator,
|
||||
@NotNull CodegenContext startContext,
|
||||
@NotNull KtElement callElement,
|
||||
@NotNull String classNameToInline,
|
||||
@NotNull InlineCallSiteInfo classNameToInline,
|
||||
@NotNull ReifiedTypeInliner inliner,
|
||||
@Nullable TypeParameterMappings typeParameterMappings
|
||||
) {
|
||||
super(null, map, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), inliner, false, false);
|
||||
this.callElement = callElement;
|
||||
this.startContext = startContext;
|
||||
this.classNameToInline = classNameToInline;
|
||||
this.inlineCallSiteInfo = classNameToInline;
|
||||
this.typeParameterMappings = typeParameterMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getClassNameToInline() {
|
||||
return classNameToInline;
|
||||
public InlineCallSiteInfo getCallSiteInfo() {
|
||||
return inlineCallSiteInfo;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user