[FIR] Fix missing INVISIBLE_REFERENCE on imports

^KT-59927 Fixed
This commit is contained in:
Nikolay Lunyak
2023-10-05 11:37:47 +03:00
committed by Space Team
parent 21cb5cf83a
commit e452113a7a
3 changed files with 23 additions and 4 deletions
@@ -10,6 +10,7 @@ import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.name.FqName
fun KtSourceElement.getChild(type: IElementType, index: Int = 0, depth: Int = -1, reverse: Boolean = false): KtSourceElement? {
return getChild(setOf(type), index, depth, reverse)
@@ -69,3 +70,10 @@ fun FirImport.getSourceForImportSegment(indexFromLast: Int): KtSourceElement? {
return segmentSource.takeIf { it.elementType == KtNodeTypes.REFERENCE_EXPRESSION }
?: segmentSource.getChild(KtNodeTypes.REFERENCE_EXPRESSION, depth = 1, reverse = true)
}
/**
* Looks for the source element of the last segment
* of `importedFqName`.
*/
fun FirImport.getLastImportedFqNameSegmentSource(): KtSourceElement? =
source?.getChild(KtNodeTypes.REFERENCE_EXPRESSION, reverse = true)
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationCheck
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.toInvisibleReferenceDiagnostic
import org.jetbrains.kotlin.fir.analysis.getLastImportedFqNameSegmentSource
import org.jetbrains.kotlin.fir.analysis.getSourceForImportSegment
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
@@ -26,6 +27,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.getContainingFile
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.PackageResolutionResult
import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
@@ -71,11 +74,19 @@ object FirImportsChecker : FirFileChecker() {
private fun checkAllUnderFromObject(import: FirImport, context: CheckerContext, reporter: DiagnosticReporter) {
val fqName = import.importedFqName ?: return
if (fqName.isRoot) return
val classId = ClassId.topLevel(fqName)
val classSymbol = classId.resolveToClass(context) ?: return
if (classSymbol.classKind.isObject) {
val classLike = when (val resolutionResult = resolveToPackageOrClass(context.session.symbolProvider, fqName)) {
is PackageResolutionResult.PackageOrClass -> resolutionResult.classSymbol ?: return
// Already an error import, already reported
is PackageResolutionResult.Error -> return
}
val classSymbol = classLike.fullyExpandedClass(context.session)
if (classSymbol != null && classSymbol.classKind.isObject) {
reporter.reportOn(import.source, FirErrors.CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON, classSymbol.classId.shortClassName, context)
}
if (!classLike.fir.isVisible(context)) {
val source = import.getLastImportedFqNameSegmentSource() ?: error("`${import.source}` does not contain `$fqName`")
reporter.report(classLike.toInvisibleReferenceDiagnostic(source), context)
}
}
private fun checkCanBeImported(import: FirImport, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -17,7 +17,7 @@ public class B {
// FILE: C.kt
import A.Nested.*
import A.<!INVISIBLE_REFERENCE!>Nested<!>.*
import B.<!INVISIBLE_REFERENCE!>JC<!>.JC1
fun test() {