diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt index 89adad0997a..0eb5123943c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirAnalysisSessionComponent.kt @@ -50,9 +50,9 @@ internal interface KtFirAnalysisSessionComponent { fun ConeDiagnostic.asKtDiagnostic( source: KtSourceElement, - qualifiedAccessSource: KtSourceElement?, + callOrAssignmentSource: KtSourceElement?, ): KtDiagnosticWithPsi<*>? { - val firDiagnostic = toFirDiagnostics(analysisSession.useSiteSession, source, qualifiedAccessSource).firstOrNull() ?: return null + val firDiagnostic = toFirDiagnostics(analysisSession.useSiteSession, source, callOrAssignmentSource).firstOrNull() ?: return null check(firDiagnostic is KtPsiDiagnostic) return firDiagnostic.asKtDiagnostic() } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmSuspensionPointInsideMutexLockChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmSuspensionPointInsideMutexLockChecker.kt index c2694e82f6d..2576896e019 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmSuspensionPointInsideMutexLockChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJvmSuspensionPointInsideMutexLockChecker.kt @@ -28,7 +28,7 @@ object FirJvmSuspensionPointInsideMutexLockChecker : FirFunctionCallChecker() { if (!symbol.isSuspend) return val closestAnonymousFunction = context.findClosest() ?: return - for (call in context.qualifiedAccessOrAssignmentsOrAnnotationCalls.asReversed()) { + for (call in context.callsOrAssignments.asReversed()) { if (call is FirFunctionCall) { val callableSymbol = call.calleeReference.toResolvedCallableSymbol() ?: continue if (callableSymbol.callableId == synchronizedCallableId) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index 6e406d8e5ea..c19ef3ee8a5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -764,7 +764,7 @@ fun FirBasedSymbol<*>.getAnnotationStringParameter(classId: ClassId, session: Fi fun FirElement.isLhsOfAssignment(context: CheckerContext): Boolean { if (this !is FirQualifiedAccessExpression) return false - val lastQualified = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull { it != this } ?: return false + val lastQualified = context.callsOrAssignments.lastOrNull { it != this } ?: return false return lastQualified is FirVariableAssignment && lastQualified.lValue == this } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt index 08099aeb133..ba6035c92f2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContext.kt @@ -33,7 +33,9 @@ abstract class CheckerContext : DiagnosticContext { // Context abstract val implicitReceiverStack: ImplicitReceiverStack abstract val containingDeclarations: List - abstract val qualifiedAccessOrAssignmentsOrAnnotationCalls: List + + /** Contains qualified access, annotation call, delegated constructor call, and variable assignment. */ + abstract val callsOrAssignments: List abstract val getClassCalls: List abstract val annotationContainers: List abstract val containingElements: List diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContextForProvider.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContextForProvider.kt index 68f2ab8eb16..292c42b1372 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContextForProvider.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/CheckerContextForProvider.kt @@ -50,9 +50,9 @@ abstract class CheckerContextForProvider( } } - abstract fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): CheckerContextForProvider + abstract fun addCallOrAssignment(qualifiedAccessOrAnnotationCall: FirStatement): CheckerContextForProvider - abstract fun dropQualifiedAccessOrAnnotationCall() + abstract fun dropCallOrAssignment() abstract fun addGetClassCall(getClassCall: FirGetClassCall): CheckerContextForProvider diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/MutableCheckerContext.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/MutableCheckerContext.kt index 687947e6618..b9bdd0a3b91 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/MutableCheckerContext.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/MutableCheckerContext.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.name.Name class MutableCheckerContext private constructor( override val implicitReceiverStack: PersistentImplicitReceiverStack, override val containingDeclarations: MutableList, - override val qualifiedAccessOrAssignmentsOrAnnotationCalls: MutableList, + override val callsOrAssignments: MutableList, override val getClassCalls: MutableList, override val annotationContainers: MutableList, override val containingElements: MutableList, @@ -56,7 +56,7 @@ class MutableCheckerContext private constructor( return MutableCheckerContext( implicitReceiverStack.add(name, value), containingDeclarations, - qualifiedAccessOrAssignmentsOrAnnotationCalls, + callsOrAssignments, getClassCalls, annotationContainers, containingElements, @@ -80,13 +80,13 @@ class MutableCheckerContext private constructor( containingDeclarations.removeLast() } - override fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): MutableCheckerContext { - qualifiedAccessOrAssignmentsOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall) + override fun addCallOrAssignment(qualifiedAccessOrAnnotationCall: FirStatement): MutableCheckerContext { + callsOrAssignments.add(qualifiedAccessOrAnnotationCall) return this } - override fun dropQualifiedAccessOrAnnotationCall() { - qualifiedAccessOrAssignmentsOrAnnotationCalls.removeLast() + override fun dropCallOrAssignment() { + callsOrAssignments.removeLast() } override fun addGetClassCall(getClassCall: FirGetClassCall): MutableCheckerContext { @@ -127,7 +127,7 @@ class MutableCheckerContext private constructor( return MutableCheckerContext( implicitReceiverStack, containingDeclarations, - qualifiedAccessOrAssignmentsOrAnnotationCalls, + callsOrAssignments, getClassCalls, annotationContainers, containingElements, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt index bbf6e1c31b6..5fb2a03c625 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/context/PersistentCheckerContext.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.name.Name class PersistentCheckerContext private constructor( override val implicitReceiverStack: PersistentImplicitReceiverStack, override val containingDeclarations: PersistentList, - override val qualifiedAccessOrAssignmentsOrAnnotationCalls: PersistentList, + override val callsOrAssignments: PersistentList, override val getClassCalls: PersistentList, override val annotationContainers: PersistentList, override val containingElements: PersistentList, @@ -62,13 +62,13 @@ class PersistentCheckerContext private constructor( override fun dropDeclaration() {} - override fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): PersistentCheckerContext = + override fun addCallOrAssignment(qualifiedAccessOrAnnotationCall: FirStatement): PersistentCheckerContext = copy( qualifiedAccessOrAssignmentsOrAnnotationCalls = - qualifiedAccessOrAssignmentsOrAnnotationCalls.add(qualifiedAccessOrAnnotationCall) + callsOrAssignments.add(qualifiedAccessOrAnnotationCall) ) - override fun dropQualifiedAccessOrAnnotationCall() {} + override fun dropCallOrAssignment() {} override fun addGetClassCall(getClassCall: FirGetClassCall): PersistentCheckerContext = copy(getClassCalls = getClassCalls.add(getClassCall)) @@ -102,7 +102,7 @@ class PersistentCheckerContext private constructor( private fun copy( implicitReceiverStack: PersistentImplicitReceiverStack = this.implicitReceiverStack, - qualifiedAccessOrAssignmentsOrAnnotationCalls: PersistentList = this.qualifiedAccessOrAssignmentsOrAnnotationCalls, + qualifiedAccessOrAssignmentsOrAnnotationCalls: PersistentList = this.callsOrAssignments, getClassCalls: PersistentList = this.getClassCalls, annotationContainers: PersistentList = this.annotationContainers, containingElements: PersistentList = this.containingElements, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index 163e8d4d25b..0796d4ee076 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -253,8 +253,8 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { private fun FirStatement.partOfCall(context: CheckerContext): Boolean { if (this !is FirExpression) return false - val containingQualifiedAccess = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.getOrNull( - context.qualifiedAccessOrAssignmentsOrAnnotationCalls.size - 2 + val containingQualifiedAccess = context.callsOrAssignments.getOrNull( + context.callsOrAssignments.size - 2 ) ?: return false if (this == (containingQualifiedAccess as? FirQualifiedAccessExpression)?.explicitReceiver) return true val call = containingQualifiedAccess as? FirCall ?: return false diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConstructorCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConstructorCallChecker.kt index 59f4c96e981..1e9eabd5e6e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConstructorCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConstructorCallChecker.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.utils.isAbstract import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol @@ -26,7 +25,7 @@ object FirConstructorCallChecker : FirFunctionCallChecker() { if (declarationClass != null) { if (declarationClass.classKind == ClassKind.ANNOTATION_CLASS && - context.qualifiedAccessOrAssignmentsOrAnnotationCalls.all { call -> + context.callsOrAssignments.all { call -> call !is FirAnnotation } && context.containingDeclarations.all { klass -> diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReceiverAccessBeforeSuperCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReceiverAccessBeforeSuperCallChecker.kt index 2d53b75fac5..306da711e8c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReceiverAccessBeforeSuperCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReceiverAccessBeforeSuperCallChecker.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression object FirReceiverAccessBeforeSuperCallChecker : FirInaccessibleReceiverChecker() { override fun check(expression: FirInaccessibleReceiverExpression, context: CheckerContext, reporter: DiagnosticReporter) { - val containingCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.last() as FirQualifiedAccessExpression + val containingCall = context.callsOrAssignments.last() as FirQualifiedAccessExpression containingCall.run { require(expression == dispatchReceiver || expression == extensionReceiver || expression in contextReceiverArguments) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReturnSyntaxAndLabelChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReturnSyntaxAndLabelChecker.kt index 246a2679fa3..35758e100d7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReturnSyntaxAndLabelChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirReturnSyntaxAndLabelChecker.kt @@ -36,7 +36,7 @@ object FirReturnSyntaxAndLabelChecker : FirReturnExpressionChecker() { if (targetSymbol is FirAnonymousFunctionSymbol) { val label = targetSymbol.label if (label?.source?.kind !is KtRealSourceElementKind) { - val functionCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.asReversed().find { + val functionCall = context.callsOrAssignments.asReversed().find { it is FirFunctionCall && (it.calleeReference.toResolvedFunctionSymbol())?.callableId == FirSuspendCallChecker.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirStandaloneQualifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirStandaloneQualifierChecker.kt index 25b09ed88cc..556ecd092a5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirStandaloneQualifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirStandaloneQualifierChecker.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.types.isUnit object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() { override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) { - val lastQualifiedAccess = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull() as? FirQualifiedAccessExpression + val lastQualifiedAccess = context.callsOrAssignments.lastOrNull() as? FirQualifiedAccessExpression // Note: qualifier isn't standalone when it's in receiver (SomeClass.foo) or getClass (SomeClass::class) position if (lastQualifiedAccess?.explicitReceiver === expression || lastQualifiedAccess?.dispatchReceiver === expression) return val lastGetClass = context.getClassCalls.lastOrNull() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt index 4b9784aee2a..921aeacdd5f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeParameterInQualifiedAccessChecker.kt @@ -33,7 +33,7 @@ object FirTypeParameterInQualifiedAccessChecker : FirQualifiedAccessExpressionCh // Make sure the current expression is not the receiver of a qualified access expression. // E.g., for `T::toString`, which is a callable reference (a subtype of qualified access), type parameter T is checked once as an // explicit receiver. When we visit `T` (as a qualified access expression), we should not regard it as an expression here. - val secondLast = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.elementAtOrNull(context.qualifiedAccessOrAssignmentsOrAnnotationCalls.size - 2) + val secondLast = context.callsOrAssignments.elementAtOrNull(context.callsOrAssignments.size - 2) if (secondLast is FirQualifiedAccessExpression && secondLast.explicitReceiver == expression) return val diagnostic = expression.typeRef.coneTypeParameterInQualifiedAccess ?: return diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUnsupportedArrayLiteralChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUnsupportedArrayLiteralChecker.kt index dc37d46524d..16b369d481f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUnsupportedArrayLiteralChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUnsupportedArrayLiteralChecker.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.expressions.* object FirUnsupportedArrayLiteralChecker : FirArrayOfCallChecker() { override fun check(expression: FirArrayOfCall, context: CheckerContext, reporter: DiagnosticReporter) { if (!isInsideAnnotationCall(expression, context) && - (context.qualifiedAccessOrAssignmentsOrAnnotationCalls.isNotEmpty() || !isInsideAnnotationClass(context)) + (context.callsOrAssignments.isNotEmpty() || !isInsideAnnotationClass(context)) ) { reporter.reportOn( expression.source, @@ -32,7 +32,7 @@ object FirUnsupportedArrayLiteralChecker : FirArrayOfCallChecker() { } private fun isInsideAnnotationCall(expression: FirArrayOfCall, context: CheckerContext): Boolean { - context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull()?.let { + context.callsOrAssignments.lastOrNull()?.let { val arguments = when (it) { is FirFunctionCall -> if (it.typeRef.toRegularClassSymbol(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirOptInUsageTypeRefChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirOptInUsageTypeRefChecker.kt index 6b3a1720a77..2507e6235a8 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirOptInUsageTypeRefChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/type/FirOptInUsageTypeRefChecker.kt @@ -36,7 +36,7 @@ object FirOptInUsageTypeRefChecker : FirTypeRefChecker() { val symbol = coneType.lookupTag.toSymbol(context.session) ?: return symbol.lazyResolveToPhase(FirResolvePhase.STATUS) val classId = symbol.classId - val lastAnnotationCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.lastOrNull() as? FirAnnotation + val lastAnnotationCall = context.callsOrAssignments.lastOrNull() as? FirAnnotation if (lastAnnotationCall == null || lastAnnotationCall.annotationTypeRef !== typeRef) { if (classId == OptInNames.REQUIRES_OPT_IN_CLASS_ID || classId == OptInNames.OPT_IN_CLASS_ID) { reporter.reportOn(source, OPT_IN_CAN_ONLY_BE_USED_AS_ANNOTATION, context) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt index 5ee4c473ec7..e7bc9a9e754 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/AbstractDiagnosticCollectorVisitor.kt @@ -216,23 +216,27 @@ abstract class AbstractDiagnosticCollectorVisitor( } override fun visitFunctionCall(functionCall: FirFunctionCall, data: Nothing?) { - visitWithQualifiedAccessOrAnnotationCall(functionCall) + visitWithCallOrAssignment(functionCall) } override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: Nothing?) { - visitWithQualifiedAccessOrAnnotationCall(qualifiedAccessExpression) + visitWithCallOrAssignment(qualifiedAccessExpression) } override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: Nothing?) { - visitWithQualifiedAccessOrAnnotationCall(propertyAccessExpression) + visitWithCallOrAssignment(propertyAccessExpression) } override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: Nothing?) { - visitWithQualifiedAccessOrAnnotationCall(annotationCall) + visitWithCallOrAssignment(annotationCall) } override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Nothing?) { - visitWithQualifiedAccessOrAnnotationCall(variableAssignment) + visitWithCallOrAssignment(variableAssignment) + } + + override fun visitDelegatedConstructorCall(delegatedConstructorCall: FirDelegatedConstructorCall, data: Nothing?) { + visitWithCallOrAssignment(delegatedConstructorCall) } override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Nothing?) { @@ -273,9 +277,9 @@ abstract class AbstractDiagnosticCollectorVisitor( } } - private fun visitWithQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement) { - return withQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall) { - visitElement(qualifiedAccessOrAnnotationCall, null) + private fun visitWithCallOrAssignment(callOrAssignment: FirStatement) { + return withCallOrAssignment(callOrAssignment) { + visitElement(callOrAssignment, null) } } @@ -286,15 +290,15 @@ abstract class AbstractDiagnosticCollectorVisitor( } @OptIn(PrivateForInline::class) - inline fun withQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement, block: () -> R): R { + inline fun withCallOrAssignment(callOrAssignment: FirStatement, block: () -> R): R { val existingContext = context - context = context.addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall) + context = context.addCallOrAssignment(callOrAssignment) try { - return whileAnalysing(context.session, qualifiedAccessOrAnnotationCall) { + return whileAnalysing(context.session, callOrAssignment) { block() } } finally { - existingContext.dropQualifiedAccessOrAnnotationCall() + existingContext.dropCallOrAssignment() context = existingContext } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 47e3f04053a..c772984c47c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -63,7 +63,7 @@ class ErrorNodeDiagnosticCollectorComponent( private fun processErrorReference(reference: FirNamedReference, diagnostic: ConeDiagnostic, context: CheckerContext) { var source = reference.source ?: return - val qualifiedAccessOrAnnotationCall = context.qualifiedAccessOrAssignmentsOrAnnotationCalls.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. it.calleeReference == reference } @@ -75,10 +75,10 @@ class ErrorNodeDiagnosticCollectorComponent( ) return // If the receiver cannot be resolved, we skip reporting any further problems for this call. - if (qualifiedAccessOrAnnotationCall is FirQualifiedAccessExpression) { - if (qualifiedAccessOrAnnotationCall.dispatchReceiver.cannotBeResolved() || - qualifiedAccessOrAnnotationCall.extensionReceiver.cannotBeResolved() || - qualifiedAccessOrAnnotationCall.explicitReceiver.cannotBeResolved() + if (callOrAssignment is FirQualifiedAccessExpression) { + if (callOrAssignment.dispatchReceiver.cannotBeResolved() || + callOrAssignment.extensionReceiver.cannotBeResolved() || + callOrAssignment.explicitReceiver.cannotBeResolved() ) return } @@ -87,7 +87,7 @@ class ErrorNodeDiagnosticCollectorComponent( source = property.delegate?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: return } - reportFirDiagnostic(diagnostic, source, context, qualifiedAccessOrAnnotationCall?.source) + reportFirDiagnostic(diagnostic, source, context, callOrAssignment?.source) } private fun FirExpression?.cannotBeResolved(): Boolean { @@ -129,7 +129,7 @@ class ErrorNodeDiagnosticCollectorComponent( diagnostic: ConeDiagnostic, source: KtSourceElement, context: CheckerContext, - qualifiedAccessSource: KtSourceElement? = null + callOrAssignmentSource: KtSourceElement? = null ) { // Will be handled by [FirDestructuringDeclarationChecker] if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) { @@ -153,7 +153,7 @@ class ErrorNodeDiagnosticCollectorComponent( return } - for (coneDiagnostic in diagnostic.toFirDiagnostics(session, source, qualifiedAccessSource)) { + for (coneDiagnostic in diagnostic.toFirDiagnostics(session, source, callOrAssignmentSource)) { reporter.report(coneDiagnostic, context) } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index f4fc1f6dbda..52b1efcb0bb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -46,7 +46,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled private fun ConeDiagnostic.toKtDiagnostic( source: KtSourceElement, - qualifiedAccessSource: KtSourceElement? + callOrAssignmentSource: KtSourceElement? ): KtDiagnostic? = when (this) { is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn( source, @@ -83,7 +83,7 @@ private fun ConeDiagnostic.toKtDiagnostic( applicability.isSuccess -> FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.createOn(source, this.candidates.map { it.symbol }) applicability == CandidateApplicability.UNSAFE_CALL -> { val (unsafeCall, candidate) = candidates.firstNotNullOf { it.diagnostics.firstIsInstanceOrNull()?.to(it) } - mapUnsafeCallError(candidate, unsafeCall, source, qualifiedAccessSource) + mapUnsafeCallError(candidate, unsafeCall, source, callOrAssignmentSource) } applicability == CandidateApplicability.UNSTABLE_SMARTCAST -> { @@ -109,22 +109,22 @@ private fun ConeDiagnostic.toKtDiagnostic( FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.createOn(this.source, this.desiredCount, this.symbol) is ConeOuterClassArgumentsRequired -> - FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(qualifiedAccessSource ?: source, this.symbol) + FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED.createOn(callOrAssignmentSource ?: source, this.symbol) is ConeNoTypeArgumentsOnRhsError -> - FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(qualifiedAccessSource ?: source, this.desiredCount, this.symbol) + FirErrors.NO_TYPE_ARGUMENTS_ON_RHS.createOn(callOrAssignmentSource ?: source, this.desiredCount, this.symbol) - is ConeSyntaxDiagnostic -> FirSyntaxErrors.SYNTAX.createOn(qualifiedAccessSource ?: source, reason) + is ConeSyntaxDiagnostic -> FirSyntaxErrors.SYNTAX.createOn(callOrAssignmentSource ?: source, reason) is ConeSimpleDiagnostic -> when { source.kind is KtFakeSourceElementKind && source.kind != KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess -> null - else -> this.getFactory(source).createOn(qualifiedAccessSource ?: source) + else -> this.getFactory(source).createOn(callOrAssignmentSource ?: source) } is ConeDestructuringDeclarationsOnTopLevel -> null // TODO Currently a parsing error. Would be better to report here instead KT-58563 is ConeCannotInferTypeParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) is ConeCannotInferValueParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) - is ConeTypeVariableTypeIsNotInferred -> FirErrors.INFERENCE_ERROR.createOn(qualifiedAccessSource ?: source) + is ConeTypeVariableTypeIsNotInferred -> FirErrors.INFERENCE_ERROR.createOn(callOrAssignmentSource ?: source) is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target) is ConeStubDiagnostic -> null is ConeIntermediateDiagnostic -> null @@ -162,12 +162,12 @@ fun FirBasedSymbol<*>.toInvisibleReferenceDiagnostic(source: KtSourceElement?): fun ConeDiagnostic.toFirDiagnostics( session: FirSession, source: KtSourceElement, - qualifiedAccessSource: KtSourceElement? + callOrAssignmentSource: KtSourceElement? ): List { return when (this) { - is ConeInapplicableCandidateError -> mapInapplicableCandidateError(session, this, source, qualifiedAccessSource) - is ConeConstraintSystemHasContradiction -> mapSystemHasContradictionError(session, this, source, qualifiedAccessSource) - else -> listOfNotNull(toKtDiagnostic(source, qualifiedAccessSource)) + is ConeInapplicableCandidateError -> mapInapplicableCandidateError(session, this, source, callOrAssignmentSource) + is ConeConstraintSystemHasContradiction -> mapSystemHasContradictionError(session, this, source, callOrAssignmentSource) + else -> listOfNotNull(toKtDiagnostic(source, callOrAssignmentSource)) } } diff --git a/compiler/testData/diagnostics/tests/enum/constructorWithDefaultParametersOnly.fir.kt b/compiler/testData/diagnostics/tests/enum/constructorWithDefaultParametersOnly.fir.kt index a53bcadd231..9041f58f412 100644 --- a/compiler/testData/diagnostics/tests/enum/constructorWithDefaultParametersOnly.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/constructorWithDefaultParametersOnly.fir.kt @@ -6,7 +6,7 @@ enum class TestOk(val x: String = "OK") { enum class TestErrors(val x: String) { TEST1, - TEST2(), + TEST2(), TEST3("Hello") } diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/errorsOnEmptyDelegationCall.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/errorsOnEmptyDelegationCall.fir.kt index a38169a2f0a..4dd23ce1c53 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/errorsOnEmptyDelegationCall.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/errorsOnEmptyDelegationCall.fir.kt @@ -3,7 +3,7 @@ open class B0(x: Int) class A0 : B0 { constructor() - constructor(x: Int) : super() + constructor(x: Int) : super() } // -------------------------- diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsConstructors.fir.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsConstructors.fir.kt index c1b118c9454..33ffd91af68 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsConstructors.fir.kt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsConstructors.fir.kt @@ -17,4 +17,4 @@ val test2 = C2_Alias() class Test3 : C1_Alias() -class Test4 : C2_Alias() +class Test4 : C2_Alias()