[KT-58817] Implicit import issues cannot be reported
To be reported with [1] imports require source. It was missing for implicit script imports. `FirScriptConfiguratorExtensionImpl` was extended and now adds fake source elements (users don't see imports in the source code). Since diagnostics for implicit import statements are meaningless for IDE, they are suppressed in `LLFirDiagnosticReporter`. ---------------------------------------------------------------------- [1]: DiagnosticReporter.reportOn()
This commit is contained in:
committed by
Space Team
parent
28ff94533a
commit
2a1d4a42ae
+10
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.AbstractKtSourceElement
|
import org.jetbrains.kotlin.AbstractKtSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtFakeSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
|
||||||
import org.jetbrains.kotlin.diagnostics.*
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
|
|
||||||
@@ -18,6 +20,10 @@ internal class LLFirDiagnosticReporter : DiagnosticReporter() {
|
|||||||
if (diagnostic == null) return
|
if (diagnostic == null) return
|
||||||
if (context.isDiagnosticSuppressed(diagnostic)) return
|
if (context.isDiagnosticSuppressed(diagnostic)) return
|
||||||
|
|
||||||
|
// Implicit imports for scripts are currently implemented via FIR-tree mutation (they do not exist in default importing scopes).
|
||||||
|
// So as a temporary solution we filter out related diagnostics here.
|
||||||
|
if (diagnostic.isAboutImplicitImport()) return
|
||||||
|
|
||||||
val psiDiagnostic = when (diagnostic) {
|
val psiDiagnostic = when (diagnostic) {
|
||||||
is KtPsiDiagnostic -> diagnostic
|
is KtPsiDiagnostic -> diagnostic
|
||||||
is KtLightDiagnostic -> diagnostic.toPsiDiagnostic()
|
is KtLightDiagnostic -> diagnostic.toPsiDiagnostic()
|
||||||
@@ -51,6 +57,10 @@ internal class LLFirDiagnosticReporter : DiagnosticReporter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtDiagnostic.isAboutImplicitImport() =
|
||||||
|
(element is KtFakeSourceElement && (element as KtFakeSourceElement).kind == KtFakeSourceElementKind.ImplicitImport)
|
||||||
|
|
||||||
|
|
||||||
private fun KtLightDiagnostic.toPsiDiagnostic(): KtPsiDiagnostic {
|
private fun KtLightDiagnostic.toPsiDiagnostic(): KtPsiDiagnostic {
|
||||||
val psiSourceElement = element.unwrapToKtPsiSourceElement()
|
val psiSourceElement = element.unwrapToKtPsiSourceElement()
|
||||||
?: error("Diagnostic should be created from PSI in IDE")
|
?: error("Diagnostic should be created from PSI in IDE")
|
||||||
|
|||||||
+1
-2
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
|||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationChecker
|
||||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.getSourceForImportSegment
|
import org.jetbrains.kotlin.fir.analysis.getSourceForImportSegment
|
||||||
@@ -128,7 +127,7 @@ object FirImportsChecker : FirFileChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resolvedDeclaration?.let {
|
resolvedDeclaration?.let {
|
||||||
val source = import.getSourceForImportSegment(0)
|
val source = import.getSourceForImportSegment(0) ?: import.source
|
||||||
reporter.reportOn(source, FirErrors.INVISIBLE_REFERENCE, it.symbol, context)
|
reporter.reportOn(source, FirErrors.INVISIBLE_REFERENCE, it.symbol, context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -272,6 +272,9 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor
|
|||||||
|
|
||||||
// When property doesn't have an initializer and explicit return type, but its getter's return type is specified
|
// When property doesn't have an initializer and explicit return type, but its getter's return type is specified
|
||||||
object PropertyTypeFromGetterReturnType : KtFakeSourceElementKind()
|
object PropertyTypeFromGetterReturnType : KtFakeSourceElementKind()
|
||||||
|
|
||||||
|
// Scripts get implicit imports from their configurations
|
||||||
|
object ImplicitImport : KtFakeSourceElementKind()
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class AbstractKtSourceElement {
|
sealed class AbstractKtSourceElement {
|
||||||
|
|||||||
+8
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.scripting.compiler.plugin.services
|
package org.jetbrains.kotlin.scripting.compiler.plugin.services
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.*
|
import org.jetbrains.kotlin.*
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.scripting.definitions.annotationsForSamWithReceivers
|
import org.jetbrains.kotlin.scripting.definitions.annotationsForSamWithReceivers
|
||||||
import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource
|
import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource
|
||||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||||
@@ -61,6 +63,10 @@ class FirScriptConfiguratorExtensionImpl(
|
|||||||
val stripped = if (endsWithStar) trimmed.substring(0, trimmed.length - 2) else trimmed
|
val stripped = if (endsWithStar) trimmed.substring(0, trimmed.length - 2) else trimmed
|
||||||
val fqName = FqName.fromSegments(stripped.split("."))
|
val fqName = FqName.fromSegments(stripped.split("."))
|
||||||
fileBuilder.imports += buildImport {
|
fileBuilder.imports += buildImport {
|
||||||
|
fileBuilder.sourceFile?.project()?.let {
|
||||||
|
val dummyElement = KtPsiFactory(it, markGenerated = true).createColon()
|
||||||
|
source = KtFakeSourceElement(dummyElement, KtFakeSourceElementKind.ImplicitImport)
|
||||||
|
}
|
||||||
importedFqName = fqName
|
importedFqName = fqName
|
||||||
isAllUnder = endsWithStar
|
isAllUnder = endsWithStar
|
||||||
}
|
}
|
||||||
@@ -148,6 +154,8 @@ class FirScriptConfiguratorExtensionImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtSourceFile.project(): Project? = (toSourceCode() as? KtFileScriptSource)?.ktFile?.project
|
||||||
|
|
||||||
fun KtSourceFile.toSourceCode(): SourceCode? = when (this) {
|
fun KtSourceFile.toSourceCode(): SourceCode? = when (this) {
|
||||||
is KtPsiSourceFile -> (psiFile as? KtFile)?.let(::KtFileScriptSource) ?: VirtualFileScriptSource(psiFile.virtualFile)
|
is KtPsiSourceFile -> (psiFile as? KtFile)?.let(::KtFileScriptSource) ?: VirtualFileScriptSource(psiFile.virtualFile)
|
||||||
is KtVirtualFileSourceFile -> VirtualFileScriptSource(virtualFile)
|
is KtVirtualFileSourceFile -> VirtualFileScriptSource(virtualFile)
|
||||||
|
|||||||
Reference in New Issue
Block a user