Fix for: KT-14011 Compiler crash when inlining: lateinit property allRecapturedParameters has not been initialized
#KT-14011 Fixed
This commit is contained in:
+1
-1
@@ -193,7 +193,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
boolean isConstructor
|
||||
) {
|
||||
InlineResult funResult = inlineMethod(parentRemapper, deferringVisitor, next, allCapturedParamBuilder, isConstructor);
|
||||
transformationResult.addAllClassesToRemove(funResult);
|
||||
transformationResult.merge(funResult);
|
||||
transformationResult.getReifiedTypeParametersUsages().mergeAll(funResult.getReifiedTypeParametersUsages());
|
||||
return funResult;
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
|
||||
codegen.propagateChildReifiedTypeParametersUsages(result.getReifiedTypeParametersUsages());
|
||||
|
||||
state.getFactory().removeClasses(result.getClassesToRemove());
|
||||
state.getFactory().removeClasses(result.calcClassesToRemove());
|
||||
|
||||
codegen.markLineNumberAfterInlineIfNeeded();
|
||||
}
|
||||
|
||||
@@ -21,25 +21,35 @@ import java.util.HashSet
|
||||
|
||||
class InlineResult private constructor() {
|
||||
|
||||
private val notChangedTypes = hashSetOf<String>()
|
||||
private val classesToRemove = HashSet<String>()
|
||||
private val changedTypes = HashMap<String, String>()
|
||||
val reifiedTypeParametersUsages = ReifiedTypeParametersUsages()
|
||||
|
||||
fun addAllClassesToRemove(child: InlineResult): InlineResult {
|
||||
classesToRemove.addAll(child.classesToRemove)
|
||||
return this
|
||||
fun merge(child: InlineResult) {
|
||||
classesToRemove.addAll(child.calcClassesToRemove())
|
||||
}
|
||||
|
||||
fun mergeWithNotChangeInfo(child: InlineResult) {
|
||||
notChangedTypes.addAll(child.notChangedTypes)
|
||||
merge(child)
|
||||
}
|
||||
|
||||
fun addClassToRemove(classInternalName: String) {
|
||||
classesToRemove.add(classInternalName)
|
||||
}
|
||||
|
||||
fun addNotChangedClass(classInternalName: String) {
|
||||
notChangedTypes.add(classInternalName)
|
||||
}
|
||||
|
||||
fun addChangedType(oldClassInternalName: String, newClassInternalName: String) {
|
||||
changedTypes.put(oldClassInternalName, newClassInternalName)
|
||||
}
|
||||
|
||||
fun getClassesToRemove(): Set<String> {
|
||||
return classesToRemove
|
||||
|
||||
fun calcClassesToRemove(): Set<String> {
|
||||
return classesToRemove - notChangedTypes
|
||||
}
|
||||
|
||||
fun getChangedTypes(): Map<String, String> {
|
||||
|
||||
@@ -164,9 +164,9 @@ public class MethodInliner {
|
||||
private void handleAnonymousObjectRegeneration() {
|
||||
transformationInfo = iterator.next();
|
||||
|
||||
String oldClassName = transformationInfo.getOldClassName();
|
||||
if (transformationInfo.shouldRegenerate(isSameModule)) {
|
||||
//TODO: need poping of type but what to do with local funs???
|
||||
String oldClassName = transformationInfo.getOldClassName();
|
||||
String newClassName = transformationInfo.getNewClassName();
|
||||
remapper.addMapping(oldClassName, newClassName);
|
||||
|
||||
@@ -178,7 +178,7 @@ public class MethodInliner {
|
||||
ObjectTransformer transformer = transformationInfo.createTransformer(childInliningContext, isSameModule);
|
||||
|
||||
InlineResult transformResult = transformer.doTransform(nodeRemapper);
|
||||
result.addAllClassesToRemove(transformResult);
|
||||
result.merge(transformResult);
|
||||
result.addChangedType(oldClassName, newClassName);
|
||||
|
||||
if (inliningContext.isInliningLambda && transformationInfo.canRemoveAfterTransformation()) {
|
||||
@@ -191,6 +191,9 @@ public class MethodInliner {
|
||||
result.getReifiedTypeParametersUsages().mergeAll(transformResult.getReifiedTypeParametersUsages());
|
||||
}
|
||||
}
|
||||
else if (!transformationInfo.getWasAlreadyRegenerated()) {
|
||||
result.addNotChangedClass(oldClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -248,7 +251,7 @@ public class MethodInliner {
|
||||
LocalVarRemapper remapper = new LocalVarRemapper(lambdaParameters, valueParamShift);
|
||||
//TODO add skipped this and receiver
|
||||
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);
|
||||
result.addAllClassesToRemove(lambdaResult);
|
||||
result.mergeWithNotChangeInfo(lambdaResult);
|
||||
|
||||
//return value boxing/unboxing
|
||||
Method bridge = typeMapper.mapAsmMethod(ClosureCodegen.getErasedInvokeFunction(info.getFunctionDescriptor()));
|
||||
|
||||
@@ -26,6 +26,10 @@ interface TransformationInfo {
|
||||
|
||||
val nameGenerator: NameGenerator
|
||||
|
||||
val wasAlreadyRegenerated: Boolean
|
||||
get() = false
|
||||
|
||||
|
||||
fun shouldRegenerate(sameModule: Boolean): Boolean
|
||||
|
||||
fun canRemoveAfterTransformation(): Boolean
|
||||
@@ -77,6 +81,9 @@ class AnonymousObjectTransformationInfo internal constructor(
|
||||
|
||||
lateinit var capturedLambdasToInline: Map<String, LambdaInfo>
|
||||
|
||||
override val wasAlreadyRegenerated: Boolean
|
||||
get() = alreadyRegenerated
|
||||
|
||||
constructor(
|
||||
ownerInternalName: String,
|
||||
needReification: Boolean,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun inline1(crossinline action: () -> Unit) {
|
||||
action();
|
||||
{ action() }()
|
||||
}
|
||||
|
||||
inline fun inline2(crossinline action: () -> Unit) = { action() }
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
var result = "fail"
|
||||
fun box(): String {
|
||||
inline1 { inline2 { result = "OK" }() }
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun inline1(crossinline action: () -> Unit) {
|
||||
{ action () }
|
||||
action();
|
||||
}
|
||||
|
||||
inline fun inline2(crossinline action: () -> Unit) = { action() }
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
var result = "fail"
|
||||
fun box(): String {
|
||||
inline1 { inline2 { result ="OK" }() }
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun inline1(crossinline action: () -> Unit) {
|
||||
{ action () }
|
||||
action();
|
||||
}
|
||||
|
||||
inline fun inline2(crossinline action: () -> Unit) = {
|
||||
action()
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
var result = "fail"
|
||||
fun box(): String {
|
||||
inline1 {
|
||||
inline2 { { result ="OK" }() }()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -140,6 +140,24 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14011.kt")
|
||||
public void testKt14011() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt14011.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14011_2.kt")
|
||||
public void testKt14011_2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt14011_2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14011_3.kt")
|
||||
public void testKt14011_3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt14011_3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6552.kt")
|
||||
public void testKt6552() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
||||
|
||||
+18
@@ -140,6 +140,24 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14011.kt")
|
||||
public void testKt14011() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt14011.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14011_2.kt")
|
||||
public void testKt14011_2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt14011_2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14011_3.kt")
|
||||
public void testKt14011_3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt14011_3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6552.kt")
|
||||
public void testKt6552() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/anonymousObject/kt6552.kt");
|
||||
|
||||
Reference in New Issue
Block a user