[FIR] Correctly detect super type in delegated constructor call

This commit is contained in:
Dmitriy Novozhilov
2020-04-16 17:46:18 +03:00
parent adfd478361
commit 7f02d57d88
56 changed files with 199 additions and 230 deletions
@@ -0,0 +1,27 @@
// FILE: AJava.java
public class AJava {
public AJava(String s) {}
}
// FILE: main.kt
class BJava : AJava, C {
constructor(s: String) : super(s)
}
open class AKt(val s: String)
class BKt : AKt, C {
constructor(s: String) : super(s)
}
interface C
typealias QQQ = AKt
typealias DDD = C
class CKt : QQQ, DDD {
constructor(s: String) : super(s)
}
@@ -0,0 +1,32 @@
FILE: main.kt
public final class BJava : R|AJava|, R|C| {
public constructor(s: R|kotlin/String|): R|BJava| {
super<R|AJava|>(R|<local>/s|)
}
}
public open class AKt : R|kotlin/Any| {
public constructor(s: R|kotlin/String|): R|AKt| {
super<R|kotlin/Any|>()
}
public final val s: R|kotlin/String| = R|<local>/s|
public get(): R|kotlin/String|
}
public final class BKt : R|AKt|, R|C| {
public constructor(s: R|kotlin/String|): R|BKt| {
super<R|AKt|>(R|<local>/s|)
}
}
public abstract interface C : R|kotlin/Any| {
}
public final typealias QQQ = R|AKt|
public final typealias DDD = R|C|
public final class CKt : R|QQQ|, R|DDD| {
public constructor(s: R|kotlin/String|): R|CKt| {
super<R|QQQ|>(R|<local>/s|)
}
}
@@ -8,7 +8,7 @@ FILE: LinkedList.kt
FILE: HashSet.kt
public final class HashSet<T> : R|java/util/HashSet<T>| {
public constructor<T>(): R|util/HashSet<T>| {
super<R|kotlin/Any|>()
super<R|java/util/HashSet<T>|>()
}
}
@@ -10,7 +10,7 @@ FILE: notASupertype.kt
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|kotlin/Any|>()
super<R|A|>()
}
public final fun g(): R|kotlin/Unit| {
@@ -13,7 +13,7 @@ FILE: checkArguments.kt
}
public final class C : R|B| {
public constructor(): R|C| {
super<R|kotlin/Any|>()
super<R|B|>()
}
}
@@ -1,7 +1,7 @@
FILE: test.kt
public final class MyDecorator : R|Decorator<LookupElement>| {
public constructor(): R|MyDecorator| {
super<R|kotlin/Any|>()
super<R|Decorator<LookupElement>|>()
}
public final override fun getLookupString(): R|kotlin/String| {
@@ -13,7 +13,7 @@ FILE: test.kt
public final class Extra : R|test/Test| {
public constructor(x: R|kotlin/Int|): R|test/Test.Extra| {
super<R|kotlin/Any|>()
super<R|test/Test|>()
}
public final val x: R|kotlin/Int| = R|<local>/x|
@@ -723,6 +723,24 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/constructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Constructors extends AbstractFirDiagnosticsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInConstructors() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/constructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("noSuperCallInSupertypes.kt")
public void testNoSuperCallInSupertypes() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constructors/noSuperCallInSupertypes.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/delegates")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -723,6 +723,24 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/constructors")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Constructors extends AbstractFirDiagnosticsWithLightTreeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInConstructors() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/constructors"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("noSuperCallInSupertypes.kt")
public void testNoSuperCallInSupertypes() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/constructors/noSuperCallInSupertypes.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/delegates")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -6,9 +6,9 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
import org.jetbrains.kotlin.fir.expressions.builder.buildVariableAssignment
import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.*
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.candidate
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
@@ -604,6 +606,21 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
when (delegatedConstructorCall.calleeReference) {
is FirResolvedNamedReference, is FirErrorNamedReference -> return delegatedConstructorCall.compose()
}
if (delegatedConstructorCall.isSuper && delegatedConstructorCall.constructedTypeRef is FirImplicitTypeRef) {
val containers = components.context.containers
val containingClass = containers[containers.lastIndex - 1] as FirClass<*>
val superClass = containingClass.superTypeRefs.firstOrNull {
if (it !is FirResolvedTypeRef) return@firstOrNull false
val declaration = extractSuperTypeDeclaration(it) ?: return@firstOrNull false
declaration.classKind == ClassKind.CLASS
} as FirResolvedTypeRef? ?: session.builtinTypes.anyType
delegatedConstructorCall.replaceConstructedTypeRef(superClass)
delegatedConstructorCall.replaceCalleeReference(buildExplicitSuperReference {
source = delegatedConstructorCall.calleeReference.source
superTypeRef = superClass
})
}
dataFlowAnalyzer.enterCall(delegatedConstructorCall)
var callCompleted = true
var result = delegatedConstructorCall
@@ -661,6 +678,15 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
}
}
private fun extractSuperTypeDeclaration(typeRef: FirTypeRef): FirRegularClass? {
if (typeRef !is FirResolvedTypeRef) return null
return when (val declaration = typeRef.firClassLike(session)) {
is FirRegularClass -> declaration
is FirTypeAlias -> extractSuperTypeDeclaration(declaration.expandedTypeRef)
else -> null
}
}
@OptIn(ExperimentalStdlibApi::class)
override fun transformAugmentedArraySetCall(augmentedArraySetCall: FirAugmentedArraySetCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
assert(augmentedArraySetCall.operation in FirOperation.ASSIGNMENTS)