Support different target platforms for modules in AnalyzerFacade
Instead of reusing the same AnalyzerFacade that is used for resolution of a module to resolve its dependencies, analyze each dependency module/library with a facade depending on its target platform. Introduce and use CommonLibraryDetectionUtil in addition to KotlinJavaScriptLibraryDetectionUtil, to detect common libraries (with .kotlin_metadata files). Note that before multi-platform projects, this was not needed because there were only two platforms (JVM and JS), and JVM module had only JVM modules/libraries as dependencies, JS module had only JS modules/libraries as dependencies. Now, for example, a JVM module can have a common module/library as a dependency, and it would be incorrect to analyze that dependency with JvmAnalyzerFacade because that facade does not know anything about .kotlin_metadata files. The changes in Dsl.kt and KotlinCacheServiceImpl.kt are needed because PsiElement.getJavaDescriptorResolver, called from some IDE code, started to fail on a common module, because the container for a common module does not have the JavaDescriptorResolver
This commit is contained in:
@@ -34,9 +34,12 @@ inline fun <reified T : Any> ComponentProvider.get(): T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun <T : Any> ComponentProvider.tryGetService(request: Class<T>): T? {
|
||||||
|
return resolve(request)?.getValue() as T?
|
||||||
|
}
|
||||||
|
|
||||||
fun <T : Any> ComponentProvider.getService(request: Class<T>): T {
|
fun <T : Any> ComponentProvider.getService(request: Class<T>): T {
|
||||||
val valueDescriptor = resolve(request) ?: throw IllegalArgumentException("Unresolved service: $request")
|
return tryGetService(request) ?: throw IllegalArgumentException("Unresolved service: $request")
|
||||||
return valueDescriptor.getValue() as T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun StorageComponentContainer.useInstance(instance: Any) {
|
fun StorageComponentContainer.useInstance(instance: Any) {
|
||||||
|
|||||||
@@ -157,66 +157,71 @@ interface ModuleInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||||
fun <M : ModuleInfo> setupResolverForProject(
|
companion object {
|
||||||
debugName: String,
|
fun <P : PlatformAnalysisParameters, M : ModuleInfo> setupResolverForProject(
|
||||||
projectContext: ProjectContext,
|
debugName: String,
|
||||||
modules: Collection<M>,
|
projectContext: ProjectContext,
|
||||||
modulesContent: (M) -> ModuleContent,
|
modules: Collection<M>,
|
||||||
platformParameters: P,
|
analyzerFacade: (M) -> AnalyzerFacade<P>,
|
||||||
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
modulesContent: (M) -> ModuleContent,
|
||||||
builtIns: (M) -> KotlinBuiltIns = { DefaultBuiltIns.Instance },
|
platformParameters: P,
|
||||||
delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
||||||
packagePartProviderFactory: (M, ModuleContent) -> PackagePartProvider = { _, _ -> PackagePartProvider.Empty },
|
builtIns: (M) -> KotlinBuiltIns = { DefaultBuiltIns.Instance },
|
||||||
firstDependency: M? = null,
|
delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
||||||
modulePlatforms: (M) -> MultiTargetPlatform?
|
packagePartProviderFactory: (M, ModuleContent) -> PackagePartProvider = { _, _ -> PackagePartProvider.Empty },
|
||||||
): ResolverForProject<M> {
|
firstDependency: M? = null,
|
||||||
val storageManager = projectContext.storageManager
|
modulePlatforms: (M) -> MultiTargetPlatform?
|
||||||
|
): ResolverForProject<M> {
|
||||||
|
val storageManager = projectContext.storageManager
|
||||||
|
|
||||||
val resolverForProject = ResolverForProjectImpl(debugName, modules.keysToMap { module ->
|
val resolverForProject = ResolverForProjectImpl(debugName, modules.keysToMap { module ->
|
||||||
ModuleDescriptorImpl(module.name, storageManager, builtIns(module), modulePlatforms(module), module.capabilities)
|
ModuleDescriptorImpl(module.name, storageManager, builtIns(module), modulePlatforms(module), module.capabilities)
|
||||||
}, delegateResolver)
|
}, delegateResolver)
|
||||||
|
|
||||||
for (module in modules) {
|
for (module in modules) {
|
||||||
resolverForProject.descriptorForModule(module).setDependencies(LazyModuleDependencies(
|
resolverForProject.descriptorForModule(module).setDependencies(LazyModuleDependencies(
|
||||||
storageManager,
|
storageManager,
|
||||||
computeDependencies = {
|
computeDependencies = {
|
||||||
val orderedDependencies = listOfNotNull(firstDependency) + module.dependencies()
|
val orderedDependencies = listOfNotNull(firstDependency) + module.dependencies()
|
||||||
val dependenciesDescriptors = orderedDependencies.mapTo(ArrayList<ModuleDescriptorImpl>()) { dependencyInfo ->
|
val dependenciesDescriptors = orderedDependencies.mapTo(ArrayList<ModuleDescriptorImpl>()) { dependencyInfo ->
|
||||||
resolverForProject.descriptorForModule(dependencyInfo as M)
|
resolverForProject.descriptorForModule(dependencyInfo as M)
|
||||||
|
}
|
||||||
|
module.dependencyOnBuiltIns().adjustDependencies(
|
||||||
|
resolverForProject.descriptorForModule(module).builtIns.builtInsModule, dependenciesDescriptors)
|
||||||
|
dependenciesDescriptors
|
||||||
|
},
|
||||||
|
computeModulesWhoseInternalsAreVisible = {
|
||||||
|
module.modulesWhoseInternalsAreVisible().mapTo(LinkedHashSet()) {
|
||||||
|
resolverForProject.descriptorForModule(it as M)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computeImplementingModules = {
|
||||||
|
if (modulePlatforms(module) != MultiTargetPlatform.Common) emptySet()
|
||||||
|
else modules
|
||||||
|
.filter { modulePlatforms(it) != MultiTargetPlatform.Common && module in it.dependencies() }
|
||||||
|
.mapTo(mutableSetOf(), resolverForProject::descriptorForModule)
|
||||||
}
|
}
|
||||||
module.dependencyOnBuiltIns().adjustDependencies(
|
)
|
||||||
resolverForProject.descriptorForModule(module).builtIns.builtInsModule, dependenciesDescriptors)
|
|
||||||
dependenciesDescriptors
|
|
||||||
},
|
|
||||||
computeModulesWhoseInternalsAreVisible = {
|
|
||||||
module.modulesWhoseInternalsAreVisible().mapTo(LinkedHashSet()) { resolverForProject.descriptorForModule(it as M) }
|
|
||||||
},
|
|
||||||
computeImplementingModules = {
|
|
||||||
if (modulePlatforms(module) != MultiTargetPlatform.Common) emptySet()
|
|
||||||
else modules
|
|
||||||
.filter { modulePlatforms(it) != MultiTargetPlatform.Common && module in it.dependencies() }
|
|
||||||
.mapTo(mutableSetOf(), resolverForProject::descriptorForModule)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (module in modules) {
|
|
||||||
val descriptor = resolverForProject.descriptorForModule(module)
|
|
||||||
val computeResolverForModule = storageManager.createLazyValue {
|
|
||||||
val content = modulesContent(module)
|
|
||||||
createResolverForModule(
|
|
||||||
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
|
|
||||||
platformParameters, targetEnvironment, resolverForProject,
|
|
||||||
packagePartProviderFactory(module, content)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptor.initialize(DelegatingPackageFragmentProvider { computeResolverForModule().packageFragmentProvider })
|
for (module in modules) {
|
||||||
resolverForProject.resolverByModuleDescriptor[descriptor] = computeResolverForModule
|
val descriptor = resolverForProject.descriptorForModule(module)
|
||||||
}
|
val computeResolverForModule = storageManager.createLazyValue {
|
||||||
|
val content = modulesContent(module)
|
||||||
|
analyzerFacade(module).createResolverForModule(
|
||||||
|
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
|
||||||
|
platformParameters, targetEnvironment, resolverForProject,
|
||||||
|
packagePartProviderFactory(module, content)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return resolverForProject
|
descriptor.initialize(DelegatingPackageFragmentProvider { computeResolverForModule().packageFragmentProvider })
|
||||||
|
resolverForProject.resolverByModuleDescriptor[descriptor] = computeResolverForModule
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolverForProject
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun <M : ModuleInfo> createResolverForModule(
|
protected abstract fun <M : ModuleInfo> createResolverForModule(
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ object DefaultAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
|||||||
val project = files.firstOrNull()?.project ?: throw AssertionError("No files to analyze")
|
val project = files.firstOrNull()?.project ?: throw AssertionError("No files to analyze")
|
||||||
val resolver = setupResolverForProject(
|
val resolver = setupResolverForProject(
|
||||||
"sources for metadata serializer",
|
"sources for metadata serializer",
|
||||||
ProjectContext(project), listOf(moduleInfo),
|
ProjectContext(project), listOf(moduleInfo), { DefaultAnalyzerFacade },
|
||||||
{ ModuleContent(files, GlobalSearchScope.allScope(project)) },
|
{ ModuleContent(files, GlobalSearchScope.allScope(project)) },
|
||||||
object : PlatformAnalysisParameters {},
|
object : PlatformAnalysisParameters {},
|
||||||
packagePartProviderFactory = packagePartProviderFactory,
|
packagePartProviderFactory = packagePartProviderFactory,
|
||||||
|
|||||||
+5
@@ -61,6 +61,11 @@ public class ForTestCompileRuntime {
|
|||||||
return assertExists(new File("dist/kotlinc/lib/kotlin-runtime-sources.jar"));
|
return assertExists(new File("dist/kotlinc/lib/kotlin-runtime-sources.jar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static File stdlibCommonForTests() {
|
||||||
|
return assertExists(new File("dist/common/kotlin-stdlib-common.jar"));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Do not use these classes, remove them after stdlib tests are merged in the same build as the compiler
|
// TODO: Do not use these classes, remove them after stdlib tests are merged in the same build as the compiler
|
||||||
@NotNull
|
@NotNull
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.lazy
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analyzer.AnalyzerFacade
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleContent
|
import org.jetbrains.kotlin.analyzer.ModuleContent
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
@@ -35,9 +36,9 @@ fun createResolveSessionForFiles(
|
|||||||
): ResolveSession {
|
): ResolveSession {
|
||||||
val projectContext = ProjectContext(project)
|
val projectContext = ProjectContext(project)
|
||||||
val testModule = TestModule(addBuiltIns)
|
val testModule = TestModule(addBuiltIns)
|
||||||
val resolverForProject = JvmAnalyzerFacade.setupResolverForProject(
|
val resolverForProject = AnalyzerFacade.setupResolverForProject(
|
||||||
"test",
|
"test",
|
||||||
projectContext, listOf(testModule),
|
projectContext, listOf(testModule), { JvmAnalyzerFacade },
|
||||||
{ ModuleContent(syntheticFiles, GlobalSearchScope.allScope(project)) },
|
{ ModuleContent(syntheticFiles, GlobalSearchScope.allScope(project)) },
|
||||||
JvmPlatformParameters { testModule },
|
JvmPlatformParameters { testModule },
|
||||||
modulePlatforms = { MultiTargetPlatform.Specific("JVM") }
|
modulePlatforms = { MultiTargetPlatform.Specific("JVM") }
|
||||||
|
|||||||
+3
-2
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.jvm.compiler
|
|||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analyzer.AnalyzerFacade
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleContent
|
import org.jetbrains.kotlin.analyzer.ModuleContent
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||||
@@ -65,9 +66,9 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
|
|||||||
val modules = setupModules(environment, moduleDirs)
|
val modules = setupModules(environment, moduleDirs)
|
||||||
val projectContext = ProjectContext(environment.project)
|
val projectContext = ProjectContext(environment.project)
|
||||||
val builtIns = JvmBuiltIns(projectContext.storageManager)
|
val builtIns = JvmBuiltIns(projectContext.storageManager)
|
||||||
val resolverForProject = JvmAnalyzerFacade.setupResolverForProject(
|
val resolverForProject = AnalyzerFacade.setupResolverForProject(
|
||||||
"test",
|
"test",
|
||||||
projectContext, modules,
|
projectContext, modules, { JvmAnalyzerFacade },
|
||||||
{ module -> ModuleContent(module.kotlinFiles, module.javaFilesScope) },
|
{ module -> ModuleContent(module.kotlinFiles, module.javaFilesScope) },
|
||||||
JvmPlatformParameters {
|
JvmPlatformParameters {
|
||||||
javaClass ->
|
javaClass ->
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ object JsAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
|||||||
)
|
)
|
||||||
var packageFragmentProvider = container.get<ResolveSession>().packageFragmentProvider
|
var packageFragmentProvider = container.get<ResolveSession>().packageFragmentProvider
|
||||||
|
|
||||||
if (moduleInfo is LibraryModuleInfo && moduleInfo.isJsLibrary()) {
|
if (moduleInfo is LibraryModuleInfo && moduleInfo.libraryPlatform == JsPlatform) {
|
||||||
val providers = moduleInfo.getLibraryRoots()
|
val providers = moduleInfo.getLibraryRoots()
|
||||||
.flatMap { KotlinJavascriptMetadataUtils.loadMetadata(it) }
|
.flatMap { KotlinJavascriptMetadataUtils.loadMetadata(it) }
|
||||||
.filter { it.version.isCompatible() }
|
.filter { it.version.isCompatible() }
|
||||||
|
|||||||
@@ -17,8 +17,10 @@
|
|||||||
package org.jetbrains.kotlin.caches.resolve
|
package org.jetbrains.kotlin.caches.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
|
|
||||||
interface LibraryModuleInfo : ModuleInfo {
|
interface LibraryModuleInfo : ModuleInfo {
|
||||||
fun isJsLibrary(): Boolean
|
val libraryPlatform: TargetPlatform
|
||||||
|
|
||||||
fun getLibraryRoots(): Collection<String>
|
fun getLibraryRoots(): Collection<String>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,15 @@ import com.intellij.util.SmartList
|
|||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.caches.resolve.LibraryModuleInfo
|
import org.jetbrains.kotlin.caches.resolve.LibraryModuleInfo
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.framework.CommonLibraryDetectionUtil
|
||||||
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil
|
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||||
import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected
|
import org.jetbrains.kotlin.idea.util.isInSourceContentWithoutInjected
|
||||||
|
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.jvm.GlobalSearchScopeWithModuleSources
|
import org.jetbrains.kotlin.resolve.jvm.GlobalSearchScopeWithModuleSources
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface IdeaModuleInfo : ModuleInfo {
|
interface IdeaModuleInfo : ModuleInfo {
|
||||||
@@ -200,7 +204,12 @@ class LibraryInfo(val project: Project, val library: Library) : IdeaModuleInfo,
|
|||||||
return result.toList()
|
return result.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isJsLibrary(): Boolean = KotlinJavaScriptLibraryDetectionUtil.isKotlinJavaScriptLibrary(library)
|
override val libraryPlatform: TargetPlatform
|
||||||
|
get() = when {
|
||||||
|
KotlinJavaScriptLibraryDetectionUtil.isKotlinJavaScriptLibrary(library) -> JsPlatform
|
||||||
|
CommonLibraryDetectionUtil.isCommonLibrary(library) -> TargetPlatform.Default
|
||||||
|
else -> JvmPlatform
|
||||||
|
}
|
||||||
|
|
||||||
override val sourcesModuleInfo: SourceForBinaryModuleInfo
|
override val sourcesModuleInfo: SourceForBinaryModuleInfo
|
||||||
get() = LibrarySourceInfo(project, library)
|
get() = LibrarySourceInfo(project, library)
|
||||||
|
|||||||
+2
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||||
import org.jetbrains.kotlin.container.getService
|
import org.jetbrains.kotlin.container.getService
|
||||||
|
import org.jetbrains.kotlin.container.tryGetService
|
||||||
import org.jetbrains.kotlin.context.GlobalContext
|
import org.jetbrains.kotlin.context.GlobalContext
|
||||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
@@ -164,7 +165,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Any> tryGetProjectService(platform: TargetPlatform, ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T? {
|
fun <T : Any> tryGetProjectService(platform: TargetPlatform, ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T? {
|
||||||
return globalFacade(platform, ideaModuleInfo.sdk).tryGetResolverForModuleInfo(ideaModuleInfo)?.componentProvider?.getService(serviceClass)
|
return globalFacade(platform, ideaModuleInfo.sdk).tryGetResolverForModuleInfo(ideaModuleInfo)?.componentProvider?.tryGetService(serviceClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun globalFacade(platform: TargetPlatform, sdk: Sdk?) =
|
private fun globalFacade(platform: TargetPlatform, sdk: Sdk?) =
|
||||||
|
|||||||
+14
-7
@@ -23,10 +23,12 @@ import com.intellij.openapi.projectRoots.Sdk
|
|||||||
import com.intellij.openapi.roots.JdkOrderEntry
|
import com.intellij.openapi.roots.JdkOrderEntry
|
||||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||||
import com.intellij.openapi.roots.ModuleRootManager
|
import com.intellij.openapi.roots.ModuleRootManager
|
||||||
|
import org.jetbrains.kotlin.analyzer.AnalyzerFacade
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleContent
|
import org.jetbrains.kotlin.analyzer.ModuleContent
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.caches.resolve.LibraryModuleInfo
|
||||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||||
import org.jetbrains.kotlin.context.withProject
|
import org.jetbrains.kotlin.context.withProject
|
||||||
import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider
|
import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider
|
||||||
@@ -78,15 +80,13 @@ fun createModuleResolverProvider(
|
|||||||
psiClass.getNullableModuleInfo()
|
psiClass.getNullableModuleInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
return AnalyzerFacadeProvider.getAnalyzerFacade(platform).setupResolverForProject(
|
return AnalyzerFacade.setupResolverForProject(
|
||||||
debugName, globalContext.withProject(project), modulesToCreateResolversFor, modulesContent,
|
debugName, globalContext.withProject(project), modulesToCreateResolversFor,
|
||||||
jvmPlatformParameters, IdeaEnvironment, builtInsProvider,
|
{ module -> AnalyzerFacadeProvider.getAnalyzerFacade(module.getTargetPlatform() ?: platform) },
|
||||||
|
modulesContent, jvmPlatformParameters, IdeaEnvironment, builtInsProvider,
|
||||||
delegateResolver, { _, c -> IDEPackagePartProvider(c.moduleContentScope) },
|
delegateResolver, { _, c -> IDEPackagePartProvider(c.moduleContentScope) },
|
||||||
sdk?.let { SdkInfo(project, it) },
|
sdk?.let { SdkInfo(project, it) },
|
||||||
modulePlatforms = { moduleInfo ->
|
modulePlatforms = { module -> module.getTargetPlatform()?.multiTargetPlatform }
|
||||||
val module = (moduleInfo as? ModuleSourceInfo)?.module
|
|
||||||
module?.let { TargetPlatformDetector.getPlatform(module).multiTargetPlatform }
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +105,13 @@ fun createModuleResolverProvider(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ModuleInfo.getTargetPlatform(): TargetPlatform? =
|
||||||
|
when (this) {
|
||||||
|
is ModuleSourceInfo -> TargetPlatformDetector.getPlatform(module)
|
||||||
|
is LibraryModuleInfo -> libraryPlatform
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModuleInfo> {
|
fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModuleInfo> {
|
||||||
val ideaModules = ModuleManager.getInstance(project).modules.toList()
|
val ideaModules = ModuleManager.getInstance(project).modules.toList()
|
||||||
val modulesSourcesInfos = ideaModules.flatMap { listOf(it.productionSourceInfo(), it.testSourceInfo()) }
|
val modulesSourcesInfos = ideaModules.flatMap { listOf(it.productionSourceInfo(), it.testSourceInfo()) }
|
||||||
|
|||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.framework
|
||||||
|
|
||||||
|
import com.intellij.openapi.roots.OrderRootType
|
||||||
|
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||||
|
import com.intellij.openapi.roots.libraries.Library
|
||||||
|
import com.intellij.openapi.vfs.VfsUtilCore
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import org.jetbrains.kotlin.idea.caches.JarUserDataManager
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragment
|
||||||
|
|
||||||
|
object CommonLibraryDetectionUtil {
|
||||||
|
fun isCommonLibrary(library: Library): Boolean {
|
||||||
|
if (library is LibraryEx && library.isDisposed) return false
|
||||||
|
|
||||||
|
for (root in library.getFiles(OrderRootType.CLASSES)) {
|
||||||
|
val hasMetadata = JarUserDataManager.hasFileWithProperty(HasCommonKotlinMetadataInJar, root)
|
||||||
|
if (hasMetadata != null) {
|
||||||
|
return hasMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!VfsUtilCore.processFilesRecursively(root) { !isKotlinMetadataFile(it) }) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isKotlinMetadataFile(file: VirtualFile): Boolean =
|
||||||
|
!file.isDirectory &&
|
||||||
|
file.extension == MetadataPackageFragment.METADATA_FILE_EXTENSION
|
||||||
|
|
||||||
|
object HasCommonKotlinMetadataInJar : JarUserDataManager.JarBooleanPropertyCounter(HasCommonKotlinMetadataInJar::class.simpleName!!) {
|
||||||
|
override fun hasProperty(file: VirtualFile) = isKotlinMetadataFile(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.idea.caches.JarUserDataManager;
|
import org.jetbrains.kotlin.idea.caches.JarUserDataManager;
|
||||||
import org.jetbrains.kotlin.idea.debugger.filter.DebuggerFiltersUtilKt;
|
import org.jetbrains.kotlin.idea.debugger.filter.DebuggerFiltersUtilKt;
|
||||||
|
import org.jetbrains.kotlin.idea.framework.CommonLibraryDetectionUtil;
|
||||||
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil;
|
import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil;
|
||||||
import org.jetbrains.kotlin.utils.PathUtil;
|
import org.jetbrains.kotlin.utils.PathUtil;
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ public class PluginStartupComponent implements ApplicationComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JarUserDataManager.INSTANCE.register(KotlinJavaScriptLibraryDetectionUtil.HasKotlinJSMetadataInJar.INSTANCE);
|
JarUserDataManager.INSTANCE.register(KotlinJavaScriptLibraryDetectionUtil.HasKotlinJSMetadataInJar.INSTANCE);
|
||||||
|
JarUserDataManager.INSTANCE.register(CommonLibraryDetectionUtil.HasCommonKotlinMetadataInJar.INSTANCE);
|
||||||
|
|
||||||
DebuggerFiltersUtilKt.addKotlinStdlibDebugFilterIfNeeded();
|
DebuggerFiltersUtilKt.addKotlinStdlibDebugFilterIfNeeded();
|
||||||
|
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class MyException : Exception()
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun test(f: () -> Unit) {
|
||||||
|
try {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
catch (e: MyException) {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.caches.resolve
|
package org.jetbrains.kotlin.idea.caches.resolve
|
||||||
|
|
||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
|
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.JvmTarget
|
||||||
import org.jetbrains.kotlin.config.TargetPlatformKind
|
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||||
|
|
||||||
@@ -64,9 +65,12 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() {
|
|||||||
class MultiPlatform : AbstractMultiModuleHighlightingTest() {
|
class MultiPlatform : AbstractMultiModuleHighlightingTest() {
|
||||||
override val testPath get() = super.testPath + "multiplatform/"
|
override val testPath get() = super.testPath + "multiplatform/"
|
||||||
|
|
||||||
private fun doTest(vararg platforms: TargetPlatformKind<*>) {
|
private fun doTest(vararg platforms: TargetPlatformKind<*>, withStdlibCommon: Boolean = false) {
|
||||||
val commonModule = module("common")
|
val commonModule = module("common")
|
||||||
commonModule.createFacet(TargetPlatformKind.Common)
|
commonModule.createFacet(TargetPlatformKind.Common)
|
||||||
|
if (withStdlibCommon) {
|
||||||
|
commonModule.addLibrary(ForTestCompileRuntime.stdlibCommonForTests())
|
||||||
|
}
|
||||||
|
|
||||||
for (platform in platforms) {
|
for (platform in platforms) {
|
||||||
val path = when (platform) {
|
val path = when (platform) {
|
||||||
@@ -106,5 +110,9 @@ class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() {
|
|||||||
fun testSuppressHeaderWithoutImpl() {
|
fun testSuppressHeaderWithoutImpl() {
|
||||||
doTest(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6])
|
doTest(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testCatchHeaderExceptionInPlatformModule() {
|
||||||
|
doTest(TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], withStdlibCommon = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ import com.intellij.openapi.module.Module
|
|||||||
import com.intellij.openapi.module.StdModuleTypes
|
import com.intellij.openapi.module.StdModuleTypes
|
||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||||
|
import com.intellij.openapi.roots.OrderRootType
|
||||||
|
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
|
import com.intellij.openapi.vfs.VfsUtil
|
||||||
import com.intellij.testFramework.PsiTestUtil
|
import com.intellij.testFramework.PsiTestUtil
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument
|
import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument
|
||||||
@@ -35,6 +38,7 @@ import org.jetbrains.kotlin.config.TargetPlatformKind
|
|||||||
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
|
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
|
||||||
import org.jetbrains.kotlin.idea.facet.initializeIfNeeded
|
import org.jetbrains.kotlin.idea.facet.initializeIfNeeded
|
||||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||||
|
import org.jetbrains.kotlin.idea.test.KotlinJdkAndLibraryProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -75,6 +79,13 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() {
|
|||||||
exported: Boolean = false
|
exported: Boolean = false
|
||||||
) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported)
|
) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported)
|
||||||
|
|
||||||
|
protected fun Module.addLibrary(jar: File) {
|
||||||
|
ConfigLibraryUtil.addLibrary(NewLibraryEditor().apply {
|
||||||
|
name = KotlinJdkAndLibraryProjectDescriptor.LIBRARY_NAME
|
||||||
|
addRoot(VfsUtil.getUrlForLibraryRoot(jar), OrderRootType.CLASSES)
|
||||||
|
}, this)
|
||||||
|
}
|
||||||
|
|
||||||
protected fun Module.createFacet(platformKind: TargetPlatformKind<*>? = null) {
|
protected fun Module.createFacet(platformKind: TargetPlatformKind<*>? = null) {
|
||||||
val accessToken = WriteAction.start()
|
val accessToken = WriteAction.start()
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -43,4 +43,13 @@ task sourcesJar(type: Jar, dependsOn: classes) {
|
|||||||
artifacts {
|
artifacts {
|
||||||
archives sourcesJar
|
archives sourcesJar
|
||||||
archives javadocJar
|
archives javadocJar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: call the "dist" task instead, once we need to publish kotlin-stdlib-common.jar with the compiler distribution
|
||||||
|
task distCommon(type: Copy) {
|
||||||
|
from(jar)
|
||||||
|
into "$distDir/common"
|
||||||
|
rename "-${java.util.regex.Pattern.quote(version)}", ''
|
||||||
|
}
|
||||||
|
|
||||||
|
dist.dependsOn distCommon
|
||||||
|
|||||||
Reference in New Issue
Block a user