[FIR JS] Report WRONG_JS_QUALIFIER for the argument of JsQualifier
This commit is contained in:
committed by
Space Team
parent
73c89a5d9d
commit
f422a3a4e8
@@ -206,6 +206,7 @@
|
||||
/core/builtins/ "Kotlin Compiler Core"
|
||||
/core/compiler.common/ "Kotlin Compiler Core"
|
||||
/core/compiler.common.jvm/ "Kotlin Compiler Core"
|
||||
/core/compiler.common.js/ "Kotlin Compiler Core"
|
||||
/core/descriptors/ "Kotlin Compiler Core"
|
||||
/core/descriptors.jvm/ "Kotlin Compiler Core"
|
||||
/core/descriptors.runtime/ "Kotlin Libraries"
|
||||
|
||||
+2
-1
@@ -10,10 +10,11 @@ import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.JVM_DIAGNOSTICS_L
|
||||
import java.nio.file.Paths
|
||||
import org.jetbrains.kotlin.analysis.api.fir.generator.DiagnosticClassGenerator.generate
|
||||
import org.jetbrains.kotlin.fir.builder.SYNTAX_DIAGNOSTIC_LIST
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.JS_DIAGNOSTICS_LIST
|
||||
|
||||
fun main() {
|
||||
val rootPath = Paths.get("analysis/analysis-api-fir/src").toAbsolutePath()
|
||||
val packageName = "org.jetbrains.kotlin.analysis.api.fir.diagnostics"
|
||||
val diagnostics = DIAGNOSTICS_LIST + JVM_DIAGNOSTICS_LIST + SYNTAX_DIAGNOSTIC_LIST
|
||||
val diagnostics = DIAGNOSTICS_LIST + JVM_DIAGNOSTICS_LIST + JS_DIAGNOSTICS_LIST + SYNTAX_DIAGNOSTIC_LIST
|
||||
generate(rootPath, diagnostics, packageName)
|
||||
}
|
||||
|
||||
+6
@@ -976,6 +976,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirJsErrors.WRONG_JS_QUALIFIER) { firDiagnostic ->
|
||||
WrongJsQualifierImpl(
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.OPT_IN_USAGE) { firDiagnostic ->
|
||||
OptInUsageImpl(
|
||||
firDiagnostic.a,
|
||||
|
||||
+4
@@ -703,6 +703,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val typeFromTypesPhase: KtType
|
||||
}
|
||||
|
||||
abstract class WrongJsQualifier : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = WrongJsQualifier::class
|
||||
}
|
||||
|
||||
abstract class OptInUsage : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = OptInUsage::class
|
||||
abstract val optInMarkerFqName: FqName
|
||||
|
||||
+5
@@ -844,6 +844,11 @@ internal class PluginAnnotationAmbiguityImpl(
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.PluginAnnotationAmbiguity(), KtAbstractFirDiagnostic<PsiElement>
|
||||
|
||||
internal class WrongJsQualifierImpl(
|
||||
override val firDiagnostic: KtPsiDiagnostic,
|
||||
override val token: KtLifetimeToken,
|
||||
) : KtFirDiagnostic.WrongJsQualifier(), KtAbstractFirDiagnostic<KtElement>
|
||||
|
||||
internal class OptInUsageImpl(
|
||||
override val optInMarkerFqName: FqName,
|
||||
override val message: String,
|
||||
|
||||
@@ -14,6 +14,7 @@ dependencies {
|
||||
compileOnly(project(":compiler:psi"))
|
||||
compileOnly(project(":core:compiler.common"))
|
||||
compileOnly(project(":core:compiler.common.jvm"))
|
||||
compileOnly(project(":core:compiler.common.js"))
|
||||
implementation(project(":analysis:analysis-internal-utils"))
|
||||
implementation(project(":analysis:analysis-api-providers"))
|
||||
implementation(project(":analysis:kt-references"))
|
||||
|
||||
@@ -142,6 +142,7 @@ val commonCompilerModules = arrayOf(
|
||||
":core:deserialization.common.jvm",
|
||||
":core:compiler.common",
|
||||
":core:compiler.common.jvm",
|
||||
":core:compiler.common.js",
|
||||
":core:util.runtime",
|
||||
":compiler:frontend.common.jvm",
|
||||
":compiler:frontend.java", // TODO this is fe10 module but some utils used in fir ide now
|
||||
@@ -237,6 +238,7 @@ extra["kotlinJpsPluginEmbeddedDependencies"] = listOf(
|
||||
":daemon-common",
|
||||
":core:compiler.common",
|
||||
":core:compiler.common.jvm",
|
||||
":core:compiler.common.js",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":compiler:backend.common.jvm",
|
||||
|
||||
+6
-1
@@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.checkers.generator.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.DiagnosticList
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
@Suppress("UNUSED_VARIABLE", "LocalVariableName", "ClassName", "unused")
|
||||
@OptIn(PrivateForInline::class)
|
||||
object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors")
|
||||
object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
||||
val ANNOTATIONS by object : DiagnosticGroup("Annotations") {
|
||||
val WRONG_JS_QUALIFIER by error<KtElement>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":core:compiler.common.js"))
|
||||
api(project(":compiler:fir:checkers"))
|
||||
|
||||
/*
|
||||
|
||||
+4
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics.js
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
@@ -15,6 +16,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
*/
|
||||
|
||||
object FirJsErrors {
|
||||
// Annotations
|
||||
val WRONG_JS_QUALIFIER by error0<KtElement>()
|
||||
|
||||
init {
|
||||
RootDiagnosticRendererFactory.registerFactory(FirJsErrorsDefaultMessages)
|
||||
}
|
||||
|
||||
+6
-1
@@ -7,9 +7,14 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics.js
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.checkMissingMessages
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
||||
|
||||
@Suppress("unused")
|
||||
object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
override val MAP = KtDiagnosticFactoryToRendererMap("FIR").also { _ ->
|
||||
override val MAP = KtDiagnosticFactoryToRendererMap("FIR").also { map ->
|
||||
map.put(WRONG_JS_QUALIFIER, "Qualifier contains illegal characters")
|
||||
|
||||
map.checkMissingMessages(FirJsErrors)
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -6,5 +6,11 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.*
|
||||
import org.jetbrains.kotlin.fir.analysis.js.checkers.expression.FirJsQualifierChecker
|
||||
|
||||
object JsExpressionCheckers : ExpressionCheckers()
|
||||
object JsExpressionCheckers : ExpressionCheckers() {
|
||||
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
||||
get() = setOf(
|
||||
FirJsQualifierChecker,
|
||||
)
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.fir.analysis.js.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnnotationCallChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClassId
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.js.validateQualifier
|
||||
import org.jetbrains.kotlin.name.JsStandardClassIds.Annotations.JsQualifier
|
||||
|
||||
object FirJsQualifierChecker : FirAnnotationCallChecker() {
|
||||
override fun check(expression: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val annotationFqName = expression.fullyExpandedClassId(context.session)
|
||||
|
||||
if (annotationFqName != JsQualifier) {
|
||||
return
|
||||
}
|
||||
|
||||
val string = (expression.argumentMapping.mapping.values.firstOrNull() as? FirConstExpression<*>)?.value as? String ?: return
|
||||
|
||||
if (!validateQualifier(string)) {
|
||||
reporter.reportOn(expression.argumentList.arguments.first().source, FirJsErrors.WRONG_JS_QUALIFIER, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// FILE: a.kt
|
||||
@file:JsQualifier("")
|
||||
|
||||
// FILE: b.kt
|
||||
@file:JsQualifier("a..b")
|
||||
|
||||
// FILE: c.kt
|
||||
@file:JsQualifier("a.")
|
||||
|
||||
// FILE: d.kt
|
||||
@file:JsQualifier(".a")
|
||||
|
||||
// FILE: e.kt
|
||||
@file:JsQualifier("%^&")
|
||||
|
||||
// FILE: f.kt
|
||||
@file:JsQualifier("a.bc.d23._$")
|
||||
+8
-1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: a.kt
|
||||
@file:JsQualifier(<!WRONG_JS_QUALIFIER!>""<!>)
|
||||
|
||||
@@ -14,4 +15,10 @@
|
||||
@file:JsQualifier(<!WRONG_JS_QUALIFIER!>"%^&"<!>)
|
||||
|
||||
// FILE: f.kt
|
||||
@file:JsQualifier("a.bc.d23._$")
|
||||
@file:JsQualifier("a.bc.d23._$")
|
||||
|
||||
// FILE: g.kt
|
||||
typealias JsQ = JsQualifier
|
||||
|
||||
// FILE: h.kt
|
||||
@file:JsQ(<!WRONG_JS_QUALIFIER!>value = "%^&"<!>)
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
package
|
||||
|
||||
public typealias JsQ = kotlin.js.JsQualifier
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
project.configureJvmToolchain(JdkMajorVersion.JDK_1_8)
|
||||
|
||||
dependencies {
|
||||
api(project(":core:compiler.common"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.js
|
||||
|
||||
fun validateQualifier(qualifier: String): Boolean {
|
||||
val parts = qualifier.split('.')
|
||||
if (parts.isEmpty()) return false
|
||||
|
||||
return parts.all { part ->
|
||||
part.isNotEmpty() && part[0].isJavaIdentifierStart() && part.drop(1).all(Char::isJavaIdentifierPart)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.name
|
||||
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.BASE_KOTLIN_PACKAGE
|
||||
|
||||
object JsStandardClassIds {
|
||||
val BASE_JS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("js"))
|
||||
|
||||
object Annotations {
|
||||
val JsQualifier = "JsQualifier".jsId()
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.jsId() = ClassId(JsStandardClassIds.BASE_JS_PACKAGE, Name.identifier(this))
|
||||
+1
-9
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.resolve.diagnostics
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.js.validateQualifier
|
||||
import org.jetbrains.kotlin.psi.KtAnnotated
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
|
||||
@@ -44,13 +45,4 @@ object JsQualifierChecker : AdditionalAnnotationChecker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun validateQualifier(qualifier: String): Boolean {
|
||||
val parts = qualifier.split('.')
|
||||
if (parts.isEmpty()) return false
|
||||
|
||||
return parts.all { part ->
|
||||
part.isNotEmpty() && part[0].isJavaIdentifierStart() && part.drop(1).all(Char::isJavaIdentifierPart)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ include ":benchmarks",
|
||||
":native:kotlin-klib-commonizer-embeddable",
|
||||
":core:compiler.common",
|
||||
":core:compiler.common.jvm",
|
||||
":core:compiler.common.js",
|
||||
":compiler:backend.common.jvm",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
|
||||
Reference in New Issue
Block a user