[FIR] Assert source is not-null when reporting cone diagnostics
#KT-55835 #KT-59856
This commit is contained in:
committed by
Space Team
parent
2f3293f99e
commit
9288a96f6d
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// COMPARE_WITH_LIGHT_TREE
|
|
||||||
interface A
|
interface A
|
||||||
|
|
||||||
class B<T> where T : A
|
class B<T> where T : A
|
||||||
@@ -15,7 +14,7 @@ fun test() {
|
|||||||
val b1 = B<<!UPPER_BOUND_VIOLATED!>Int<!>>()
|
val b1 = B<<!UPPER_BOUND_VIOLATED!>Int<!>>()
|
||||||
val b2 = B<C>()
|
val b2 = B<C>()
|
||||||
val b3 = B<<!UPPER_BOUND_VIOLATED!>Any?<!>>()
|
val b3 = B<<!UPPER_BOUND_VIOLATED!>Any?<!>>()
|
||||||
val b4 = B<<!UNRESOLVED_REFERENCE!>UnexistingType<!>>()<!UNRESOLVED_REFERENCE!>NL<!><!SYNTAX!><<!>Int<!SYNTAX{LT}!><!SYNTAX!>><!>()<!>NumberPhile<!SYNTAX!><!>
|
val b4 = B<<!UNRESOLVED_REFERENCE!>UnexistingType<!>>()<!UNRESOLVED_REFERENCE!>NL<!><!SYNTAX!><<!>Int<!SYNTAX!><!SYNTAX!>><!>()<!>NumberPhile<!SYNTAX!><!>
|
||||||
val b5 = B<<!UPPER_BOUND_VIOLATED!>B<<!UNRESOLVED_REFERENCE!>UnexistingType<!>><!>>()
|
val b5 = B<<!UPPER_BOUND_VIOLATED!>B<<!UNRESOLVED_REFERENCE!>UnexistingType<!>><!>>()
|
||||||
fest<<!UPPER_BOUND_VIOLATED!>Boolean<!>>()
|
fest<<!UPPER_BOUND_VIOLATED!>Boolean<!>>()
|
||||||
fest<C>()
|
fest<C>()
|
||||||
|
|||||||
+27
-26
@@ -13,14 +13,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fakeElement
|
import org.jetbrains.kotlin.fakeElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirErrorImport
|
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirErrorProperty
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeAmbiguousSuper
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
@@ -33,12 +27,12 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
) : AbstractDiagnosticCollectorComponent(session, reporter) {
|
||||||
override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) {
|
override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) {
|
||||||
val source = errorLoop.source ?: return
|
val source = errorLoop.source
|
||||||
reportFirDiagnostic(errorLoop.diagnostic, source, data)
|
reportFirDiagnostic(errorLoop.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: CheckerContext) {
|
override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: CheckerContext) {
|
||||||
val source = errorTypeRef.source ?: return
|
val source = errorTypeRef.source
|
||||||
reportFirDiagnostic(errorTypeRef.diagnostic, source, data)
|
reportFirDiagnostic(errorTypeRef.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +43,7 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: CheckerContext) {
|
override fun visitErrorAnnotationCall(errorAnnotationCall: FirErrorAnnotationCall, data: CheckerContext) {
|
||||||
val source = errorAnnotationCall.source ?: return
|
val source = errorAnnotationCall.source
|
||||||
reportFirDiagnostic(errorAnnotationCall.diagnostic, source, data)
|
reportFirDiagnostic(errorAnnotationCall.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,15 +56,15 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processErrorReference(reference: FirNamedReference, diagnostic: ConeDiagnostic, context: CheckerContext) {
|
private fun processErrorReference(reference: FirNamedReference, diagnostic: ConeDiagnostic, context: CheckerContext) {
|
||||||
var source = reference.source ?: return
|
var source = reference.source
|
||||||
val callOrAssignment = context.callsOrAssignments.lastOrNull()?.takeIf {
|
val callOrAssignment = context.callsOrAssignments.lastOrNull()?.takeIf {
|
||||||
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
|
// Use the source of the enclosing FirQualifiedAccess if it is exactly the call to the erroneous callee.
|
||||||
it.calleeReference == reference
|
it.calleeReference == reference
|
||||||
}
|
}
|
||||||
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
// Don't report duplicated unresolved reference on annotation entry (already reported on its type)
|
||||||
if (source.elementType == KtNodeTypes.ANNOTATION_ENTRY && diagnostic is ConeUnresolvedNameError) return
|
if (source?.elementType == KtNodeTypes.ANNOTATION_ENTRY && diagnostic is ConeUnresolvedNameError) return
|
||||||
// Already reported in FirConventionFunctionCallChecker
|
// Already reported in FirConventionFunctionCallChecker
|
||||||
if (source.kind == KtFakeSourceElementKind.ArrayAccessNameReference &&
|
if (source?.kind == KtFakeSourceElementKind.ArrayAccessNameReference &&
|
||||||
diagnostic is ConeUnresolvedNameError
|
diagnostic is ConeUnresolvedNameError
|
||||||
) return
|
) return
|
||||||
|
|
||||||
@@ -82,7 +76,7 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
) return
|
) return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor) {
|
if (source?.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor) {
|
||||||
val property = context.containingDeclarations.lastOrNull { it is FirProperty } as? FirProperty ?: return
|
val property = context.containingDeclarations.lastOrNull { it is FirProperty } as? FirProperty ?: return
|
||||||
source = property.delegate?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: return
|
source = property.delegate?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: return
|
||||||
}
|
}
|
||||||
@@ -101,55 +95,62 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorExpression(errorExpression: FirErrorExpression, data: CheckerContext) {
|
override fun visitErrorExpression(errorExpression: FirErrorExpression, data: CheckerContext) {
|
||||||
val source = errorExpression.source ?: return
|
val source = errorExpression.source
|
||||||
reportFirDiagnostic(errorExpression.diagnostic, source, data)
|
val diagnostic = errorExpression.diagnostic
|
||||||
|
if (source == null) {
|
||||||
|
// ConeSyntaxDiagnostic and DiagnosticKind.ExpressionExpected with no source (see check above) are typically symptoms of some
|
||||||
|
// syntax error that was already reported during parsing.
|
||||||
|
if (diagnostic is ConeSyntaxDiagnostic) return
|
||||||
|
if (diagnostic is ConeSimpleDiagnostic && diagnostic.kind == DiagnosticKind.ExpressionExpected) return
|
||||||
|
}
|
||||||
|
reportFirDiagnostic(diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorFunction(errorFunction: FirErrorFunction, data: CheckerContext) {
|
override fun visitErrorFunction(errorFunction: FirErrorFunction, data: CheckerContext) {
|
||||||
val source = errorFunction.source ?: return
|
val source = errorFunction.source
|
||||||
reportFirDiagnostic(errorFunction.diagnostic, source, data)
|
reportFirDiagnostic(errorFunction.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorProperty(errorProperty: FirErrorProperty, data: CheckerContext) {
|
override fun visitErrorProperty(errorProperty: FirErrorProperty, data: CheckerContext) {
|
||||||
val source = errorProperty.source ?: return
|
val source = errorProperty.source
|
||||||
reportFirDiagnostic(errorProperty.diagnostic, source, data)
|
reportFirDiagnostic(errorProperty.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorResolvedQualifier(errorResolvedQualifier: FirErrorResolvedQualifier, data: CheckerContext) {
|
override fun visitErrorResolvedQualifier(errorResolvedQualifier: FirErrorResolvedQualifier, data: CheckerContext) {
|
||||||
val source = errorResolvedQualifier.source ?: return
|
val source = errorResolvedQualifier.source
|
||||||
reportFirDiagnostic(errorResolvedQualifier.diagnostic, source, data)
|
reportFirDiagnostic(errorResolvedQualifier.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorImport(errorImport: FirErrorImport, data: CheckerContext) {
|
override fun visitErrorImport(errorImport: FirErrorImport, data: CheckerContext) {
|
||||||
val source = errorImport.source ?: return
|
val source = errorImport.source
|
||||||
reportFirDiagnostic(errorImport.diagnostic, source, data)
|
reportFirDiagnostic(errorImport.diagnostic, source, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportFirDiagnostic(
|
private fun reportFirDiagnostic(
|
||||||
diagnostic: ConeDiagnostic,
|
diagnostic: ConeDiagnostic,
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
callOrAssignmentSource: KtSourceElement? = null
|
callOrAssignmentSource: KtSourceElement? = null
|
||||||
) {
|
) {
|
||||||
// Will be handled by [FirDestructuringDeclarationChecker]
|
// Will be handled by [FirDestructuringDeclarationChecker]
|
||||||
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) {
|
if (source?.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will be handled by [FirDelegatedPropertyChecker]
|
// Will be handled by [FirDelegatedPropertyChecker]
|
||||||
if (source.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor &&
|
if (source?.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor &&
|
||||||
(diagnostic is ConeUnresolvedNameError || diagnostic is ConeAmbiguityError || diagnostic is ConeInapplicableWrongReceiver || diagnostic is ConeInapplicableCandidateError)
|
(diagnostic is ConeUnresolvedNameError || diagnostic is ConeAmbiguityError || diagnostic is ConeInapplicableWrongReceiver || diagnostic is ConeInapplicableCandidateError)
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.kind == KtFakeSourceElementKind.ImplicitConstructor || source.kind == KtFakeSourceElementKind.DesugaredForLoop) {
|
if (source?.kind == KtFakeSourceElementKind.ImplicitConstructor || source?.kind == KtFakeSourceElementKind.DesugaredForLoop) {
|
||||||
// See FirForLoopChecker
|
// See FirForLoopChecker
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefix inc/dec on array access will have two calls to .get(...), don't report for the second one.
|
// Prefix inc/dec on array access will have two calls to .get(...), don't report for the second one.
|
||||||
if (source.kind == KtFakeSourceElementKind.DesugaredPrefixSecondGetReference) {
|
if (source?.kind == KtFakeSourceElementKind.DesugaredPrefixSecondGetReference) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-25
@@ -45,7 +45,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||||
|
|
||||||
private fun ConeDiagnostic.toKtDiagnostic(
|
private fun ConeDiagnostic.toKtDiagnostic(
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
callOrAssignmentSource: KtSourceElement?
|
callOrAssignmentSource: KtSourceElement?
|
||||||
): KtDiagnostic? = when (this) {
|
): KtDiagnostic? = when (this) {
|
||||||
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn(
|
is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn(
|
||||||
@@ -118,7 +118,7 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
|||||||
is ConeSyntaxDiagnostic -> FirSyntaxErrors.SYNTAX.createOn(callOrAssignmentSource ?: source, reason)
|
is ConeSyntaxDiagnostic -> FirSyntaxErrors.SYNTAX.createOn(callOrAssignmentSource ?: source, reason)
|
||||||
|
|
||||||
is ConeSimpleDiagnostic -> when {
|
is ConeSimpleDiagnostic -> when {
|
||||||
source.kind is KtFakeSourceElementKind && source.kind != KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess -> null
|
source?.kind is KtFakeSourceElementKind && source.kind != KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess -> null
|
||||||
else -> this.getFactory(source).createOn(callOrAssignmentSource ?: source)
|
else -> this.getFactory(source).createOn(callOrAssignmentSource ?: source)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ fun FirBasedSymbol<*>.toInvisibleReferenceDiagnostic(source: KtSourceElement?):
|
|||||||
|
|
||||||
fun ConeDiagnostic.toFirDiagnostics(
|
fun ConeDiagnostic.toFirDiagnostics(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
callOrAssignmentSource: KtSourceElement?
|
callOrAssignmentSource: KtSourceElement?
|
||||||
): List<KtDiagnostic> {
|
): List<KtDiagnostic> {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
@@ -175,9 +175,9 @@ fun ConeDiagnostic.toFirDiagnostics(
|
|||||||
private fun mapUnsafeCallError(
|
private fun mapUnsafeCallError(
|
||||||
candidate: AbstractCandidate,
|
candidate: AbstractCandidate,
|
||||||
rootCause: UnsafeCall,
|
rootCause: UnsafeCall,
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
qualifiedAccessSource: KtSourceElement?,
|
qualifiedAccessSource: KtSourceElement?,
|
||||||
): KtDiagnostic? {
|
): KtDiagnostic {
|
||||||
if (candidate.callInfo.isImplicitInvoke) {
|
if (candidate.callInfo.isImplicitInvoke) {
|
||||||
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType)
|
return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.createOn(source, rootCause.actualType)
|
||||||
}
|
}
|
||||||
@@ -187,14 +187,14 @@ private fun mapUnsafeCallError(
|
|||||||
val receiverExpression = candidate.callInfo.explicitReceiver
|
val receiverExpression = candidate.callInfo.explicitReceiver
|
||||||
val singleArgument = candidate.callInfo.argumentList.arguments.singleOrNull()
|
val singleArgument = candidate.callInfo.argumentList.arguments.singleOrNull()
|
||||||
if (receiverExpression != null && singleArgument != null &&
|
if (receiverExpression != null && singleArgument != null &&
|
||||||
(source.elementType == KtNodeTypes.OPERATION_REFERENCE || source.elementType == KtNodeTypes.BINARY_EXPRESSION) &&
|
(source?.elementType == KtNodeTypes.OPERATION_REFERENCE || source?.elementType == KtNodeTypes.BINARY_EXPRESSION) &&
|
||||||
(candidateFunctionSymbol?.isOperator == true || candidateFunctionSymbol?.isInfix == true)
|
(candidateFunctionSymbol?.isOperator == true || candidateFunctionSymbol?.isInfix == true)
|
||||||
) {
|
) {
|
||||||
// For augmented assignment operations (e.g., `a += b`), the source is the entire binary expression (BINARY_EXPRESSION).
|
// For augmented assignment operations (e.g., `a += b`), the source is the entire binary expression (BINARY_EXPRESSION).
|
||||||
// TODO, KT-59809: No need to check for source.elementType == BINARY_EXPRESSION if we use operator as callee reference source
|
// TODO, KT-59809: No need to check for source.elementType == BINARY_EXPRESSION if we use operator as callee reference source
|
||||||
// (see FirExpressionsResolveTransformer.transformAssignmentOperatorStatement)
|
// (see FirExpressionsResolveTransformer.transformAssignmentOperatorStatement)
|
||||||
val operationSource = if (source.elementType == KtNodeTypes.BINARY_EXPRESSION) {
|
val operationSource = if (source?.elementType == KtNodeTypes.BINARY_EXPRESSION) {
|
||||||
source.getChild(KtNodeTypes.OPERATION_REFERENCE)
|
source?.getChild(KtNodeTypes.OPERATION_REFERENCE)
|
||||||
} else {
|
} else {
|
||||||
source
|
source
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,7 @@ private fun mapUnsafeCallError(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return if (source.kind == KtFakeSourceElementKind.ArrayAccessNameReference) {
|
return if (source?.kind == KtFakeSourceElementKind.ArrayAccessNameReference) {
|
||||||
FirErrors.UNSAFE_CALL.createOn(source, rootCause.actualType, receiverExpression)
|
FirErrors.UNSAFE_CALL.createOn(source, rootCause.actualType, receiverExpression)
|
||||||
} else {
|
} else {
|
||||||
FirErrors.UNSAFE_CALL.createOn(qualifiedAccessSource ?: source, rootCause.actualType, receiverExpression)
|
FirErrors.UNSAFE_CALL.createOn(qualifiedAccessSource ?: source, rootCause.actualType, receiverExpression)
|
||||||
@@ -226,7 +226,7 @@ private fun mapUnsafeCallError(
|
|||||||
private fun mapInapplicableCandidateError(
|
private fun mapInapplicableCandidateError(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
diagnostic: ConeInapplicableCandidateError,
|
diagnostic: ConeInapplicableCandidateError,
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
qualifiedAccessSource: KtSourceElement?,
|
qualifiedAccessSource: KtSourceElement?,
|
||||||
): List<KtDiagnostic> {
|
): List<KtDiagnostic> {
|
||||||
val typeContext = session.typeContext
|
val typeContext = session.typeContext
|
||||||
@@ -341,7 +341,7 @@ private fun mapInapplicableCandidateError(
|
|||||||
private fun mapSystemHasContradictionError(
|
private fun mapSystemHasContradictionError(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
diagnostic: ConeConstraintSystemHasContradiction,
|
diagnostic: ConeConstraintSystemHasContradiction,
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
qualifiedAccessSource: KtSourceElement?,
|
qualifiedAccessSource: KtSourceElement?,
|
||||||
): List<KtDiagnostic> {
|
): List<KtDiagnostic> {
|
||||||
return buildList {
|
return buildList {
|
||||||
@@ -380,7 +380,7 @@ private fun mapSystemHasContradictionError(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConstraintSystemError.toDiagnostic(
|
private fun ConstraintSystemError.toDiagnostic(
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
qualifiedAccessSource: KtSourceElement?,
|
qualifiedAccessSource: KtSourceElement?,
|
||||||
typeContext: ConeTypeContext,
|
typeContext: ConeTypeContext,
|
||||||
candidate: AbstractCandidate,
|
candidate: AbstractCandidate,
|
||||||
@@ -507,7 +507,7 @@ private fun findInferredEmptyIntersectionNarrowedSource(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun reportInferredIntoEmptyIntersection(
|
private fun reportInferredIntoEmptyIntersection(
|
||||||
source: KtSourceElement,
|
source: KtSourceElement?,
|
||||||
typeVariable: ConeTypeVariable,
|
typeVariable: ConeTypeVariable,
|
||||||
incompatibleTypes: Collection<ConeKotlinType>,
|
incompatibleTypes: Collection<ConeKotlinType>,
|
||||||
causingTypes: Collection<ConeKotlinType>,
|
causingTypes: Collection<ConeKotlinType>,
|
||||||
@@ -531,7 +531,7 @@ private fun reportInferredIntoEmptyIntersection(
|
|||||||
private val NewConstraintError.lowerConeType: ConeKotlinType get() = lowerType as ConeKotlinType
|
private val NewConstraintError.lowerConeType: ConeKotlinType get() = lowerType as ConeKotlinType
|
||||||
private val NewConstraintError.upperConeType: ConeKotlinType get() = upperType as ConeKotlinType
|
private val NewConstraintError.upperConeType: ConeKotlinType get() = upperType as ConeKotlinType
|
||||||
|
|
||||||
private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): KtDiagnosticFactory0 {
|
private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement?): KtDiagnosticFactory0 {
|
||||||
return when (kind) {
|
return when (kind) {
|
||||||
DiagnosticKind.ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED
|
DiagnosticKind.ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED
|
||||||
DiagnosticKind.NotAFunctionLabel -> FirErrors.NOT_A_FUNCTION_LABEL
|
DiagnosticKind.NotAFunctionLabel -> FirErrors.NOT_A_FUNCTION_LABEL
|
||||||
@@ -544,7 +544,7 @@ private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): KtDiagnost
|
|||||||
DiagnosticKind.RecursionInImplicitTypes -> FirErrors.RECURSION_IN_IMPLICIT_TYPES
|
DiagnosticKind.RecursionInImplicitTypes -> FirErrors.RECURSION_IN_IMPLICIT_TYPES
|
||||||
DiagnosticKind.Java -> FirErrors.ERROR_FROM_JAVA_RESOLUTION
|
DiagnosticKind.Java -> FirErrors.ERROR_FROM_JAVA_RESOLUTION
|
||||||
DiagnosticKind.SuperNotAllowed -> FirErrors.SUPER_IS_NOT_AN_EXPRESSION
|
DiagnosticKind.SuperNotAllowed -> FirErrors.SUPER_IS_NOT_AN_EXPRESSION
|
||||||
DiagnosticKind.ExpressionExpected -> when (source.elementType) {
|
DiagnosticKind.ExpressionExpected -> when (source?.elementType) {
|
||||||
KtNodeTypes.BINARY_EXPRESSION -> FirErrors.ASSIGNMENT_IN_EXPRESSION_CONTEXT
|
KtNodeTypes.BINARY_EXPRESSION -> FirErrors.ASSIGNMENT_IN_EXPRESSION_CONTEXT
|
||||||
KtNodeTypes.FUN -> FirErrors.ANONYMOUS_FUNCTION_WITH_NAME
|
KtNodeTypes.FUN -> FirErrors.ANONYMOUS_FUNCTION_WITH_NAME
|
||||||
KtNodeTypes.WHEN_CONDITION_IN_RANGE, KtNodeTypes.WHEN_CONDITION_IS_PATTERN, KtNodeTypes.WHEN_CONDITION_EXPRESSION ->
|
KtNodeTypes.WHEN_CONDITION_IN_RANGE, KtNodeTypes.WHEN_CONDITION_IS_PATTERN, KtNodeTypes.WHEN_CONDITION_EXPRESSION ->
|
||||||
@@ -586,16 +586,16 @@ private fun ConeSimpleDiagnostic.getFactory(source: KtSourceElement): KtDiagnost
|
|||||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||||
private fun KtDiagnosticFactory0.createOn(
|
private fun KtDiagnosticFactory0.createOn(
|
||||||
element: KtSourceElement?
|
element: KtSourceElement?
|
||||||
): KtSimpleDiagnostic? {
|
): KtSimpleDiagnostic {
|
||||||
return element?.let { on(it, positioningStrategy = null) }
|
return on(element.requireNotNull(), positioningStrategy = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||||
private fun <A> KtDiagnosticFactory1<A>.createOn(
|
private fun <A> KtDiagnosticFactory1<A>.createOn(
|
||||||
element: KtSourceElement?,
|
element: KtSourceElement?,
|
||||||
a: A
|
a: A
|
||||||
): KtDiagnosticWithParameters1<A>? {
|
): KtDiagnosticWithParameters1<A> {
|
||||||
return element?.let { on(it, a, positioningStrategy = null) }
|
return on(element.requireNotNull(), a, positioningStrategy = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||||
@@ -603,8 +603,8 @@ private fun <A, B> KtDiagnosticFactory2<A, B>.createOn(
|
|||||||
element: KtSourceElement?,
|
element: KtSourceElement?,
|
||||||
a: A,
|
a: A,
|
||||||
b: B
|
b: B
|
||||||
): KtDiagnosticWithParameters2<A, B>? {
|
): KtDiagnosticWithParameters2<A, B> {
|
||||||
return element?.let { on(it, a, b, positioningStrategy = null) }
|
return on(element.requireNotNull(), a, b, positioningStrategy = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||||
@@ -613,8 +613,8 @@ private fun <A, B, C> KtDiagnosticFactory3<A, B, C>.createOn(
|
|||||||
a: A,
|
a: A,
|
||||||
b: B,
|
b: B,
|
||||||
c: C
|
c: C
|
||||||
): KtDiagnosticWithParameters3<A, B, C>? {
|
): KtDiagnosticWithParameters3<A, B, C> {
|
||||||
return element?.let { on(it, a, b, c, positioningStrategy = null) }
|
return on(element.requireNotNull(), a, b, c, positioningStrategy = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(InternalDiagnosticFactoryMethod::class)
|
@OptIn(InternalDiagnosticFactoryMethod::class)
|
||||||
@@ -624,6 +624,6 @@ private fun <A, B, C, D> KtDiagnosticFactory4<A, B, C, D>.createOn(
|
|||||||
b: B,
|
b: B,
|
||||||
c: C,
|
c: C,
|
||||||
d: D
|
d: D
|
||||||
): KtDiagnosticWithParameters4<A, B, C, D>? {
|
): KtDiagnosticWithParameters4<A, B, C, D> {
|
||||||
return element?.let { on(it, a, b, c, d, positioningStrategy = null) }
|
return on(element.requireNotNull(), a, b, c, d, positioningStrategy = null)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -66,7 +66,8 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
return converted as? R
|
return converted as? R
|
||||||
?: buildErrorExpression(
|
?: buildErrorExpression(
|
||||||
expression?.toFirSourceElement(),
|
expression?.toFirSourceElement(),
|
||||||
ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected),
|
if (expression == null) ConeSyntaxDiagnostic(errorReason)
|
||||||
|
else ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected),
|
||||||
converted,
|
converted,
|
||||||
) as R
|
) as R
|
||||||
}
|
}
|
||||||
@@ -116,7 +117,7 @@ class LightTreeRawFirExpressionBuilder(
|
|||||||
OBJECT_LITERAL -> declarationBuilder.convertObjectLiteral(expression)
|
OBJECT_LITERAL -> declarationBuilder.convertObjectLiteral(expression)
|
||||||
FUN -> declarationBuilder.convertFunctionDeclaration(expression)
|
FUN -> declarationBuilder.convertFunctionDeclaration(expression)
|
||||||
DESTRUCTURING_DECLARATION -> declarationBuilder.convertDestructingDeclaration(expression).toFirDestructingDeclaration(baseModuleData)
|
DESTRUCTURING_DECLARATION -> declarationBuilder.convertDestructingDeclaration(expression).toFirDestructingDeclaration(baseModuleData)
|
||||||
else -> buildErrorExpression(null, ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected))
|
else -> buildErrorExpression(expression.toFirSourceElement(KtFakeSourceElementKind.ErrorTypeRef), ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -50,7 +50,7 @@ import org.jetbrains.kotlin.name.CallableId
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
class FirSyntheticCallGenerator(
|
class FirSyntheticCallGenerator(
|
||||||
@@ -259,17 +259,18 @@ class FirSyntheticCallGenerator(
|
|||||||
val callInfo = generateCallInfo(callSite, name, argumentList, callKind)
|
val callInfo = generateCallInfo(callSite, name, argumentList, callKind)
|
||||||
val candidate = generateCandidate(callInfo, function, context)
|
val candidate = generateCandidate(callInfo, function, context)
|
||||||
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
val applicability = components.resolutionStageRunner.processCandidate(candidate, context)
|
||||||
if (applicability <= CandidateApplicability.INAPPLICABLE) {
|
val source = callSite.source?.fakeElement(KtFakeSourceElementKind.SyntheticCall)
|
||||||
|
if (!applicability.isSuccess) {
|
||||||
return createErrorReferenceWithExistingCandidate(
|
return createErrorReferenceWithExistingCandidate(
|
||||||
candidate,
|
candidate,
|
||||||
ConeInapplicableCandidateError(applicability, candidate),
|
ConeInapplicableCandidateError(applicability, candidate),
|
||||||
source = null,
|
source,
|
||||||
context,
|
context,
|
||||||
components.resolutionStageRunner
|
components.resolutionStageRunner
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return FirNamedReferenceWithCandidate(callSite.source?.fakeElement(KtFakeSourceElementKind.SyntheticCall), name, candidate)
|
return FirNamedReferenceWithCandidate(source, name, candidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunction, context: ResolutionContext): Candidate {
|
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunction, context: ResolutionContext): Candidate {
|
||||||
|
|||||||
+7
-7
@@ -15,7 +15,7 @@ fun DiagnosticReporter.reportOn(
|
|||||||
context: DiagnosticContext,
|
context: DiagnosticContext,
|
||||||
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
||||||
) {
|
) {
|
||||||
report(factory.on(requireSourceNotNull(source), positioningStrategy), context)
|
report(factory.on(source.requireNotNull(), positioningStrategy), context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <A : Any> DiagnosticReporter.reportOn(
|
fun <A : Any> DiagnosticReporter.reportOn(
|
||||||
@@ -25,7 +25,7 @@ fun <A : Any> DiagnosticReporter.reportOn(
|
|||||||
context: DiagnosticContext,
|
context: DiagnosticContext,
|
||||||
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
||||||
) {
|
) {
|
||||||
report(factory.on(requireSourceNotNull(source), a, positioningStrategy), context)
|
report(factory.on(source.requireNotNull(), a, positioningStrategy), context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
|
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
|
||||||
@@ -36,7 +36,7 @@ fun <A : Any, B : Any> DiagnosticReporter.reportOn(
|
|||||||
context: DiagnosticContext,
|
context: DiagnosticContext,
|
||||||
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
||||||
) {
|
) {
|
||||||
report(factory.on(requireSourceNotNull(source), a, b, positioningStrategy), context)
|
report(factory.on(source.requireNotNull(), a, b, positioningStrategy), context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
|
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
|
||||||
@@ -48,7 +48,7 @@ fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
|
|||||||
context: DiagnosticContext,
|
context: DiagnosticContext,
|
||||||
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
||||||
) {
|
) {
|
||||||
report(factory.on(requireSourceNotNull(source), a, b, c, positioningStrategy), context)
|
report(factory.on(source.requireNotNull(), a, b, c, positioningStrategy), context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
|
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
|
||||||
@@ -61,11 +61,11 @@ fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
|
|||||||
context: DiagnosticContext,
|
context: DiagnosticContext,
|
||||||
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
positioningStrategy: AbstractSourceElementPositioningStrategy? = null
|
||||||
) {
|
) {
|
||||||
report(factory.on(requireSourceNotNull(source), a, b, c, d, positioningStrategy), context)
|
report(factory.on(source.requireNotNull(), a, b, c, d, positioningStrategy), context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requireSourceNotNull(source: AbstractKtSourceElement?): AbstractKtSourceElement =
|
fun AbstractKtSourceElement?.requireNotNull(): AbstractKtSourceElement =
|
||||||
requireNotNull(source) { "source must not be null" }
|
requireNotNull(this) { "source must not be null" }
|
||||||
|
|
||||||
fun DiagnosticReporter.reportOn(
|
fun DiagnosticReporter.reportOn(
|
||||||
source: AbstractKtSourceElement?,
|
source: AbstractKtSourceElement?,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// COMPARE_WITH_LIGHT_TREE
|
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val list = <!UNRESOLVED_REFERENCE!>mutable<!> ListOf<!SYNTAX!><<!>Int<!SYNTAX{LT}!><!SYNTAX!>><!>(1) {}<!>
|
val list = <!UNRESOLVED_REFERENCE!>mutable<!> ListOf<!SYNTAX!><<!>Int<!SYNTAX!><!SYNTAX!>><!>(1) {}<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// COMPARE_WITH_LIGHT_TREE
|
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// NI_EXPECTED_FILE
|
// NI_EXPECTED_FILE
|
||||||
// COMPARE_WITH_LIGHT_TREE
|
|
||||||
|
|
||||||
val unwrapped = <!UNRESOLVED_REFERENCE!>some<!>.<!SYNTAX!><<!><!UNRESOLVED_REFERENCE!>cabc<!><!SYNTAX{LT}!><!SYNTAX!>$Wrapper<!><<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out Any<!>><!>::<!UNRESOLVED_REFERENCE!>unwrap<!>
|
val unwrapped = <!UNRESOLVED_REFERENCE!>some<!>.<!SYNTAX!><<!><!UNRESOLVED_REFERENCE!>cabc<!><!SYNTAX!><!SYNTAX!>$Wrapper<!><<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>out Any<!>><!>::<!UNRESOLVED_REFERENCE!>unwrap<!>
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// NI_EXPECTED_FILE
|
// NI_EXPECTED_FILE
|
||||||
// COMPARE_WITH_LIGHT_TREE
|
|
||||||
|
|
||||||
val unwrapped = <!UNRESOLVED_REFERENCE!>some<!>.<!SYNTAX!><<!><!DEBUG_INFO_MISSING_UNRESOLVED!>cabc<!><!SYNTAX!>$Wrapper<!><out <!DEBUG_INFO_MISSING_UNRESOLVED!>Any<!>>::<!DEBUG_INFO_MISSING_UNRESOLVED!>unwrap<!>
|
val unwrapped = <!UNRESOLVED_REFERENCE!>some<!>.<!SYNTAX!><<!><!DEBUG_INFO_MISSING_UNRESOLVED!>cabc<!><!SYNTAX!>$Wrapper<!><out <!DEBUG_INFO_MISSING_UNRESOLVED!>Any<!>>::<!DEBUG_INFO_MISSING_UNRESOLVED!>unwrap<!>
|
||||||
|
|||||||
Reference in New Issue
Block a user