From b5afdc7553e07cf459e883f8ff0a62354520e2a0 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 15 Jan 2020 00:32:19 +0100 Subject: [PATCH] Keep annotation FQ name in experimental API diagnostics This fixes compilation of ExperimentalFixesFactory where this FQ name is used to construct a correct quick fix instance. --- .../jetbrains/kotlin/diagnostics/Errors.java | 8 +++--- .../rendering/DefaultErrorMessages.java | 8 +++--- .../checkers/ExperimentalUsageChecker.kt | 24 +++++++++++------ .../evaluate/ConstantExpressionEvaluator.kt | 26 +++++++++++++------ 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 0a06489be8e..84edd31a911 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -255,11 +255,11 @@ public interface Errors { DiagnosticFactory1 ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING); - DiagnosticFactory1 EXPERIMENTAL_API_USAGE = DiagnosticFactory1.create(WARNING); - DiagnosticFactory1 EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory1.create(ERROR); + DiagnosticFactory2 EXPERIMENTAL_API_USAGE = DiagnosticFactory2.create(WARNING); + DiagnosticFactory2 EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory2.create(ERROR); - DiagnosticFactory1 EXPERIMENTAL_OVERRIDE = DiagnosticFactory1.create(WARNING); - DiagnosticFactory1 EXPERIMENTAL_OVERRIDE_ERROR = DiagnosticFactory1.create(ERROR); + DiagnosticFactory2 EXPERIMENTAL_OVERRIDE = DiagnosticFactory2.create(WARNING); + DiagnosticFactory2 EXPERIMENTAL_OVERRIDE_ERROR = DiagnosticFactory2.create(ERROR); DiagnosticFactory0 EXPERIMENTAL_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION = DiagnosticFactory0.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 3201c756752..397d14f7f26 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -147,11 +147,11 @@ public class DefaultErrorMessages { MAP.put(ILLEGAL_KOTLIN_VERSION_STRING_VALUE, "Invalid @{0} annotation value (should be ''major.minor'' or ''major.minor.patch'')", TO_STRING); MAP.put(NEWER_VERSION_IN_SINCE_KOTLIN, "The version is greater than the specified API version {0}", STRING); - MAP.put(EXPERIMENTAL_API_USAGE, "{0}", STRING); - MAP.put(EXPERIMENTAL_API_USAGE_ERROR, "{0}", STRING); + MAP.put(EXPERIMENTAL_API_USAGE, "{1}", TO_STRING, STRING); + MAP.put(EXPERIMENTAL_API_USAGE_ERROR, "{1}", TO_STRING, STRING); - MAP.put(EXPERIMENTAL_OVERRIDE, "{0}", STRING); - MAP.put(EXPERIMENTAL_OVERRIDE_ERROR, "{0}", STRING); + MAP.put(EXPERIMENTAL_OVERRIDE, "{1}", TO_STRING, STRING); + MAP.put(EXPERIMENTAL_OVERRIDE_ERROR, "{1}", TO_STRING, STRING); MAP.put(EXPERIMENTAL_IS_NOT_ENABLED, "This class can only be used with the compiler argument '-Xopt-in=kotlin.RequiresOptIn'"); MAP.put(EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION, "This class can only be used as an annotation"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt index 854fd50f4a1..2be5174a0fc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt @@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 +import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2 import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -60,10 +60,18 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { } } - class ExperimentalityDiagnostic( - val factory: DiagnosticFactory1, + interface ExperimentalityDiagnostic { + fun report(trace: BindingTrace, element: PsiElement, fqName: FqName, message: String?) + } + + class ExperimentalityDiagnostic2( + val factory: DiagnosticFactory2, val defaultMessage: (FqName) -> String - ) + ) : ExperimentalityDiagnostic { + override fun report(trace: BindingTrace, element: PsiElement, fqName: FqName, message: String?) { + trace.reportDiagnosticOnce(factory.on(element, fqName, message ?: defaultMessage(fqName))) + } + } data class ExperimentalityDiagnostics( val warning: ExperimentalityDiagnostic, @@ -99,11 +107,11 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { } private val USAGE_DIAGNOSTICS = ExperimentalityDiagnostics( - warning = ExperimentalityDiagnostic( + warning = ExperimentalityDiagnostic2( Errors.EXPERIMENTAL_API_USAGE, getDefaultDiagnosticMessage("This declaration is experimental and its usage should be marked") ), - error = ExperimentalityDiagnostic( + error = ExperimentalityDiagnostic2( Errors.EXPERIMENTAL_API_USAGE_ERROR, getDefaultDiagnosticMessage("This declaration is experimental and its usage must be marked") ) @@ -130,7 +138,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { Experimentality.Severity.WARNING -> diagnostics.warning Experimentality.Severity.ERROR -> diagnostics.error } - trace.reportDiagnosticOnce(diagnostic.factory.on(element, message ?: diagnostic.defaultMessage(annotationFqName))) + diagnostic.report(trace, element, annotationFqName, message) } } } @@ -375,7 +383,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { ?: "This declaration overrides experimental member of supertype " + "'${member.containingDeclaration.name.asString()}' and $defaultMessageVerb be annotated " + "with '@${experimentality.annotationFqName.asString()}'" - context.trace.report(diagnostic.on(reportOn, message)) + context.trace.report(diagnostic.on(reportOn, experimentality.annotationFqName, message)) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 5a6017de7f6..4bdbb853ee7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.resolve.constants.evaluate import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.TypeConversionUtil import org.jetbrains.kotlin.KtNodeTypes @@ -15,8 +16,11 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl +import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType @@ -318,15 +322,21 @@ class ConstantExpressionEvaluator( } companion object { + private class ExperimentalityDiagnostic1( + val factory: DiagnosticFactory1, + val verb: String + ) : ExperimentalUsageChecker.ExperimentalityDiagnostic { + override fun report(trace: BindingTrace, element: PsiElement, fqName: FqName, message: String?) { + val defaultMessage = ExperimentalUsageChecker.getDefaultDiagnosticMessage( + "Unsigned literals are experimental and their usages $verb be marked" + ) + trace.reportDiagnosticOnce(factory.on(element, defaultMessage(fqName))) + } + } + private val EXPERIMENTAL_UNSIGNED_LITERALS_DIAGNOSTICS = ExperimentalUsageChecker.ExperimentalityDiagnostics( - warning = ExperimentalUsageChecker.ExperimentalityDiagnostic( - Errors.EXPERIMENTAL_UNSIGNED_LITERALS, - ExperimentalUsageChecker.getDefaultDiagnosticMessage("Unsigned literals are experimental and their usages should be marked") - ), - error = ExperimentalUsageChecker.ExperimentalityDiagnostic( - Errors.EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, - ExperimentalUsageChecker.getDefaultDiagnosticMessage("Unsigned literals are experimental and their usages must be marked") - ) + warning = ExperimentalityDiagnostic1(Errors.EXPERIMENTAL_UNSIGNED_LITERALS, "should"), + error = ExperimentalityDiagnostic1(Errors.EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "must") ) @JvmStatic