[FIR] Implement DANGEROUS_CHARACTERS
This commit is contained in:
+3
@@ -1073,6 +1073,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val INVALID_CHARACTERS by error<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
|
||||
parameter<String>("message")
|
||||
}
|
||||
val DANGEROUS_CHARACTERS by warning<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
|
||||
parameter<String>("characters")
|
||||
}
|
||||
|
||||
val EQUALITY_NOT_APPLICABLE by error<KtBinaryExpression> {
|
||||
parameter<String>("operator")
|
||||
|
||||
@@ -557,6 +557,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 INVALID_CHARACTERS by error1<KtNamedDeclaration, 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>()
|
||||
val INCOMPATIBLE_ENUM_COMPARISON_ERROR by error2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirExposedVisibilityDeclarationChecker,
|
||||
FirCyclicTypeBoundsChecker,
|
||||
FirExpectActualDeclarationChecker,
|
||||
FirInvalidCharactersChecker
|
||||
FirInvalidAndDangerousCharactersChecker
|
||||
)
|
||||
|
||||
override val functionCheckers: Set<FirFunctionChecker>
|
||||
|
||||
+22
-12
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
@@ -15,9 +14,13 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
object FirInvalidCharactersChecker : FirBasicDeclarationChecker() {
|
||||
object FirInvalidAndDangerousCharactersChecker : FirBasicDeclarationChecker() {
|
||||
// See The Java Virtual Machine Specification, section 4.7.9.1 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.9.1
|
||||
private val INVALID_CHARS = setOf('.', ';', '[', ']', '/', '<', '>', ':', '\\')
|
||||
|
||||
// These characters can cause problems on Windows. '?*"|' are not allowed in file names, and % leads to unexpected env var expansion.
|
||||
private val DANGEROUS_CHARS = setOf('?', '*', '"', '|', '%')
|
||||
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val source = declaration.source
|
||||
when (declaration) {
|
||||
@@ -32,19 +35,26 @@ object FirInvalidCharactersChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
|
||||
private fun checkNameAndReport(name: Name, source: FirSourceElement?, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val nameString = name.asString()
|
||||
if (source != null &&
|
||||
source.kind !is FirFakeSourceElementKind &&
|
||||
source.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION &&
|
||||
!name.isSpecial &&
|
||||
nameString.any { it in INVALID_CHARS }
|
||||
!name.isSpecial
|
||||
) {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
FirErrors.INVALID_CHARACTERS,
|
||||
"contains illegal characters: ${INVALID_CHARS.intersect(nameString.toSet()).joinToString("")}",
|
||||
context
|
||||
)
|
||||
val nameString = name.asString()
|
||||
if (nameString.any { it in INVALID_CHARS }) {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
FirErrors.INVALID_CHARACTERS,
|
||||
"contains illegal characters: ${INVALID_CHARS.intersect(nameString.toSet()).joinToString("")}",
|
||||
context
|
||||
)
|
||||
} else if (nameString.any { it in DANGEROUS_CHARS }) {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
FirErrors.DANGEROUS_CHARACTERS,
|
||||
DANGEROUS_CHARS.intersect(nameString.toSet()).joinToString(""),
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
@@ -108,6 +108,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CREATING_AN_INSTA
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_GENERIC_UPPER_BOUND
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_INHERITANCE_HIERARCHY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DANGEROUS_CHARACTERS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_OVERRIDE_CONFLICT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_VARARG_PARAMETER
|
||||
@@ -1404,6 +1405,11 @@ class FirDefaultErrorMessages {
|
||||
"Name {0}",
|
||||
STRING
|
||||
)
|
||||
map.put(
|
||||
DANGEROUS_CHARACTERS,
|
||||
"Name contains characters which can cause problems on Windows: {0}",
|
||||
STRING
|
||||
)
|
||||
map.put(
|
||||
EQUALITY_NOT_APPLICABLE,
|
||||
"Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''",
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
class `A?B`
|
||||
class `A*B`
|
||||
class `A"B`
|
||||
class `A|B`
|
||||
class `A%B`
|
||||
|
||||
fun `?*"|%`(): Int {
|
||||
val `?` = 0
|
||||
return `?`
|
||||
}
|
||||
|
||||
val `"a"+"b"` = "c"
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class <!DANGEROUS_CHARACTERS!>`A?B`<!>
|
||||
class <!DANGEROUS_CHARACTERS!>`A*B`<!>
|
||||
class <!DANGEROUS_CHARACTERS!>`A"B`<!>
|
||||
|
||||
+7
@@ -2883,6 +2883,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.DANGEROUS_CHARACTERS) { firDiagnostic ->
|
||||
DangerousCharactersImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.EQUALITY_NOT_APPLICABLE) { firDiagnostic ->
|
||||
EqualityNotApplicableImpl(
|
||||
firDiagnostic.a,
|
||||
|
||||
+5
@@ -2016,6 +2016,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val message: String
|
||||
}
|
||||
|
||||
abstract class DangerousCharacters : KtFirDiagnostic<KtNamedDeclaration>() {
|
||||
override val diagnosticClass get() = DangerousCharacters::class
|
||||
abstract val characters: String
|
||||
}
|
||||
|
||||
abstract class EqualityNotApplicable : KtFirDiagnostic<KtBinaryExpression>() {
|
||||
override val diagnosticClass get() = EqualityNotApplicable::class
|
||||
abstract val operator: String
|
||||
|
||||
+8
@@ -3247,6 +3247,14 @@ internal class InvalidCharactersImpl(
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class DangerousCharactersImpl(
|
||||
override val characters: String,
|
||||
firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.DangerousCharacters(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class EqualityNotApplicableImpl(
|
||||
override val operator: String,
|
||||
override val leftType: KtType,
|
||||
|
||||
Reference in New Issue
Block a user