diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index d6e3adbece9..40b33d6c369 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -945,6 +945,12 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON by error(PositioningStrategy.IMPORT_LAST_NAME) { parameter("objectName") } + + val PACKAGE_CANNOT_BE_IMPORTED by error(PositioningStrategy.IMPORT_LAST_NAME) + + val CANNOT_BE_IMPORTED by error(PositioningStrategy.IMPORT_LAST_NAME) { + parameter("name") + } } } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 6d7f82093c9..46b261b49de 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -520,5 +520,7 @@ object FirErrors { // Imports val CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON by error1(SourceElementPositioningStrategies.IMPORT_LAST_NAME) + val PACKAGE_CANNOT_BE_IMPORTED by error0(SourceElementPositioningStrategies.IMPORT_LAST_NAME) + val CANNOT_BE_IMPORTED by error1(SourceElementPositioningStrategies.IMPORT_LAST_NAME) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImportsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImportsChecker.kt index df0a603d4e9..0272a9f907b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImportsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImportsChecker.kt @@ -16,9 +16,13 @@ import org.jetbrains.kotlin.name.ClassId object FirImportsChecker : FirFileChecker() { override fun check(declaration: FirFile, context: CheckerContext, reporter: DiagnosticReporter) { declaration.imports.forEach { import -> - if (import.isAllUnder && import !is FirResolvedImport && import !is FirErrorImport) { + if (import is FirErrorImport) return@forEach + if (import.isAllUnder && import !is FirResolvedImport) { checkAllUnderFromEnumEntry(import, context, reporter) } + if (!import.isAllUnder) { + checkCanBeImported(import, context, reporter) + } } } @@ -32,4 +36,33 @@ object FirImportsChecker : FirFileChecker() { reporter.reportOn(import.source, FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON, classFir.name, context) } } + + private fun checkCanBeImported(import: FirImport, context: CheckerContext, reporter: DiagnosticReporter) { + val importedFqName = import.importedFqName ?: return + val importedName = importedFqName.shortName() + //empty name come from LT in some erroneous cases + if (importedName.isSpecial || importedName.identifier.isEmpty()) return + val classId = (import as? FirResolvedImport)?.resolvedClassId + if (classId != null) { + val classSymbol = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) ?: return + val classFir = classSymbol.fir as? FirRegularClass ?: return + if (classFir.classKind.isSingleton) return + + val illegalImport = classFir.declarations.any { + it is FirSimpleFunction && !it.isStatic && it.name == importedName || + it is FirProperty && it.name == importedName + } + if (illegalImport) { + reporter.reportOn(import.source, FirErrors.CANNOT_BE_IMPORTED, importedName, context) + } + } else { + val importedClassId = ClassId.topLevel(importedFqName) + if (context.session.symbolProvider.getClassLikeSymbolByFqName(importedClassId) != null) { + return + } + context.session.symbolProvider.getPackage(importedFqName)?.let { + reporter.reportOn(import.source, FirErrors.PACKAGE_CANNOT_BE_IMPORTED, context) + } + } + } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 5a29b2127cd..15e46e1a61a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -54,6 +54,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_LHS_NOT_A_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_BE_IMPORTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_INFER_PARAMETER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE @@ -229,6 +230,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ONLY_ONE_CLASS_BO 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 +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE_IMPORTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIVATE_CLASS_MEMBER_FROM_INLINE @@ -1166,6 +1168,12 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { "Cannot import-on-demand from object ''{0}''", TO_STRING ) + map.put(PACKAGE_CANNOT_BE_IMPORTED, "Packages cannot be imported") + map.put( + CANNOT_BE_IMPORTED, + "Cannot import ''{0}'', functions and properties can be imported only from packages or objects", + TO_STRING + ) // Extended checkers group map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier") diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt index 11f5a3f6231..27f2aa1b234 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers -import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirFile @@ -14,8 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.builder.buildErrorImport import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport -import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.lookupTracker import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeImportFromSingleton diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.fir.kt b/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.fir.kt index 2507357e92f..62c31a650bc 100644 --- a/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.fir.kt +++ b/compiler/testData/diagnostics/tests/imports/ExplicitPackageImportsAmbiguity.fir.kt @@ -11,7 +11,7 @@ class X // FILE: c.kt package c -import a.x -import b.x +import a.x +import b.x class Y : x.X \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/SyntaxError.fir.kt b/compiler/testData/diagnostics/tests/imports/SyntaxError.fir.kt index 1dd3c4ec94c..2175157f64d 100644 --- a/compiler/testData/diagnostics/tests/imports/SyntaxError.fir.kt +++ b/compiler/testData/diagnostics/tests/imports/SyntaxError.fir.kt @@ -57,4 +57,4 @@ import a.%.b.c. import a.b.c.D. import a.b.c.D.E. -import a?.b \ No newline at end of file +import a?.b diff --git a/compiler/testData/diagnostics/tests/imports/WrongImport.fir.kt b/compiler/testData/diagnostics/tests/imports/WrongImport.fir.kt index a27c1812348..18e22675bfb 100644 --- a/compiler/testData/diagnostics/tests/imports/WrongImport.fir.kt +++ b/compiler/testData/diagnostics/tests/imports/WrongImport.fir.kt @@ -48,17 +48,17 @@ class D { // FILE:c.kt -import a -import a.b +import a +import a.b import a.foo import a.foo.bar import a.bar import a.bar.foo -import a.B.foo +import a.B.foo import a.B.foo.bar -import a.B.bar +import a.B.bar import a.B.bar.foo import a.C.foo diff --git a/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt b/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt index 3b9adbb86ca..996ee5f8bb4 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt @@ -8,7 +8,7 @@ import reflect.Constructor import b.* import d import d.Test -import b.d +import b.d class Some: Test() diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 7088cd20849..594293b8aaa 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -2580,6 +2580,19 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.PACKAGE_CANNOT_BE_IMPORTED) { firDiagnostic -> + PackageCannotBeImportedImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.CANNOT_BE_IMPORTED) { firDiagnostic -> + CannotBeImportedImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic -> ConflictingJvmDeclarationsImpl( firDiagnostic as FirPsiDiagnostic<*>, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index b11eabea4ef..a335490f5ff 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -1810,6 +1810,15 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val objectName: Name } + abstract class PackageCannotBeImported : KtFirDiagnostic() { + override val diagnosticClass get() = PackageCannotBeImported::class + } + + abstract class CannotBeImported : KtFirDiagnostic() { + override val diagnosticClass get() = CannotBeImported::class + abstract val name: Name + } + abstract class ConflictingJvmDeclarations : KtFirDiagnostic() { override val diagnosticClass get() = ConflictingJvmDeclarations::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 925d8eb93cc..fa01fe1bedf 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -2936,6 +2936,21 @@ internal class CannotAllUnderImportFromSingletonImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class PackageCannotBeImportedImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.PackageCannotBeImported(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class CannotBeImportedImpl( + override val name: Name, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.CannotBeImported(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class ConflictingJvmDeclarationsImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken,