Refactored code in QualifiedExpressionResolver so that WritableScope.import* methods are not used anymore

This commit is contained in:
Valentin Kipyatkov
2015-04-02 21:44:54 +03:00
parent 21083b48ce
commit 0162980ff7
11 changed files with 90 additions and 202 deletions
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.Collection;
@@ -76,21 +75,20 @@ public class QualifiedExpressionResolver {
}
@NotNull
public Collection<DeclarationDescriptor> processImportReference(
public JetScope processImportReference(
@NotNull JetImportDirective importDirective,
@NotNull JetScope scope,
@NotNull JetScope scopeToCheckVisibility,
@Nullable WritableScope importIntoScope,
@NotNull BindingTrace trace,
@NotNull LookupMode lookupMode
) {
if (importDirective.isAbsoluteInRootPackage()) {
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
return Collections.emptyList();
return JetScope.Empty.INSTANCE$;
}
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference == null) {
return Collections.emptyList();
return JetScope.Empty.INSTANCE$;
}
Collection<DeclarationDescriptor> descriptors;
@@ -115,31 +113,19 @@ public class QualifiedExpressionResolver {
}
if (referenceExpression == null || !canImportMembersFrom(descriptors, referenceExpression, trace, lookupMode)) {
return Collections.emptyList();
return JetScope.Empty.INSTANCE$;
}
if (importIntoScope != null) {
AllUnderImportsScope importsScope = new AllUnderImportsScope();
for (DeclarationDescriptor descriptor : descriptors) {
importsScope.addAllUnderImport(descriptor);
}
importIntoScope.importScope(importsScope);
AllUnderImportsScope importsScope = new AllUnderImportsScope();
for (DeclarationDescriptor descriptor : descriptors) {
importsScope.addAllUnderImport(descriptor);
}
return Collections.emptyList();
return importsScope;
}
else {
Name aliasName = JetPsiUtil.getAliasName(importDirective);
if (aliasName == null) {
return Collections.emptyList();
}
if (importIntoScope != null) {
for (DeclarationDescriptor descriptor : descriptors) {
importIntoScope.importAlias(aliasName, descriptor);
}
}
return descriptors;
if (aliasName == null) return JetScope.Empty.INSTANCE$;
return new SingleAliasScope(aliasName, descriptors);
}
}
@@ -0,0 +1,53 @@
/*
* 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
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.utils.Printer
class SingleAliasScope(private val aliasName: Name, private val descriptors: Collection<DeclarationDescriptor>) : JetScope {
override fun getClassifier(name: Name)
= if (name == aliasName) descriptors.filterIsInstance<ClassifierDescriptor>().singleOrNull() else null
override fun getPackage(name: Name)
= if (name == aliasName) descriptors.filterIsInstance<PackageViewDescriptor>().singleOrNull() else null
override fun getProperties(name: Name)
= if (name == aliasName) descriptors.filterIsInstance<VariableDescriptor>() else emptyList()
override fun getFunctions(name: Name)
= if (name == aliasName) descriptors.filterIsInstance<FunctionDescriptor>() else emptyList()
override fun getLocalVariable(name: Name): VariableDescriptor? = null
override fun getContainingDeclaration(): DeclarationDescriptor = throw UnsupportedOperationException()
override fun getDeclarationsByLabel(labelName: Name): Collection<DeclarationDescriptor> = emptyList()
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = emptyList()
override fun getOwnDeclaredDescriptors(): Collection<DeclarationDescriptor> = emptyList()
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getSimpleName())
}
}
@@ -16,26 +16,27 @@
package org.jetbrains.kotlin.resolve.lazy
import com.google.common.collect.ImmutableListMultimap
import com.google.common.collect.ListMultimap
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetImportDirective
import org.jetbrains.kotlin.psi.debugText.*
import org.jetbrains.kotlin.psi.JetPsiUtil
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.JetModuleUtil
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.resolve.PlatformTypesMappedToKotlinChecker
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.LookupMode
import java.util.LinkedHashSet
import java.util.HashSet
import com.google.common.collect.ListMultimap
import kotlin.properties.Delegates
import com.google.common.collect.ImmutableListMultimap
import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameSelector
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil
import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameMultiSelector
import org.jetbrains.kotlin.psi.JetPsiUtil
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameSelector
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.utils.Printer
import java.util.HashSet
import java.util.LinkedHashSet
import kotlin.properties.Delegates
trait IndexedImports {
val imports: List<JetImportDirective>
@@ -72,7 +73,7 @@ class LazyImportResolver(
includeRootPackageClasses: Boolean
) {
private val importedScopesProvider = resolveSession.getStorageManager().createMemoizedFunction {
(directive: JetImportDirective) -> ImportDirectiveResolveCache(directive)
directive: JetImportDirective -> ImportDirectiveResolveCache(directive)
}
private val rootScope = JetModuleUtil.getImportsResolutionScope(resolveSession.getModuleDescriptor(), includeRootPackageClasses)
@@ -96,23 +97,21 @@ class LazyImportResolver(
cachedStatus.scope
}
else {
val directiveImportScope = WritableScopeImpl(JetScope.Empty, packageView, RedeclarationHandler.DO_NOTHING, "Scope for import '" + directive.getDebugText() + "' resolve in " + toString())
directiveImportScope.changeLockLevel(WritableScope.LockLevel.BOTH)
directiveUnderResolve = directive
val directiveImportScope: JetScope
val descriptors: Collection<DeclarationDescriptor>
try {
val resolver = resolveSession.getQualifiedExpressionResolver()
descriptors = resolver.processImportReference(directive, rootScope, packageView.getMemberScope(),
directiveImportScope, traceForImportResolve, mode)
directiveImportScope = resolver.processImportReference(
directive, rootScope, packageView.getMemberScope(), traceForImportResolve, mode)
descriptors = if (directive.isAllUnder()) emptyList() else directiveImportScope.getAllDescriptors()
if (mode == LookupMode.EVERYTHING) {
org.jetbrains.kotlin.resolve.PlatformTypesMappedToKotlinChecker.checkPlatformTypesMappedToKotlin(packageView.getModule(), traceForImportResolve, directive, descriptors)
PlatformTypesMappedToKotlinChecker.checkPlatformTypesMappedToKotlin(packageView.getModule(), traceForImportResolve, directive, descriptors)
}
}
finally {
directiveUnderResolve = null
directiveImportScope.changeLockLevel(WritableScope.LockLevel.READING)
}
importResolveStatus = ImportResolveStatus(mode, directiveImportScope, descriptors)
@@ -43,36 +43,10 @@ public trait WritableScope : JetScope {
public fun addClassifierAlias(name: Name, classifierDescriptor: ClassifierDescriptor)
public fun addPackageAlias(name: Name, packageView: PackageViewDescriptor)
public fun addFunctionAlias(name: Name, functionDescriptor: FunctionDescriptor)
public fun addVariableAlias(name: Name, variableDescriptor: VariableDescriptor)
public fun getDeclaredDescriptorsAccessibleBySimpleName(): Multimap<Name, DeclarationDescriptor>
public fun importScope(imported: JetScope)
public fun setImplicitReceiver(implicitReceiver: ReceiverParameterDescriptor)
public fun importClassifierAlias(importedClassifierName: Name, classifierDescriptor: ClassifierDescriptor)
public fun importPackageAlias(aliasName: Name, packageView: PackageViewDescriptor)
public fun importFunctionAlias(aliasName: Name, functionDescriptor: FunctionDescriptor)
public fun importVariableAlias(aliasName: Name, variableDescriptor: VariableDescriptor)
public fun clearImports()
public fun importAlias(aliasName: Name, descriptor: DeclarationDescriptor) {
when (descriptor) {
is ClassifierDescriptor -> importClassifierAlias(aliasName, descriptor)
is PackageViewDescriptor -> importPackageAlias(aliasName, descriptor)
is FunctionDescriptor -> importFunctionAlias(aliasName, descriptor)
is VariableDescriptor -> importVariableAlias(aliasName, descriptor)
else -> error("Unknown descriptor")
}
}
}
@@ -60,41 +60,6 @@ public class WritableScopeImpl(scope: JetScope,
super.importScope(imported)
}
override fun importClassifierAlias(importedClassifierName: Name, classifierDescriptor: ClassifierDescriptor) {
checkMayWrite()
explicitlyAddedDescriptors.add(classifierDescriptor)
super.importClassifierAlias(importedClassifierName, classifierDescriptor)
}
override fun importPackageAlias(aliasName: Name, packageView: PackageViewDescriptor) {
checkMayWrite()
explicitlyAddedDescriptors.add(packageView)
super.importPackageAlias(aliasName, packageView)
}
override fun importFunctionAlias(aliasName: Name, functionDescriptor: FunctionDescriptor) {
checkMayWrite()
addFunctionDescriptor(functionDescriptor)
super.importFunctionAlias(aliasName, functionDescriptor)
}
override fun importVariableAlias(aliasName: Name, variableDescriptor: VariableDescriptor) {
checkMayWrite()
addPropertyDescriptor(variableDescriptor)
super.importVariableAlias(aliasName, variableDescriptor)
}
override fun clearImports() {
checkMayWrite()
super.clearImports()
}
override fun getDescriptors(kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
checkMayRead()
@@ -253,35 +218,6 @@ public class WritableScopeImpl(scope: JetScope,
addToDeclared(classifierDescriptor)
}
override fun addPackageAlias(name: Name, packageView: PackageViewDescriptor) {
checkMayWrite()
checkForRedeclaration(name, packageView)
getPackageAliases().put(name, packageView)
explicitlyAddedDescriptors.add(packageView)
addToDeclared(packageView)
}
override fun addFunctionAlias(name: Name, functionDescriptor: FunctionDescriptor) {
checkMayWrite()
checkForRedeclaration(name, functionDescriptor)
getFunctionGroups().put(name, functionDescriptor)
explicitlyAddedDescriptors.add(functionDescriptor)
}
override fun addVariableAlias(name: Name, variableDescriptor: VariableDescriptor) {
checkMayWrite()
checkForRedeclaration(name, variableDescriptor)
getVariableOrClassDescriptors().put(name, variableDescriptor)
getPropertyGroups().put(name, variableDescriptor)
explicitlyAddedDescriptors.add(variableDescriptor)
addToDeclared(variableDescriptor)
}
private fun checkForPropertyRedeclaration(name: Name, variableDescriptor: VariableDescriptor) {
val properties = getPropertyGroups()[name]
val receiverParameter = variableDescriptor.getExtensionReceiverParameter()
@@ -55,12 +55,6 @@ public abstract class WritableScopeWithImports(override val workerScope: JetScop
}
}
protected fun checkMayNotWrite() {
if (lockLevel == WritableScope.LockLevel.WRITING || lockLevel == WritableScope.LockLevel.BOTH) {
throw IllegalStateException("cannot write with lock level " + lockLevel + " at " + toString())
}
}
protected fun getImports(): MutableList<JetScope> {
if (imports == null) {
imports = ArrayList<JetScope>()
@@ -160,45 +154,6 @@ public abstract class WritableScopeWithImports(override val workerScope: JetScop
return null
}
private fun getCurrentIndividualImportScope(): WritableScope {
if (currentIndividualImportScope == null) {
val writableScope = WritableScopeImpl(JetScope.Empty, getContainingDeclaration(), RedeclarationHandler.DO_NOTHING, "Individual import scope")
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH)
importScope(writableScope)
currentIndividualImportScope = writableScope
}
return currentIndividualImportScope!!
}
override fun importClassifierAlias(importedClassifierName: Name, classifierDescriptor: ClassifierDescriptor) {
checkMayWrite()
getCurrentIndividualImportScope().addClassifierAlias(importedClassifierName, classifierDescriptor)
}
override fun importPackageAlias(aliasName: Name, packageView: PackageViewDescriptor) {
checkMayWrite()
getCurrentIndividualImportScope().addPackageAlias(aliasName, packageView)
}
override fun importFunctionAlias(aliasName: Name, functionDescriptor: FunctionDescriptor) {
checkMayWrite()
getCurrentIndividualImportScope().addFunctionAlias(aliasName, functionDescriptor)
}
override fun importVariableAlias(aliasName: Name, variableDescriptor: VariableDescriptor) {
checkMayWrite()
getCurrentIndividualImportScope().addVariableAlias(aliasName, variableDescriptor)
}
override fun clearImports() {
currentIndividualImportScope = null
getImports().clear()
}
override fun toString(): String {
return javaClass.getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration()
}
@@ -130,24 +130,6 @@ public class WriteThroughScope(outerScope: JetScope, private val writableWorker:
writableWorker.addClassifierAlias(name, classifierDescriptor)
}
override fun addPackageAlias(name: Name, packageView: PackageViewDescriptor) {
checkMayWrite()
writableWorker.addPackageAlias(name, packageView)
}
override fun addVariableAlias(name: Name, variableDescriptor: VariableDescriptor) {
checkMayWrite()
writableWorker.addVariableAlias(name, variableDescriptor)
}
override fun addFunctionAlias(name: Name, functionDescriptor: FunctionDescriptor) {
checkMayWrite()
writableWorker.addFunctionAlias(name, functionDescriptor)
}
override fun getDeclaredDescriptorsAccessibleBySimpleName(): Multimap<Name, DeclarationDescriptor> {
return writableWorker.getDeclaredDescriptorsAccessibleBySimpleName()
}
@@ -202,6 +202,6 @@ public class KotlinIndicesHelper(
private fun analyzeImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
return QualifiedExpressionResolver().processImportReference(importDirective, scope, scope, null, BindingTraceContext(), LookupMode.EVERYTHING)
return QualifiedExpressionResolver().processImportReference(importDirective, scope, scope, BindingTraceContext(), LookupMode.EVERYTHING).getAllDescriptors()
}
}
@@ -287,7 +287,8 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
val moduleDescriptor = file.getResolutionFacade().findModuleDescriptor(file)
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
val descriptors = QualifiedExpressionResolver()
.processImportReference(importDirective, scope, scope, null, BindingTraceContext(), LookupMode.EVERYTHING)
.processImportReference(importDirective, scope, scope, BindingTraceContext(), LookupMode.EVERYTHING)
.getAllDescriptors()
.filterIsInstance<CallableDescriptor>()
return descriptors.singleOrNull()
}
@@ -46,7 +46,8 @@ public abstract class AbstractAddImportTest : AbstractImportsTest() {
val moduleDescriptor = file.getResolutionFacade().findModuleDescriptor(file)
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
val descriptors = QualifiedExpressionResolver()
.processImportReference(importDirective, scope, scope, null, BindingTraceContext(), LookupMode.EVERYTHING)
.processImportReference(importDirective, scope, scope, BindingTraceContext(), LookupMode.EVERYTHING)
.getAllDescriptors()
.filter(filter)
when {
@@ -63,7 +63,8 @@ public abstract class AbstractCodeFragmentHighlightingTest : AbstractJetPsiCheck
val moduleDescriptor = file.getResolutionFacade().findModuleDescriptor(file)
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
val descriptor = QualifiedExpressionResolver()
.processImportReference(importDirective, scope, scope, null, BindingTraceContext(), LookupMode.EVERYTHING)
.processImportReference(importDirective, scope, scope, BindingTraceContext(), LookupMode.EVERYTHING)
.getAllDescriptors()
.singleOrNull() ?: error("Could not resolve descriptor to import: $it")
ImportInsertHelper.getInstance(getProject()).importDescriptor(file, descriptor)
}