Distinguish captured field from general one

This commit is contained in:
Mikhael Bogdanov
2014-04-21 15:19:36 +04:00
parent 9007ba9c53
commit 9181302ce4
5 changed files with 23 additions and 11 deletions
@@ -41,8 +41,10 @@ public class FieldRemapper {
params = methodParams;
}
public boolean canProcess(@NotNull String fieldOwner, boolean isFolding) {
return fieldOwner.equals(getLambdaInternalName());
protected boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) {
return fieldOwner.equals(getLambdaInternalName()) &&
//don't process general field of anonymous objects
InlineCodegenUtil.isCapturedFieldName(fieldName);
}
@Nullable
@@ -73,7 +75,7 @@ public class FieldRemapper {
if (transformed == null) {
//if parent couldn't transform
FieldInsnNode insnNode = (FieldInsnNode) capturedFieldAccess.get(currentInstruction);
if (canProcess(insnNode.owner, true)) {
if (canProcess(insnNode.owner, insnNode.name, true)) {
insnNode.name = "$$$" + insnNode.name;
insnNode.setOpcode(Opcodes.GETSTATIC);
@@ -56,6 +56,12 @@ public class InlineCodegenUtil {
public static final String INVOKE = "invoke";
public static final boolean DEFAULT_INLINE_FLAG = true;
public static final String CAPTURED_FIELD_PREFIX = "$";
public static final String THIS$0 = "this$0";
public static final String RECEIVER$0 = "receiver$0";
@Nullable
public static MethodNode getMethodNode(
InputStream classData,
@@ -259,4 +265,8 @@ public class InlineCodegenUtil {
return true;
}
public static boolean isCapturedFieldName(@NotNull String fieldName) {
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) || THIS$0.equals(fieldName) || RECEIVER$0.equals(fieldName);
}
}
@@ -34,8 +34,8 @@ public class InlinedLambdaRemapper extends FieldRemapper {
@Override
public boolean canProcess(@NotNull String fieldOwner, boolean isFolding) {
return isFolding ? super.canProcess(fieldOwner, isFolding) : false;
public boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) {
return isFolding ? super.canProcess(fieldOwner, fieldName, isFolding) : false;
}
@Override
@@ -244,7 +244,7 @@ public class LambdaTransformer {
AbstractInsnNode cur = constructor.instructions.getFirst();
//load captured parameters (NB: there is also could be object fields)
while (cur != null) {
if (cur.getType() == AbstractInsnNode.FIELD_INSN) {
if (cur instanceof FieldInsnNode && cur.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(((FieldInsnNode) cur).name)) {
FieldInsnNode fieldNode = (FieldInsnNode) cur;
CapturedParamInfo info = builder.addCapturedParam(owner, fieldNode.name, Type.getType(fieldNode.desc), false, null);
@@ -290,7 +290,7 @@ public class LambdaTransformer {
@NotNull
public String getNewFieldName(@NotNull String oldName) {
if (oldName.equals("this$0")) {
if (InlineCodegenUtil.THIS$0.equals(oldName)) {
//"this$0" couldn't clash and we should keep this name invariant for further transformations
return oldName;
}
@@ -51,8 +51,8 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
}
@Override
public boolean canProcess(@NotNull String fieldOwner, boolean isFolding) {
return super.canProcess(fieldOwner, isFolding) || isRecapturedLambdaType(fieldOwner);
public boolean canProcess(@NotNull String fieldOwner, String fieldName, boolean isFolding) {
return super.canProcess(fieldOwner, fieldName, isFolding) || isRecapturedLambdaType(fieldOwner);
}
private boolean isRecapturedLambdaType(String owner) {
@@ -62,7 +62,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
@Nullable
@Override
public CapturedParamInfo findField(@NotNull FieldInsnNode fieldInsnNode, @NotNull Collection<CapturedParamInfo> captured) {
boolean searchInParent = !canProcess(fieldInsnNode.owner, false);
boolean searchInParent = !canProcess(fieldInsnNode.owner, fieldInsnNode.name, false);
if (searchInParent) {
return parent.findField(fieldInsnNode);
} else {
@@ -87,7 +87,7 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
field = findFieldInMyCaptured(new FieldInsnNode(Opcodes.GETSTATIC, oldOwnerType, "this$0", Type.getObjectType(parent.getLambdaInternalName()).getDescriptor()));
searchInParent = true;
if (field == null) {
throw new IllegalStateException("Could find captured this " + getLambdaInternalName());
throw new IllegalStateException("Couldn't find captured this " + getLambdaInternalName() + " for " + node.name);
}
}