FIR: Fix resolution scope of constructor delegation calls

This commit is contained in:
Denis.Zharkov
2021-10-04 15:07:49 +03:00
committed by teamcityserver
parent f038b575f1
commit 0a3c950e7f
12 changed files with 175 additions and 39 deletions
@@ -12541,6 +12541,22 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
public class CorrectFrontendCode {
@Test
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@@ -195,17 +195,6 @@ open class FirTypeResolveTransformer(
return block
}
override fun transformDelegatedConstructorCall(
delegatedConstructorCall: FirDelegatedConstructorCall,
data: Any?
): FirStatement {
delegatedConstructorCall.replaceConstructedTypeRef(
delegatedConstructorCall.constructedTypeRef.transform<FirTypeRef, Any?>(this, data)
)
delegatedConstructorCall.transformCalleeReference(this, data)
return delegatedConstructorCall
}
override fun transformAnnotation(annotation: FirAnnotation, data: Any?): FirStatement {
annotation.transformAnnotationTypeRef(this, data)
return annotation
@@ -230,12 +219,22 @@ open class FirTypeResolveTransformer(
firClass: FirClass,
data: Any?
): FirStatement {
return withScopeCleanup {
// Otherwise annotations may try to resolve
// themselves as inner classes of the `firClass`
// if their names match
withScopeCleanup {
firClass.transformAnnotations(this, null)
if (firClass is FirRegularClass) {
firClass.addTypeParametersScope()
}
// ConstructedTypeRef should be resolved only with type parameters, but not with nested classes and classes from supertypes
for (constructor in firClass.declarations.filterIsInstance<FirConstructor>()) {
constructor.delegatedConstructor?.let(this::resolveConstructedTypeRefForDelegatedConstructorCall)
}
}
return withScopeCleanup {
// ? Is it Ok to use original file session here ?
val superTypes = lookupSuperTypes(
firClass,
@@ -262,10 +261,20 @@ open class FirTypeResolveTransformer(
// Note that annotations are still visited here
// again, although there's no need in it
transformElement(firClass, data) as FirClass
transformElement(firClass, data)
}
}
private fun resolveConstructedTypeRefForDelegatedConstructorCall(
delegatedConstructorCall: FirDelegatedConstructorCall
) {
delegatedConstructorCall.replaceConstructedTypeRef(
delegatedConstructorCall.constructedTypeRef.transform<FirTypeRef, Any?>(this, null)
)
delegatedConstructorCall.transformCalleeReference(this, null)
}
private fun FirMemberDeclaration.addTypeParametersScope() {
if (typeParameters.isNotEmpty()) {
scopes.add(FirMemberTypeParameterScope(this))
@@ -0,0 +1,11 @@
open class OtherClass {
fun foo(): String = "OK"
private class OtherClass<T> {}
}
class Derived : OtherClass()
fun box() = Derived().foo()
@@ -1,23 +0,0 @@
// KT-5508 Stackoverflow in type substitution
abstract class A<T> {
public abstract fun foo(x: T)
public abstract fun bar(x: T)
public inner abstract class B<S> : A<B<S>>() {
public inner <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class C<!><U> : <!UNRESOLVED_REFERENCE!>B<C<U>><!>()
{
// Here B<C<U>> means A<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>>.B<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>.C<U>>
// while for being a correct override it should be A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>
// It happens because at the beginning we search implicit arguments for an outer classes through supertypes
// See TypeResolver.computeImplicitOuterClassArguments for clarifications
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: B<C<U>>) {
throw UnsupportedOperationException()
}
override fun bar(x: A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>) {
throw UnsupportedOperationException()
}
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// KT-5508 Stackoverflow in type substitution
abstract class A<T> {
@@ -12463,6 +12463,22 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
public class CorrectFrontendCode {
@Test
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@@ -12541,6 +12541,22 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
public class CorrectFrontendCode {
@Test
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@@ -10053,6 +10053,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
}
}
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CorrectFrontendCode extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -8922,6 +8922,24 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
}
}
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CorrectFrontendCode extends AbstractIrJsCodegenBoxES6Test {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
}
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -8328,6 +8328,24 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
}
}
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CorrectFrontendCode extends AbstractIrJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
}
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -8293,6 +8293,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
}
}
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CorrectFrontendCode extends AbstractJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
}
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -5634,6 +5634,24 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
}
}
@TestMetadata("compiler/testData/codegen/box/correctFrontendCode")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class CorrectFrontendCode extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInCorrectFrontendCode() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/correctFrontendCode"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("privateNestedClassInSuper.kt")
public void testPrivateNestedClassInSuper() throws Exception {
runTest("compiler/testData/codegen/box/correctFrontendCode/privateNestedClassInSuper.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/dataClasses")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)