[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) {