[FIR] Fix computeTypeArguments() & add diagnostic for type args
This commit is contained in:
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class A<in T, out K>
|
||||||
|
class B
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a1 = A<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>in Int<!>, <!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out B<!>>()
|
||||||
|
val a2 = A<Int, B>()
|
||||||
|
val a3 = A<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>, <!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
FILE: projectionsOnNonClassTypeArguments.kt
|
||||||
|
public final class A<in T, out K> : R|kotlin/Any| {
|
||||||
|
public constructor<in T, out K>(): R|A<T, K>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class B : R|kotlin/Any| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval a1: R|A<kotlin/Int, B>| = R|/A.A|<in R|kotlin/Int|, out R|B|>()
|
||||||
|
lval a2: R|A<kotlin/Int, B>| = R|/A.A|<R|kotlin/Int|, R|B|>()
|
||||||
|
lval a3: R|A<kotlin/Any?, kotlin/Any?>| = R|/A.A|<*, *>()
|
||||||
|
}
|
||||||
Generated
+5
@@ -901,6 +901,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("projectionsOnNonClassTypeArguments.kt")
|
||||||
|
public void testProjectionsOnNonClassTypeArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/projectionsOnNonClassTypeArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("qualifiedSupertypeExtendedByOtherSupertype.kt")
|
@TestMetadata("qualifiedSupertypeExtendedByOtherSupertype.kt")
|
||||||
public void testQualifiedSupertypeExtendedByOtherSupertype() throws Exception {
|
public void testQualifiedSupertypeExtendedByOtherSupertype() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.kt");
|
||||||
|
|||||||
+5
@@ -901,6 +901,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/notASupertype.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("projectionsOnNonClassTypeArguments.kt")
|
||||||
|
public void testProjectionsOnNonClassTypeArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/projectionsOnNonClassTypeArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("qualifiedSupertypeExtendedByOtherSupertype.kt")
|
@TestMetadata("qualifiedSupertypeExtendedByOtherSupertype.kt")
|
||||||
public void testQualifiedSupertypeExtendedByOtherSupertype() throws Exception {
|
public void testQualifiedSupertypeExtendedByOtherSupertype() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/qualifiedSupertypeExtendedByOtherSupertype.kt");
|
||||||
|
|||||||
+1
@@ -13,6 +13,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirSuperclassNotAccessibleFromInterfaceChecker,
|
FirSuperclassNotAccessibleFromInterfaceChecker,
|
||||||
FirAbstractSuperCallChecker,
|
FirAbstractSuperCallChecker,
|
||||||
FirQualifiedSupertypeExtendedByOtherSupertypeChecker,
|
FirQualifiedSupertypeExtendedByOtherSupertypeChecker,
|
||||||
|
FirProjectionsOnNonClassTypeArgumentChecker
|
||||||
)
|
)
|
||||||
override val functionCallCheckers: List<FirFunctionCallChecker> = listOf()
|
override val functionCallCheckers: List<FirFunctionCallChecker> = listOf()
|
||||||
}
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirStarProjection
|
||||||
|
import org.jetbrains.kotlin.fir.types.FirTypeProjectionWithVariance
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
|
object FirProjectionsOnNonClassTypeArgumentChecker : FirQualifiedAccessChecker() {
|
||||||
|
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
for (it in functionCall.typeArguments) {
|
||||||
|
when (it) {
|
||||||
|
is FirStarProjection -> reporter.report(it.source)
|
||||||
|
is FirTypeProjectionWithVariance -> {
|
||||||
|
if (it.variance != Variance.INVARIANT) {
|
||||||
|
reporter.report(it.source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DiagnosticReporter.report(source: FirSourceElement?) {
|
||||||
|
source?.let {
|
||||||
|
report(FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT.on(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,6 +78,9 @@ object FirErrors {
|
|||||||
val DEPRECATED_MODIFIER_PAIR by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
val DEPRECATED_MODIFIER_PAIR by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||||
val INCOMPATIBLE_MODIFIERS by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
val INCOMPATIBLE_MODIFIERS by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||||
|
|
||||||
|
// projection
|
||||||
|
val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error0<FirSourceElement, PsiElement>()
|
||||||
|
|
||||||
// Control flow diagnostics
|
// Control flow diagnostics
|
||||||
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
|
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
|||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.builder.buildStarProjection
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
@@ -331,7 +332,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
private fun computeTypeArguments(
|
private fun computeTypeArguments(
|
||||||
access: FirQualifiedAccess,
|
access: FirQualifiedAccess,
|
||||||
candidate: Candidate
|
candidate: Candidate
|
||||||
): List<FirTypeProjectionWithVariance> {
|
): List<FirTypeProjection> {
|
||||||
return computeTypeArgumentTypes(candidate)
|
return computeTypeArgumentTypes(candidate)
|
||||||
.mapIndexed { index, type ->
|
.mapIndexed { index, type ->
|
||||||
when (val argument = access.typeArguments.getOrNull(index)) {
|
when (val argument = access.typeArguments.getOrNull(index)) {
|
||||||
@@ -343,6 +344,11 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
variance = argument.variance
|
variance = argument.variance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is FirStarProjection -> {
|
||||||
|
buildStarProjection {
|
||||||
|
source = argument.source
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
buildTypeProjectionWithVariance {
|
buildTypeProjectionWithVariance {
|
||||||
source = argument?.source
|
source = argument?.source
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
fun <T> foo(){}
|
fun <T> foo(){}
|
||||||
foo<in Int>()
|
foo<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>in Int<!>>()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ fun <A, B, C> getTTT(x : Any) {}
|
|||||||
fun foo(a : Any?) {}
|
fun foo(a : Any?) {}
|
||||||
|
|
||||||
public fun main() {
|
public fun main() {
|
||||||
getT<*>()
|
getT<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
|
||||||
<!UNRESOLVED_REFERENCE!>ggetT<!><*>()
|
<!UNRESOLVED_REFERENCE!>ggetT<!><*>()
|
||||||
getTT<*, *>()
|
getTT<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>, <!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
|
||||||
getTT<*, Int>()
|
getTT<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>, Int>()
|
||||||
getTT<Int, *>()
|
getTT<Int, <!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
|
||||||
foo(getTTT<Int, *, Int>(1))
|
foo(getTTT<Int, <!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>, Int>(1))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -19,5 +19,5 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test4(a: A) {
|
fun test4(a: A) {
|
||||||
a.bar<out out Int>()
|
a.bar<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out out Int<!>>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
// NI_EXPECTED_FILE
|
// NI_EXPECTED_FILE
|
||||||
|
|
||||||
val unwrapped = some.<!SYNTAX!><<!><!UNRESOLVED_REFERENCE!>cabc<!><!UNRESOLVED_REFERENCE!><!SYNTAX!>$Wrapper<!><out Any>::unwrap<!>
|
val unwrapped = some.<!SYNTAX!><<!><!UNRESOLVED_REFERENCE!>cabc<!><!UNRESOLVED_REFERENCE!><!SYNTAX!>$Wrapper<!><<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out Any<!>>::unwrap<!>
|
||||||
+2
-2
@@ -2,5 +2,5 @@ class In<in T>(val x: Any)
|
|||||||
|
|
||||||
typealias InAlias<T> = In<T>
|
typealias InAlias<T> = In<T>
|
||||||
|
|
||||||
val test1 = In<out String>("")
|
val test1 = In<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out String<!>>("")
|
||||||
val test2 = InAlias<out String>("")
|
val test2 = InAlias<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out String<!>>("")
|
||||||
|
|||||||
+1
-1
@@ -11,5 +11,5 @@ typealias CT<T> = C<T>
|
|||||||
val test1 = CStar()
|
val test1 = CStar()
|
||||||
val test2 = CIn()
|
val test2 = CIn()
|
||||||
val test3 = COut()
|
val test3 = COut()
|
||||||
val test4 = CT<*>()
|
val test4 = CT<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
|
||||||
val test5 = CT<CT<*>>()
|
val test5 = CT<CT<*>>()
|
||||||
Reference in New Issue
Block a user