diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt new file mode 100644 index 00000000000..39c14366aa4 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.cli.jvm.compiler + +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.lang.jvm.facade.JvmElementProvider +import com.intellij.openapi.extensions.ExtensionsArea +import com.intellij.psi.JavaModuleSystem +import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy + +internal object IdeaExtensionPoints { + const val IDEA_COMPATIBLE_BUILD_NUMBER = "181.3" + + fun registerVersionSpecificAppExtensionPoints(area: ExtensionsArea) { + @Suppress("DEPRECATION") + CoreApplicationEnvironment.registerExtensionPoint(area, ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java) + CoreApplicationEnvironment.registerExtensionPoint(area, JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java) + } + + fun registerVersionSpecificProjectExtensionPoints(area: ExtensionsArea) { + CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java) + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.172 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.172 new file mode 100644 index 00000000000..4dcaf07d36e --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.172 @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.cli.jvm.compiler + +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.openapi.extensions.ExtensionsArea +import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy + +internal object IdeaExtensionPoints { + const val IDEA_COMPATIBLE_BUILD_NUMBER = "172.9999" + + fun registerVersionSpecificAppExtensionPoints(area: ExtensionsArea) { + @Suppress("DEPRECATION") + CoreApplicationEnvironment.registerExtensionPoint(area, ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java) + } + + fun registerVersionSpecificProjectExtensionPoints(area: ExtensionsArea) { + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.173 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.173 new file mode 100644 index 00000000000..20de9fa35d3 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.173 @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.cli.jvm.compiler + +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.lang.jvm.facade.JvmElementProvider +import com.intellij.openapi.extensions.ExtensionsArea +import com.intellij.psi.JavaModuleSystem +import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy + +internal object IdeaExtensionPoints { + const val IDEA_COMPATIBLE_BUILD_NUMBER = "173.1" + + fun registerVersionSpecificAppExtensionPoints(area: ExtensionsArea) { + @Suppress("DEPRECATION") + CoreApplicationEnvironment.registerExtensionPoint(area, ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java) + CoreApplicationEnvironment.registerExtensionPoint(area, JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java) + } + + fun registerVersionSpecificProjectExtensionPoints(area: ExtensionsArea) { + CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java) + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.182 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.182 new file mode 100644 index 00000000000..1f7fe07e555 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/IdeaExtensionPoints.kt.182 @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.cli.jvm.compiler + +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.lang.jvm.facade.JvmElementProvider +import com.intellij.openapi.extensions.ExtensionsArea +import com.intellij.psi.JavaModuleSystem + +internal object IdeaExtensionPoints { + const val IDEA_COMPATIBLE_BUILD_NUMBER = "181.3" + + fun registerVersionSpecificAppExtensionPoints(area: ExtensionsArea) { + CoreApplicationEnvironment.registerExtensionPoint(area, JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java) + } + + fun registerVersionSpecificProjectExtensionPoints(area: ExtensionsArea) { + CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java) + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 2fd614c35cb..a551c998d03 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -28,7 +28,6 @@ import com.intellij.ide.highlighter.JavaFileType import com.intellij.ide.plugins.PluginManagerCore import com.intellij.lang.MetaLanguage import com.intellij.lang.java.JavaParserDefinition -import com.intellij.lang.jvm.facade.JvmElementProvider import com.intellij.openapi.Disposable import com.intellij.openapi.application.TransactionGuard import com.intellij.openapi.application.TransactionGuardImpl @@ -44,7 +43,6 @@ import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.* import com.intellij.openapi.vfs.impl.ZipHandler import com.intellij.psi.FileContextProvider -import com.intellij.psi.JavaModuleSystem import com.intellij.psi.PsiElementFinder import com.intellij.psi.PsiManager import com.intellij.psi.augment.PsiAugmentProvider @@ -53,7 +51,6 @@ import com.intellij.psi.compiled.ClassFileDecompilers import com.intellij.psi.impl.JavaClassSupersImpl import com.intellij.psi.impl.PsiElementFinderImpl import com.intellij.psi.impl.PsiTreeChangePreprocessor -import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy import com.intellij.psi.impl.file.impl.JavaFileManager import com.intellij.psi.meta.MetaDataContributor import com.intellij.psi.search.GlobalSearchScope @@ -398,8 +395,6 @@ class KotlinCoreEnvironment private constructor( } companion object { - private val ideaCompatibleBuildNumber = "181.3" - init { setCompatibleBuild() } @@ -443,8 +438,10 @@ class KotlinCoreEnvironment private constructor( @JvmStatic private fun setCompatibleBuild() { - PluginManagerCore.BUILD_NUMBER = ideaCompatibleBuildNumber - System.getProperties().setProperty("idea.plugins.compatible.build", ideaCompatibleBuildNumber) + IdeaExtensionPoints.IDEA_COMPATIBLE_BUILD_NUMBER.let { buildNumber -> + PluginManagerCore.BUILD_NUMBER = buildNumber + System.getProperties().setProperty("idea.plugins.compatible.build", buildNumber) + } } @TestOnly @@ -525,13 +522,12 @@ class KotlinCoreEnvironment private constructor( CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java) // CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContainerProvider.EP_NAME, ContainerProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java) CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java) // CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java) CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java) // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java) + IdeaExtensionPoints.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea()) } private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) { @@ -582,7 +578,8 @@ class KotlinCoreEnvironment private constructor( private fun registerProjectExtensionPoints(area: ExtensionsArea) { CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java) CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java) - CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java) + + IdeaExtensionPoints.registerVersionSpecificProjectExtensionPoints(area) } // made public for Upsource diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.172 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.172 deleted file mode 100644 index 630f9df6ff7..00000000000 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.172 +++ /dev/null @@ -1,632 +0,0 @@ -/* - * 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.cli.jvm.compiler - -import com.intellij.codeInsight.ContainerProvider -import com.intellij.codeInsight.ExternalAnnotationsManager -import com.intellij.codeInsight.InferredAnnotationsManager -import com.intellij.codeInsight.runner.JavaMainMethodProvider -import com.intellij.core.CoreApplicationEnvironment -import com.intellij.core.CoreJavaFileManager -import com.intellij.core.JavaCoreApplicationEnvironment -import com.intellij.core.JavaCoreProjectEnvironment -import com.intellij.ide.highlighter.JavaFileType -import com.intellij.ide.plugins.PluginManagerCore -import com.intellij.lang.MetaLanguage -import com.intellij.lang.java.JavaParserDefinition -import com.intellij.openapi.Disposable -import com.intellij.openapi.application.TransactionGuard -import com.intellij.openapi.application.TransactionGuardImpl -import com.intellij.openapi.components.ServiceManager -import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.extensions.ExtensionsArea -import com.intellij.openapi.fileTypes.FileTypeExtensionPoint -import com.intellij.openapi.fileTypes.PlainTextFileType -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Disposer -import com.intellij.openapi.util.io.FileUtilRt -import com.intellij.openapi.util.text.StringUtil -import com.intellij.openapi.vfs.* -import com.intellij.openapi.vfs.impl.ZipHandler -import com.intellij.psi.FileContextProvider -import com.intellij.psi.PsiElementFinder -import com.intellij.psi.PsiManager -import com.intellij.psi.augment.PsiAugmentProvider -import com.intellij.psi.augment.TypeAnnotationModifier -import com.intellij.psi.compiled.ClassFileDecompilers -import com.intellij.psi.impl.JavaClassSupersImpl -import com.intellij.psi.impl.PsiElementFinderImpl -import com.intellij.psi.impl.PsiTreeChangePreprocessor -import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy -import com.intellij.psi.impl.file.impl.JavaFileManager -import com.intellij.psi.meta.MetaDataContributor -import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.stubs.BinaryFileStubBuilders -import com.intellij.psi.util.JavaClassSupers -import com.intellij.util.io.URLUtil -import com.intellij.util.lang.UrlClassLoader -import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport -import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade -import org.jetbrains.kotlin.asJava.finder.JavaElementFinder -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl -import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.script.CliScriptDefinitionProvider -import org.jetbrains.kotlin.cli.common.script.CliScriptDependenciesProvider -import org.jetbrains.kotlin.cli.common.script.CliScriptReportSink -import org.jetbrains.kotlin.cli.common.toBooleanLenient -import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker -import org.jetbrains.kotlin.cli.jvm.config.* -import org.jetbrains.kotlin.cli.jvm.index.* -import org.jetbrains.kotlin.cli.jvm.javac.JavacWrapperRegistrar -import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder -import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver -import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem -import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension -import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension -import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension -import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension -import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor -import org.jetbrains.kotlin.idea.KotlinFileType -import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension -import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory -import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager -import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory -import org.jetbrains.kotlin.parsing.KotlinParserDefinition -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver -import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension -import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade -import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension -import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension -import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver -import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService -import org.jetbrains.kotlin.script.ScriptDefinitionProvider -import org.jetbrains.kotlin.script.ScriptDependenciesProvider -import org.jetbrains.kotlin.script.ScriptReportSink -import org.jetbrains.kotlin.script.StandardScriptDefinition -import org.jetbrains.kotlin.utils.PathUtil -import java.io.File -import java.util.zip.ZipFile - -class KotlinCoreEnvironment private constructor( - parentDisposable: Disposable, - applicationEnvironment: JavaCoreApplicationEnvironment, - initialConfiguration: CompilerConfiguration, - configFiles: EnvironmentConfigFiles -) { - private val projectEnvironment: JavaCoreProjectEnvironment = object : KotlinCoreProjectEnvironment(parentDisposable, applicationEnvironment) { - override fun preregisterServices() { - registerProjectExtensionPoints(Extensions.getArea(project)) - } - - override fun registerJavaPsiFacade() { - with (project) { - registerService(CoreJavaFileManager::class.java, ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager) - - val traceHolder = CliTraceHolder() - val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder) - val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) - registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) - registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) - registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport) - registerService(CodeAnalyzerInitializer::class.java, traceHolder) - - registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager()) - registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager()) - - val area = Extensions.getArea(this) - - area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, kotlinAsJavaSupport)) - area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension( - PsiElementFinderImpl(this, ServiceManager.getService(this, JavaFileManager::class.java))) - } - - super.registerJavaPsiFacade() - } - } - - private val sourceFiles = mutableListOf() - private val rootsIndex: JvmDependenciesDynamicCompoundIndex - private val packagePartProviders = mutableListOf() - - private val classpathRootsResolver: ClasspathRootsResolver - private val initialRoots: List - - val configuration: CompilerConfiguration = initialConfiguration.apply { setupJdkClasspathRoots(configFiles) }.copy() - - init { - PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize") - .apply { isAccessible = true } - .setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING) - - val project = projectEnvironment.project - - ExpressionCodegenExtension.registerExtensionPoint(project) - SyntheticResolveExtension.registerExtensionPoint(project) - ClassBuilderInterceptorExtension.registerExtensionPoint(project) - AnalysisHandlerExtension.registerExtensionPoint(project) - PackageFragmentProviderExtension.registerExtensionPoint(project) - StorageComponentContainerContributor.registerExtensionPoint(project) - DeclarationAttributeAltererExtension.registerExtensionPoint(project) - PreprocessedVirtualFileFactoryExtension.registerExtensionPoint(project) - JsSyntheticTranslateExtension.registerExtensionPoint(project) - CompilerConfigurationExtension.registerExtensionPoint(project) - - for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) { - try { - registrar.registerProjectComponents(project, configuration) - } catch (e: AbstractMethodError) { - throw IllegalStateException("The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler", e) - } - } - - project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles)) - project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES)) - - registerProjectServicesForCLI(projectEnvironment) - - val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - registerProjectServices(projectEnvironment, messageCollector) - - CompilerConfigurationExtension.getInstances(project).forEach { - it.updateConfiguration(configuration) - } - - sourceFiles += CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration, { - message -> - report(ERROR, message) - }) - sourceFiles.sortBy { it.virtualFile.path } - - val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? CliScriptDefinitionProvider - if (scriptDefinitionProvider != null) { - scriptDefinitionProvider.setScriptDefinitionsSources( - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS_SOURCES) - ) - scriptDefinitionProvider.setScriptDefinitions( - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS)) - - ScriptDependenciesProvider.getInstance(project).let { importsProvider -> - configuration.addJvmClasspathRoots( - sourceFiles.mapNotNull(importsProvider::getScriptDependencies) - .flatMap { it.classpath } - .distinctBy { it.absolutePath }) - } - } - - val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME) - val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL) - val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path -> - jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR) - }) - - val outputDirectory = - configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory() - ?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath - - classpathRootsResolver = ClasspathRootsResolver( - PsiManager.getInstance(project), - messageCollector, - configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES), - this::contentRootToVirtualFile, - javaModuleFinder, - !configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE), - outputDirectory?.let(this::findLocalFile) - ) - - val (initialRoots, javaModules) = - classpathRootsResolver.convertClasspathRoots(configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS)) - this.initialRoots = initialRoots - - if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) { - JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency( - messageCollector, - configuration, - initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null } - ) - } - - val (roots, singleJavaFileRoots) = - initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION } - - // REPL and kapt2 update classpath dynamically - rootsIndex = JvmDependenciesDynamicCompoundIndex().apply { - addIndex(JvmDependenciesIndexImpl(roots)) - updateClasspathFromRootsIndex(this) - } - - (ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize( - rootsIndex, - packagePartProviders, - SingleJavaFileRootsIndex(singleJavaFileRoots), - configuration.getBoolean(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING) - ) - - project.registerService( - JavaModuleResolver::class.java, - CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList()) - ) - - val finderFactory = CliVirtualFileFinderFactory(rootsIndex) - project.registerService(MetadataFinderFactory::class.java, finderFactory) - project.registerService(VirtualFileFinderFactory::class.java, finderFactory) - - project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List) { - updateClasspath(roots.map { JavaSourceRoot(it, null) }) - }) - } - - fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider { - return JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply { - addRoots(initialRoots) - packagePartProviders += this - (ModuleAnnotationsResolver.getInstance(project) as CliModuleAnnotationsResolver).addPackagePartProvider(this) - } - } - - private val VirtualFile.javaFiles: List - get() = mutableListOf().apply { - VfsUtilCore.processFilesRecursively(this@javaFiles) { file -> - if (file.fileType == JavaFileType.INSTANCE) { - add(file) - } - true - } - } - - private val allJavaFiles: List - get() = configuration.javaSourceRoots - .mapNotNull(this::findLocalFile) - .flatMap { it.javaFiles } - .map { File(it.canonicalPath) } - - fun registerJavac( - javaFiles: List = allJavaFiles, - kotlinFiles: List = sourceFiles, - arguments: Array? = null, - bootClasspath: List? = null, - sourcePath: List? = null - ): Boolean { - return JavacWrapperRegistrar.registerJavac(projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath, LightClassGenerationSupport.getInstance(project)) - } - - private val applicationEnvironment: CoreApplicationEnvironment - get() = projectEnvironment.environment - - val project: Project - get() = projectEnvironment.project - - internal fun countLinesOfCode(sourceFiles: List): Int = - sourceFiles.sumBy { sourceFile -> - val text = sourceFile.text - StringUtil.getLineBreakCount(text) + (if (StringUtil.endsWithLineBreak(text)) 0 else 1) - } - - private fun updateClasspathFromRootsIndex(index: JvmDependenciesIndex) { - index.indexedRoots.forEach { - projectEnvironment.addSourcesToClasspath(it.file) - } - } - - fun updateClasspath(contentRoots: List): List? { - // TODO: add new Java modules to CliJavaModuleResolver - val newRoots = classpathRootsResolver.convertClasspathRoots(contentRoots).roots - - for (packagePartProvider in packagePartProviders) { - packagePartProvider.addRoots(newRoots) - } - - return rootsIndex.addNewIndexForRoots(newRoots)?.let { newIndex -> - updateClasspathFromRootsIndex(newIndex) - newIndex.indexedRoots.mapNotNull { (file) -> - VfsUtilCore.virtualToIoFile(VfsUtilCore.getVirtualFileForJar(file) ?: file) - }.toList() - }.orEmpty() - } - - private fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? { - return when (root) { - is JvmClasspathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root) - is JvmModulePathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root) - is JavaSourceRoot -> findLocalFile(root) - else -> throw IllegalStateException("Unexpected root: $root") - } - } - - internal fun findLocalFile(path: String): VirtualFile? = - applicationEnvironment.localFileSystem.findFileByPath(path) - - private fun findLocalFile(root: JvmContentRoot): VirtualFile? { - return findLocalFile(root.file.absolutePath).also { - if (it == null) { - report(STRONG_WARNING, "Classpath entry points to a non-existent location: ${root.file}") - } - } - } - - private fun findJarRoot(file: File): VirtualFile? = - applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}") - - private fun getSourceRootsCheckingForDuplicates(): Collection { - val uniqueSourceRoots = linkedSetOf() - - configuration.kotlinSourceRoots.forEach { path -> - if (!uniqueSourceRoots.add(path)) { - report(STRONG_WARNING, "Duplicate source root: $path") - } - } - - return uniqueSourceRoots - } - - fun getSourceFiles(): List = sourceFiles - - private fun report(severity: CompilerMessageSeverity, message: String) { - configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(severity, message) - } - - companion object { - private val ideaCompatibleBuildNumber = "172.9999" - - init { - setCompatibleBuild() - } - - private val APPLICATION_LOCK = Object() - private var ourApplicationEnvironment: JavaCoreApplicationEnvironment? = null - private var ourProjectCount = 0 - - @JvmStatic - fun createForProduction( - parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles - ): KotlinCoreEnvironment { - setCompatibleBuild() - if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) && - StandardScriptDefinition !in configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS) - ) { - configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) - } - val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration) - // Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally - // breaks a lot of tests, therefore it is disabled for production and enabled for tests - if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY).toBooleanLenient() != true) { - // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) - // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well - Disposer.register(parentDisposable, Disposable { - synchronized (APPLICATION_LOCK) { - if (--ourProjectCount <= 0) { - disposeApplicationEnvironment() - } - } - }) - } - val environment = KotlinCoreEnvironment(parentDisposable, appEnv, configuration, configFiles) - - synchronized (APPLICATION_LOCK) { - ourProjectCount++ - } - return environment - } - - @JvmStatic - private fun setCompatibleBuild() { - PluginManagerCore.BUILD_NUMBER = ideaCompatibleBuildNumber - System.getProperties().setProperty("idea.plugins.compatible.build", ideaCompatibleBuildNumber) - } - - @TestOnly - @JvmStatic - fun createForTests( - parentDisposable: Disposable, initialConfiguration: CompilerConfiguration, extensionConfigs: EnvironmentConfigFiles - ): KotlinCoreEnvironment { - val configuration = initialConfiguration.copy() - // in tests we assume that standard definition should only be added if no other explicit defs are already added - if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) && - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS).isEmpty() - ) { - configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) - } - // Tests are supposed to create a single project and dispose it right after use - return KotlinCoreEnvironment( - parentDisposable, - createApplicationEnvironment(parentDisposable, configuration, unitTestMode = true), - configuration, - extensionConfigs - ) - } - - // used in the daemon for jar cache cleanup - val applicationEnvironment: JavaCoreApplicationEnvironment? get() = ourApplicationEnvironment - - private fun getOrCreateApplicationEnvironmentForProduction(configuration: CompilerConfiguration): JavaCoreApplicationEnvironment { - synchronized (APPLICATION_LOCK) { - if (ourApplicationEnvironment != null) - return ourApplicationEnvironment!! - - val parentDisposable = Disposer.newDisposable() - ourApplicationEnvironment = createApplicationEnvironment(parentDisposable, configuration, unitTestMode = false) - ourProjectCount = 0 - Disposer.register(parentDisposable, Disposable { - synchronized (APPLICATION_LOCK) { - ourApplicationEnvironment = null - } - }) - return ourApplicationEnvironment!! - } - } - - private fun disposeApplicationEnvironment() { - synchronized (APPLICATION_LOCK) { - val environment = ourApplicationEnvironment ?: return - ourApplicationEnvironment = null - Disposer.dispose(environment.parentDisposable) - ZipHandler.clearFileAccessorCache() - } - } - - private fun createApplicationEnvironment( - parentDisposable: Disposable, - configuration: CompilerConfiguration, - unitTestMode: Boolean - ): JavaCoreApplicationEnvironment { - Extensions.cleanRootArea(parentDisposable) - registerAppExtensionPoints() - val applicationEnvironment = object : JavaCoreApplicationEnvironment(parentDisposable, unitTestMode) { - override fun createJrtFileSystem(): VirtualFileSystem? = CoreJrtFileSystem() - } - - registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml") - - registerApplicationServicesForCLI(applicationEnvironment) - registerApplicationServices(applicationEnvironment) - - return applicationEnvironment - } - - private fun registerAppExtensionPoints() { - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), FileContextProvider.EP_NAME, FileContextProvider::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaDataContributor.EP_NAME, MetaDataContributor::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, PsiAugmentProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContainerProvider.EP_NAME, ContainerProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java) - } - - private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) { - fun File.hasConfigFile(configFile: String): Boolean = - if (isDirectory) File(this, "META-INF" + File.separator + configFile).exists() - else try { - ZipFile(this).use { - it.getEntry("META-INF/" + configFile) != null - } - } - catch (e: Throwable) { - false - } - - val pluginRoot = - configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File) - ?: configuration.get(CLIConfigurationKeys.COMPILER_JAR_LOCATOR)?.compilerJar - ?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) } - // hack for load extensions when compiler run directly from project directory (e.g. in tests) - ?: File("idea/src").takeIf { it.hasConfigFile(configFilePath) } - ?: throw IllegalStateException( - "Unable to find extension point configuration $configFilePath " + - "(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})") - - CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, configFilePath, Extensions.getRootArea()) - } - - private fun registerApplicationServicesForCLI(applicationEnvironment: JavaCoreApplicationEnvironment) { - // ability to get text from annotations xml files - applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml") - applicationEnvironment.registerParserDefinition(JavaParserDefinition()) - } - - // made public for Upsource - @Suppress("MemberVisibilityCanPrivate") - @JvmStatic - fun registerApplicationServices(applicationEnvironment: JavaCoreApplicationEnvironment) { - with(applicationEnvironment) { - registerFileType(KotlinFileType.INSTANCE, "kt") - registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX) - registerParserDefinition(KotlinParserDefinition()) - application.registerService(KotlinBinaryClassCache::class.java, KotlinBinaryClassCache()) - application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java) - application.registerService(TransactionGuard::class.java, TransactionGuardImpl::class.java) - } - } - - private fun registerProjectExtensionPoints(area: ExtensionsArea) { - CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java) - CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java) - } - - // made public for Upsource - @JvmStatic - fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment, messageCollector: MessageCollector?) { - with (projectEnvironment.project) { - val scriptDefinitionProvider = CliScriptDefinitionProvider() - registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider) - registerService(ScriptDependenciesProvider::class.java, CliScriptDependenciesProvider(projectEnvironment.project, scriptDefinitionProvider)) - registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this)) - registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this)) - registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver()) - if (messageCollector != null) { - registerService(ScriptReportSink::class.java, CliScriptReportSink(messageCollector)) - } - } - } - - private fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) { - /** - * Note that Kapt may restart code analysis process, and CLI services should be aware of that. - * Use PsiManager.getModificationTracker() to ensure that all the data you cached is still valid. - */ - - } - - private fun CompilerConfiguration.setupJdkClasspathRoots(configFiles: EnvironmentConfigFiles) { - if (getBoolean(JVMConfigurationKeys.NO_JDK)) return - - val jvmTarget = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES - if (!jvmTarget) return - - val jdkHome = get(JVMConfigurationKeys.JDK_HOME) - val (javaRoot, classesRoots) = if (jdkHome == null) { - val javaHome = File(System.getProperty("java.home")) - put(JVMConfigurationKeys.JDK_HOME, javaHome) - - javaHome to PathUtil.getJdkClassesRootsFromCurrentJre() - } - else { - jdkHome to PathUtil.getJdkClassesRoots(jdkHome) - } - - if (!CoreJrtFileSystem.isModularJdk(javaRoot)) { - if (classesRoots.isEmpty()) { - val messageCollector = get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - messageCollector?.report(ERROR, "No class roots are found in the JDK path: $javaRoot") - } - else { - addJvmSdkRoots(classesRoots) - } - } - } - - } -} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.173 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.173 deleted file mode 100644 index 575c7947fa0..00000000000 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.173 +++ /dev/null @@ -1,637 +0,0 @@ -/* - * 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.cli.jvm.compiler - -import com.intellij.codeInsight.ContainerProvider -import com.intellij.codeInsight.ExternalAnnotationsManager -import com.intellij.codeInsight.InferredAnnotationsManager -import com.intellij.codeInsight.runner.JavaMainMethodProvider -import com.intellij.core.CoreApplicationEnvironment -import com.intellij.core.CoreJavaFileManager -import com.intellij.core.JavaCoreApplicationEnvironment -import com.intellij.core.JavaCoreProjectEnvironment -import com.intellij.ide.highlighter.JavaFileType -import com.intellij.ide.plugins.PluginManagerCore -import com.intellij.lang.MetaLanguage -import com.intellij.lang.java.JavaParserDefinition -import com.intellij.lang.jvm.facade.JvmElementProvider -import com.intellij.openapi.Disposable -import com.intellij.openapi.application.TransactionGuard -import com.intellij.openapi.application.TransactionGuardImpl -import com.intellij.openapi.components.ServiceManager -import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.extensions.ExtensionsArea -import com.intellij.openapi.fileTypes.FileTypeExtensionPoint -import com.intellij.openapi.fileTypes.PlainTextFileType -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Disposer -import com.intellij.openapi.util.io.FileUtilRt -import com.intellij.openapi.util.text.StringUtil -import com.intellij.openapi.vfs.* -import com.intellij.openapi.vfs.impl.ZipHandler -import com.intellij.psi.FileContextProvider -import com.intellij.psi.JavaModuleSystem -import com.intellij.psi.PsiElementFinder -import com.intellij.psi.PsiManager -import com.intellij.psi.augment.PsiAugmentProvider -import com.intellij.psi.augment.TypeAnnotationModifier -import com.intellij.psi.compiled.ClassFileDecompilers -import com.intellij.psi.impl.JavaClassSupersImpl -import com.intellij.psi.impl.PsiElementFinderImpl -import com.intellij.psi.impl.PsiTreeChangePreprocessor -import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy -import com.intellij.psi.impl.file.impl.JavaFileManager -import com.intellij.psi.meta.MetaDataContributor -import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.stubs.BinaryFileStubBuilders -import com.intellij.psi.util.JavaClassSupers -import com.intellij.util.io.URLUtil -import com.intellij.util.lang.UrlClassLoader -import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport -import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade -import org.jetbrains.kotlin.asJava.finder.JavaElementFinder -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl -import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.script.CliScriptDefinitionProvider -import org.jetbrains.kotlin.cli.common.script.CliScriptDependenciesProvider -import org.jetbrains.kotlin.cli.common.script.CliScriptReportSink -import org.jetbrains.kotlin.cli.common.toBooleanLenient -import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker -import org.jetbrains.kotlin.cli.jvm.config.* -import org.jetbrains.kotlin.cli.jvm.index.* -import org.jetbrains.kotlin.cli.jvm.javac.JavacWrapperRegistrar -import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder -import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver -import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem -import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension -import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension -import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension -import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension -import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor -import org.jetbrains.kotlin.idea.KotlinFileType -import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension -import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory -import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager -import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory -import org.jetbrains.kotlin.parsing.KotlinParserDefinition -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver -import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension -import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade -import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension -import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension -import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver -import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService -import org.jetbrains.kotlin.script.ScriptDefinitionProvider -import org.jetbrains.kotlin.script.ScriptDependenciesProvider -import org.jetbrains.kotlin.script.ScriptReportSink -import org.jetbrains.kotlin.script.StandardScriptDefinition -import org.jetbrains.kotlin.utils.PathUtil -import java.io.File -import java.util.zip.ZipFile - -class KotlinCoreEnvironment private constructor( - parentDisposable: Disposable, - applicationEnvironment: JavaCoreApplicationEnvironment, - initialConfiguration: CompilerConfiguration, - configFiles: EnvironmentConfigFiles -) { - private val projectEnvironment: JavaCoreProjectEnvironment = object : KotlinCoreProjectEnvironment(parentDisposable, applicationEnvironment) { - override fun preregisterServices() { - registerProjectExtensionPoints(Extensions.getArea(project)) - } - - override fun registerJavaPsiFacade() { - with (project) { - registerService(CoreJavaFileManager::class.java, ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager) - - val traceHolder = CliTraceHolder() - val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder) - val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) - registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) - registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) - registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport) - registerService(CodeAnalyzerInitializer::class.java, traceHolder) - - registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager()) - registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager()) - - val area = Extensions.getArea(this) - - area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, kotlinAsJavaSupport)) - area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension( - PsiElementFinderImpl(this, ServiceManager.getService(this, JavaFileManager::class.java))) - } - - super.registerJavaPsiFacade() - } - } - - private val sourceFiles = mutableListOf() - private val rootsIndex: JvmDependenciesDynamicCompoundIndex - private val packagePartProviders = mutableListOf() - - private val classpathRootsResolver: ClasspathRootsResolver - private val initialRoots: List - - val configuration: CompilerConfiguration = initialConfiguration.apply { setupJdkClasspathRoots(configFiles) }.copy() - - init { - PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize") - .apply { isAccessible = true } - .setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING) - - val project = projectEnvironment.project - - ExpressionCodegenExtension.registerExtensionPoint(project) - SyntheticResolveExtension.registerExtensionPoint(project) - ClassBuilderInterceptorExtension.registerExtensionPoint(project) - AnalysisHandlerExtension.registerExtensionPoint(project) - PackageFragmentProviderExtension.registerExtensionPoint(project) - StorageComponentContainerContributor.registerExtensionPoint(project) - DeclarationAttributeAltererExtension.registerExtensionPoint(project) - PreprocessedVirtualFileFactoryExtension.registerExtensionPoint(project) - JsSyntheticTranslateExtension.registerExtensionPoint(project) - CompilerConfigurationExtension.registerExtensionPoint(project) - - for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) { - try { - registrar.registerProjectComponents(project, configuration) - } catch (e: AbstractMethodError) { - throw IllegalStateException("The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler", e) - } - } - - project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles)) - project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES)) - - registerProjectServicesForCLI(projectEnvironment) - - val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - registerProjectServices(projectEnvironment, messageCollector) - - CompilerConfigurationExtension.getInstances(project).forEach { - it.updateConfiguration(configuration) - } - - sourceFiles += CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration, { - message -> - report(ERROR, message) - }) - sourceFiles.sortBy { it.virtualFile.path } - - val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? CliScriptDefinitionProvider - if (scriptDefinitionProvider != null) { - scriptDefinitionProvider.setScriptDefinitionsSources( - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS_SOURCES) - ) - scriptDefinitionProvider.setScriptDefinitions( - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS)) - - ScriptDependenciesProvider.getInstance(project).let { importsProvider -> - configuration.addJvmClasspathRoots( - sourceFiles.mapNotNull(importsProvider::getScriptDependencies) - .flatMap { it.classpath } - .distinctBy { it.absolutePath }) - } - } - - val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME) - val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL) - val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path -> - jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR) - }) - - val outputDirectory = - configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory() - ?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath - - classpathRootsResolver = ClasspathRootsResolver( - PsiManager.getInstance(project), - messageCollector, - configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES), - this::contentRootToVirtualFile, - javaModuleFinder, - !configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE), - outputDirectory?.let(this::findLocalFile) - ) - - val (initialRoots, javaModules) = - classpathRootsResolver.convertClasspathRoots(configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS)) - this.initialRoots = initialRoots - - if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) { - JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency( - messageCollector, - configuration, - initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null } - ) - } - - val (roots, singleJavaFileRoots) = - initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION } - - // REPL and kapt2 update classpath dynamically - rootsIndex = JvmDependenciesDynamicCompoundIndex().apply { - addIndex(JvmDependenciesIndexImpl(roots)) - updateClasspathFromRootsIndex(this) - } - - (ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize( - rootsIndex, - packagePartProviders, - SingleJavaFileRootsIndex(singleJavaFileRoots), - configuration.getBoolean(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING) - ) - - project.registerService( - JavaModuleResolver::class.java, - CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList()) - ) - - val finderFactory = CliVirtualFileFinderFactory(rootsIndex) - project.registerService(MetadataFinderFactory::class.java, finderFactory) - project.registerService(VirtualFileFinderFactory::class.java, finderFactory) - - project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List) { - updateClasspath(roots.map { JavaSourceRoot(it, null) }) - }) - } - - fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider { - return JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply { - addRoots(initialRoots) - packagePartProviders += this - (ModuleAnnotationsResolver.getInstance(project) as CliModuleAnnotationsResolver).addPackagePartProvider(this) - } - } - - private val VirtualFile.javaFiles: List - get() = mutableListOf().apply { - VfsUtilCore.processFilesRecursively(this@javaFiles) { file -> - if (file.fileType == JavaFileType.INSTANCE) { - add(file) - } - true - } - } - - private val allJavaFiles: List - get() = configuration.javaSourceRoots - .mapNotNull(this::findLocalFile) - .flatMap { it.javaFiles } - .map { File(it.canonicalPath) } - - fun registerJavac( - javaFiles: List = allJavaFiles, - kotlinFiles: List = sourceFiles, - arguments: Array? = null, - bootClasspath: List? = null, - sourcePath: List? = null - ): Boolean { - return JavacWrapperRegistrar.registerJavac(projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath, LightClassGenerationSupport.getInstance(project)) - } - - private val applicationEnvironment: CoreApplicationEnvironment - get() = projectEnvironment.environment - - val project: Project - get() = projectEnvironment.project - - internal fun countLinesOfCode(sourceFiles: List): Int = - sourceFiles.sumBy { sourceFile -> - val text = sourceFile.text - StringUtil.getLineBreakCount(text) + (if (StringUtil.endsWithLineBreak(text)) 0 else 1) - } - - private fun updateClasspathFromRootsIndex(index: JvmDependenciesIndex) { - index.indexedRoots.forEach { - projectEnvironment.addSourcesToClasspath(it.file) - } - } - - fun updateClasspath(contentRoots: List): List? { - // TODO: add new Java modules to CliJavaModuleResolver - val newRoots = classpathRootsResolver.convertClasspathRoots(contentRoots).roots - - for (packagePartProvider in packagePartProviders) { - packagePartProvider.addRoots(newRoots) - } - - return rootsIndex.addNewIndexForRoots(newRoots)?.let { newIndex -> - updateClasspathFromRootsIndex(newIndex) - newIndex.indexedRoots.mapNotNull { (file) -> - VfsUtilCore.virtualToIoFile(VfsUtilCore.getVirtualFileForJar(file) ?: file) - }.toList() - }.orEmpty() - } - - private fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? { - return when (root) { - is JvmClasspathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root) - is JvmModulePathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root) - is JavaSourceRoot -> findLocalFile(root) - else -> throw IllegalStateException("Unexpected root: $root") - } - } - - internal fun findLocalFile(path: String): VirtualFile? = - applicationEnvironment.localFileSystem.findFileByPath(path) - - private fun findLocalFile(root: JvmContentRoot): VirtualFile? { - return findLocalFile(root.file.absolutePath).also { - if (it == null) { - report(STRONG_WARNING, "Classpath entry points to a non-existent location: ${root.file}") - } - } - } - - private fun findJarRoot(file: File): VirtualFile? = - applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}") - - private fun getSourceRootsCheckingForDuplicates(): Collection { - val uniqueSourceRoots = linkedSetOf() - - configuration.kotlinSourceRoots.forEach { path -> - if (!uniqueSourceRoots.add(path)) { - report(STRONG_WARNING, "Duplicate source root: $path") - } - } - - return uniqueSourceRoots - } - - fun getSourceFiles(): List = sourceFiles - - private fun report(severity: CompilerMessageSeverity, message: String) { - configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(severity, message) - } - - companion object { - private val ideaCompatibleBuildNumber = "173.1" - - init { - setCompatibleBuild() - } - - private val APPLICATION_LOCK = Object() - private var ourApplicationEnvironment: JavaCoreApplicationEnvironment? = null - private var ourProjectCount = 0 - - @JvmStatic - fun createForProduction( - parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles - ): KotlinCoreEnvironment { - setCompatibleBuild() - if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) && - StandardScriptDefinition !in configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS) - ) { - configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) - } - val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration) - // Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally - // breaks a lot of tests, therefore it is disabled for production and enabled for tests - if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY).toBooleanLenient() != true) { - // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) - // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well - Disposer.register(parentDisposable, Disposable { - synchronized (APPLICATION_LOCK) { - if (--ourProjectCount <= 0) { - disposeApplicationEnvironment() - } - } - }) - } - val environment = KotlinCoreEnvironment(parentDisposable, appEnv, configuration, configFiles) - - synchronized (APPLICATION_LOCK) { - ourProjectCount++ - } - return environment - } - - @JvmStatic - private fun setCompatibleBuild() { - PluginManagerCore.BUILD_NUMBER = ideaCompatibleBuildNumber - System.getProperties().setProperty("idea.plugins.compatible.build", ideaCompatibleBuildNumber) - } - - @TestOnly - @JvmStatic - fun createForTests( - parentDisposable: Disposable, initialConfiguration: CompilerConfiguration, extensionConfigs: EnvironmentConfigFiles - ): KotlinCoreEnvironment { - val configuration = initialConfiguration.copy() - // in tests we assume that standard definition should only be added if no other explicit defs are already added - if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) && - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS).isEmpty() - ) { - configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) - } - // Tests are supposed to create a single project and dispose it right after use - return KotlinCoreEnvironment( - parentDisposable, - createApplicationEnvironment(parentDisposable, configuration, unitTestMode = true), - configuration, - extensionConfigs - ) - } - - // used in the daemon for jar cache cleanup - val applicationEnvironment: JavaCoreApplicationEnvironment? get() = ourApplicationEnvironment - - private fun getOrCreateApplicationEnvironmentForProduction(configuration: CompilerConfiguration): JavaCoreApplicationEnvironment { - synchronized (APPLICATION_LOCK) { - if (ourApplicationEnvironment != null) - return ourApplicationEnvironment!! - - val parentDisposable = Disposer.newDisposable() - ourApplicationEnvironment = createApplicationEnvironment(parentDisposable, configuration, unitTestMode = false) - ourProjectCount = 0 - Disposer.register(parentDisposable, Disposable { - synchronized (APPLICATION_LOCK) { - ourApplicationEnvironment = null - } - }) - return ourApplicationEnvironment!! - } - } - - private fun disposeApplicationEnvironment() { - synchronized (APPLICATION_LOCK) { - val environment = ourApplicationEnvironment ?: return - ourApplicationEnvironment = null - Disposer.dispose(environment.parentDisposable) - ZipHandler.clearFileAccessorCache() - } - } - - private fun createApplicationEnvironment( - parentDisposable: Disposable, - configuration: CompilerConfiguration, - unitTestMode: Boolean - ): JavaCoreApplicationEnvironment { - Extensions.cleanRootArea(parentDisposable) - registerAppExtensionPoints() - val applicationEnvironment = object : JavaCoreApplicationEnvironment(parentDisposable, unitTestMode) { - override fun createJrtFileSystem(): VirtualFileSystem? = CoreJrtFileSystem() - } - - registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml") - - registerApplicationServicesForCLI(applicationEnvironment) - registerApplicationServices(applicationEnvironment) - - return applicationEnvironment - } - - private fun registerAppExtensionPoints() { - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), FileContextProvider.EP_NAME, FileContextProvider::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaDataContributor.EP_NAME, MetaDataContributor::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, PsiAugmentProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContainerProvider.EP_NAME, ContainerProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java) - } - - private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) { - fun File.hasConfigFile(configFile: String): Boolean = - if (isDirectory) File(this, "META-INF" + File.separator + configFile).exists() - else try { - ZipFile(this).use { - it.getEntry("META-INF/" + configFile) != null - } - } - catch (e: Throwable) { - false - } - - val pluginRoot = - configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File) - ?: configuration.get(CLIConfigurationKeys.COMPILER_JAR_LOCATOR)?.compilerJar - ?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) } - // hack for load extensions when compiler run directly from project directory (e.g. in tests) - ?: File("idea/src").takeIf { it.hasConfigFile(configFilePath) } - ?: throw IllegalStateException( - "Unable to find extension point configuration $configFilePath " + - "(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})") - - CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, configFilePath, Extensions.getRootArea()) - } - - private fun registerApplicationServicesForCLI(applicationEnvironment: JavaCoreApplicationEnvironment) { - // ability to get text from annotations xml files - applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml") - applicationEnvironment.registerParserDefinition(JavaParserDefinition()) - } - - // made public for Upsource - @Suppress("MemberVisibilityCanPrivate") - @JvmStatic - fun registerApplicationServices(applicationEnvironment: JavaCoreApplicationEnvironment) { - with(applicationEnvironment) { - registerFileType(KotlinFileType.INSTANCE, "kt") - registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX) - registerParserDefinition(KotlinParserDefinition()) - application.registerService(KotlinBinaryClassCache::class.java, KotlinBinaryClassCache()) - application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java) - application.registerService(TransactionGuard::class.java, TransactionGuardImpl::class.java) - } - } - - private fun registerProjectExtensionPoints(area: ExtensionsArea) { - CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java) - CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java) - CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java) - } - - // made public for Upsource - @JvmStatic - fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment, messageCollector: MessageCollector?) { - with (projectEnvironment.project) { - val scriptDefinitionProvider = CliScriptDefinitionProvider() - registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider) - registerService(ScriptDependenciesProvider::class.java, CliScriptDependenciesProvider(projectEnvironment.project, scriptDefinitionProvider)) - registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this)) - registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this)) - registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver()) - if (messageCollector != null) { - registerService(ScriptReportSink::class.java, CliScriptReportSink(messageCollector)) - } - } - } - - private fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) { - /** - * Note that Kapt may restart code analysis process, and CLI services should be aware of that. - * Use PsiManager.getModificationTracker() to ensure that all the data you cached is still valid. - */ - - } - - private fun CompilerConfiguration.setupJdkClasspathRoots(configFiles: EnvironmentConfigFiles) { - if (getBoolean(JVMConfigurationKeys.NO_JDK)) return - - val jvmTarget = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES - if (!jvmTarget) return - - val jdkHome = get(JVMConfigurationKeys.JDK_HOME) - val (javaRoot, classesRoots) = if (jdkHome == null) { - val javaHome = File(System.getProperty("java.home")) - put(JVMConfigurationKeys.JDK_HOME, javaHome) - - javaHome to PathUtil.getJdkClassesRootsFromCurrentJre() - } - else { - jdkHome to PathUtil.getJdkClassesRoots(jdkHome) - } - - if (!CoreJrtFileSystem.isModularJdk(javaRoot)) { - if (classesRoots.isEmpty()) { - val messageCollector = get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - messageCollector?.report(ERROR, "No class roots are found in the JDK path: $javaRoot") - } - else { - addJvmSdkRoots(classesRoots) - } - } - } - - } -} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.182 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.182 deleted file mode 100644 index 138076a59ef..00000000000 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.182 +++ /dev/null @@ -1,636 +0,0 @@ -/* - * 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.cli.jvm.compiler - -import com.intellij.codeInsight.ContainerProvider -import com.intellij.codeInsight.ExternalAnnotationsManager -import com.intellij.codeInsight.InferredAnnotationsManager -import com.intellij.codeInsight.runner.JavaMainMethodProvider -import com.intellij.core.CoreApplicationEnvironment -import com.intellij.core.CoreJavaFileManager -import com.intellij.core.JavaCoreApplicationEnvironment -import com.intellij.core.JavaCoreProjectEnvironment -import com.intellij.ide.highlighter.JavaFileType -import com.intellij.ide.plugins.PluginManagerCore -import com.intellij.lang.MetaLanguage -import com.intellij.lang.java.JavaParserDefinition -import com.intellij.lang.jvm.facade.JvmElementProvider -import com.intellij.openapi.Disposable -import com.intellij.openapi.application.TransactionGuard -import com.intellij.openapi.application.TransactionGuardImpl -import com.intellij.openapi.components.ServiceManager -import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.extensions.ExtensionsArea -import com.intellij.openapi.fileTypes.FileTypeExtensionPoint -import com.intellij.openapi.fileTypes.PlainTextFileType -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Disposer -import com.intellij.openapi.util.io.FileUtilRt -import com.intellij.openapi.util.text.StringUtil -import com.intellij.openapi.vfs.* -import com.intellij.openapi.vfs.impl.ZipHandler -import com.intellij.psi.FileContextProvider -import com.intellij.psi.JavaModuleSystem -import com.intellij.psi.PsiElementFinder -import com.intellij.psi.PsiManager -import com.intellij.psi.augment.PsiAugmentProvider -import com.intellij.psi.augment.TypeAnnotationModifier -import com.intellij.psi.compiled.ClassFileDecompilers -import com.intellij.psi.impl.JavaClassSupersImpl -import com.intellij.psi.impl.PsiElementFinderImpl -import com.intellij.psi.impl.PsiTreeChangePreprocessor -import com.intellij.psi.impl.file.impl.JavaFileManager -import com.intellij.psi.meta.MetaDataContributor -import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.stubs.BinaryFileStubBuilders -import com.intellij.psi.util.JavaClassSupers -import com.intellij.util.io.URLUtil -import com.intellij.util.lang.UrlClassLoader -import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport -import org.jetbrains.kotlin.asJava.LightClassGenerationSupport -import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade -import org.jetbrains.kotlin.asJava.finder.JavaElementFinder -import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys -import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl -import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.script.CliScriptDefinitionProvider -import org.jetbrains.kotlin.cli.common.script.CliScriptDependenciesProvider -import org.jetbrains.kotlin.cli.common.script.CliScriptReportSink -import org.jetbrains.kotlin.cli.common.toBooleanLenient -import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker -import org.jetbrains.kotlin.cli.jvm.config.* -import org.jetbrains.kotlin.cli.jvm.index.* -import org.jetbrains.kotlin.cli.jvm.javac.JavacWrapperRegistrar -import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder -import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver -import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem -import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension -import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension -import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension -import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension -import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor -import org.jetbrains.kotlin.idea.KotlinFileType -import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension -import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory -import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager -import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory -import org.jetbrains.kotlin.parsing.KotlinParserDefinition -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer -import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver -import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension -import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade -import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension -import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension -import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver -import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService -import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService -import org.jetbrains.kotlin.script.ScriptDefinitionProvider -import org.jetbrains.kotlin.script.ScriptDependenciesProvider -import org.jetbrains.kotlin.script.ScriptReportSink -import org.jetbrains.kotlin.script.StandardScriptDefinition -import org.jetbrains.kotlin.utils.PathUtil -import java.io.File -import java.util.zip.ZipFile - -class KotlinCoreEnvironment private constructor( - parentDisposable: Disposable, - applicationEnvironment: JavaCoreApplicationEnvironment, - initialConfiguration: CompilerConfiguration, - configFiles: EnvironmentConfigFiles -) { - private val projectEnvironment: JavaCoreProjectEnvironment = object : KotlinCoreProjectEnvironment(parentDisposable, applicationEnvironment) { - override fun preregisterServices() { - registerProjectExtensionPoints(Extensions.getArea(project)) - } - - override fun registerJavaPsiFacade() { - with (project) { - registerService(CoreJavaFileManager::class.java, ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager) - - val traceHolder = CliTraceHolder() - val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder) - val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder) - registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport) - registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport) - registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport) - registerService(CodeAnalyzerInitializer::class.java, traceHolder) - - registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager()) - registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager()) - - val area = Extensions.getArea(this) - - area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, kotlinAsJavaSupport)) - area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension( - PsiElementFinderImpl(this, ServiceManager.getService(this, JavaFileManager::class.java))) - } - - super.registerJavaPsiFacade() - } - } - - private val sourceFiles = mutableListOf() - private val rootsIndex: JvmDependenciesDynamicCompoundIndex - private val packagePartProviders = mutableListOf() - - private val classpathRootsResolver: ClasspathRootsResolver - private val initialRoots: List - - val configuration: CompilerConfiguration = initialConfiguration.apply { setupJdkClasspathRoots(configFiles) }.copy() - - init { - PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize") - .apply { isAccessible = true } - .setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING) - - val project = projectEnvironment.project - - ExpressionCodegenExtension.registerExtensionPoint(project) - SyntheticResolveExtension.registerExtensionPoint(project) - ClassBuilderInterceptorExtension.registerExtensionPoint(project) - AnalysisHandlerExtension.registerExtensionPoint(project) - PackageFragmentProviderExtension.registerExtensionPoint(project) - StorageComponentContainerContributor.registerExtensionPoint(project) - DeclarationAttributeAltererExtension.registerExtensionPoint(project) - PreprocessedVirtualFileFactoryExtension.registerExtensionPoint(project) - JsSyntheticTranslateExtension.registerExtensionPoint(project) - CompilerConfigurationExtension.registerExtensionPoint(project) - - for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) { - try { - registrar.registerProjectComponents(project, configuration) - } catch (e: AbstractMethodError) { - throw IllegalStateException("The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler", e) - } - } - - project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles)) - project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES)) - - registerProjectServicesForCLI(projectEnvironment) - - val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - registerProjectServices(projectEnvironment, messageCollector) - - CompilerConfigurationExtension.getInstances(project).forEach { - it.updateConfiguration(configuration) - } - - sourceFiles += CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration, { - message -> - report(ERROR, message) - }) - sourceFiles.sortBy { it.virtualFile.path } - - val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? CliScriptDefinitionProvider - if (scriptDefinitionProvider != null) { - scriptDefinitionProvider.setScriptDefinitionsSources( - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS_SOURCES) - ) - scriptDefinitionProvider.setScriptDefinitions( - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS)) - - ScriptDependenciesProvider.getInstance(project).let { importsProvider -> - configuration.addJvmClasspathRoots( - sourceFiles.mapNotNull(importsProvider::getScriptDependencies) - .flatMap { it.classpath } - .distinctBy { it.absolutePath }) - } - } - - val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME) - val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL) - val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path -> - jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR) - }) - - val outputDirectory = - configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory() - ?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath - - classpathRootsResolver = ClasspathRootsResolver( - PsiManager.getInstance(project), - messageCollector, - configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES), - this::contentRootToVirtualFile, - javaModuleFinder, - !configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE), - outputDirectory?.let(this::findLocalFile) - ) - - val (initialRoots, javaModules) = - classpathRootsResolver.convertClasspathRoots(configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS)) - this.initialRoots = initialRoots - - if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) { - JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency( - messageCollector, - configuration, - initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null } - ) - } - - val (roots, singleJavaFileRoots) = - initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION } - - // REPL and kapt2 update classpath dynamically - rootsIndex = JvmDependenciesDynamicCompoundIndex().apply { - addIndex(JvmDependenciesIndexImpl(roots)) - updateClasspathFromRootsIndex(this) - } - - (ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize( - rootsIndex, - packagePartProviders, - SingleJavaFileRootsIndex(singleJavaFileRoots), - configuration.getBoolean(JVMConfigurationKeys.USE_FAST_CLASS_FILES_READING) - ) - - project.registerService( - JavaModuleResolver::class.java, - CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList()) - ) - - val finderFactory = CliVirtualFileFinderFactory(rootsIndex) - project.registerService(MetadataFinderFactory::class.java, finderFactory) - project.registerService(VirtualFileFinderFactory::class.java, finderFactory) - - project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List) { - updateClasspath(roots.map { JavaSourceRoot(it, null) }) - }) - } - - fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider { - return JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply { - addRoots(initialRoots) - packagePartProviders += this - (ModuleAnnotationsResolver.getInstance(project) as CliModuleAnnotationsResolver).addPackagePartProvider(this) - } - } - - private val VirtualFile.javaFiles: List - get() = mutableListOf().apply { - VfsUtilCore.processFilesRecursively(this@javaFiles) { file -> - if (file.fileType == JavaFileType.INSTANCE) { - add(file) - } - true - } - } - - private val allJavaFiles: List - get() = configuration.javaSourceRoots - .mapNotNull(this::findLocalFile) - .flatMap { it.javaFiles } - .map { File(it.canonicalPath) } - - fun registerJavac( - javaFiles: List = allJavaFiles, - kotlinFiles: List = sourceFiles, - arguments: Array? = null, - bootClasspath: List? = null, - sourcePath: List? = null - ): Boolean { - return JavacWrapperRegistrar.registerJavac(projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath, LightClassGenerationSupport.getInstance(project)) - } - - private val applicationEnvironment: CoreApplicationEnvironment - get() = projectEnvironment.environment - - val project: Project - get() = projectEnvironment.project - - internal fun countLinesOfCode(sourceFiles: List): Int = - sourceFiles.sumBy { sourceFile -> - val text = sourceFile.text - StringUtil.getLineBreakCount(text) + (if (StringUtil.endsWithLineBreak(text)) 0 else 1) - } - - private fun updateClasspathFromRootsIndex(index: JvmDependenciesIndex) { - index.indexedRoots.forEach { - projectEnvironment.addSourcesToClasspath(it.file) - } - } - - fun updateClasspath(contentRoots: List): List? { - // TODO: add new Java modules to CliJavaModuleResolver - val newRoots = classpathRootsResolver.convertClasspathRoots(contentRoots).roots - - for (packagePartProvider in packagePartProviders) { - packagePartProvider.addRoots(newRoots) - } - - return rootsIndex.addNewIndexForRoots(newRoots)?.let { newIndex -> - updateClasspathFromRootsIndex(newIndex) - newIndex.indexedRoots.mapNotNull { (file) -> - VfsUtilCore.virtualToIoFile(VfsUtilCore.getVirtualFileForJar(file) ?: file) - }.toList() - }.orEmpty() - } - - private fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? { - return when (root) { - is JvmClasspathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root) - is JvmModulePathRoot -> if (root.file.isFile) findJarRoot(root.file) else findLocalFile(root) - is JavaSourceRoot -> findLocalFile(root) - else -> throw IllegalStateException("Unexpected root: $root") - } - } - - internal fun findLocalFile(path: String): VirtualFile? = - applicationEnvironment.localFileSystem.findFileByPath(path) - - private fun findLocalFile(root: JvmContentRoot): VirtualFile? { - return findLocalFile(root.file.absolutePath).also { - if (it == null) { - report(STRONG_WARNING, "Classpath entry points to a non-existent location: ${root.file}") - } - } - } - - private fun findJarRoot(file: File): VirtualFile? = - applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}") - - private fun getSourceRootsCheckingForDuplicates(): Collection { - val uniqueSourceRoots = linkedSetOf() - - configuration.kotlinSourceRoots.forEach { path -> - if (!uniqueSourceRoots.add(path)) { - report(STRONG_WARNING, "Duplicate source root: $path") - } - } - - return uniqueSourceRoots - } - - fun getSourceFiles(): List = sourceFiles - - private fun report(severity: CompilerMessageSeverity, message: String) { - configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(severity, message) - } - - companion object { - private val ideaCompatibleBuildNumber = "181.3" - - init { - setCompatibleBuild() - } - - private val APPLICATION_LOCK = Object() - private var ourApplicationEnvironment: JavaCoreApplicationEnvironment? = null - private var ourProjectCount = 0 - - @JvmStatic - fun createForProduction( - parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles - ): KotlinCoreEnvironment { - setCompatibleBuild() - // If not disabled explicitly, we should always support at least the standard script definition - if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) && - StandardScriptDefinition !in configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS) - ) { - configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) - } - val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration) - // Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally - // breaks a lot of tests, therefore it is disabled for production and enabled for tests - if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY).toBooleanLenient() != true) { - // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) - // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well - Disposer.register(parentDisposable, Disposable { - synchronized (APPLICATION_LOCK) { - if (--ourProjectCount <= 0) { - disposeApplicationEnvironment() - } - } - }) - } - val environment = KotlinCoreEnvironment(parentDisposable, appEnv, configuration, configFiles) - - synchronized (APPLICATION_LOCK) { - ourProjectCount++ - } - return environment - } - - @JvmStatic - private fun setCompatibleBuild() { - PluginManagerCore.BUILD_NUMBER = ideaCompatibleBuildNumber - System.getProperties().setProperty("idea.plugins.compatible.build", ideaCompatibleBuildNumber) - } - - @TestOnly - @JvmStatic - fun createForTests( - parentDisposable: Disposable, initialConfiguration: CompilerConfiguration, extensionConfigs: EnvironmentConfigFiles - ): KotlinCoreEnvironment { - val configuration = initialConfiguration.copy() - // in tests we assume that standard definition should only be added if no other explicit defs are already added - if (!configuration.getBoolean(JVMConfigurationKeys.DISABLE_STANDARD_SCRIPT_DEFINITION) && - configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS).isEmpty() - ) { - configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition) - } - // Tests are supposed to create a single project and dispose it right after use - return KotlinCoreEnvironment( - parentDisposable, - createApplicationEnvironment(parentDisposable, configuration, unitTestMode = true), - configuration, - extensionConfigs - ) - } - - // used in the daemon for jar cache cleanup - val applicationEnvironment: JavaCoreApplicationEnvironment? get() = ourApplicationEnvironment - - private fun getOrCreateApplicationEnvironmentForProduction(configuration: CompilerConfiguration): JavaCoreApplicationEnvironment { - synchronized (APPLICATION_LOCK) { - if (ourApplicationEnvironment != null) - return ourApplicationEnvironment!! - - val parentDisposable = Disposer.newDisposable() - ourApplicationEnvironment = createApplicationEnvironment(parentDisposable, configuration, unitTestMode = false) - ourProjectCount = 0 - Disposer.register(parentDisposable, Disposable { - synchronized (APPLICATION_LOCK) { - ourApplicationEnvironment = null - } - }) - return ourApplicationEnvironment!! - } - } - - private fun disposeApplicationEnvironment() { - synchronized (APPLICATION_LOCK) { - val environment = ourApplicationEnvironment ?: return - ourApplicationEnvironment = null - Disposer.dispose(environment.parentDisposable) - ZipHandler.clearFileAccessorCache() - } - } - - private fun createApplicationEnvironment( - parentDisposable: Disposable, - configuration: CompilerConfiguration, - unitTestMode: Boolean - ): JavaCoreApplicationEnvironment { - Extensions.cleanRootArea(parentDisposable) - registerAppExtensionPoints() - val applicationEnvironment = object : JavaCoreApplicationEnvironment(parentDisposable, unitTestMode) { - override fun createJrtFileSystem(): VirtualFileSystem? = CoreJrtFileSystem() - } - - registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml") - - registerApplicationServicesForCLI(applicationEnvironment) - registerApplicationServices(applicationEnvironment) - - return applicationEnvironment - } - - private fun registerAppExtensionPoints() { - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), FileContextProvider.EP_NAME, FileContextProvider::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaDataContributor.EP_NAME, MetaDataContributor::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, PsiAugmentProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContainerProvider.EP_NAME, ContainerProvider::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java) - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java) - // - CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java) - } - - private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) { - fun File.hasConfigFile(configFile: String): Boolean = - if (isDirectory) File(this, "META-INF" + File.separator + configFile).exists() - else try { - ZipFile(this).use { - it.getEntry("META-INF/" + configFile) != null - } - } - catch (e: Throwable) { - false - } - - val pluginRoot = - configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File) - ?: configuration.get(CLIConfigurationKeys.COMPILER_JAR_LOCATOR)?.compilerJar - ?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) } - // hack for load extensions when compiler run directly from project directory (e.g. in tests) - ?: File("idea/src").takeIf { it.hasConfigFile(configFilePath) } - ?: throw IllegalStateException( - "Unable to find extension point configuration $configFilePath " + - "(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})") - - CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, configFilePath, Extensions.getRootArea()) - } - - private fun registerApplicationServicesForCLI(applicationEnvironment: JavaCoreApplicationEnvironment) { - // ability to get text from annotations xml files - applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml") - applicationEnvironment.registerParserDefinition(JavaParserDefinition()) - } - - // made public for Upsource - @Suppress("MemberVisibilityCanPrivate") - @JvmStatic - fun registerApplicationServices(applicationEnvironment: JavaCoreApplicationEnvironment) { - with(applicationEnvironment) { - registerFileType(KotlinFileType.INSTANCE, "kt") - registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX) - registerParserDefinition(KotlinParserDefinition()) - application.registerService(KotlinBinaryClassCache::class.java, KotlinBinaryClassCache()) - application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java) - application.registerService(TransactionGuard::class.java, TransactionGuardImpl::class.java) - } - } - - private fun registerProjectExtensionPoints(area: ExtensionsArea) { - CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java) - CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java) - CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java) - } - - // made public for Upsource - @JvmStatic - fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment, messageCollector: MessageCollector?) { - with (projectEnvironment.project) { - val scriptDefinitionProvider = CliScriptDefinitionProvider() - registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider) - registerService(ScriptDependenciesProvider::class.java, CliScriptDependenciesProvider(projectEnvironment.project, scriptDefinitionProvider)) - registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this)) - registerService(KtLightClassForFacade.FacadeStubCache::class.java, KtLightClassForFacade.FacadeStubCache(this)) - registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver()) - if (messageCollector != null) { - registerService(ScriptReportSink::class.java, CliScriptReportSink(messageCollector)) - } - } - } - - private fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) { - /** - * Note that Kapt may restart code analysis process, and CLI services should be aware of that. - * Use PsiManager.getModificationTracker() to ensure that all the data you cached is still valid. - */ - - } - - private fun CompilerConfiguration.setupJdkClasspathRoots(configFiles: EnvironmentConfigFiles) { - if (getBoolean(JVMConfigurationKeys.NO_JDK)) return - - val jvmTarget = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES - if (!jvmTarget) return - - val jdkHome = get(JVMConfigurationKeys.JDK_HOME) - val (javaRoot, classesRoots) = if (jdkHome == null) { - val javaHome = File(System.getProperty("java.home")) - put(JVMConfigurationKeys.JDK_HOME, javaHome) - - javaHome to PathUtil.getJdkClassesRootsFromCurrentJre() - } - else { - jdkHome to PathUtil.getJdkClassesRoots(jdkHome) - } - - if (!CoreJrtFileSystem.isModularJdk(javaRoot)) { - if (classesRoots.isEmpty()) { - val messageCollector = get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - messageCollector?.report(ERROR, "No class roots are found in the JDK path: $javaRoot") - } - else { - addJvmSdkRoots(classesRoots) - } - } - } - - } -}