[FIR] Implement INVALID_CHARACTERS

This commit is contained in:
Ivan Kochurkin
2021-07-22 23:47:01 +03:00
committed by Space
parent 63fc3645ab
commit 83895c49c5
14 changed files with 99 additions and 116 deletions
@@ -1068,8 +1068,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<ConeKotlinType>("actualType")
}
val UNDERSCORE_IS_RESERVED by error<PsiElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<PsiElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_IS_RESERVED by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val INVALID_CHARACTERS by error<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
parameter<String>("message")
}
val EQUALITY_NOT_APPLICABLE by error<KtBinaryExpression> {
parameter<String>("operator")
@@ -69,7 +69,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
FUN_MODIFIER,
SUSPEND_MODIFIER,
FUN_INTERFACE,
RESERVED_UNDERSCORE,
NAME_IDENTIFIER,
QUESTION_MARK_BY_TYPE,
ANNOTATION_USE_SITE,
ASSIGNMENT_LHS,
@@ -554,8 +554,9 @@ object FirErrors {
val DELEGATE_SPECIAL_FUNCTION_AMBIGUITY by error2<KtExpression, String, Collection<FirBasedSymbol<*>>>()
val DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE by error2<KtExpression, String, Collection<FirBasedSymbol<*>>>()
val DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH by error3<KtExpression, String, ConeKotlinType, ConeKotlinType>()
val UNDERSCORE_IS_RESERVED by error0<PsiElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error0<PsiElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
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 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>()
@@ -30,7 +30,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirInfixFunctionDeclarationChecker,
FirExposedVisibilityDeclarationChecker,
FirCyclicTypeBoundsChecker,
FirExpectActualDeclarationChecker
FirExpectActualDeclarationChecker,
FirInvalidCharactersChecker
)
override val functionCheckers: Set<FirFunctionChecker>
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2021 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.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
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.name.Name
object FirInvalidCharactersChecker : FirBasicDeclarationChecker() {
private val INVALID_CHARS = setOf('.', ';', '[', ']', '/', '<', '>', ':', '\\')
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
val source = declaration.source
when (declaration) {
is FirRegularClass -> checkNameAndReport(declaration.name, source, context, reporter)
is FirSimpleFunction -> checkNameAndReport(declaration.name, source, context, reporter)
is FirTypeParameter -> checkNameAndReport(declaration.name, source, context, reporter)
is FirProperty -> checkNameAndReport(declaration.name, source, context, reporter)
is FirTypeAlias -> checkNameAndReport(declaration.name, source, context, reporter)
is FirValueParameter -> checkNameAndReport(declaration.name, source, context, reporter)
else -> return
}
}
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 }
) {
reporter.reportOn(
source,
FirErrors.INVALID_CHARACTERS,
"contains illegal characters: ${INVALID_CHARS.intersect(nameString.toSet()).joinToString("")}",
context
)
}
}
}
@@ -228,6 +228,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSID
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_CHARACTERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_REFERENCE
@@ -1398,6 +1399,11 @@ class FirDefaultErrorMessages {
UNDERSCORE_USAGE_WITHOUT_BACKTICKS,
"Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)"
)
map.put(
INVALID_CHARACTERS,
"Name {0}",
STRING
)
map.put(
EQUALITY_NOT_APPLICABLE,
"Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''",
@@ -708,7 +708,7 @@ object LightTreePositioningStrategies {
}
}
val RESERVED_UNDERSCORE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
val NAME_IDENTIFIER: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
@@ -238,9 +238,9 @@ object SourceElementPositioningStrategies {
PositioningStrategies.TYPE_PARAMETERS_LIST
)
val RESERVED_UNDERSCORE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.RESERVED_UNDERSCORE,
PositioningStrategies.RESERVED_UNDERSCORE
val NAME_IDENTIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.NAME_IDENTIFIER,
PositioningStrategies.NAME_IDENTIFIER
)
val QUESTION_MARK_BY_TYPE = SourceElementPositioningStrategy(