Less conversion between KtScope and ImportingScope

This commit is contained in:
Valentin Kipyatkov
2015-10-24 12:17:32 +03:00
parent 3471667aa0
commit 99aeb305db
9 changed files with 77 additions and 89 deletions
@@ -16,15 +16,17 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.Printer
class AllUnderImportsScope(descriptor: DeclarationDescriptor) : KtScope {
class AllUnderImportsScope(descriptor: DeclarationDescriptor) : ImportingScope by ImportingScope.Empty {
private val scopes = if (descriptor is ClassDescriptor) {
listOf(descriptor.staticScope, descriptor.unsubstitutedInnerClassesScope)
}
@@ -35,52 +37,32 @@ class AllUnderImportsScope(descriptor: DeclarationDescriptor) : KtScope {
listOf(NoSubpackagesInPackageScope(descriptor as PackageViewDescriptor))
}
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
return scopes.flatMap { it.getDescriptors(kindFilter, nameFilter) }
}
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
= scopes.flatMap { it.getDescriptors(kindFilter, nameFilter) }
override fun getClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
return scopes.asSequence().map { it.getClassifier(name, location) }.filterNotNull().singleOrNull()
}
override fun getDeclaredClassifier(name: Name, location: LookupLocation)
= scopes.asSequence().map { it.getClassifier(name, location) }.filterNotNull().singleOrNull()
override fun getProperties(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
return scopes.flatMap { it.getProperties(name, location) }
}
override fun getDeclaredVariables(name: Name, location: LookupLocation)
= scopes.flatMap { it.getProperties(name, location) }
override fun getFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
return scopes.flatMap { it.getFunctions(name, location) }
}
override fun getDeclaredFunctions(name: Name, location: LookupLocation)
= scopes.flatMap { it.getFunctions(name, location) }
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
return scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, name, location) }
}
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation)
= scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, name, location) }
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
return scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes, name, location) }
}
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation)
= scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes, name, location) }
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> {
return scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes) }
}
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>)
= scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes) }
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> {
return scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes) }
}
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>)
= scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes) }
override fun getPackage(name: Name): PackageViewDescriptor? = null // packages are not imported by all under imports
override fun getLocalVariable(name: Name): VariableDescriptor? = null
override fun getContainingDeclaration(): DeclarationDescriptor = throw UnsupportedOperationException()
override fun getDeclarationsByLabel(labelName: Name): Collection<DeclarationDescriptor> = listOf()
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = listOf()
override fun getOwnDeclaredDescriptors(): Collection<DeclarationDescriptor> = listOf()
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getSimpleName())
override fun printStructure(p: Printer) {
p.println(javaClass.simpleName)
}
}
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -118,7 +118,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
moduleDescriptor: ModuleDescriptor,
trace: BindingTrace,
packageFragmentForVisibilityCheck: PackageFragmentDescriptor?
): KtScope? { // null if some error happened
): ImportingScope? { // null if some error happened
val importedReference = importDirective.importedReference ?: return null
val path = importedReference.asQualifierPartList(trace)
val lastPart = path.lastOrNull() ?: return null
@@ -17,30 +17,29 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.KtScopeImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.utils.Printer
class SingleImportScope(private val aliasName: Name, private val descriptors: Collection<DeclarationDescriptor>) : KtScopeImpl() {
override fun getClassifier(name: Name, location: LookupLocation)
class SingleImportScope(private val aliasName: Name, private val descriptors: Collection<DeclarationDescriptor>) : ImportingScope by ImportingScope.Empty {
override fun getDeclaredClassifier(name: Name, location: LookupLocation)
= 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, location: LookupLocation)
override fun getDeclaredVariables(name: Name, location: LookupLocation)
= if (name == aliasName) descriptors.filterIsInstance<VariableDescriptor>() else emptyList()
override fun getFunctions(name: Name, location: LookupLocation)
override fun getDeclaredFunctions(name: Name, location: LookupLocation)
= if (name == aliasName) descriptors.filterIsInstance<FunctionDescriptor>() else emptyList()
override fun getContainingDeclaration(): DeclarationDescriptor = throw UnsupportedOperationException()
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
= descriptors
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
override fun printScopeStructure(p: Printer) {
p.println(javaClass.getSimpleName(), ": ", aliasName)
override fun printStructure(p: Printer) {
p.println(javaClass.simpleName, ": ", aliasName)
}
}
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.PlatformTypesMappedToKotlinChecker
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.KotlinType
@@ -87,7 +86,7 @@ class LazyImportResolver(
if (!directive.isAllUnder) {
PlatformTypesMappedToKotlinChecker.checkPlatformTypesMappedToKotlin(
moduleDescriptor, traceForImportResolve, directive, directiveImportScope.getAllDescriptors())
moduleDescriptor, traceForImportResolve, directive, directiveImportScope.getDescriptors())
}
directiveImportScope
@@ -101,7 +100,7 @@ class LazyImportResolver(
val alias = KtPsiUtil.getAliasName(importDirective)?.identifier
if (scope != null && alias != null) {
if (scope.getClassifier(Name.identifier(alias), KotlinLookupLocation(importDirective)) != null) {
if (scope.getDeclaredClassifier(Name.identifier(alias), KotlinLookupLocation(importDirective)) != null) {
explicitClassImports.put(alias, importDirective)
}
}
@@ -127,7 +126,7 @@ class LazyImportResolver(
public fun <D : DeclarationDescriptor> selectSingleFromImports(
name: Name,
descriptorSelector: (KtScope, Name) -> D?
descriptorSelector: (ImportingScope, Name) -> D?
): D? {
fun compute(): D? {
val imports = indexedImports.importsForName(name)
@@ -145,7 +144,7 @@ class LazyImportResolver(
public fun <D : DeclarationDescriptor> collectFromImports(
name: Name,
descriptorsSelector: (KtScope, Name) -> Collection<D>
descriptorsSelector: (ImportingScope, Name) -> Collection<D>
): Collection<D> {
return storageManager.compute {
var descriptors: Collection<D>? = null
@@ -158,8 +157,8 @@ class LazyImportResolver(
}
}
public fun getImportScope(directive: KtImportDirective): KtScope {
return importedScopesProvider(directive) ?: KtScope.Empty
public fun getImportScope(directive: KtImportDirective): ImportingScope {
return importedScopesProvider(directive) ?: ImportingScope.Empty
}
}
@@ -187,7 +186,7 @@ class LazyImportScope(
override fun getDeclaredClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
return importResolver.selectSingleFromImports(name) { scope, name ->
val descriptor = scope.getClassifier(name, location)
val descriptor = scope.getDeclaredClassifier(name, location)
if (descriptor != null && isClassVisible(descriptor as ClassDescriptor/*no type parameter can be imported*/)) descriptor else null
}
}
@@ -199,12 +198,12 @@ class LazyImportScope(
override fun getDeclaredVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> {
if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf()
return importResolver.collectFromImports(name) { scope, name -> scope.getProperties(name, location) }
return importResolver.collectFromImports(name) { scope, name -> scope.getDeclaredVariables(name, location) }
}
override fun getDeclaredFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf()
return importResolver.collectFromImports(name) { scope, name -> scope.getFunctions(name, location) }
return importResolver.collectFromImports(name) { scope, name -> scope.getDeclaredFunctions(name, location) }
}
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
@@ -273,15 +273,26 @@ inline fun <T: Any> LexicalScope.findFirstFromImportingScopes(fetch: (ImportingS
return findFirstFromMeAndParent { if (it is ImportingScope) fetch(it) else null }
}
fun LexicalScope.addImportScope(importScope: KtScope): LexicalScope {
fun LexicalScope.addImportScopes(importScopes: Collection<ImportingScope>): LexicalScope {
return importScopes.fold(this) { scope, importingScope -> scope.addImportScope(importingScope) }
}
fun LexicalScope.addImportScope(importScope: ImportingScope): LexicalScope {
assert(importScope.parent == null)
if (this is ImportingScope) {
return importScope.memberScopeAsImportingScope(this)
return importScope.withParent(this)
}
else {
val lastNonImporting = parentsWithSelf.last { it !is ImportingScope }
val firstImporting = lastNonImporting.parent as ImportingScope?
val newImportingScope = importScope.memberScopeAsImportingScope(firstImporting)
return LexicalScopeWrapper(this, newImportingScope)
return LexicalScopeWrapper(this, importScope.withParent(firstImporting))
}
}
fun ImportingScope.withParent(newParent: ImportingScope?): ImportingScope {
return object: ImportingScope by this {
override val parent: ImportingScope?
get() = newParent
}
}
@@ -22,20 +22,23 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
public class ExplicitImportsScope(private val descriptors: Collection<DeclarationDescriptor>) : KtScopeImpl() {
override fun getClassifier(name: Name, location: LookupLocation) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
public class ExplicitImportsScope(private val descriptors: Collection<DeclarationDescriptor>) : ImportingScope by ImportingScope.Empty {
override fun getDeclaredClassifier(name: Name, location: LookupLocation)
= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<ClassifierDescriptor>()
override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getPackage(name: Name)
= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull<PackageViewDescriptor>()
override fun getProperties(name: Name, location: LookupLocation) = descriptors.filter { it.getName() == name }.filterIsInstance<VariableDescriptor>()
override fun getDeclaredVariables(name: Name, location: LookupLocation)
= descriptors.filter { it.getName() == name }.filterIsInstance<VariableDescriptor>()
override fun getFunctions(name: Name, location: LookupLocation) = descriptors.filter { it.getName() == name }.filterIsInstance<FunctionDescriptor>()
override fun getDeclaredFunctions(name: Name, location: LookupLocation)
= descriptors.filter { it.getName() == name }.filterIsInstance<FunctionDescriptor>()
override fun getContainingDeclaration() = throw UnsupportedOperationException()
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
= descriptors
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = descriptors
override fun printScopeStructure(p: Printer) {
override fun printStructure(p: Printer) {
p.println(javaClass.getName())
}
}
@@ -29,9 +29,8 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.addImportScope
import org.jetbrains.kotlin.resolve.scopes.utils.addImportScopes
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
@@ -136,18 +135,13 @@ public class CodeFragmentAnalyzer(
val importList = codeFragment.importsAsImportList()
if (importList == null || importList.imports.isEmpty()) {
return scopeForContextElement to dataFlowInfo
return scopeForContextElement to dataFlowInfo
}
val importScopes = importList.imports.map {
qualifierResolver.processImportReference(it, resolveSession.moduleDescriptor, resolveSession.trace, null)
}.filterNotNull()
val chainedScope = ChainedScope(
scopeForContextElement.ownerDescriptor,
"Scope for resolve code fragment",
*importScopes.toTypedArray())
return scopeForContextElement.addImportScope(chainedScope) to dataFlowInfo
return scopeForContextElement.addImportScopes(importScopes) to dataFlowInfo
}
}
@@ -91,7 +91,7 @@ public fun ResolutionFacade.resolveImportReference(
val importDirective = KtPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java)
return qualifiedExpressionResolver.processImportReference(
importDirective, moduleDescriptor, BindingTraceContext(), packageFragmentForVisibilityCheck = null)?.getAllDescriptors() ?: emptyList()
importDirective, moduleDescriptor, BindingTraceContext(), packageFragmentForVisibilityCheck = null)?.getDescriptors() ?: emptyList()
}
//NOTE: idea default API returns module search scope for file under module but not in source or production source (for example, test data )
@@ -95,7 +95,7 @@ object ReplaceWithAnnotationAnalyzer {
val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module)
val additionalScopes = resolutionFacade.getFrontendService(FileScopeProvider.AdditionalScopes::class.java)
val scope = getResolutionScope(symbolDescriptor, symbolDescriptor,
listOf(explicitImportsScope) + additionalScopes.scopes) ?: return null
listOf(explicitImportsScope.asKtScope()) + additionalScopes.scopes) ?: return null
var bindingContext = analyzeInContext(expression, module, scope, resolutionFacade)
@@ -179,7 +179,7 @@ object ReplaceWithAnnotationAnalyzer {
val module = symbolDescriptor.module
val explicitImportsScope = buildExplicitImportsScope(annotation, resolutionFacade, module)
val scope = getResolutionScope(symbolDescriptor, symbolDescriptor, listOf(explicitImportsScope)) ?: return null
val scope = getResolutionScope(symbolDescriptor, symbolDescriptor, listOf(explicitImportsScope.asKtScope())) ?: return null
val typeResolver = resolutionFacade.getFrontendService(TypeResolver::class.java)
val bindingTrace = BindingTraceContext()