Fix for KT-9064
#KT-9064 Fixed
This commit is contained in:
+2
-2
@@ -237,7 +237,7 @@ public class AnonymousObjectTransformer {
|
|||||||
RegeneratedLambdaFieldRemapper remapper =
|
RegeneratedLambdaFieldRemapper remapper =
|
||||||
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
||||||
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
parameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
||||||
parentRemapper);
|
parentRemapper, false);
|
||||||
|
|
||||||
MethodInliner inliner = new MethodInliner(sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
MethodInliner inliner = new MethodInliner(sourceNode, parameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||||
remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
|
remapper, isSameModule, "Transformer for " + anonymousObjectGen.getOwnerInternalName(),
|
||||||
@@ -325,7 +325,7 @@ public class AnonymousObjectTransformer {
|
|||||||
RegeneratedLambdaFieldRemapper remapper =
|
RegeneratedLambdaFieldRemapper remapper =
|
||||||
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(),
|
||||||
constructorParameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
constructorParameters, anonymousObjectGen.getCapturedLambdasToInline(),
|
||||||
parentRemapper);
|
parentRemapper, true);
|
||||||
|
|
||||||
MethodInliner inliner = new MethodInliner(constructor, constructorParameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
MethodInliner inliner = new MethodInliner(constructor, constructorParameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")),
|
||||||
remapper, isSameModule, "Transformer for constructor of " + anonymousObjectGen.getOwnerInternalName(),
|
remapper, isSameModule, "Transformer for constructor of " + anonymousObjectGen.getOwnerInternalName(),
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ public class FieldRemapper {
|
|||||||
return foldFieldAccessChainIfNeeded(capturedFieldAccess, 1, node);
|
return foldFieldAccessChainIfNeeded(capturedFieldAccess, 1, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: seems that this method is redundant but it added from safety purposes before new milestone
|
||||||
|
public boolean processNonAload0FieldAccessChains(boolean isInlinedLambda) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private AbstractInsnNode foldFieldAccessChainIfNeeded(
|
private AbstractInsnNode foldFieldAccessChainIfNeeded(
|
||||||
@NotNull List<AbstractInsnNode> capturedFieldAccess,
|
@NotNull List<AbstractInsnNode> capturedFieldAccess,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline;
|
package org.jetbrains.kotlin.codegen.inline;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.ClosureCodegen;
|
import org.jetbrains.kotlin.codegen.ClosureCodegen;
|
||||||
@@ -25,11 +24,6 @@ import org.jetbrains.kotlin.codegen.StackValue;
|
|||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||||
import org.jetbrains.kotlin.codegen.optimization.MandatoryMethodTransformer;
|
import org.jetbrains.kotlin.codegen.optimization.MandatoryMethodTransformer;
|
||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache;
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass;
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
@@ -551,9 +545,7 @@ public class MethodInliner {
|
|||||||
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
|
public LambdaInfo getLambdaIfExists(AbstractInsnNode insnNode) {
|
||||||
if (insnNode.getOpcode() == Opcodes.ALOAD) {
|
if (insnNode.getOpcode() == Opcodes.ALOAD) {
|
||||||
int varIndex = ((VarInsnNode) insnNode).var;
|
int varIndex = ((VarInsnNode) insnNode).var;
|
||||||
if (varIndex < parameters.totalSize()) {
|
return getLambdaIfExists(varIndex);
|
||||||
return parameters.get(varIndex).getLambda();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (insnNode instanceof FieldInsnNode) {
|
else if (insnNode instanceof FieldInsnNode) {
|
||||||
FieldInsnNode fieldInsnNode = (FieldInsnNode) insnNode;
|
FieldInsnNode fieldInsnNode = (FieldInsnNode) insnNode;
|
||||||
@@ -565,6 +557,13 @@ public class MethodInliner {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LambdaInfo getLambdaIfExists(int varIndex) {
|
||||||
|
if (varIndex < parameters.totalSize()) {
|
||||||
|
return parameters.get(varIndex).getLambda();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void removeClosureAssertions(MethodNode node) {
|
private static void removeClosureAssertions(MethodNode node) {
|
||||||
AbstractInsnNode cur = node.instructions.getFirst();
|
AbstractInsnNode cur = node.instructions.getFirst();
|
||||||
while (cur != null && cur.getNext() != null) {
|
while (cur != null && cur.getNext() != null) {
|
||||||
@@ -598,7 +597,8 @@ public class MethodInliner {
|
|||||||
AbstractInsnNode cur = node.instructions.getFirst();
|
AbstractInsnNode cur = node.instructions.getFirst();
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if (cur instanceof VarInsnNode && cur.getOpcode() == Opcodes.ALOAD) {
|
if (cur instanceof VarInsnNode && cur.getOpcode() == Opcodes.ALOAD) {
|
||||||
if (((VarInsnNode) cur).var == 0) {
|
int varIndex = ((VarInsnNode) cur).var;
|
||||||
|
if (varIndex == 0 || nodeRemapper.processNonAload0FieldAccessChains(getLambdaIfExists(varIndex) != null)) {
|
||||||
List<AbstractInsnNode> accessChain = getCapturedFieldAccessChain((VarInsnNode) cur);
|
List<AbstractInsnNode> accessChain = getCapturedFieldAccessChain((VarInsnNode) cur);
|
||||||
AbstractInsnNode insnNode = nodeRemapper.foldFieldAccessChainIfNeeded(accessChain, node);
|
AbstractInsnNode insnNode = nodeRemapper.foldFieldAccessChainIfNeeded(accessChain, node);
|
||||||
if (insnNode != null) {
|
if (insnNode != null) {
|
||||||
|
|||||||
+9
-1
@@ -31,19 +31,22 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
|||||||
private final String newOwnerType;
|
private final String newOwnerType;
|
||||||
private final Parameters parameters;
|
private final Parameters parameters;
|
||||||
private final Map<String, LambdaInfo> recapturedLambdas;
|
private final Map<String, LambdaInfo> recapturedLambdas;
|
||||||
|
private final boolean isConstructor;
|
||||||
|
|
||||||
public RegeneratedLambdaFieldRemapper(
|
public RegeneratedLambdaFieldRemapper(
|
||||||
String oldOwnerType,
|
String oldOwnerType,
|
||||||
String newOwnerType,
|
String newOwnerType,
|
||||||
Parameters parameters,
|
Parameters parameters,
|
||||||
Map<String, LambdaInfo> recapturedLambdas,
|
Map<String, LambdaInfo> recapturedLambdas,
|
||||||
FieldRemapper remapper
|
FieldRemapper remapper,
|
||||||
|
boolean isConstructor
|
||||||
) {
|
) {
|
||||||
super(oldOwnerType, remapper, parameters);
|
super(oldOwnerType, remapper, parameters);
|
||||||
this.oldOwnerType = oldOwnerType;
|
this.oldOwnerType = oldOwnerType;
|
||||||
this.newOwnerType = newOwnerType;
|
this.newOwnerType = newOwnerType;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.recapturedLambdas = recapturedLambdas;
|
this.recapturedLambdas = recapturedLambdas;
|
||||||
|
this.isConstructor = isConstructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -66,6 +69,11 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processNonAload0FieldAccessChains(boolean isInlinedLambda) {
|
||||||
|
return isInlinedLambda && isConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CapturedParamInfo findFieldInMyCaptured(@NotNull FieldInsnNode fieldInsnNode) {
|
public CapturedParamInfo findFieldInMyCaptured(@NotNull FieldInsnNode fieldInsnNode) {
|
||||||
return super.findField(fieldInsnNode, parameters.getCaptured());
|
return super.findField(fieldInsnNode, parameters.getCaptured());
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
//NO_CHECK_LAMBDA_INLINING
|
||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
|
||||||
|
val test = Test("OK")
|
||||||
|
|
||||||
|
return test._parameter.property
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class Test(val _member: String) {
|
||||||
|
val _parameter: Z = test {
|
||||||
|
object : Z {
|
||||||
|
override val property = _member
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Z {
|
||||||
|
val property: String
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun test(s: () -> Z): Z {
|
||||||
|
return s()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
//NO_CHECK_LAMBDA_INLINING
|
||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
|
||||||
|
val test = Test("OK")
|
||||||
|
|
||||||
|
return test._parameter.property.property
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class Test(val _member: String) {
|
||||||
|
val _parameter: Z<Z<String>> = test {
|
||||||
|
object : Z<Z<String>> {
|
||||||
|
override val property = test {
|
||||||
|
object : Z<String> {
|
||||||
|
override val property = _member
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Z<T> {
|
||||||
|
val property: T
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> test(s: () -> Z<T>): Z<T> {
|
||||||
|
return s()
|
||||||
|
}
|
||||||
+12
@@ -96,6 +96,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/changingReturnType.1.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/changingReturnType.1.kt");
|
||||||
doTestMultiFileWithInlineCheck(fileName);
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt9064.1.kt")
|
||||||
|
public void testKt9064() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt9064.1.kt");
|
||||||
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt9064v2.1.kt")
|
||||||
|
public void testKt9064v2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt9064v2.1.kt");
|
||||||
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
||||||
|
|||||||
+12
@@ -96,6 +96,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/changingReturnType.1.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/changingReturnType.1.kt");
|
||||||
doBoxTestWithInlineCheck(fileName);
|
doBoxTestWithInlineCheck(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt9064.1.kt")
|
||||||
|
public void testKt9064() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt9064.1.kt");
|
||||||
|
doBoxTestWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt9064v2.1.kt")
|
||||||
|
public void testKt9064v2() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt9064v2.1.kt");
|
||||||
|
doBoxTestWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
@TestMetadata("compiler/testData/codegen/boxInline/builders")
|
||||||
|
|||||||
Reference in New Issue
Block a user