[FIR] Try to make diagnostics that are independent of file work in tests WIP
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LowLevelFirAnalyzerFacade.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LowLevelFirAnalyzerFacade.kt
index 8ced4cb..ad6b8df 100644
--- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LowLevelFirAnalyzerFacade.kt
+++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/LowLevelFirAnalyzerFacade.kt
@@ -62,7 +62,7 @@
class AnalysisApiFirDiagnosticCollectorService(testServices: TestServices) : FirDiagnosticCollectorService(testServices) {
override fun getFrontendDiagnosticsForModule(info: FirOutputArtifact): DiagnosticsMap {
- val result = listMultimapOf<FirFile, DiagnosticWithKmpCompilationMode>()
+ val result = listMultimapOf<FirFile?, DiagnosticWithKmpCompilationMode>()
for (part in info.partsForDependsOnModules) {
val facade = part.firAnalyzerFacade
require(facade is LowLevelFirAnalyzerFacade)
diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt
index 52ddecc..c9b8951 100644
--- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt
+++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/analyse.kt
@@ -30,7 +30,7 @@
firFiles: Collection<FirFile>,
reporter: BaseDiagnosticsCollector,
mppCheckerKind: MppCheckerKind
-): Map<FirFile, List<KtDiagnostic>> {
+): Map<FirFile?, List<KtDiagnostic>> {
val collector = DiagnosticComponentsFactory.create(this, scopeSession, mppCheckerKind)
for (file in firFiles) {
withFileAnalysisExceptionWrapping(file) {
@@ -41,7 +41,7 @@
return firFiles.associateWith {
val path = it.sourceFile?.path ?: return@associateWith emptyList()
reporter.diagnosticsByFilePath[path] ?: emptyList()
- }
+ } + (null to reporter.diagnosticsByFilePath[null].orEmpty())
}
fun FirSession.collectLostDiagnosticsOnFile(
diff --git a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategy.kt b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategy.kt
index a492750..b359067 100644
--- a/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategy.kt
+++ b/compiler/frontend.common-psi/src/org/jetbrains/kotlin/diagnostics/SourceElementPositioningStrategy.kt
@@ -10,6 +10,7 @@
import org.jetbrains.kotlin.AbstractKtSourceElement
import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement
+import org.jetbrains.kotlin.NoSourceElement
@OptIn(DiagnosticLossRisk::class)
class SourceElementPositioningStrategy(
@@ -21,6 +22,7 @@
return when (val element = diagnostic.element) {
is KtPsiSourceElement -> psiStrategy.markDiagnostic(diagnostic)
is KtLightSourceElement -> lightTreeStrategy.markKtDiagnostic(element, diagnostic)
+ is NoSourceElement -> emptyList()
else -> offsetsOnlyPositioningStrategy.markKtDiagnostic(element, diagnostic)
}
}
diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt
index d0336b5..415c5af 100644
--- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt
+++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/backend/handlers/NoFirCompilationErrorsHandler.kt
@@ -48,11 +48,15 @@
if (diagnostic.severity == Severity.ERROR) {
if (!ignoreErrors) {
val diagnosticText = RootDiagnosticRendererFactory(diagnostic).render(diagnostic)
- val range = diagnostic.textRanges.first()
- val locationText = firFile.source?.psi?.containingFile?.let { psiFile ->
- PsiDiagnosticUtils.atLocation(psiFile, range)
- } ?: "${firFile.name}:$range"
- error("${diagnostic.factory.name}: $diagnosticText at $locationText")
+ if (firFile != null) {
+ val range = diagnostic.textRanges.first()
+ val locationText = firFile.source?.psi?.containingFile?.let { psiFile ->
+ PsiDiagnosticUtils.atLocation(psiFile, range)
+ } ?: "${firFile.name}:$range"
+ error("${diagnostic.factory.name}: $diagnosticText at $locationText")
+ } else {
+ error(diagnostic.factory.name)
+ }
}
}
}
diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDiagnosticsHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDiagnosticsHandler.kt
index 7f227a7..4b77f06 100644
--- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDiagnosticsHandler.kt
+++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDiagnosticsHandler.kt
@@ -586,7 +586,7 @@
metaInfo
}
-typealias DiagnosticsMap = Multimap<FirFile, DiagnosticWithKmpCompilationMode, List<DiagnosticWithKmpCompilationMode>>
+typealias DiagnosticsMap = Multimap<FirFile?, DiagnosticWithKmpCompilationMode, List<DiagnosticWithKmpCompilationMode>>
data class DiagnosticWithKmpCompilationMode(val diagnostic: KtDiagnostic, val kmpCompilationMode: KmpCompilationMode)
@@ -629,11 +629,11 @@
return getFrontendDiagnosticsForModule(info).values.any { it.diagnostic.severity == Severity.ERROR }
}
- private fun computeDiagnostics(info: FirOutputArtifact): ListMultimap<FirFile, DiagnosticWithKmpCompilationMode> {
+ private fun computeDiagnostics(info: FirOutputArtifact): ListMultimap<FirFile?, DiagnosticWithKmpCompilationMode> {
val allFiles = info.partsForDependsOnModules.flatMap { it.firFiles.values }
val platformPart = info.partsForDependsOnModules.last()
val lazyDeclarationResolver = platformPart.session.lazyDeclarationResolver
- val result = listMultimapOf<FirFile, DiagnosticWithKmpCompilationMode>()
+ val result = listMultimapOf<FirFile?, DiagnosticWithKmpCompilationMode>()
lazyDeclarationResolver.disableLazyResolveContractChecksInside {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(platformPart.module)
@@ -644,8 +644,7 @@
val diagnosticsCollector = info.cliArtifact.diagnosticCollector
val diagnosticsPerFirFile = buildMap {
for ((filePath, diagnostics) in diagnosticsCollector.diagnosticsByFilePath) {
- if (filePath == null) continue
- val firFile = allFiles.first { it.sourceFile?.path == filePath }
+ val firFile = filePath?.let { allFiles.first { it.sourceFile?.path == filePath } }
put(firFile, diagnostics)
}
}
@@ -705,9 +704,9 @@
return result
}
- private fun Map<FirFile, List<KtDiagnostic>>.convertToTestDiagnostics(
+ private fun Map<FirFile?, List<KtDiagnostic>>.convertToTestDiagnostics(
mode: KmpCompilationMode
- ): Map<FirFile, List<DiagnosticWithKmpCompilationMode>> {
+ ): Map<FirFile?, List<DiagnosticWithKmpCompilationMode>> {
return mapValues { entry -> entry.value.mapNotNull {
runIf(it.isValid) {
DiagnosticWithKmpCompilationMode(it, mode)
@@ -718,7 +717,7 @@
protected fun collectSyntaxDiagnostics(
part: FirOutputPartForDependsOnModule,
- destination: ListMultimap<FirFile, DiagnosticWithKmpCompilationMode>,
+ destination: ListMultimap<FirFile?, DiagnosticWithKmpCompilationMode>,
) {
for ((testFile, firFile) in part.firFiles) {
val syntaxErrors = if (firFile.psi != null) {