FIR: Do not copy type parameters from class to constructors
Use the same instances from class declaration instead Otherwise, primary constructor value parameter types when used in the class body are considered as different from types based on the class type parameters See the test genericConstructors.kt, before this commit "id" call was reported in inapplicable
This commit is contained in:
@@ -9,10 +9,13 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.KtNodeTypes.*
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirErrorFunctionImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
@@ -35,11 +38,9 @@ import org.jetbrains.kotlin.lexer.KtTokens.OPEN_QUOTE
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateEntryWithExpression
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.kotlin.psi.KtUnaryExpression
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
//T can be either PsiElement, or LighterASTNode
|
||||
@@ -150,17 +151,11 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
|
||||
}
|
||||
|
||||
fun KtClassOrObject?.toDelegatedSelfType(firClass: FirRegularClass): FirTypeRef {
|
||||
val typeParameters = firClass.typeParameters.map {
|
||||
FirTypeParameterImpl(it.source, session, it.name, FirTypeParameterSymbol(), Variance.INVARIANT, false).apply {
|
||||
this.bounds += it.bounds
|
||||
addDefaultBoundIfNecessary()
|
||||
}
|
||||
}
|
||||
return FirResolvedTypeRefImpl(
|
||||
this?.toFirSourceElement(),
|
||||
ConeClassLikeTypeImpl(
|
||||
firClass.symbol.toLookupTag(),
|
||||
typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
|
||||
firClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
|
||||
false
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FILE: complexTypes.kt
|
||||
public? final? class C<T, out S> : R|kotlin/Any| {
|
||||
public? constructor<T, S>(): R|a/b/C<T, S>| {
|
||||
public? constructor<T, out S>(): R|a/b/C<T, S>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public? final? inner class D<R, in P> : R|kotlin/Any| {
|
||||
public? constructor<R, P>(): R|a/b/C.D<R, P>| {
|
||||
public? constructor<R, in P>(): R|a/b/C.D<R, P>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ FILE: typeParameters.kt
|
||||
public? final typealias StringList = List<out String>
|
||||
public? final typealias AnyList = List<*>
|
||||
public? abstract class AbstractList<out T : Any> : List<T> {
|
||||
public? constructor<T : Any>(): R|AbstractList<T>| {
|
||||
public? constructor<out T : Any>(): R|AbstractList<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
+15
-8
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.FirSessionBase
|
||||
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWrappedDelegateExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||
@@ -134,16 +135,14 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
override fun visitElement(element: FirElement) {
|
||||
// NB: types are reused sometimes (e.g. in accessors)
|
||||
if (!result.add(element)) {
|
||||
if (element !is FirTypeRef && element !is FirNoReceiverExpression && element !is FirEmptyContractDescription && !element.isExtensionFunctionAnnotation) {
|
||||
val elementDump = StringBuilder().also { element.accept(FirRenderer(it)) }.toString()
|
||||
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
||||
}
|
||||
throwTwiceVisitingError(element)
|
||||
} else if (element !is FirWrappedDelegateExpression) {
|
||||
element.acceptChildren(this)
|
||||
} else {
|
||||
element.delegateProvider.accept(this)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ConsistencyTransformer : FirTransformer<Unit>() {
|
||||
@@ -151,10 +150,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
|
||||
override fun <E : FirElement> transformElement(element: E, data: Unit): CompositeTransformResult<E> {
|
||||
if (!result.add(element)) {
|
||||
if (element !is FirTypeRef && element !is FirNoReceiverExpression && element !is FirEmptyContractDescription && !element.isExtensionFunctionAnnotation) {
|
||||
val elementDump = StringBuilder().also { element.accept(FirRenderer(it)) }.toString()
|
||||
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
||||
}
|
||||
throwTwiceVisitingError(element)
|
||||
} else if (element !is FirWrappedDelegateExpressionImpl) {
|
||||
element.transformChildren(this, Unit)
|
||||
} else {
|
||||
@@ -171,5 +167,16 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
|
||||
}
|
||||
|
||||
private fun throwTwiceVisitingError(element: FirElement) {
|
||||
if (element is FirTypeRef || element is FirNoReceiverExpression || element is FirTypeParameter ||
|
||||
element is FirEmptyContractDescription || element.isExtensionFunctionAnnotation
|
||||
) {
|
||||
return
|
||||
}
|
||||
val elementDump = StringBuilder().also { element.accept(FirRenderer(it)) }.toString()
|
||||
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
||||
}
|
||||
|
||||
|
||||
private val FirElement.isExtensionFunctionAnnotation: Boolean
|
||||
get() = (this as? FirAnnotationCall)?.isExtensionFunctionAnnotationCall == true
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FILE: complexTypes.kt
|
||||
public final class C<T, out S> : R|kotlin/Any| {
|
||||
public constructor<T, S>(): R|a/b/C<T, S>| {
|
||||
public constructor<T, out S>(): R|a/b/C<T, S>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final inner class D<R, in P> : R|kotlin/Any| {
|
||||
public constructor<R, P>(): R|a/b/C.D<R, P>| {
|
||||
public constructor<R, in P>(): R|a/b/C.D<R, P>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ FILE: typeParameters.kt
|
||||
public final typealias StringList = R|List<out kotlin/String>|
|
||||
public final typealias AnyList = R|List<*>|
|
||||
public abstract class AbstractList<out T : R|kotlin/Any|> : R|List<T>| {
|
||||
public constructor<T : R|kotlin/Any|>(): R|AbstractList<T>| {
|
||||
public constructor<out T : R|kotlin/Any|>(): R|AbstractList<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
class A<T>(t: T) {
|
||||
fun foo(x: T) {}
|
||||
}
|
||||
|
||||
abstract class B<E>(e: E) {
|
||||
val myE: E = id(e)
|
||||
val a = A(e)
|
||||
|
||||
fun id(e: E): E = e
|
||||
}
|
||||
|
||||
class C : B<String>("") {
|
||||
fun bar() {
|
||||
a.foo("")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
FILE: genericConstructors.kt
|
||||
public final class A<T> : R|kotlin/Any| {
|
||||
public constructor<T>(t: R|T|): R|A<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun foo(x: R|T|): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
}
|
||||
public abstract class B<E> : R|kotlin/Any| {
|
||||
public constructor<E>(e: R|E|): R|B<E>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val myE: R|E| = this@R|/B|.R|FakeOverride</B.id: R|E|>|(R|<local>/e|)
|
||||
public get(): R|E|
|
||||
|
||||
public final val a: R|A<E>| = R|/A.A|<R|E|>(R|<local>/e|)
|
||||
public get(): R|A<E>|
|
||||
|
||||
public final fun id(e: R|E|): R|E| {
|
||||
^id R|<local>/e|
|
||||
}
|
||||
|
||||
}
|
||||
public final class C : R|B<kotlin/String>| {
|
||||
public constructor(): R|C| {
|
||||
super<R|B<kotlin/String>|>(String())
|
||||
}
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
this@R|/B|.R|FakeOverride</B.a: R|A<kotlin/String>|>|.R|FakeOverride</A.foo: R|kotlin/Unit|>|(String())
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FILE: supertypeGenericsComplex.kt
|
||||
public final class Out<out T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|Out<T>| {
|
||||
public constructor<out T>(): R|Out<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ FILE: eagerResolveOfSingleCallableReference.kt
|
||||
|
||||
}
|
||||
public final class Out<out T> : R|kotlin/Any| {
|
||||
public constructor<T>(): R|Out<T>| {
|
||||
public constructor<out T>(): R|Out<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: typeParameterVsNested.kt
|
||||
public abstract interface Some : R|kotlin/Any| {
|
||||
}
|
||||
public abstract class My<T : R|test/Some|> : R|kotlin/Any| {
|
||||
public constructor<T : R|test/My.Some|>(): R|test/My<T>| {
|
||||
public constructor<T : R|test/Some|>(): R|test/My<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -113,6 +113,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/resolve/functionTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericConstructors.kt")
|
||||
public void testGenericConstructors() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/genericConstructors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericFunctions.kt")
|
||||
public void testGenericFunctions() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/genericFunctions.kt");
|
||||
|
||||
Reference in New Issue
Block a user