[FIR] Implement OPERATOR_RENAMED_ON_IMPORT diagnostic
This commit is contained in:
+2
@@ -955,6 +955,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val CONFLICTING_IMPORT by error<KtImportDirective>(PositioningStrategy.IMPORT_LAST_NAME) {
|
val CONFLICTING_IMPORT by error<KtImportDirective>(PositioningStrategy.IMPORT_LAST_NAME) {
|
||||||
parameter<Name>("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 PACKAGE_CANNOT_BE_IMPORTED by error0<KtSimpleNameExpression>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
|
||||||
val CANNOT_BE_IMPORTED by error1<KtSimpleNameExpression, Name>(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 CONFLICTING_IMPORT by error1<KtImportDirective, Name>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
|
||||||
|
val OPERATOR_RENAMED_ON_IMPORT by error0<KtSimpleNameExpression>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -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.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
object FirImportsChecker : FirFileChecker() {
|
object FirImportsChecker : FirFileChecker() {
|
||||||
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -25,6 +26,9 @@ object FirImportsChecker : FirFileChecker() {
|
|||||||
}
|
}
|
||||||
if (!import.isAllUnder) {
|
if (!import.isAllUnder) {
|
||||||
checkCanBeImported(import, context, reporter)
|
checkCanBeImported(import, context, reporter)
|
||||||
|
if (import is FirResolvedImport) {
|
||||||
|
checkOperatorRename(import, context, reporter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkConflictingImports(declaration.imports, 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 {
|
private fun FirResolvedImport.resolvesToClass(context: CheckerContext): Boolean {
|
||||||
if (resolvedClassId != null) {
|
if (resolvedClassId != null) {
|
||||||
if (isAllUnder) return true
|
if (isAllUnder) return true
|
||||||
|
|||||||
+2
@@ -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_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.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.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.OTHER_ERROR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER
|
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",
|
"Conflicting import, imported name ''{0}'' is ambiguous",
|
||||||
TO_STRING
|
TO_STRING
|
||||||
)
|
)
|
||||||
|
map.put(OPERATOR_RENAMED_ON_IMPORT, "Operator renamed to a different operator on import")
|
||||||
|
|
||||||
// Extended checkers group
|
// Extended checkers group
|
||||||
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
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
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
// FILE: a.kt
|
// FILE: a.kt
|
||||||
package a
|
package a
|
||||||
|
|||||||
+6
@@ -2601,6 +2601,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.OPERATOR_RENAMED_ON_IMPORT) { firDiagnostic ->
|
||||||
|
OperatorRenamedOnImportImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
|
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
|
||||||
ConflictingJvmDeclarationsImpl(
|
ConflictingJvmDeclarationsImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic<*>,
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
|||||||
+4
@@ -1825,6 +1825,10 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val name: Name
|
abstract val name: Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class OperatorRenamedOnImport : KtFirDiagnostic<KtSimpleNameExpression>() {
|
||||||
|
override val diagnosticClass get() = OperatorRenamedOnImport::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
|
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = ConflictingJvmDeclarations::class
|
override val diagnosticClass get() = ConflictingJvmDeclarations::class
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -2960,6 +2960,13 @@ internal class ConflictingImportImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
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(
|
internal class ConflictingJvmDeclarationsImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user