[IR] Support ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE in K2
It's implemented as IR checker because in K2 constant expressions are evaluated on backend. FIR diagnostic removed because isn't needed. "annotationViaActualTypeAlias" test has no `// FIR_IDENTICAL` because diagnostic reported on entire typealias declaration instead of its name. This is because in IR+LightTree we have only offsets, so can't navigate to typealias name element. ^KT-59940 Fixed
This commit is contained in:
committed by
Space Team
parent
ce666182a2
commit
ad4d1a5ba8
+9
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.EXPECT_ACTUAL_ANNOTATION_INCOMPATIBILITY
|
||||
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.INCOMPATIBILITY
|
||||
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.DECLARATION_NAME
|
||||
import org.jetbrains.kotlin.backend.common.BackendDiagnosticRenderers.SYMBOL_OWNER_DECLARATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderer
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.MODULE_WITH_PLATFORM
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classFqName
|
||||
@@ -31,6 +33,7 @@ object CommonBackendErrors {
|
||||
val INCOMPATIBLE_MATCHING by error3<PsiElement, String, String, ExpectActualCompatibility.Incompatible<*>>()
|
||||
val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3<PsiElement, IrSymbol, IrSymbol, ExpectActualAnnotationsIncompatibilityType<IrConstructorCall>>()
|
||||
val EVALUATION_ERROR by error1<PsiElement, String>()
|
||||
val ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE by error1<PsiElement, IrValueParameter>()
|
||||
|
||||
init {
|
||||
RootDiagnosticRendererFactory.registerFactory(KtDefaultCommonBackendErrorMessages)
|
||||
@@ -77,6 +80,11 @@ object KtDefaultCommonBackendErrorMessages : BaseDiagnosticRendererFactory() {
|
||||
"Cannot evaluate constant expression: {0}",
|
||||
STRING,
|
||||
)
|
||||
map.put(
|
||||
CommonBackendErrors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE,
|
||||
"Parameter ''{0}'' has conflicting values in expected and actual annotations.",
|
||||
DECLARATION_NAME,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,4 +104,5 @@ object BackendDiagnosticRenderers {
|
||||
}
|
||||
"Annotation `$expectAnnotationFqName` $reason"
|
||||
}
|
||||
val DECLARATION_NAME = Renderer<IrDeclarationWithName> { it.name.asString() }
|
||||
}
|
||||
|
||||
+11
@@ -138,6 +138,17 @@ internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportActualAnnotati
|
||||
)
|
||||
}
|
||||
|
||||
internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportActualAnnotationConflictingDefaultArgumentValue(
|
||||
reportOn: IrElement,
|
||||
file: IrFile,
|
||||
actualParam: IrValueParameter,
|
||||
) {
|
||||
at(reportOn, file).report(
|
||||
CommonBackendErrors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE,
|
||||
actualParam,
|
||||
)
|
||||
}
|
||||
|
||||
internal fun IrElement.containsOptionalExpectation(): Boolean {
|
||||
return this is IrClass &&
|
||||
this.kind == ClassKind.ANNOTATION_CLASS &&
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.backend.common.actualizer.checker
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.actualizer.reportActualAnnotationConflictingDefaultArgumentValue
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy
|
||||
|
||||
internal object IrExpectActualAnnotationConflictingDefaultArgumentValueChecker : IrExpectActualChecker {
|
||||
override fun check(context: IrExpectActualChecker.Context) = with(context) {
|
||||
for ((expectSymbol, actualSymbol) in matchedExpectToActual) {
|
||||
if (expectSymbol !is IrConstructorSymbol || actualSymbol !is IrConstructorSymbol) continue
|
||||
|
||||
val expectClass = expectSymbol.owner.parentAsClass
|
||||
if (expectClass.kind != ClassKind.ANNOTATION_CLASS) continue
|
||||
|
||||
val expectValueParams = expectSymbol.owner.valueParameters
|
||||
val actualValueParams = actualSymbol.owner.valueParameters
|
||||
if (expectValueParams.size != actualValueParams.size) continue
|
||||
|
||||
for ((expectParam, actualParam) in expectValueParams.zip(actualValueParams)) {
|
||||
val expectDefaultValue = expectParam.defaultValue?.expression ?: continue
|
||||
val actualDefaultValue = actualParam.defaultValue?.expression ?: continue
|
||||
with(matchingContext) {
|
||||
if (!areIrExpressionConstValuesEqual(
|
||||
expectDefaultValue, actualDefaultValue,
|
||||
ExpectActualCollectionArgumentsCompatibilityCheckStrategy.Default
|
||||
)
|
||||
) {
|
||||
reportError(expectClass, actualDefaultValue, actualParam)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpectActualChecker.Context.reportError(
|
||||
expectAnnotationClass: IrClass,
|
||||
actualDefaultValue: IrExpression,
|
||||
actualParam: IrValueParameter,
|
||||
) {
|
||||
val actualTypealias = getTypealiasSymbolIfActualizedViaTypealias(expectAnnotationClass, classActualizationInfo)?.owner
|
||||
if (actualTypealias != null) {
|
||||
diagnosticsReporter.reportActualAnnotationConflictingDefaultArgumentValue(
|
||||
actualTypealias, actualTypealias.file, actualParam
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
diagnosticsReporter.reportActualAnnotationConflictingDefaultArgumentValue(
|
||||
actualDefaultValue, actualParam.file, actualParam
|
||||
)
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -20,7 +20,8 @@ internal class IrExpectActualCheckers(
|
||||
) : IrExpectActualChecker.Context {
|
||||
|
||||
private val checkers: Set<IrExpectActualChecker> = setOf(
|
||||
IrExpectActualAnnotationMatchingChecker
|
||||
IrExpectActualAnnotationMatchingChecker,
|
||||
IrExpectActualAnnotationConflictingDefaultArgumentValueChecker,
|
||||
)
|
||||
|
||||
override val matchingContext = object : IrExpectActualMatchingContext(typeSystemContext, classActualizationInfo.actualClasses) {
|
||||
|
||||
Reference in New Issue
Block a user