IR: close over the set of captured type parameters
This commit is contained in:
+12
-15
@@ -55,7 +55,7 @@ class ClosureAnnotator(irFile: IrFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ClosureBuilder(val owner: IrDeclaration) {
|
private class ClosureBuilder(val owner: IrDeclaration) {
|
||||||
val capturedValues = mutableSetOf<IrValueSymbol>()
|
private val capturedValues = mutableSetOf<IrValueSymbol>()
|
||||||
private val declaredValues = mutableSetOf<IrValueDeclaration>()
|
private val declaredValues = mutableSetOf<IrValueDeclaration>()
|
||||||
private val includes = mutableSetOf<ClosureBuilder>()
|
private val includes = mutableSetOf<ClosureBuilder>()
|
||||||
|
|
||||||
@@ -70,15 +70,16 @@ class ClosureAnnotator(irFile: IrFile) {
|
|||||||
* variables declared in the node.
|
* variables declared in the node.
|
||||||
*/
|
*/
|
||||||
fun buildClosure(): Closure {
|
fun buildClosure(): Closure {
|
||||||
val result = mutableSetOf<IrValueSymbol>().apply { addAll(capturedValues) }
|
|
||||||
includes.forEach { builder ->
|
includes.forEach { builder ->
|
||||||
if (!builder.processed) {
|
if (!builder.processed) {
|
||||||
builder.processed = true
|
builder.processed = true
|
||||||
builder.buildClosure().capturedValues.filterTo(result) { isExternal(it.owner) }
|
val subClosure = builder.buildClosure()
|
||||||
|
subClosure.capturedValues.filterTo(capturedValues) { isExternal(it.owner) }
|
||||||
|
subClosure.capturedTypeParameters.filterTo(capturedTypeParameters) { isExternal(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: We can save the closure and reuse it.
|
// TODO: We can save the closure and reuse it.
|
||||||
return Closure(result.toList(), capturedTypeParameters.toList())
|
return Closure(capturedValues.toList(), capturedTypeParameters.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -110,18 +111,14 @@ class ClosureAnnotator(irFile: IrFile) {
|
|||||||
|
|
||||||
fun seeType(type: IrType) {
|
fun seeType(type: IrType) {
|
||||||
if (type !is IrSimpleType) return
|
if (type !is IrSimpleType) return
|
||||||
(type.classifier as? IrTypeParameterSymbol)?.let { typeParameterSymbol ->
|
val classifier = type.classifier
|
||||||
val typeParameter = typeParameterSymbol.owner
|
if (classifier is IrTypeParameterSymbol && isExternal(classifier.owner) && capturedTypeParameters.add(classifier.owner))
|
||||||
if (isExternal(typeParameter))
|
classifier.owner.superTypes.forEach(::seeType)
|
||||||
capturedTypeParameters.add(typeParameter)
|
type.arguments.forEach {
|
||||||
|
(it as? IrTypeProjection)?.type?.let(::seeType)
|
||||||
}
|
}
|
||||||
for (arg in type.arguments) {
|
type.abbreviation?.arguments?.forEach {
|
||||||
(arg as? IrTypeProjection)?.let { seeType(arg.type) }
|
(it as? IrTypeProjection)?.type?.let(::seeType)
|
||||||
}
|
|
||||||
type.abbreviation?.let { abbreviation ->
|
|
||||||
for (arg in abbreviation.arguments) {
|
|
||||||
(arg as? IrTypeProjection)?.let { seeType(arg.type) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
fun <T, V : T> f(x: V): V {
|
||||||
|
fun g(y: V) = y
|
||||||
|
return g(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = f<Any, String>("OK")
|
||||||
+5
@@ -12023,6 +12023,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("captureUpperBoundedTypeParameter.kt")
|
||||||
|
public void testCaptureUpperBoundedTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("definedWithinLambda.kt")
|
@TestMetadata("definedWithinLambda.kt")
|
||||||
public void testDefinedWithinLambda() throws Exception {
|
public void testDefinedWithinLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
||||||
|
|||||||
+5
@@ -12023,6 +12023,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("captureUpperBoundedTypeParameter.kt")
|
||||||
|
public void testCaptureUpperBoundedTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("definedWithinLambda.kt")
|
@TestMetadata("definedWithinLambda.kt")
|
||||||
public void testDefinedWithinLambda() throws Exception {
|
public void testDefinedWithinLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
||||||
|
|||||||
+5
@@ -10873,6 +10873,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("captureUpperBoundedTypeParameter.kt")
|
||||||
|
public void testCaptureUpperBoundedTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("definedWithinLambda.kt")
|
@TestMetadata("definedWithinLambda.kt")
|
||||||
public void testDefinedWithinLambda() throws Exception {
|
public void testDefinedWithinLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
||||||
|
|||||||
+5
@@ -10873,6 +10873,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("captureUpperBoundedTypeParameter.kt")
|
||||||
|
public void testCaptureUpperBoundedTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("definedWithinLambda.kt")
|
@TestMetadata("definedWithinLambda.kt")
|
||||||
public void testDefinedWithinLambda() throws Exception {
|
public void testDefinedWithinLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
||||||
|
|||||||
Generated
+5
@@ -9383,6 +9383,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("captureUpperBoundedTypeParameter.kt")
|
||||||
|
public void testCaptureUpperBoundedTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("definedWithinLambda.kt")
|
@TestMetadata("definedWithinLambda.kt")
|
||||||
public void testDefinedWithinLambda() throws Exception {
|
public void testDefinedWithinLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
||||||
|
|||||||
+5
@@ -10458,6 +10458,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/callInlineLocalInLambda.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("captureUpperBoundedTypeParameter.kt")
|
||||||
|
public void testCaptureUpperBoundedTypeParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/functions/localFunctions/captureUpperBoundedTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("definedWithinLambda.kt")
|
@TestMetadata("definedWithinLambda.kt")
|
||||||
public void testDefinedWithinLambda() throws Exception {
|
public void testDefinedWithinLambda() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
runTest("compiler/testData/codegen/box/functions/localFunctions/definedWithinLambda.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user