[FIR] Implement OPERATOR_RENAMED_ON_IMPORT diagnostic

This commit is contained in:
Andrey Zinovyev
2021-06-02 16:03:21 +03:00
committed by Space
parent 7c669b65c3
commit c507d1c938
9 changed files with 45 additions and 16 deletions
@@ -955,6 +955,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val CONFLICTING_IMPORT by error<KtImportDirective>(PositioningStrategy.IMPORT_LAST_NAME) {
parameter<Name>("name")
}
val OPERATOR_RENAMED_ON_IMPORT by error<KtSimpleNameExpression>(PositioningStrategy.IMPORT_LAST_NAME)
}
}
@@ -524,5 +524,6 @@ object FirErrors {
val PACKAGE_CANNOT_BE_IMPORTED by error0<KtSimpleNameExpression>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
val CANNOT_BE_IMPORTED by error1<KtSimpleNameExpression, Name>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
val CONFLICTING_IMPORT by error1<KtImportDirective, Name>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
val OPERATOR_RENAMED_ON_IMPORT by error0<KtSimpleNameExpression>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.expressions.OperatorConventions
object FirImportsChecker : FirFileChecker() {
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -25,6 +26,9 @@ object FirImportsChecker : FirFileChecker() {
}
if (!import.isAllUnder) {
checkCanBeImported(import, context, reporter)
if (import is FirResolvedImport) {
checkOperatorRename(import, context, reporter)
}
}
}
checkConflictingImports(declaration.imports, context, reporter)
@@ -88,6 +92,24 @@ object FirImportsChecker : FirFileChecker() {
}
}
private fun checkOperatorRename(import: FirResolvedImport, context: CheckerContext, reporter: DiagnosticReporter) {
val alias = import.aliasName ?: return
val importedName = import.importedName ?: return
if (!OperatorConventions.isConventionName(alias)) return
val classId = import.resolvedClassId
val illegalRename = if (classId != null) {
val classFir = classId.resolveToClass(context) ?: return
classFir.classKind.isSingleton && classFir.declarations.any { it is FirSimpleFunction && it.isOperator}
} else {
context.session.symbolProvider.getTopLevelFunctionSymbols(import.packageFqName, importedName).any {
it.fir.isOperator
}
}
if (illegalRename) {
reporter.reportOn(import.source, FirErrors.OPERATOR_RENAMED_ON_IMPORT, context)
}
}
private fun FirResolvedImport.resolvesToClass(context: CheckerContext): Boolean {
if (resolvedClassId != null) {
if (isAllUnder) return true
@@ -228,6 +228,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_SUPERTYP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_RENAMED_ON_IMPORT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER
@@ -1180,6 +1181,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
"Conflicting import, imported name ''{0}'' is ambiguous",
TO_STRING
)
map.put(OPERATOR_RENAMED_ON_IMPORT, "Operator renamed to a different operator on import")
// Extended checkers group
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
@@ -1,16 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: a.kt
package a
interface A
operator fun A.plus(other: A): A = this
// FILE: b.kt
package b
import a.A
import a.plus as minus
fun test(a1: A, a2: A) =
a1 - a2
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: a.kt
package a
@@ -2601,6 +2601,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.OPERATOR_RENAMED_ON_IMPORT) { firDiagnostic ->
OperatorRenamedOnImportImpl(
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
ConflictingJvmDeclarationsImpl(
firDiagnostic as FirPsiDiagnostic<*>,
@@ -1825,6 +1825,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val name: Name
}
abstract class OperatorRenamedOnImport : KtFirDiagnostic<KtSimpleNameExpression>() {
override val diagnosticClass get() = OperatorRenamedOnImport::class
}
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = ConflictingJvmDeclarations::class
}
@@ -2960,6 +2960,13 @@ internal class ConflictingImportImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class OperatorRenamedOnImportImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.OperatorRenamedOnImport(), KtAbstractFirDiagnostic<KtSimpleNameExpression> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ConflictingJvmDeclarationsImpl(
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,