From fcb094cd9043d192159aeba409145702a3770cb4 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 9 Nov 2016 15:26:41 +0300 Subject: [PATCH] Introduce DefaultAnalyzerFacade, use it to analyze built-ins --- .../builtins/BuiltInsSerializer.kt | 31 ++--- .../analyzer/common/DefaultAnalyzerFacade.kt | 129 ++++++++++++++++++ 2 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt diff --git a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt index d5a315239ad..928a4830d3c 100644 --- a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt +++ b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt @@ -18,26 +18,23 @@ package org.jetbrains.kotlin.serialization.builtins import com.intellij.openapi.Disposable import com.intellij.openapi.util.Disposer -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.analyzer.ModuleContent -import org.jetbrains.kotlin.analyzer.ModuleInfo +import org.jetbrains.kotlin.analyzer.AnalysisResult +import org.jetbrains.kotlin.analyzer.common.DefaultAnalyzerFacade import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.builtins.BuiltInsBinaryVersion import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.addKotlinSourceRoots -import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageViewDescriptor import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade -import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.DescriptorSerializer @@ -65,13 +62,6 @@ class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) { } } - private inner class BuiltInsSourcesModule : ModuleInfo { - override val name = Name.special("") - override fun dependencies() = listOf(this) - override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns = - if (dependOnOldBuiltIns) ModuleInfo.DependenciesOnBuiltIns.LAST else ModuleInfo.DependenciesOnBuiltIns.NONE - } - private fun serialize(disposable: Disposable, destDir: File, srcDirs: List, extraClassPath: List) { val configuration = CompilerConfiguration() configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) @@ -83,15 +73,14 @@ class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) { val files = environment.getSourceFiles() - val builtInModule = BuiltInsSourcesModule() - val resolver = JvmAnalyzerFacade.setupResolverForProject( - "builtIns source", - ProjectContext(environment.project), listOf(builtInModule), - { ModuleContent(files, GlobalSearchScope.EMPTY_SCOPE) }, - JvmPlatformParameters { throw IllegalStateException() } - ) + val analyzer = AnalyzerWithCompilerReport(MessageCollector.NONE) + analyzer.analyzeAndReport(files, object : AnalyzerWithCompilerReport.Analyzer { + override fun analyze(): AnalysisResult = DefaultAnalyzerFacade.analyzeFiles( + files, Name.special(""), dependOnOldBuiltIns + ) + }) - val moduleDescriptor = resolver.descriptorForModule(builtInModule) + val moduleDescriptor = analyzer.analysisResult.moduleDescriptor destDir.deleteRecursively() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt new file mode 100644 index 00000000000..d4cd2e518e6 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt @@ -0,0 +1,129 @@ +/* + * Copyright 2010-2016 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.analyzer.common + +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analyzer.* +import org.jetbrains.kotlin.config.ApiVersion +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl +import org.jetbrains.kotlin.container.StorageComponentContainer +import org.jetbrains.kotlin.container.get +import org.jetbrains.kotlin.container.useImpl +import org.jetbrains.kotlin.container.useInstance +import org.jetbrains.kotlin.context.LazyResolveToken +import org.jetbrains.kotlin.context.ModuleContext +import org.jetbrains.kotlin.context.ProjectContext +import org.jetbrains.kotlin.descriptors.PackagePartProvider +import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.frontend.di.configureModule +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.lazy.FileScopeProviderImpl +import org.jetbrains.kotlin.resolve.lazy.ResolveSession +import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory +import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService + +/** + * A facade that is used to analyze platform independent modules in multi-platform projects. + * See [TargetPlatform.Default] + */ +object DefaultAnalyzerFacade : AnalyzerFacade() { + private val languageVersionSettings = LanguageVersionSettingsImpl( + LanguageVersion.LATEST, ApiVersion.LATEST, setOf(LanguageFeature.MultiPlatformProjects) + ) + + private class SourceModuleInfo(override val name: Name, private val dependOnOldBuiltIns: Boolean) : ModuleInfo { + override fun dependencies() = listOf(this) + + override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns = + if (dependOnOldBuiltIns) ModuleInfo.DependenciesOnBuiltIns.LAST else ModuleInfo.DependenciesOnBuiltIns.NONE + } + + fun analyzeFiles(files: Collection, moduleName: Name, dependOnBuiltIns: Boolean): AnalysisResult { + val moduleInfo = SourceModuleInfo(moduleName, dependOnBuiltIns) + val project = files.firstOrNull()?.project ?: throw AssertionError("No files to analyze") + val resolver = setupResolverForProject( + "sources for metadata serializer", + ProjectContext(project), listOf(moduleInfo), + { ModuleContent(files, GlobalSearchScope.EMPTY_SCOPE) }, + object : PlatformAnalysisParameters {} + ) + + val moduleDescriptor = resolver.descriptorForModule(moduleInfo) + val container = resolver.resolverForModule(moduleInfo).componentProvider + + container.get().analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files) + + return AnalysisResult.success(container.get().bindingContext, moduleDescriptor) + } + + override fun createResolverForModule( + moduleInfo: M, + moduleDescriptor: ModuleDescriptorImpl, + moduleContext: ModuleContext, + moduleContent: ModuleContent, + platformParameters: PlatformAnalysisParameters, + targetEnvironment: TargetEnvironment, + resolverForProject: ResolverForProject, + packagePartProvider: PackagePartProvider + ): ResolverForModule { + val (syntheticFiles, moduleContentScope) = moduleContent + val project = moduleContext.project + val declarationProviderFactory = DeclarationProviderFactoryService.createDeclarationProviderFactory( + project, moduleContext.storageManager, syntheticFiles, + if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope + ) + + val trace = CodeAnalyzerInitializer.getInstance(project).createTrace() + val container = createContainerToResolveCommonCode( + moduleContext, trace, declarationProviderFactory, moduleContentScope, targetEnvironment, packagePartProvider + ) + + return ResolverForModule(container.get().packageFragmentProvider, container) + } + + private fun createContainerToResolveCommonCode( + moduleContext: ModuleContext, + bindingTrace: BindingTrace, + declarationProviderFactory: DeclarationProviderFactory, + moduleContentScope: GlobalSearchScope, + targetEnvironment: TargetEnvironment, + packagePartProvider: PackagePartProvider + ): StorageComponentContainer = createContainer("ResolveCommonCode", targetPlatform) { + configureModule(moduleContext, targetPlatform, bindingTrace) + + useInstance(moduleContentScope) + useInstance(LookupTracker.DO_NOTHING) + useImpl() + useImpl() + useImpl() + useInstance(languageVersionSettings) + useImpl() + useInstance(packagePartProvider) + useInstance(declarationProviderFactory) + + targetEnvironment.configure(this) + useImpl() + } + + override val targetPlatform: TargetPlatform + get() = TargetPlatform.Default +}