Introduce experimental -Xuse-javac compilation mode

In this mode, javac AST and Symbol files are used during
Kotlin compilation instead of PSI / binary stuff.
Later, they are reused for Java file compilation.
javac in this mode is integrated into kotlinc.
This commit is contained in:
baratynskiy
2017-04-05 13:11:26 +03:00
committed by Mikhail Glukhikh
parent c9a04fe1e2
commit 5eea3b6569
217 changed files with 6537 additions and 565 deletions
+1
View File
@@ -11,5 +11,6 @@
<orderEntry type="library" scope="PROVIDED" name="intellij-core" level="project" />
<orderEntry type="module" module-name="descriptor.loader.java" exported="" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="javac-wrapper" />
</component>
</module>
@@ -113,4 +113,8 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<Boolean> USE_FAST_CLASS_FILES_READING =
CompilerConfigurationKey.create("use fast class files reading implementation [experimental]");
public static final CompilerConfigurationKey<Boolean> USE_JAVAC =
CompilerConfigurationKey.create("use javac");
}
@@ -19,6 +19,9 @@ package org.jetbrains.kotlin.frontend.java.di
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.builtins.JvmBuiltInsPackageFragmentProvider
import org.jetbrains.kotlin.javac.components.JavacBasedClassFinder
import org.jetbrains.kotlin.javac.components.StubJavaResolverCache
import org.jetbrains.kotlin.javac.components.JavacBasedSourceElementFactory
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -48,7 +51,8 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
private fun StorageComponentContainer.configureJavaTopDownAnalysis(
moduleContentScope: GlobalSearchScope,
project: Project,
lookupTracker: LookupTracker
lookupTracker: LookupTracker,
useJavac: Boolean
) {
useInstance(moduleContentScope)
useInstance(lookupTracker)
@@ -60,17 +64,23 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis(
useInstance(VirtualFileFinderFactory.getInstance(project).create(moduleContentScope))
useImpl<AnnotationResolverImpl>()
if (useJavac) {
useImpl<JavacBasedClassFinder>()
useImpl<StubJavaResolverCache>()
useImpl<JavacBasedSourceElementFactory>()
} else {
useImpl<JavaClassFinderImpl>()
useImpl<LazyResolveBasedCache>()
useImpl<JavaSourceElementFactoryImpl>()
}
useImpl<JavaClassFinderImpl>()
useImpl<JavaPropertyInitializerEvaluatorImpl>()
useImpl<AnnotationResolverImpl>()
useImpl<SignaturePropagatorImpl>()
useImpl<LazyResolveBasedCache>()
useImpl<TraceBasedErrorReporter>()
useImpl<PsiBasedExternalAnnotationResolver>()
useImpl<JavaPropertyInitializerEvaluatorImpl>()
useInstance(SamWithReceiverResolver())
useImpl<SamConversionResolverImpl>()
useImpl<JavaSourceElementFactoryImpl>()
useInstance(InternalFlexibleTypeTransformer)
useImpl<CompilerDeserializationConfiguration>()
@@ -88,10 +98,11 @@ fun createContainerForLazyResolveWithJava(
jvmTarget: JvmTarget,
languageVersionSettings: LanguageVersionSettings,
useBuiltInsProvider: Boolean,
useLazyResolve: Boolean
useLazyResolve: Boolean,
useJavac: Boolean = false
): StorageComponentContainer = createContainer("LazyResolveWithJava", JvmPlatform) {
configureModule(moduleContext, JvmPlatform, jvmTarget, bindingTrace)
configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker)
configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker, useJavac)
useInstance(packagePartProvider)
useInstance(moduleClassResolver)
@@ -110,7 +121,10 @@ fun createContainerForLazyResolveWithJava(
useImpl<LazyResolveToken>()
}
}.apply {
get<JavaClassFinderImpl>().initialize(bindingTrace, get<KotlinCodeAnalyzer>())
if (useJavac)
get<JavacBasedClassFinder>().initialize(bindingTrace, get<KotlinCodeAnalyzer>())
else
get<JavaClassFinderImpl>().initialize(bindingTrace, get<KotlinCodeAnalyzer>())
}
@@ -123,11 +137,12 @@ fun createContainerForTopDownAnalyzerForJvm(
packagePartProvider: PackagePartProvider,
moduleClassResolver: ModuleClassResolver,
jvmTarget: JvmTarget,
languageVersionSettings: LanguageVersionSettings
languageVersionSettings: LanguageVersionSettings,
useJavac: Boolean = false
): ComponentProvider = createContainerForLazyResolveWithJava(
moduleContext, bindingTrace, declarationProviderFactory, moduleContentScope, moduleClassResolver,
CompilerEnvironment, lookupTracker, packagePartProvider, jvmTarget, languageVersionSettings,
useBuiltInsProvider = true, useLazyResolve = false
useBuiltInsProvider = true, useLazyResolve = false, useJavac = useJavac
)
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.frontend.java.di.createContainerForTopDownAnalyzerFo
import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
import org.jetbrains.kotlin.frontend.java.di.initialize
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.javac.MockKotlinClassifier
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
@@ -61,6 +62,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.javac.wrappers.trees.TreeBasedClass
import java.util.*
object TopDownAnalyzerFacadeForJVM {
@@ -143,6 +145,8 @@ object TopDownAnalyzerFacadeForJVM {
}
else null
val useJavac = configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC)
val dependencyModule = if (separateModules) {
val dependenciesContext = ContextForNewModule(
moduleContext, Name.special("<dependencies of ${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"),
@@ -154,7 +158,7 @@ object TopDownAnalyzerFacadeForJVM {
val dependenciesContainer = createContainerForTopDownAnalyzerForJvm(
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker,
packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings
packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings, useJavac
)
StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(dependenciesContainer, null) }
@@ -181,7 +185,7 @@ object TopDownAnalyzerFacadeForJVM {
// TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport
val container = createContainerForTopDownAnalyzerForJvm(
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker,
partProvider, moduleClassResolver, jvmTarget, languageVersionSettings
partProvider, moduleClassResolver, jvmTarget, languageVersionSettings, useJavac
).apply {
initJvmBuiltInsForTopDownAnalysis()
(partProvider as? IncrementalPackagePartProvider)?.deserializationConfiguration = get<DeserializationConfiguration>()
@@ -243,7 +247,8 @@ object TopDownAnalyzerFacadeForJVM {
lateinit var sourceCodeResolver: JavaDescriptorResolver
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
val resolver = if (javaClass is JavaClassImpl && javaClass.psi.containingFile.virtualFile in sourceScope)
val resolver = if (javaClass is JavaClassImpl && javaClass.psi.containingFile.virtualFile in sourceScope
|| javaClass is TreeBasedClass || javaClass is MockKotlinClassifier)
sourceCodeResolver
else
compiledCodeResolver