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.
This commit is contained in:
Alexander Udalov
2020-01-15 00:32:19 +01:00
parent 514bf3eec0
commit b5afdc7553
4 changed files with 42 additions and 24 deletions
@@ -255,11 +255,11 @@ public interface Errors {
DiagnosticFactory1<PsiElement, FqName> ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_API_USAGE = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<PsiElement, FqName, String> EXPERIMENTAL_API_USAGE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory2<PsiElement, FqName, String> EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory2.create(ERROR);
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_OVERRIDE = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_OVERRIDE_ERROR = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<PsiElement, FqName, String> EXPERIMENTAL_OVERRIDE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory2<PsiElement, FqName, String> EXPERIMENTAL_OVERRIDE_ERROR = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<PsiElement> EXPERIMENTAL_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION = DiagnosticFactory0.create(ERROR);
@@ -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");
@@ -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<PsiElement, String>,
interface ExperimentalityDiagnostic {
fun report(trace: BindingTrace, element: PsiElement, fqName: FqName, message: String?)
}
class ExperimentalityDiagnostic2(
val factory: DiagnosticFactory2<PsiElement, FqName, String>,
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))
}
}
}
@@ -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<PsiElement, String>,
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