Rename this$0 on decl site
This commit is contained in:
+31
-9
@@ -35,6 +35,7 @@ import org.jetbrains.org.objectweb.asm.tree.VarInsnNode;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.isThis0;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
|
||||||
|
|
||||||
public class AnonymousObjectTransformer {
|
public class AnonymousObjectTransformer {
|
||||||
@@ -399,7 +400,8 @@ public class AnonymousObjectTransformer {
|
|||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if (cur instanceof FieldInsnNode) {
|
if (cur instanceof FieldInsnNode) {
|
||||||
FieldInsnNode fieldNode = (FieldInsnNode) cur;
|
FieldInsnNode fieldNode = (FieldInsnNode) cur;
|
||||||
if (fieldNode.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(fieldNode.name)) {
|
String fieldName = fieldNode.name;
|
||||||
|
if (fieldNode.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(fieldName)) {
|
||||||
|
|
||||||
boolean isPrevVarNode = fieldNode.getPrevious() instanceof VarInsnNode;
|
boolean isPrevVarNode = fieldNode.getPrevious() instanceof VarInsnNode;
|
||||||
boolean isPrevPrevVarNode = isPrevVarNode && fieldNode.getPrevious().getPrevious() instanceof VarInsnNode;
|
boolean isPrevPrevVarNode = isPrevVarNode && fieldNode.getPrevious().getPrevious() instanceof VarInsnNode;
|
||||||
@@ -410,7 +412,8 @@ public class AnonymousObjectTransformer {
|
|||||||
VarInsnNode previous = (VarInsnNode) fieldNode.getPrevious();
|
VarInsnNode previous = (VarInsnNode) fieldNode.getPrevious();
|
||||||
int varIndex = previous.var;
|
int varIndex = previous.var;
|
||||||
LambdaInfo lambdaInfo = indexToLambda.get(varIndex);
|
LambdaInfo lambdaInfo = indexToLambda.get(varIndex);
|
||||||
CapturedParamInfo info = capturedParamBuilder.addCapturedParam(owner, fieldNode.name, Type.getType(fieldNode.desc), lambdaInfo != null, null);
|
String newFieldName = isThis0(fieldName) && shouldRenameThis0(parentFieldRemapper, indexToLambda.values()) ? getNewFieldName(fieldName, true) : fieldName;
|
||||||
|
CapturedParamInfo info = capturedParamBuilder.addCapturedParam(owner, fieldName, newFieldName, Type.getType(fieldNode.desc), lambdaInfo != null, null);
|
||||||
if (lambdaInfo != null) {
|
if (lambdaInfo != null) {
|
||||||
info.setLambda(lambdaInfo);
|
info.setLambda(lambdaInfo);
|
||||||
capturedLambdas.add(lambdaInfo);
|
capturedLambdas.add(lambdaInfo);
|
||||||
@@ -459,7 +462,7 @@ public class AnonymousObjectTransformer {
|
|||||||
for (LambdaInfo info : capturedLambdas) {
|
for (LambdaInfo info : capturedLambdas) {
|
||||||
if (addCapturedNotAddOuter) {
|
if (addCapturedNotAddOuter) {
|
||||||
for (CapturedParamDesc desc : info.getCapturedVars()) {
|
for (CapturedParamDesc desc : info.getCapturedVars()) {
|
||||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, getNewFieldName(desc.getFieldName()));
|
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, getNewFieldName(desc.getFieldName(), false));
|
||||||
StackValue composed = StackValue.field(desc.getType(),
|
StackValue composed = StackValue.field(desc.getType(),
|
||||||
oldObjectType, /*TODO owner type*/
|
oldObjectType, /*TODO owner type*/
|
||||||
recapturedParamInfo.getNewFieldName(),
|
recapturedParamInfo.getNewFieldName(),
|
||||||
@@ -486,7 +489,7 @@ public class AnonymousObjectTransformer {
|
|||||||
return ownerType;
|
return ownerType;
|
||||||
}
|
}
|
||||||
}, InlineCodegenUtil.THIS, ownerType);
|
}, InlineCodegenUtil.THIS, ownerType);
|
||||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.THIS$0);
|
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.THIS$0/*outer lambda/object*/);
|
||||||
StackValue composed = StackValue.LOCAL_0;
|
StackValue composed = StackValue.LOCAL_0;
|
||||||
recapturedParamInfo.setRemapValue(composed);
|
recapturedParamInfo.setRemapValue(composed);
|
||||||
allRecapturedParameters.add(desc);
|
allRecapturedParameters.add(desc);
|
||||||
@@ -494,19 +497,34 @@ public class AnonymousObjectTransformer {
|
|||||||
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName()).setRemapValue(composed);
|
constructorParamBuilder.addCapturedParam(recapturedParamInfo, recapturedParamInfo.getNewFieldName()).setRemapValue(composed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
anonymousObjectGen.setAllRecapturedParameters(allRecapturedParameters);
|
anonymousObjectGen.setAllRecapturedParameters(allRecapturedParameters);
|
||||||
anonymousObjectGen.setCapturedLambdasToInline(capturedLambdasToInline);
|
anonymousObjectGen.setCapturedLambdasToInline(capturedLambdasToInline);
|
||||||
|
|
||||||
return constructorAdditionalFakeParams;
|
return constructorAdditionalFakeParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean shouldRenameThis0(@NotNull FieldRemapper parentFieldRemapper, Collection<LambdaInfo> values) {
|
||||||
|
if (isFirstDeclSiteLambdaFieldRemapper(parentFieldRemapper)) {
|
||||||
|
for (LambdaInfo value : values) {
|
||||||
|
for (CapturedParamDesc desc : value.getCapturedVars()) {
|
||||||
|
if (isThis0(desc.getFieldName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String getNewFieldName(@NotNull String oldName) {
|
public String getNewFieldName(@NotNull String oldName, boolean originalField) {
|
||||||
if (InlineCodegenUtil.THIS$0.equals(oldName)) {
|
if (InlineCodegenUtil.THIS$0.equals(oldName)) {
|
||||||
//"this$0" couldn't clash and we should keep this name invariant for further transformations
|
if (!originalField) {
|
||||||
return oldName;
|
return oldName;
|
||||||
|
} else {
|
||||||
|
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
|
||||||
|
return addUniqueField(oldName + InlineCodegenUtil.INLINE_FUN_THIS_0_SUFFIX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return addUniqueField(oldName + InlineCodegenUtil.INLINE_TRANSFORMATION_SUFFIX);
|
return addUniqueField(oldName + InlineCodegenUtil.INLINE_TRANSFORMATION_SUFFIX);
|
||||||
}
|
}
|
||||||
@@ -523,4 +541,8 @@ public class AnonymousObjectTransformer {
|
|||||||
existNames.add(newName);
|
existNames.add(newName);
|
||||||
return newName;
|
return newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isFirstDeclSiteLambdaFieldRemapper(FieldRemapper parentRemapper) {
|
||||||
|
return !(parentRemapper instanceof RegeneratedLambdaFieldRemapper) && !(parentRemapper instanceof InlinedLambdaRemapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ public class InlineCodegenUtil {
|
|||||||
public static final String INLINE_MARKER_FINALLY_START = "finallyStart";
|
public static final String INLINE_MARKER_FINALLY_START = "finallyStart";
|
||||||
public static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
|
public static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
|
||||||
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
|
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
|
||||||
|
public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun";
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static SMAPAndMethodNode getMethodNode(
|
public static SMAPAndMethodNode getMethodNode(
|
||||||
@@ -487,4 +488,8 @@ public class InlineCodegenUtil {
|
|||||||
public static boolean isFakeLocalVariableForInline(@NotNull String name) {
|
public static boolean isFakeLocalVariableForInline(@NotNull String name) {
|
||||||
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT);
|
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isThis0(String name) {
|
||||||
|
return THIS$0.equals(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,10 +77,11 @@ internal class ParametersBuilder private constructor(){
|
|||||||
fun addCapturedParam(
|
fun addCapturedParam(
|
||||||
containingLambda: CapturedParamOwner,
|
containingLambda: CapturedParamOwner,
|
||||||
fieldName: String,
|
fieldName: String,
|
||||||
|
newFieldName: String,
|
||||||
type: Type,
|
type: Type,
|
||||||
skipped: Boolean,
|
skipped: Boolean,
|
||||||
original: ParameterInfo?): CapturedParamInfo {
|
original: ParameterInfo?): CapturedParamInfo {
|
||||||
val info = CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), skipped, nextCapturedIndex(),
|
val info = CapturedParamInfo(CapturedParamDesc.createDesc(containingLambda, fieldName, type), newFieldName, skipped, nextCapturedIndex(),
|
||||||
if (original != null) original.getIndex() else -1)
|
if (original != null) original.getIndex() else -1)
|
||||||
if (original != null) {
|
if (original != null) {
|
||||||
info.setLambda(original.getLambda())
|
info.setLambda(original.getLambda())
|
||||||
|
|||||||
Reference in New Issue
Block a user