FIR checker: check if callable reference targets are allowed members
This commit is contained in:
committed by
Mikhail Glukhikh
parent
6769ce0e2b
commit
8d8ed4cc18
+2
-2
@@ -36,8 +36,8 @@ class NoGenericTest {
|
|||||||
fun B.extensionFun(): A = A()
|
fun B.extensionFun(): A = A()
|
||||||
|
|
||||||
fun test_1() {
|
fun test_1() {
|
||||||
val extensionValRef = B::extensionVal
|
val extensionValRef = <!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>B::extensionVal<!>
|
||||||
val extensionFunRef = B::extensionFun
|
val extensionFunRef = <!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>B::extensionFun<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_2() {
|
fun test_2() {
|
||||||
|
|||||||
+6
@@ -2968,6 +2968,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/property"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/property"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/property/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("classFromClass.kt")
|
@TestMetadata("classFromClass.kt")
|
||||||
public void testClassFromClass() throws Exception {
|
public void testClassFromClass() throws Exception {
|
||||||
|
|||||||
+15
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiTypeElement
|
import com.intellij.psi.PsiTypeElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
@@ -33,6 +35,15 @@ import kotlin.properties.ReadOnlyProperty
|
|||||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
||||||
@OptIn(PrivateForInline::class)
|
@OptIn(PrivateForInline::class)
|
||||||
object DIAGNOSTICS_LIST : DiagnosticList() {
|
object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||||
|
val MetaErrors by object : DiagnosticGroup("Meta-errors") {
|
||||||
|
val UNSUPPORTED by error<FirSourceElement, PsiElement> {
|
||||||
|
parameter<String>("unsupported")
|
||||||
|
}
|
||||||
|
val UNSUPPORTED_FEATURE by error<FirSourceElement, PsiElement> {
|
||||||
|
parameter<Pair<LanguageFeature, LanguageVersionSettings>>("unsupportedFeature")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val Miscellaneous by object : DiagnosticGroup("Miscellaneous") {
|
val Miscellaneous by object : DiagnosticGroup("Miscellaneous") {
|
||||||
val SYNTAX by error<FirSourceElement, PsiElement>()
|
val SYNTAX by error<FirSourceElement, PsiElement>()
|
||||||
val OTHER_ERROR by error<FirSourceElement, PsiElement>()
|
val OTHER_ERROR by error<FirSourceElement, PsiElement>()
|
||||||
@@ -264,7 +275,11 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val REFLECTION by object : DiagnosticGroup("Reflection") {
|
val REFLECTION by object : DiagnosticGroup("Reflection") {
|
||||||
|
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error<FirSourceElement, KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||||
|
parameter<FirCallableDeclaration<*>>("referencedDeclaration")
|
||||||
|
}
|
||||||
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
|
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
|
||||||
|
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error<FirSourceElement, KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
||||||
|
|
||||||
val CLASS_LITERAL_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
|
val CLASS_LITERAL_LHS_NOT_A_CLASS by error<FirSourceElement, KtExpression>()
|
||||||
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<FirSourceElement, KtExpression>()
|
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<FirSourceElement, KtExpression>()
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiTypeElement
|
import com.intellij.psi.PsiTypeElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
@@ -54,6 +56,10 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
object FirErrors {
|
object FirErrors {
|
||||||
|
// Meta-errors
|
||||||
|
val UNSUPPORTED by error1<FirSourceElement, PsiElement, String>()
|
||||||
|
val UNSUPPORTED_FEATURE by error1<FirSourceElement, PsiElement, Pair<LanguageFeature, LanguageVersionSettings>>()
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
val SYNTAX by error0<FirSourceElement, PsiElement>()
|
val SYNTAX by error0<FirSourceElement, PsiElement>()
|
||||||
val OTHER_ERROR by error0<FirSourceElement, PsiElement>()
|
val OTHER_ERROR by error0<FirSourceElement, PsiElement>()
|
||||||
@@ -201,7 +207,9 @@ object FirErrors {
|
|||||||
val TYPE_PARAMETER_AS_REIFIED by error1<FirSourceElement, PsiElement, FirTypeParameterSymbol>()
|
val TYPE_PARAMETER_AS_REIFIED by error1<FirSourceElement, PsiElement, FirTypeParameterSymbol>()
|
||||||
|
|
||||||
// Reflection
|
// Reflection
|
||||||
|
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<FirSourceElement, KtExpression, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
|
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
|
||||||
|
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error0<FirSourceElement, KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
|
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<FirSourceElement, KtExpression>()
|
||||||
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0<FirSourceElement, KtExpression>()
|
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0<FirSourceElement, KtExpression>()
|
||||||
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<FirSourceElement, PsiElement, ConeKotlinType>()
|
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<FirSourceElement, PsiElement, ConeKotlinType>()
|
||||||
|
|||||||
+13
@@ -186,3 +186,16 @@ internal fun FirRegularClass.isInlineOrValueClass(): Boolean {
|
|||||||
|
|
||||||
return isInline || hasModifier(KtTokens.VALUE_KEYWORD)
|
return isInline || hasModifier(KtTokens.VALUE_KEYWORD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val FirMemberDeclaration.isLocalMember: Boolean
|
||||||
|
get() = when (this) {
|
||||||
|
is FirProperty -> this.isLocal
|
||||||
|
is FirRegularClass -> this.isLocal
|
||||||
|
is FirSimpleFunction -> this.isLocal
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val FirCallableMemberDeclaration<*>.isExtensionMember: Boolean
|
||||||
|
get() {
|
||||||
|
return receiverTypeRef != null && dispatchReceiverType != null
|
||||||
|
}
|
||||||
|
|||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isExtensionMember
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.containingClass
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
||||||
|
|
||||||
|
object FirCallableReferenceChecker : FirQualifiedAccessChecker() {
|
||||||
|
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (expression !is FirCallableReferenceAccess) return
|
||||||
|
// [FirGetClassCallChecker] will check [FirGetClassCall].
|
||||||
|
if (expression is FirGetClassCall) return
|
||||||
|
|
||||||
|
checkReferenceIsToAllowedMember(expression, context, reporter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// See FE 1.0 [DoubleColonExpressionResolver#checkReferenceIsToAllowedMember]
|
||||||
|
private fun checkReferenceIsToAllowedMember(
|
||||||
|
callableReferenceAccess: FirCallableReferenceAccess,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
// UNRESOLVED_REFERENCE will be reported separately.
|
||||||
|
val reference = callableReferenceAccess.calleeReference as? FirResolvedNamedReference ?: return
|
||||||
|
|
||||||
|
val source = reference.source ?: return
|
||||||
|
if (source.kind is FirFakeSourceElementKind) return
|
||||||
|
|
||||||
|
val referredDeclaration = reference.resolvedSymbol.fir
|
||||||
|
if (referredDeclaration is FirConstructor && referredDeclaration.containingClass?.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
|
reporter.reportOn(source, FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, context)
|
||||||
|
}
|
||||||
|
if ((referredDeclaration as? FirCallableMemberDeclaration<*>)?.isExtensionMember == true &&
|
||||||
|
(referredDeclaration as? FirMemberDeclaration)?.isLocalMember == false
|
||||||
|
) {
|
||||||
|
reporter.reportOn(source, FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED, referredDeclaration, context)
|
||||||
|
}
|
||||||
|
// The counterpart in FE 1.0 checks if the given descriptor is VariableDescriptor yet not PropertyDescriptor.
|
||||||
|
// Here, we explicitly check if the referred declaration/symbol is value parameter, local variable, or backing field.
|
||||||
|
if (referredDeclaration is FirValueParameter ||
|
||||||
|
(referredDeclaration is FirProperty && (referredDeclaration.isLocal || reference.resolvedSymbol is FirBackingFieldSymbol))
|
||||||
|
) {
|
||||||
|
// TODO: we can't set positioning strategy to meta error. Should report on reference expression, not entire reference access.
|
||||||
|
reporter.reportOn(source, FirErrors.UNSUPPORTED, "References to variables aren't supported yet", context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-8
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
@@ -110,14 +111,6 @@ object RedundantVisibilityModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirMemberDeclaration.isLocalMember: Boolean
|
|
||||||
get() = when (this) {
|
|
||||||
is FirProperty -> this.isLocal
|
|
||||||
is FirRegularClass -> this.isLocal
|
|
||||||
is FirSimpleFunction -> this.isLocal
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
private val CheckerContext.containingPropertyVisibility
|
private val CheckerContext.containingPropertyVisibility
|
||||||
get() = (this.containingDeclarations.last() as? FirProperty)?.visibility
|
get() = (this.containingDeclarations.last() as? FirProperty)?.visibility
|
||||||
}
|
}
|
||||||
|
|||||||
+15
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||||
|
import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
||||||
@@ -44,6 +45,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_A
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT
|
||||||
@@ -87,6 +89,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INT
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE
|
||||||
@@ -207,6 +210,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_CALL
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_INFIX_CALL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_INFIX_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_OPERATOR_CALL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_OPERATOR_CALL
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSUPPORTED
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSUPPORTED_FEATURE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
||||||
@@ -245,6 +250,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
// + - Better message required
|
// + - Better message required
|
||||||
// # - The new diagnostic differs from the old FE's one
|
// # - The new diagnostic differs from the old FE's one
|
||||||
val MAP = FirDiagnosticFactoryToRendererMap("FIR").also { map ->
|
val MAP = FirDiagnosticFactoryToRendererMap("FIR").also { map ->
|
||||||
|
// Meta-errors
|
||||||
|
map.put(UNSUPPORTED, "Unsupported [{0}]", TO_STRING)
|
||||||
|
map.put(UNSUPPORTED_FEATURE, "{0}", LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.UNSUPPORTED))
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
map.put(SYNTAX, "Syntax error")
|
map.put(SYNTAX, "Syntax error")
|
||||||
map.put(OTHER_ERROR, "Unknown (other) error")
|
map.put(OTHER_ERROR, "Unknown (other) error")
|
||||||
@@ -422,7 +431,13 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead", SYMBOL)
|
map.put(TYPE_PARAMETER_AS_REIFIED, "Cannot use ''{0}'' as reified type parameter. Use a class instead", SYMBOL)
|
||||||
|
|
||||||
// Reflection
|
// Reflection
|
||||||
|
map.put(
|
||||||
|
EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED,
|
||||||
|
"''{0}'' is a member and an extension at the same time. References to such elements are not allowed",
|
||||||
|
NAME
|
||||||
|
)
|
||||||
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of a callable reference cannot be a type parameter")
|
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of a callable reference cannot be a type parameter")
|
||||||
|
map.put(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, "Annotation class cannot be instantiated")
|
||||||
|
|
||||||
map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal")
|
map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal")
|
||||||
map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable")
|
map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable")
|
||||||
|
|||||||
+1
@@ -14,6 +14,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker> = setOf(
|
override val qualifiedAccessCheckers: Set<FirQualifiedAccessChecker> = setOf(
|
||||||
|
FirCallableReferenceChecker,
|
||||||
FirSuperNotAvailableChecker,
|
FirSuperNotAvailableChecker,
|
||||||
FirNotASupertypeChecker,
|
FirNotASupertypeChecker,
|
||||||
FirSuperclassNotAccessibleFromInterfaceChecker,
|
FirSuperclassNotAccessibleFromInterfaceChecker,
|
||||||
|
|||||||
Vendored
+2
-2
@@ -7,6 +7,6 @@ enum class D
|
|||||||
fun main() {
|
fun main() {
|
||||||
<!UNRESOLVED_REFERENCE!>::A<!>
|
<!UNRESOLVED_REFERENCE!>::A<!>
|
||||||
::B
|
::B
|
||||||
::C // KT-3465
|
<!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>::C<!> // KT-3465
|
||||||
<!UNRESOLVED_REFERENCE!>::D<!>
|
<!UNRESOLVED_REFERENCE!>::D<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
annotation class Ann(val prop: String)
|
annotation class Ann(val prop: String)
|
||||||
|
|
||||||
val annCtorRef = ::Ann
|
val annCtorRef = <!CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR!>::Ann<!>
|
||||||
val annClassRef = Ann::class
|
val annClassRef = Ann::class
|
||||||
val annPropRef = Ann::prop
|
val annPropRef = Ann::prop
|
||||||
|
|||||||
Vendored
+4
-4
@@ -4,11 +4,11 @@ class A {
|
|||||||
fun A.extA(x: String) = x
|
fun A.extA(x: String) = x
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
Int::extInt
|
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>Int::extInt<!>
|
||||||
A::extA
|
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>A::extA<!>
|
||||||
|
|
||||||
eat(Int::extInt)
|
eat(<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>Int::extInt<!>)
|
||||||
eat(A::extA)
|
eat(<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>A::extA<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -14,10 +14,10 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
String::ext
|
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>String::ext<!>
|
||||||
<!UNRESOLVED_REFERENCE!>Obj::ext<!>
|
<!UNRESOLVED_REFERENCE!>Obj::ext<!>
|
||||||
|
|
||||||
String::ext2
|
<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>String::ext2<!>
|
||||||
<!UNRESOLVED_REFERENCE!>A.Companion::ext2<!>
|
<!UNRESOLVED_REFERENCE!>A.Companion::ext2<!>
|
||||||
<!UNRESOLVED_REFERENCE!>A::ext2<!>
|
<!UNRESOLVED_REFERENCE!>A::ext2<!>
|
||||||
|
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
val i: Int = 10
|
||||||
|
get() {
|
||||||
|
<!UNSUPPORTED!>::field<!>
|
||||||
|
return field
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||||
|
|
||||||
|
val i: Int = 10
|
||||||
|
get() {
|
||||||
|
::<!UNSUPPORTED!>field<!>
|
||||||
|
return field
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val i: kotlin.Int = 10
|
||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
fun a() {
|
fun a() {
|
||||||
val x = 10
|
val x = 10
|
||||||
foo(::x)
|
foo(<!UNSUPPORTED!>::x<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo(a: Any) {}
|
fun foo(a: Any) {}
|
||||||
|
|||||||
+1
-1
@@ -5,4 +5,4 @@ fun a() {
|
|||||||
foo(::<!UNSUPPORTED!>x<!>)
|
foo(::<!UNSUPPORTED!>x<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo(a: Any) {}
|
fun foo(a: Any) {}
|
||||||
|
|||||||
+4
-4
@@ -3,13 +3,13 @@
|
|||||||
fun eat(value: Any) {}
|
fun eat(value: Any) {}
|
||||||
|
|
||||||
fun test(param: String) {
|
fun test(param: String) {
|
||||||
val a = ::param
|
val a = <!UNSUPPORTED!>::param<!>
|
||||||
|
|
||||||
val local = "local"
|
val local = "local"
|
||||||
val b = ::local
|
val b = <!UNSUPPORTED!>::local<!>
|
||||||
|
|
||||||
val lambda = { -> }
|
val lambda = { -> }
|
||||||
val g = ::lambda
|
val g = <!UNSUPPORTED!>::lambda<!>
|
||||||
|
|
||||||
eat(::param)
|
eat(<!UNSUPPORTED!>::param<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,6 +9,6 @@ class Foo {
|
|||||||
fun main() {
|
fun main() {
|
||||||
val f = Foo()
|
val f = Foo()
|
||||||
val a: Int
|
val a: Int
|
||||||
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, ::a) // no exception after fix
|
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, <!UNSUPPORTED!>::a<!>) // no exception after fix
|
||||||
<!UNRESOLVED_REFERENCE!>print<!>(<!UNINITIALIZED_VARIABLE!>a<!>)
|
<!UNRESOLVED_REFERENCE!>print<!>(<!UNINITIALIZED_VARIABLE!>a<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -9,6 +9,6 @@ class Foo {
|
|||||||
fun main(x: Int) {
|
fun main(x: Int) {
|
||||||
val f = Foo()
|
val f = Foo()
|
||||||
val a: Int
|
val a: Int
|
||||||
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, ::x) // no exception after fix
|
<!VARIABLE_EXPECTED!>get()<!> = f.getValue(null, <!UNSUPPORTED!>::x<!>) // no exception after fix
|
||||||
<!UNRESOLVED_REFERENCE!>print<!>(<!UNINITIALIZED_VARIABLE!>a<!>)
|
<!UNRESOLVED_REFERENCE!>print<!>(<!UNINITIALIZED_VARIABLE!>a<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ interface TypeConstructor
|
|||||||
|
|
||||||
class Refiner {
|
class Refiner {
|
||||||
val memoizedFunctionLambda = createMemoizedFunction { it.foo() } // error type infered, no diagnostic, BAD, backend fails
|
val memoizedFunctionLambda = createMemoizedFunction { it.foo() } // error type infered, no diagnostic, BAD, backend fails
|
||||||
val memoizedFunctionReference = createMemoizedFunction(TypeConstructor::foo) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine
|
val memoizedFunctionReference = createMemoizedFunction(<!EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED!>TypeConstructor::foo<!>) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine
|
||||||
val memoizedFunctionTypes = createMemoizedFunction<TypeConstructor, Boolean> { it.foo() } // works fine
|
val memoizedFunctionTypes = createMemoizedFunction<TypeConstructor, Boolean> { it.foo() } // works fine
|
||||||
|
|
||||||
private fun TypeConstructor.foo(): Boolean = true
|
private fun TypeConstructor.foo(): Boolean = true
|
||||||
|
|||||||
Generated
+6
@@ -2974,6 +2974,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/property"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/callableReference/property"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("backingField.kt")
|
||||||
|
public void testBackingField() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/property/backingField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("classFromClass.kt")
|
@TestMetadata("classFromClass.kt")
|
||||||
public void testClassFromClass() throws Exception {
|
public void testClassFromClass() throws Exception {
|
||||||
|
|||||||
+17
-5
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.idea.frontend.api.fir.generator
|
package org.jetbrains.kotlin.idea.frontend.api.fir.generator
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
@@ -47,7 +49,7 @@ object HLDiagnosticConverter {
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun convertParameter(index: Int, diagnosticParameter: DiagnosticParameter): HLDiagnosticParameter {
|
private fun convertParameter(index: Int, diagnosticParameter: DiagnosticParameter): HLDiagnosticParameter {
|
||||||
val conversion = FirToKtConversionCreator.creatConversion(diagnosticParameter.type)
|
val conversion = FirToKtConversionCreator.createConversion(diagnosticParameter.type)
|
||||||
val convertedType = conversion.convertType(diagnosticParameter.type)
|
val convertedType = conversion.convertType(diagnosticParameter.type)
|
||||||
return HLDiagnosticParameter(
|
return HLDiagnosticParameter(
|
||||||
name = diagnosticParameter.name,
|
name = diagnosticParameter.name,
|
||||||
@@ -73,12 +75,12 @@ object HLDiagnosticConverter {
|
|||||||
|
|
||||||
|
|
||||||
private object FirToKtConversionCreator {
|
private object FirToKtConversionCreator {
|
||||||
fun creatConversion(type: KType): HLParameterConversion {
|
fun createConversion(type: KType): HLParameterConversion {
|
||||||
val kClass = type.classifier as KClass<*>
|
val kClass = type.classifier as KClass<*>
|
||||||
return tryMapAllowedType(kClass)
|
return tryMapAllowedType(kClass)
|
||||||
?: tryMapPsiElementType(type, kClass)
|
?: tryMapPsiElementType(type, kClass)
|
||||||
?: tryMapFirTypeToKtType(kClass)
|
?: tryMapFirTypeToKtType(kClass)
|
||||||
?: tryMapCollectionType(type, kClass)
|
?: tryMapPlatformType(type, kClass)
|
||||||
?: error("Unsupported type $type, consider add corresponding mapping")
|
?: error("Unsupported type $type, consider add corresponding mapping")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,12 +93,20 @@ private object FirToKtConversionCreator {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryMapCollectionType(type: KType, kClass: KClass<*>): HLParameterConversion? {
|
private fun tryMapPlatformType(type: KType, kClass: KClass<*>): HLParameterConversion? {
|
||||||
if (kClass.isSubclassOf(Collection::class)) {
|
if (kClass.isSubclassOf(Collection::class)) {
|
||||||
val elementType = type.arguments.single().type ?: return HLIdParameterConversion
|
val elementType = type.arguments.single().type ?: return HLIdParameterConversion
|
||||||
return HLMapParameterConversion(
|
return HLMapParameterConversion(
|
||||||
parameterName = elementType.kClass.simpleName!!.decapitalize(),
|
parameterName = elementType.kClass.simpleName!!.decapitalize(),
|
||||||
mappingConversion = creatConversion(elementType)
|
mappingConversion = createConversion(elementType)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (kClass.isSubclassOf(Pair::class)) {
|
||||||
|
val first = type.arguments.getOrNull(0)?.type ?: return HLIdParameterConversion
|
||||||
|
val second = type.arguments.getOrNull(1)?.type ?: return HLIdParameterConversion
|
||||||
|
return HLPairParameterConversion(
|
||||||
|
mappingConversionFirst = createConversion(first),
|
||||||
|
mappingConversionSecond = createConversion(second)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@@ -175,6 +185,8 @@ private object FirToKtConversionCreator {
|
|||||||
Visibility::class,
|
Visibility::class,
|
||||||
WhenMissingCase::class,
|
WhenMissingCase::class,
|
||||||
ForbiddenNamedArgumentsTarget::class,
|
ForbiddenNamedArgumentsTarget::class,
|
||||||
|
LanguageFeature::class,
|
||||||
|
LanguageVersionSettings::class,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val KType.kClass: KClass<*>
|
private val KType.kClass: KClass<*>
|
||||||
|
|||||||
+27
@@ -47,6 +47,33 @@ class HLMapParameterConversion(
|
|||||||
override val importsToAdd get() = mappingConversion.importsToAdd
|
override val importsToAdd get() = mappingConversion.importsToAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HLPairParameterConversion(
|
||||||
|
private val mappingConversionFirst: HLParameterConversion,
|
||||||
|
private val mappingConversionSecond: HLParameterConversion,
|
||||||
|
) : HLParameterConversion() {
|
||||||
|
override fun convertExpression(expression: String, context: ConversionContext): String = expression
|
||||||
|
|
||||||
|
override fun convertType(type: KType): KType {
|
||||||
|
val first = type.arguments.getOrNull(0)?.type ?: return type
|
||||||
|
val second = type.arguments.getOrNull(1)?.type ?: return type
|
||||||
|
return Pair::class.createType(
|
||||||
|
arguments = listOf(
|
||||||
|
KTypeProjection(
|
||||||
|
variance = KVariance.INVARIANT,
|
||||||
|
type = mappingConversionFirst.convertType(first)
|
||||||
|
),
|
||||||
|
KTypeProjection(
|
||||||
|
variance = KVariance.INVARIANT,
|
||||||
|
type = mappingConversionSecond.convertType(second)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val importsToAdd
|
||||||
|
get() = mappingConversionFirst.importsToAdd + mappingConversionSecond.importsToAdd
|
||||||
|
}
|
||||||
|
|
||||||
class HLFunctionCallConversion(
|
class HLFunctionCallConversion(
|
||||||
private val callTemplate: String,
|
private val callTemplate: String,
|
||||||
private val callType: KType,
|
private val callType: KType,
|
||||||
|
|||||||
+6
-6
@@ -10,15 +10,15 @@ import kotlin.reflect.KClass
|
|||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
|
|
||||||
internal fun SmartPrinter.printTypeWithShortNames(type: KType) {
|
internal fun SmartPrinter.printTypeWithShortNames(type: KType) {
|
||||||
print((type.classifier as KClass<*>).simpleName!!)
|
fun typeConversion(type: KType): String {
|
||||||
if (type.arguments.isNotEmpty()) {
|
val simpleName = (type.classifier as KClass<*>).simpleName!!
|
||||||
print("<")
|
return if (type.arguments.isEmpty()) simpleName
|
||||||
type.arguments.map {
|
else simpleName + type.arguments.joinToString(separator = ", ", prefix = "<", postfix = ">") {
|
||||||
when (val typeArgument = it.type) {
|
when (val typeArgument = it.type) {
|
||||||
null -> "*"
|
null -> "*"
|
||||||
else -> printTypeWithShortNames(typeArgument)
|
else -> typeConversion(typeArgument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print(">")
|
|
||||||
}
|
}
|
||||||
|
print(typeConversion(type))
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -44,6 +44,20 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConverter {
|
internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConverter {
|
||||||
|
add(FirErrors.UNSUPPORTED) { firDiagnostic ->
|
||||||
|
UnsupportedImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.UNSUPPORTED_FEATURE) { firDiagnostic ->
|
||||||
|
UnsupportedFeatureImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.SYNTAX) { firDiagnostic ->
|
add(FirErrors.SYNTAX) { firDiagnostic ->
|
||||||
SyntaxImpl(
|
SyntaxImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic<*>,
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
@@ -830,12 +844,25 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic ->
|
||||||
|
ExtensionInClassReferenceNotAllowedImpl(
|
||||||
|
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration),
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS) { firDiagnostic ->
|
add(FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS) { firDiagnostic ->
|
||||||
CallableReferenceLhsNotAClassImpl(
|
CallableReferenceLhsNotAClassImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic<*>,
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR) { firDiagnostic ->
|
||||||
|
CallableReferenceToAnnotationConstructorImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS) { firDiagnostic ->
|
add(FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS) { firDiagnostic ->
|
||||||
ClassLiteralLhsNotAClassImpl(
|
ClassLiteralLhsNotAClassImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic<*>,
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
|||||||
+21
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiTypeElement
|
import com.intellij.psi.PsiTypeElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
@@ -49,6 +51,16 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||||
|
abstract class Unsupported : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = Unsupported::class
|
||||||
|
abstract val unsupported: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UnsupportedFeature : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = UnsupportedFeature::class
|
||||||
|
abstract val unsupportedFeature: Pair<LanguageFeature, LanguageVersionSettings>
|
||||||
|
}
|
||||||
|
|
||||||
abstract class Syntax : KtFirDiagnostic<PsiElement>() {
|
abstract class Syntax : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = Syntax::class
|
override val diagnosticClass get() = Syntax::class
|
||||||
}
|
}
|
||||||
@@ -589,10 +601,19 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val typeParameter: KtTypeParameterSymbol
|
abstract val typeParameter: KtTypeParameterSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
|
||||||
|
override val diagnosticClass get() = ExtensionInClassReferenceNotAllowed::class
|
||||||
|
abstract val referencedDeclaration: KtCallableSymbol
|
||||||
|
}
|
||||||
|
|
||||||
abstract class CallableReferenceLhsNotAClass : KtFirDiagnostic<KtExpression>() {
|
abstract class CallableReferenceLhsNotAClass : KtFirDiagnostic<KtExpression>() {
|
||||||
override val diagnosticClass get() = CallableReferenceLhsNotAClass::class
|
override val diagnosticClass get() = CallableReferenceLhsNotAClass::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class CallableReferenceToAnnotationConstructor : KtFirDiagnostic<KtExpression>() {
|
||||||
|
override val diagnosticClass get() = CallableReferenceToAnnotationConstructor::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ClassLiteralLhsNotAClass : KtFirDiagnostic<KtExpression>() {
|
abstract class ClassLiteralLhsNotAClass : KtFirDiagnostic<KtExpression>() {
|
||||||
override val diagnosticClass get() = ClassLiteralLhsNotAClass::class
|
override val diagnosticClass get() = ClassLiteralLhsNotAClass::class
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiTypeElement
|
import com.intellij.psi.PsiTypeElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
|
||||||
@@ -50,6 +52,22 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
|||||||
* DO NOT MODIFY IT MANUALLY
|
* DO NOT MODIFY IT MANUALLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
internal class UnsupportedImpl(
|
||||||
|
override val unsupported: String,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.Unsupported(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class UnsupportedFeatureImpl(
|
||||||
|
override val unsupportedFeature: Pair<LanguageFeature, LanguageVersionSettings>,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.UnsupportedFeature(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class SyntaxImpl(
|
internal class SyntaxImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
@@ -950,6 +968,14 @@ internal class TypeParameterAsReifiedImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ExtensionInClassReferenceNotAllowedImpl(
|
||||||
|
override val referencedDeclaration: KtCallableSymbol,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExtensionInClassReferenceNotAllowed(), KtAbstractFirDiagnostic<KtExpression> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class CallableReferenceLhsNotAClassImpl(
|
internal class CallableReferenceLhsNotAClassImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
@@ -957,6 +983,13 @@ internal class CallableReferenceLhsNotAClassImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class CallableReferenceToAnnotationConstructorImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.CallableReferenceToAnnotationConstructor(), KtAbstractFirDiagnostic<KtExpression> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ClassLiteralLhsNotAClassImpl(
|
internal class ClassLiteralLhsNotAClassImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user