AA: introduce KtNotUnderContentRootModule impl to standalone mode

to gracefully handle element/file/etc without a binding module.

This could happen, e.g.,
1) source PSI created from KtPsiFactory, which uses literally dummy.kt
2) debugger that creates a code fragment on-the-fly
3) on-air analysis of non-physical files
diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/RegisterComponentService.java b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/RegisterComponentService.java
index cd808b5..4e9d431 100644
--- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/RegisterComponentService.java
+++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/RegisterComponentService.java
@@ -8,6 +8,7 @@
 import com.intellij.mock.MockProject;
 import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionService;
 import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySessionFactory;
+import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirNonUnderContentRootSessionFactory;
 
 class RegisterComponentService {
     static void registerLLFirLibrarySessionFactory(MockProject project) {
@@ -17,6 +18,13 @@
         );
     }
 
+    static void registerLLFirNonUnderContentRootSessionFactory(MockProject project) {
+        project.registerService(
+                LLFirNonUnderContentRootSessionFactory.class,
+                new LLFirNonUnderContentRootSessionFactory(project)
+        );
+    }
+
     static void registerLLFirResolveSessionService(MockProject project) {
         project.registerService(
                 LLFirResolveSessionService.class,
diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt
index 9a8aacf..3ab435be 100644
--- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt
+++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt
@@ -144,6 +144,7 @@
             )
             registerService(LLFirBuiltinsSessionFactory::class.java, LLFirBuiltinsSessionFactory(this))
             RegisterComponentService.registerLLFirLibrarySessionFactory(this)
+            RegisterComponentService.registerLLFirNonUnderContentRootSessionFactory(this)
             RegisterComponentService.registerLLFirResolveSessionService(this)
             registerService(
                 PackagePartProviderFactory::class.java,
diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderImpl.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderImpl.kt
index d0c8146..33ecee8 100644
--- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderImpl.kt
+++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderImpl.kt
@@ -6,23 +6,38 @@
 package org.jetbrains.kotlin.analysis.project.structure.impl
 
 import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiFile
 import com.intellij.psi.PsiFileSystemItem
 import com.intellij.psi.PsiJavaFile
+import com.intellij.util.containers.ContainerUtil
 import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory.findJvmRootsForJavaFiles
 import org.jetbrains.kotlin.analysis.project.structure.*
-import org.jetbrains.kotlin.platform.TargetPlatform
 
 internal class KtModuleProviderImpl(
     internal val mainModules: List<KtModule>,
 ) : ProjectStructureProvider() {
+    private val ktNotUnderContentRootModuleWithoutPsiFile by lazy {
+        KtNotUnderContentRootModuleImpl(
+            moduleDescription = "Standalone-not-under-content-root-module-without-psi-file"
+        )
+    }
+
+    private val notUnderContentRootModuleCache = ContainerUtil.createConcurrentWeakMap<PsiFile, KtNotUnderContentRootModule>()
+
     override fun getKtModuleForKtElement(element: PsiElement): KtModule {
         val containingFileAsPsiFile = element.containingFile
-            ?: error("Can't get containing PsiFile for ${element.text}")
+            ?: return ktNotUnderContentRootModuleWithoutPsiFile
         // If an [element] is created on the fly, e.g., via [KtPsiFactory],
         // its containing [PsiFile] may not have [VirtualFile].
         // That also means the [element] is not bound to any [KtModule] either.
         val containingFileAsVirtualFile = containingFileAsPsiFile.virtualFile
-            ?: error("Can't get containing VirtualFile for ${element.text} in $containingFileAsPsiFile")
+            ?: return notUnderContentRootModuleCache.getOrPut(containingFileAsPsiFile) {
+                KtNotUnderContentRootModuleImpl(
+                    moduleDescription = "Standalone-not-under-content-root-module-for-$containingFileAsPsiFile",
+                    psiFile = containingFileAsPsiFile
+                )
+            }
+
         return mainModules.first { module ->
             containingFileAsVirtualFile in module.contentScope
         }
diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt
index ceb7084..59cc87b 100644
--- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt
+++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt
@@ -28,12 +28,11 @@
 import org.jetbrains.kotlin.config.CommonConfigurationKeys
 import org.jetbrains.kotlin.config.CompilerConfiguration
 import org.jetbrains.kotlin.config.JVMConfigurationKeys
-import org.jetbrains.kotlin.config.JvmTarget
 import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
 import org.jetbrains.kotlin.platform.TargetPlatform
 import org.jetbrains.kotlin.platform.isCommon
 import org.jetbrains.kotlin.platform.js.isJs
-import org.jetbrains.kotlin.platform.jvm.JdkPlatform
+import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
 import org.jetbrains.kotlin.platform.jvm.isJvm
 import org.jetbrains.kotlin.platform.konan.isNative
 import org.jetbrains.kotlin.psi.KtFile
@@ -102,7 +101,7 @@
 ): ProjectStructureProvider = buildProjectStructureProvider {
     addModule(
         buildKtSourceModule {
-            val platform = TargetPlatform(setOf(JdkPlatform(JvmTarget.DEFAULT)))
+            val platform = JvmPlatforms.defaultJvmPlatform
             val moduleName = compilerConfig.get(CommonConfigurationKeys.MODULE_NAME) ?: "<no module name provided>"
 
             val libraryRoots = compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots
diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtNotUnderContentRootModuleImpl.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtNotUnderContentRootModuleImpl.kt
new file mode 100644
index 0000000..ea808a4
--- /dev/null
+++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtNotUnderContentRootModuleImpl.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.analysis.project.structure.impl
+
+import com.intellij.psi.PsiFile
+import com.intellij.psi.search.GlobalSearchScope
+import org.jetbrains.kotlin.analysis.project.structure.KtModule
+import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
+import org.jetbrains.kotlin.platform.TargetPlatform
+import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
+import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
+
+internal class KtNotUnderContentRootModuleImpl(
+    override val directRegularDependencies: List<KtModule> = emptyList(),
+    override val directRefinementDependencies: List<KtModule> = emptyList(),
+    override val directFriendDependencies: List<KtModule> = emptyList(),
+    override val platform: TargetPlatform = JvmPlatforms.defaultJvmPlatform,
+    psiFile: PsiFile? = null,
+    override val moduleDescription: String,
+) : KtNotUnderContentRootModule, KtModuleWithPlatform {
+    override val analyzerServices: PlatformDependentAnalyzerServices = super.analyzerServices
+
+    override val contentScope: GlobalSearchScope =
+        if (psiFile != null) GlobalSearchScope.fileScope(psiFile) else GlobalSearchScope.EMPTY_SCOPE
+}
\ No newline at end of file