[FIR] Fix Disappeared INVALID_CHARACTERS

^KT-59996 Fixed
This commit is contained in:
Vladimir Sukharev
2023-10-17 00:45:36 +02:00
committed by Space Team
parent 50fdc2128f
commit 8e4a6759a4
12 changed files with 165 additions and 12 deletions
@@ -3036,7 +3036,7 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ResolvedToUnderscoreNamedCatchParameter::class
}
interface InvalidCharacters : KtFirDiagnostic<KtNamedDeclaration> {
interface InvalidCharacters : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = InvalidCharacters::class
val message: String
}
@@ -3661,7 +3661,7 @@ internal class InvalidCharactersImpl(
override val message: String,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.InvalidCharacters
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.InvalidCharacters
internal class DangerousCharactersImpl(
override val characters: String,
@@ -1515,7 +1515,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val UNDERSCORE_IS_RESERVED by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER by warning<KtNameReferenceExpression>()
val INVALID_CHARACTERS by error<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
val INVALID_CHARACTERS by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER) {
parameter<String>("message")
}
val DANGEROUS_CHARACTERS by warning<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
@@ -50,6 +50,7 @@ object JsDeclarationCheckers : DeclarationCheckers() {
override val fileCheckers: Set<FirFileChecker>
get() = setOf(
FirJsPackageDirectiveChecker,
FirJsNameClashFileTopLevelDeclarationsChecker
)
}
@@ -0,0 +1,39 @@
/*
* 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.declaration
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.config.LanguageFeature
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.declaration.FirFileChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.forEachChildOfType
import org.jetbrains.kotlin.fir.analysis.js.checkers.sanitizeName
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.text
object FirJsPackageDirectiveChecker: FirFileChecker() {
// inspired by FirJsNameCharsChecker.check()
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration.packageFqName.isRoot) return
if (context.languageVersionSettings.supportsFeature(LanguageFeature.JsAllowInvalidCharsIdentifiersEscaping)) return
declaration.packageDirective.source?.forEachChildOfType(setOf(KtNodeTypes.REFERENCE_EXPRESSION)) {
val name = it.text.toString()
if (sanitizeName(name) != name) {
reporter.reportOn(
it,
FirErrors.INVALID_CHARACTERS,
"$name contains illegal characters",
context,
)
}
}
}
}
@@ -765,7 +765,7 @@ object FirErrors {
val UNDERSCORE_IS_RESERVED by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER by warning0<KtNameReferenceExpression>()
val INVALID_CHARACTERS by error1<KtNamedDeclaration, String>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val INVALID_CHARACTERS by error1<PsiElement, String>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val DANGEROUS_CHARACTERS by warning1<KtNamedDeclaration, String>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val EQUALITY_NOT_APPLICABLE by error3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
val EQUALITY_NOT_APPLICABLE_WARNING by warning3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
@@ -1,3 +0,0 @@
package `//`
class A
@@ -1,3 +1,24 @@
package <!INVALID_CHARACTERS!>`//`<!>
// FIR_IDENTICAL
// FILE: slashes.kt
package a.<!INVALID_CHARACTERS!>`//`<!>.b.<!INVALID_CHARACTERS!>`/`<!>.c
class Slashes
class A
// FILE: space.kt
package <!INVALID_CHARACTERS!>` `<!>
class Space
// FILE: less.kt
package <!INVALID_CHARACTERS!>`<`<!>
class Less
// FILE: more.kt
package <!INVALID_CHARACTERS!>`>`<!>
class More
// FILE: dash.kt
package <!INVALID_CHARACTERS!>`-`<!>
class Dash
// FILE: question.kt
package <!INVALID_CHARACTERS!>`?`<!>
class Question
@@ -1,11 +1,64 @@
package
package `//` {
package ` ` {
public final class A {
public constructor A()
public final class Space {
public constructor Space()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package `-` {
public final class Dash {
public constructor Dash()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package `>` {
public final class More {
public constructor More()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package `?` {
public final class Question {
public constructor Question()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
package a {
package a.`//` {
package a.`//`.b {
package a.`//`.b.`/` {
package a.`//`.b.`/`.c {
public final class Slashes {
public constructor Slashes()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
}
}
}
@@ -0,0 +1,30 @@
// FIR_IDENTICAL
// !LANGUAGE: +JsAllowInvalidCharsIdentifiersEscaping
// FILE: slashes.kt
package a.`//`.b.`/`.c
class Slashes
// FILE: slash.kt
package `/`
class Slash
// FILE: space.kt
package ` `
class Space
// FILE: less.kt
package `<`
class Less
// FILE: more.kt
package `>`
class More
// FILE: dash.kt
package `-`
class Dash
// FILE: question.kt
package `?`
class Question
@@ -790,6 +790,12 @@ public class FirPsiJsOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiJ
runTest("compiler/testData/diagnostics/testsWithJsStdLib/name/jsNameWithoutParameter.kt");
}
@Test
@TestMetadata("legalPackageName.kt")
public void testLegalPackageName() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJsStdLib/name/legalPackageName.kt");
}
@Test
@TestMetadata("methodAndMethod.kt")
public void testMethodAndMethod() throws Exception {
@@ -790,6 +790,12 @@ public class DiagnosticsWithJsStdLibTestGenerated extends AbstractDiagnosticsTes
runTest("compiler/testData/diagnostics/testsWithJsStdLib/name/jsNameWithoutParameter.kt");
}
@Test
@TestMetadata("legalPackageName.kt")
public void testLegalPackageName() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJsStdLib/name/legalPackageName.kt");
}
@Test
@TestMetadata("methodAndMethod.kt")
public void testMethodAndMethod() throws Exception {