Introduce LocalDescriptorResolver which handles differences in local declaration resolution between compiler and ide environments

This commit is contained in:
Pavel V. Talanov
2015-07-24 18:56:06 +03:00
parent 2ef5e03f27
commit 52bc84cb5f
13 changed files with 149 additions and 25 deletions
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
@@ -88,7 +89,8 @@ public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
val resolver = JvmAnalyzerFacade.setupResolverForProject(
ProjectContext(environment.project), listOf(builtInModule),
{ ModuleContent(files, GlobalSearchScope.EMPTY_SCOPE) },
platformParameters = JvmPlatformParameters { throw IllegalStateException() }
JvmPlatformParameters { throw IllegalStateException() },
CompilerEnvironment
)
val moduleDescriptor = resolver.descriptorForModule(builtInModule)
@@ -69,7 +69,7 @@ public fun StorageComponentContainer.configureJavaTopDownAnalysis(moduleContentS
public fun createContainerForLazyResolveWithJava(
moduleContext: ModuleContext, bindingTrace: BindingTrace, declarationProviderFactory: DeclarationProviderFactory,
moduleContentScope: GlobalSearchScope, moduleClassResolver: ModuleClassResolver
moduleContentScope: GlobalSearchScope, moduleClassResolver: ModuleClassResolver, targetEnvironment: TargetEnvironment = CompilerEnvironment
): Pair<ResolveSession, JavaDescriptorResolver> = createContainer("LazyResolveWithJava") {
configureModule(moduleContext, JvmPlatform, bindingTrace)
configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, LookupTracker.DO_NOTHING)
@@ -78,7 +78,7 @@ public fun createContainerForLazyResolveWithJava(
useInstance(declarationProviderFactory)
CompilerEnvironment.configure(this)
targetEnvironment.configure(this)
useImpl<FileScopeProviderImpl>()
useImpl<LazyResolveToken>()
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import java.util.ArrayList
@@ -52,7 +53,9 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmResolverForModule, JvmPlatfo
moduleDescriptor: ModuleDescriptorImpl,
moduleContext: ModuleContext,
moduleContent: ModuleContent,
platformParameters: JvmPlatformParameters, resolverForProject: ResolverForProject<M, JvmResolverForModule>
platformParameters: JvmPlatformParameters,
targetEnvironment: TargetEnvironment,
resolverForProject: ResolverForProject<M, JvmResolverForModule>
): JvmResolverForModule {
val (syntheticFiles, moduleContentScope) = moduleContent
val project = moduleContext.project
@@ -71,7 +74,8 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmResolverForModule, JvmPlatfo
CodeAnalyzerInitializer.getInstance(project).createTrace(),
declarationProviderFactory,
moduleContentScope,
moduleClassResolver
moduleClassResolver,
targetEnvironment
)
val providersForModule = listOf(resolveSession.getPackageFragmentProvider(), javaDescriptorResolver.packageFragmentProvider)
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import java.util.ArrayList
import java.util.HashMap
@@ -126,6 +127,7 @@ public interface AnalyzerFacade<A : ResolverForModule, in P : PlatformAnalysisPa
modules: Collection<M>,
modulesContent: (M) -> ModuleContent,
platformParameters: P,
targetEnvironment: TargetEnvironment,
delegateResolver: ResolverForProject<M, A> = EmptyResolverForProject()
): ResolverForProject<M, A> {
@@ -181,8 +183,8 @@ public interface AnalyzerFacade<A : ResolverForModule, in P : PlatformAnalysisPa
val descriptor = resolverForProject.descriptorForModule(module)
val computeResolverForModule = storageManager.createLazyValue {
createResolverForModule(
module, descriptor, projectContext.withModule(descriptor),
modulesContent(module), platformParameters, resolverForProject
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
platformParameters, targetEnvironment, resolverForProject
)
}
@@ -200,7 +202,9 @@ public interface AnalyzerFacade<A : ResolverForModule, in P : PlatformAnalysisPa
moduleDescriptor: ModuleDescriptorImpl,
moduleContext: ModuleContext,
moduleContent: ModuleContent,
platformParameters: P, resolverForProject: ResolverForProject<M, A>
platformParameters: P,
targetEnvironment: TargetEnvironment,
resolverForProject: ResolverForProject<M, A>
): A
public val moduleParameters: ModuleParameters
@@ -61,7 +61,7 @@ public fun createContainerForBodyResolve(
useInstance(statementFilter)
CompilerEnvironment.configure(this)
useInstance(BodyResolveCache.ThrowException)
useImpl<BodyResolver>()
}
@@ -105,21 +105,28 @@ private fun createContainerForLazyResolve(
moduleContext: ModuleContext,
declarationProviderFactory: DeclarationProviderFactory,
bindingTrace: BindingTrace,
platform: TargetPlatform
platform: TargetPlatform,
targetEnvironment: TargetEnvironment
): StorageComponentContainer = createContainer("LazyResolve") {
configureModule(moduleContext, platform, bindingTrace)
useInstance(declarationProviderFactory)
useInstance(LookupTracker.DO_NOTHING)
targetEnvironment.configure(this)
useImpl<LazyResolveToken>()
useImpl<ResolveSession>()
}
jvmOverloads
public fun createLazyResolveSession(
moduleContext: ModuleContext, declarationProviderFactory: DeclarationProviderFactory, bindingTrace: BindingTrace,
platform: TargetPlatform
): ResolveSession = createContainerForLazyResolve(moduleContext, declarationProviderFactory, bindingTrace, platform).get<ResolveSession>()
moduleContext: ModuleContext,
declarationProviderFactory: DeclarationProviderFactory,
bindingTrace: BindingTrace,
platform: TargetPlatform,
targetEnvironment: TargetEnvironment = CompilerEnvironment
): ResolveSession = createContainerForLazyResolve(moduleContext, declarationProviderFactory, bindingTrace, platform, targetEnvironment).get<ResolveSession>()
public fun createContainerForMacros(project: Project, module: ModuleDescriptor): ContainerForMacros {
val componentContainer = createContainer("Macros") {
@@ -19,9 +19,11 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.resolve.lazy.LocalDescriptorResolverForCompiler
public object CompilerEnvironment : TargetEnvironment("Compiler") {
override fun configure(container: StorageComponentContainer) {
container.useInstance(BodyResolveCache.ThrowException)
container.useImpl<LocalDescriptorResolverForCompiler>()
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2015 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.resolve.lazy
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.JetDeclaration
import org.jetbrains.kotlin.psi.JetPsiUtil
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
public interface LocalDescriptorResolver {
fun resolveLocalDeclaration(declaration: JetDeclaration): DeclarationDescriptor
}
public class LocalDescriptorResolverForCompiler(
private val lazyDeclarationResolver: LazyDeclarationResolver
) : LocalDescriptorResolver {
override fun resolveLocalDeclaration(declaration: JetDeclaration): DeclarationDescriptor {
return lazyDeclarationResolver.resolveToDescriptor(declaration)
}
}
@@ -77,6 +77,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
private FileScopeProvider fileScopeProvider;
private DeclarationScopeProvider declarationScopeProvider;
private LookupTracker lookupTracker;
private LocalDescriptorResolver localDescriptorResolver;
@Inject
public void setJetImportFactory(JetImportsFactory jetImportFactory) {
@@ -321,7 +322,10 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
@Override
@NotNull
public DeclarationDescriptor resolveToDescriptor(@NotNull JetDeclaration declaration) {
return lazyDeclarationResolver.resolveToDescriptor(declaration);
if (!JetPsiUtil.isLocal(declaration)) {
return lazyDeclarationResolver.resolveToDescriptor(declaration);
}
return localDescriptorResolver.resolveLocalDeclaration(declaration);
}
@NotNull
@@ -414,4 +418,9 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
public LookupTracker getLookupTracker() {
return lookupTracker;
}
@Inject
public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) {
this.localDescriptorResolver = localDescriptorResolver;
}
}
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.framework.KotlinJavaScriptLibraryDetectionUtil
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
@@ -48,7 +49,9 @@ public object JsAnalyzerFacade : AnalyzerFacade<JsResolverForModule, PlatformAna
moduleDescriptor: ModuleDescriptorImpl,
moduleContext: ModuleContext,
moduleContent: ModuleContent,
platformParameters: PlatformAnalysisParameters, resolverForProject: ResolverForProject<M, JsResolverForModule>
platformParameters: PlatformAnalysisParameters,
targetEnvironment: TargetEnvironment,
resolverForProject: ResolverForProject<M, JsResolverForModule>
): JsResolverForModule {
val (syntheticFiles, moduleContentScope) = moduleContent
val project = moduleContext.project
@@ -56,7 +59,7 @@ public object JsAnalyzerFacade : AnalyzerFacade<JsResolverForModule, PlatformAna
project, moduleContext.storageManager, syntheticFiles, if (moduleInfo.isLibrary) GlobalSearchScope.EMPTY_SCOPE else moduleContentScope
)
val resolveSession = createLazyResolveSession(moduleContext, declarationProviderFactory, BindingTraceContext(), JsPlatform)
val resolveSession = createLazyResolveSession(moduleContext, declarationProviderFactory, BindingTraceContext(), JsPlatform, targetEnvironment)
var packageFragmentProvider = resolveSession.getPackageFragmentProvider()
if (moduleInfo is LibraryInfo && KotlinJavaScriptLibraryDetectionUtil.isKotlinJavaScriptLibrary(moduleInfo.library)) {
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analyzer.*
import org.jetbrains.kotlin.context.GlobalContextImpl
import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.project.IdeEnvironment
import org.jetbrains.kotlin.idea.project.ResolveSessionForBodies
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
@@ -63,7 +64,7 @@ fun createModuleResolverProvider(
val resolverForProject = analyzerFacade.setupResolverForProject(
globalContext.withProject(project), modulesToCreateResolversFor, modulesContent,
jvmPlatformParameters, delegateProvider.resolverForProject
jvmPlatformParameters, IdeEnvironment, delegateProvider.resolverForProject
)
return resolverForProject
}
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.project
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.resolve.TargetEnvironment
public object IdeEnvironment : TargetEnvironment("Ide") {
override fun configure(container: StorageComponentContainer) {
container.useImpl<LocalDescriptorResolverForIde>()
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.project
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.JetDeclaration
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.LocalDescriptorResolver
public class LocalDescriptorResolverForIde(
private val resolveElementCache: ResolveElementCache
): LocalDescriptorResolver {
override fun resolveLocalDeclaration(declaration: JetDeclaration): DeclarationDescriptor {
val context = resolveElementCache.resolveToElement(declaration, BodyResolveMode.FULL)
return BindingContextUtils.getNotNull(
context, BindingContext.DECLARATION_TO_DESCRIPTOR, declaration,
"Descriptor wasn't found for declaration $declaration\n${declaration.getElementTextWithContext()}"
)
}
}
@@ -76,14 +76,7 @@ public class ResolveSessionForBodies implements KotlinCodeAnalyzer {
@NotNull
@Override
public DeclarationDescriptor resolveToDescriptor(@NotNull JetDeclaration declaration) {
if (!JetPsiUtil.isLocal(declaration)) {
return resolveSession.resolveToDescriptor(declaration);
}
BindingContext context = resolveElementCache.resolveToElement(declaration, BodyResolveMode.FULL);
return BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, declaration,
"Descriptor wasn't found for declaration " + declaration.toString() + "\n" +
PsiUtilPackage.getElementTextWithContext(declaration));
return resolveSession.resolveToDescriptor(declaration);
}
@Override