Code clean
This commit is contained in:
@@ -33,9 +33,9 @@ public class ConstructorInvocation {
|
||||
|
||||
private String newConstructorDescriptor;
|
||||
|
||||
private List<CapturedParamInfo> recaptured;
|
||||
private List<CapturedParamInfo> allRecapturedParameters;
|
||||
|
||||
private Map<String, LambdaInfo> recapturedLambdas;
|
||||
private Map<String, LambdaInfo> capturedLambdasToInline;
|
||||
|
||||
ConstructorInvocation(String ownerInternalName, Map<Integer, LambdaInfo> lambdasToInline, boolean isSameModule) {
|
||||
this.ownerInternalName = ownerInternalName;
|
||||
@@ -55,7 +55,6 @@ public class ConstructorInvocation {
|
||||
return lambdasToInline;
|
||||
}
|
||||
|
||||
|
||||
public Type getNewLambdaType() {
|
||||
return newLambdaType;
|
||||
}
|
||||
@@ -72,19 +71,19 @@ public class ConstructorInvocation {
|
||||
this.newConstructorDescriptor = newConstructorDescriptor;
|
||||
}
|
||||
|
||||
public List<CapturedParamInfo> getRecaptured() {
|
||||
return recaptured;
|
||||
public List<CapturedParamInfo> getAllRecapturedParameters() {
|
||||
return allRecapturedParameters;
|
||||
}
|
||||
|
||||
public void setRecaptured(List<CapturedParamInfo> recaptured) {
|
||||
this.recaptured = recaptured;
|
||||
public void setAllRecapturedParameters(List<CapturedParamInfo> allRecapturedParameters) {
|
||||
this.allRecapturedParameters = allRecapturedParameters;
|
||||
}
|
||||
|
||||
public Map<String, LambdaInfo> getRecapturedLambdas() {
|
||||
return recapturedLambdas;
|
||||
public Map<String, LambdaInfo> getCapturedLambdasToInline() {
|
||||
return capturedLambdasToInline;
|
||||
}
|
||||
|
||||
public void setRecapturedLambdas(Map<String, LambdaInfo> recapturedLambdas) {
|
||||
this.recapturedLambdas = recapturedLambdas;
|
||||
public void setCapturedLambdasToInline(Map<String, LambdaInfo> capturedLambdasToInline) {
|
||||
this.capturedLambdasToInline = capturedLambdasToInline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
|
||||
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
|
||||
|
||||
inliner.doTransformAndMerge(codegen.v, remapper);
|
||||
inliner.doInline(codegen.v, remapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class InlineCodegenUtil {
|
||||
FqName namespaceFqName =
|
||||
PackageClassUtils.getPackageClassFqName(((PackageFragmentDescriptor) parentDeclatation).getFqName()).parent().child(
|
||||
name);
|
||||
file = findVirtualFile(state.getProject(), namespaceFqName, true);
|
||||
file = findVirtualFileWithHeader(state.getProject(), namespaceFqName);
|
||||
} else {
|
||||
assert false : "Function in namespace should have implClassName property in proto: " + deserializedDescriptor;
|
||||
}
|
||||
@@ -103,13 +103,15 @@ public class InlineCodegenUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findVirtualFile(@NotNull Project project, @NotNull FqName containerFqName, boolean onlyKotlin) {
|
||||
public static VirtualFile findVirtualFileWithHeader(@NotNull Project project, @NotNull FqName containerFqName) {
|
||||
VirtualFileFinder fileFinder = ServiceManager.getService(project, VirtualFileFinder.class);
|
||||
if (onlyKotlin) {
|
||||
return fileFinder.findVirtualFileWithHeader(containerFqName);
|
||||
} else {
|
||||
return fileFinder.findVirtualFile(containerFqName.asString().replace('.', '/'));
|
||||
}
|
||||
return fileFinder.findVirtualFileWithHeader(containerFqName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findVirtualFile(@NotNull Project project, @NotNull String internalName) {
|
||||
VirtualFileFinder fileFinder = ServiceManager.getService(project, VirtualFileFinder.class);
|
||||
return fileFinder.findVirtualFile(internalName);
|
||||
}
|
||||
|
||||
//TODO: navigate to inner classes
|
||||
@@ -185,7 +187,7 @@ public class InlineCodegenUtil {
|
||||
if (containerFqName == null) {
|
||||
return null;
|
||||
}
|
||||
return findVirtualFile(project, containerFqName, true);
|
||||
return findVirtualFileWithHeader(project, containerFqName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@ import org.jetbrains.asm4.tree.FieldInsnNode;
|
||||
import org.jetbrains.asm4.tree.MethodNode;
|
||||
import org.jetbrains.asm4.tree.VarInsnNode;
|
||||
import org.jetbrains.jet.OutputFile;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.AsmUtil;
|
||||
import org.jetbrains.jet.codegen.ClassBuilder;
|
||||
import org.jetbrains.jet.codegen.ClosureCodegen;
|
||||
import org.jetbrains.jet.codegen.FieldInfo;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -55,8 +57,6 @@ public class LambdaTransformer {
|
||||
|
||||
private final InliningInfo info;
|
||||
|
||||
private final Map<String, Integer> paramMapping = new HashMap<String, Integer>();
|
||||
|
||||
private final Type oldLambdaType;
|
||||
|
||||
private final Type newLambdaType;
|
||||
@@ -82,7 +82,7 @@ public class LambdaTransformer {
|
||||
if (outputFile != null) {
|
||||
reader = new ClassReader(outputFile.asByteArray());
|
||||
} else {
|
||||
VirtualFile file = InlineCodegenUtil.findVirtualFile(state.getProject(), new FqName(lambdaInternalName.replace('/', '.')), false);
|
||||
VirtualFile file = InlineCodegenUtil.findVirtualFile(state.getProject(), lambdaInternalName);
|
||||
if (file == null) {
|
||||
throw new RuntimeException("Couldn't find virtual file for " + lambdaInternalName);
|
||||
}
|
||||
@@ -93,6 +93,7 @@ public class LambdaTransformer {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
//TODO rewrite to one step
|
||||
constructor = getMethodNode(reader, true, false);
|
||||
invoke = getMethodNode(reader, false, false);
|
||||
bridge = getMethodNode(reader, false, true);
|
||||
@@ -110,6 +111,7 @@ public class LambdaTransformer {
|
||||
public void doTransform(ConstructorInvocation invocation) {
|
||||
ClassBuilder classBuilder = createClassBuilder();
|
||||
|
||||
//TODO: public visibility for inline function
|
||||
classBuilder.defineClass(null,
|
||||
V1_6,
|
||||
classAccess,
|
||||
@@ -122,10 +124,10 @@ public class LambdaTransformer {
|
||||
Parameters parameters = getLambdaParameters(builder, invocation);
|
||||
|
||||
MethodVisitor invokeVisitor = newMethod(classBuilder, invoke);
|
||||
InlineFieldRemapper remapper = new InlineFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getRecapturedLambdas());
|
||||
InlineFieldRemapper remapper = new InlineFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getCapturedLambdasToInline());
|
||||
MethodInliner inliner = new MethodInliner(invoke, parameters, info.subInline(info.nameGenerator.subGenerator("lambda")), oldLambdaType,
|
||||
remapper, isSameModule);
|
||||
inliner.doTransformAndMerge(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
||||
inliner.doInline(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
||||
invokeVisitor.visitMaxs(-1, -1);
|
||||
|
||||
generateConstructorAndFields(classBuilder, builder, invocation);
|
||||
@@ -162,6 +164,7 @@ public class LambdaTransformer {
|
||||
|
||||
AsmUtil.genClosureFields(newConstructorSignature, classBuilder);
|
||||
|
||||
//TODO for inline method make public class
|
||||
Method newConstructor = ClosureCodegen.generateConstructor(classBuilder, fields, null, Type.getObjectType(superName), state, AsmUtil.NO_FLAG_PACKAGE_PRIVATE);
|
||||
invocation.setNewConstructorDescriptor(newConstructor.getDescriptor());
|
||||
}
|
||||
@@ -173,7 +176,7 @@ public class LambdaTransformer {
|
||||
}
|
||||
|
||||
private ClassBuilder createClassBuilder() {
|
||||
return new RemappingClassBuilder(state.getFactory().forLambdaInlining(newLambdaType, info.call.getCalleeExpression().getContainingFile()),
|
||||
return new RemappingClassBuilder(state.getFactory().forLambdaInlining(newLambdaType, info.call.getCallElement().getContainingFile()),
|
||||
new TypeRemapper(info.typeMapping, isSameModule));
|
||||
}
|
||||
|
||||
@@ -188,7 +191,7 @@ public class LambdaTransformer {
|
||||
);
|
||||
}
|
||||
|
||||
private void extractParametersMapping(MethodNode constructor, ParametersBuilder builder, ConstructorInvocation invocation) {
|
||||
private static void extractParametersMapping(MethodNode constructor, ParametersBuilder builder, ConstructorInvocation invocation) {
|
||||
Map<Integer, LambdaInfo> indexToLambda = invocation.getLambdasToInline();
|
||||
|
||||
AbstractInsnNode cur = constructor.instructions.getFirst();
|
||||
@@ -197,34 +200,35 @@ public class LambdaTransformer {
|
||||
while (cur != null) {
|
||||
if (cur.getType() == AbstractInsnNode.FIELD_INSN) {
|
||||
FieldInsnNode fieldNode = (FieldInsnNode) cur;
|
||||
CapturedParamInfo info = builder.addCapturedParam(fieldNode.name, Type.getType(fieldNode.desc), false, null);
|
||||
|
||||
assert fieldNode.getPrevious() instanceof VarInsnNode : "Previous instruction should be VarInsnNode but was " + fieldNode.getPrevious();
|
||||
VarInsnNode previous = (VarInsnNode) fieldNode.getPrevious();
|
||||
int varIndex = previous.var;
|
||||
paramMapping.put(fieldNode.name, varIndex);
|
||||
|
||||
CapturedParamInfo info = builder.addCapturedParam(fieldNode.name, Type.getType(fieldNode.desc), false, null);
|
||||
LambdaInfo LambdaInfo = indexToLambda.get(varIndex);
|
||||
if (LambdaInfo != null) {
|
||||
info.setLambda(LambdaInfo);
|
||||
additionalCaptured.add(LambdaInfo);
|
||||
LambdaInfo lambdaInfo = indexToLambda.get(varIndex);
|
||||
if (lambdaInfo != null) {
|
||||
info.setLambda(lambdaInfo);
|
||||
additionalCaptured.add(lambdaInfo);
|
||||
}
|
||||
}
|
||||
cur = cur.getNext();
|
||||
}
|
||||
|
||||
Map<String, LambdaInfo> recapturedLambdas = new HashMap<String, LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamInfo> recaptured = new ArrayList<CapturedParamInfo>();
|
||||
//For all inlined lambdas add their captured parameters
|
||||
//TODO: some of such parameters could be skipped - we should perform additional analysis
|
||||
Map<String, LambdaInfo> capturedLambdasToInline = new HashMap<String, LambdaInfo>(); //captured var of inlined parameter
|
||||
List<CapturedParamInfo> allRecapturedParameters = new ArrayList<CapturedParamInfo>();
|
||||
for (LambdaInfo info : additionalCaptured) {
|
||||
List<CapturedParamInfo> vars = info.getCapturedVars();
|
||||
for (CapturedParamInfo var : vars) {
|
||||
for (CapturedParamInfo var : info.getCapturedVars()) {
|
||||
CapturedParamInfo recapturedParamInfo = builder.addCapturedParam(getNewFieldName(var.getFieldName()), var.getType(), true, var);
|
||||
recapturedParamInfo.setRecapturedFrom(info);
|
||||
recaptured.add(var);
|
||||
allRecapturedParameters.add(var);
|
||||
}
|
||||
recapturedLambdas.put(info.getLambdaClassType().getInternalName(), info);
|
||||
capturedLambdasToInline.put(info.getLambdaClassType().getInternalName(), info);
|
||||
}
|
||||
|
||||
invocation.setRecaptured(recaptured);
|
||||
invocation.setRecapturedLambdas(recapturedLambdas);
|
||||
invocation.setAllRecapturedParameters(allRecapturedParameters);
|
||||
invocation.setCapturedLambdasToInline(capturedLambdasToInline);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -244,7 +248,8 @@ public class LambdaTransformer {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
boolean isConstructorMethod = "<init>".equals(name);
|
||||
if (findConstructor && isConstructorMethod || (!findConstructor && !isConstructorMethod && ((access & Opcodes.ACC_BRIDGE) == (findBridge ? Opcodes.ACC_BRIDGE : 0)))) {
|
||||
boolean isBridge = (access & Opcodes.ACC_BRIDGE) != 0;
|
||||
if (findConstructor && isConstructorMethod || (!findConstructor && !isConstructorMethod && (isBridge == findBridge))) {
|
||||
assert methodNode[0] == null : "Wrong lambda/sam structure: " + methodNode[0].name + " conflicts with " + name;
|
||||
return methodNode[0] = new MethodNode(access, name, desc, signature, exceptions);
|
||||
}
|
||||
@@ -259,10 +264,6 @@ public class LambdaTransformer {
|
||||
return methodNode[0];
|
||||
}
|
||||
|
||||
public Type getNewLambdaType() {
|
||||
return newLambdaType;
|
||||
}
|
||||
|
||||
public static String getNewFieldName(String oldName) {
|
||||
return oldName + "$inlined";
|
||||
}
|
||||
|
||||
@@ -71,11 +71,11 @@ public class MethodInliner {
|
||||
}
|
||||
|
||||
|
||||
public void doTransformAndMerge(MethodVisitor adapter, VarRemapper.ParamRemapper remapper) {
|
||||
doTransformAndMerge(adapter, remapper, new LambdaFieldRemapper(), true);
|
||||
public void doInline(MethodVisitor adapter, VarRemapper.ParamRemapper remapper) {
|
||||
doInline(adapter, remapper, new LambdaFieldRemapper(), true);
|
||||
}
|
||||
|
||||
public void doTransformAndMerge(
|
||||
public void doInline(
|
||||
MethodVisitor adapter,
|
||||
VarRemapper.ParamRemapper remapper,
|
||||
LambdaFieldRemapper capturedRemapper, boolean remapReturn
|
||||
@@ -158,7 +158,7 @@ public class MethodInliner {
|
||||
capturedRemapper, true /*cause all calls in same module as lambda*/);
|
||||
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(lambdaParameters, valueParamShift);
|
||||
inliner.doTransformAndMerge(this.mv, remapper); //TODO add skipped this and receiver
|
||||
inliner.doInline(this.mv, remapper); //TODO add skipped this and receiver
|
||||
|
||||
//return value boxing/unboxing
|
||||
Method bridge = typeMapper.mapSignature(ClosureCodegen.getInvokeFunction(info.getFunctionDescriptor())).getAsmMethod();
|
||||
@@ -170,7 +170,7 @@ public class MethodInliner {
|
||||
assert invocation != null : "<init> call not corresponds to new call" + owner + " " + name;
|
||||
if (invocation.shouldRegenerate()) {
|
||||
//put additional captured parameters on stack
|
||||
List<CapturedParamInfo> recaptured = invocation.getRecaptured();
|
||||
List<CapturedParamInfo> recaptured = invocation.getAllRecapturedParameters();
|
||||
List<CapturedParamInfo> contextCaptured = MethodInliner.this.parameters.getCaptured();
|
||||
for (CapturedParamInfo capturedParamInfo : recaptured) {
|
||||
CapturedParamInfo result = null;
|
||||
|
||||
@@ -92,4 +92,10 @@ public class RemapVisitor extends InstructionAdapter {
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO not skip for lambdas
|
||||
@Override
|
||||
public void visitLineNumber(int line, Label start) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user