[FIR] Correctly detect super type in delegated constructor call
This commit is contained in:
+27
@@ -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)
|
||||
}
|
||||
+32
@@ -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| {
|
||||
|
||||
+1
-1
@@ -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
-1
@@ -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| {
|
||||
|
||||
+1
-1
@@ -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|
|
||||
|
||||
Generated
+18
@@ -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)
|
||||
|
||||
+18
@@ -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)
|
||||
|
||||
+28
-2
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user