diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt index a9acd08360e..84446606891 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportsScope.kt @@ -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 { - 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 { - 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 { - 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, name: Name, location: LookupLocation): Collection { - return scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, name, location) } - } + override fun getSyntheticExtensionProperties(receiverTypes: Collection, name: Name, location: LookupLocation) + = scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes, name, location) } - override fun getSyntheticExtensionFunctions(receiverTypes: Collection, name: Name, location: LookupLocation): Collection { - return scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes, name, location) } - } + override fun getSyntheticExtensionFunctions(receiverTypes: Collection, name: Name, location: LookupLocation) + = scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes, name, location) } - override fun getSyntheticExtensionProperties(receiverTypes: Collection): Collection { - return scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes) } - } + override fun getSyntheticExtensionProperties(receiverTypes: Collection) + = scopes.flatMap { it.getSyntheticExtensionProperties(receiverTypes) } - override fun getSyntheticExtensionFunctions(receiverTypes: Collection): Collection { - return scopes.flatMap { it.getSyntheticExtensionFunctions(receiverTypes) } - } + override fun getSyntheticExtensionFunctions(receiverTypes: Collection) + = 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 = listOf() - - override fun getImplicitReceiversHierarchy(): List = listOf() - - override fun getOwnDeclaredDescriptors(): Collection = listOf() - - override fun printScopeStructure(p: Printer) { - p.println(javaClass.getSimpleName()) + override fun printStructure(p: Printer) { + p.println(javaClass.simpleName) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt index 48743d47bbf..f5106def762 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt index 3fb5b046454..d992c0252d3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/SingleImportScope.kt @@ -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) : KtScopeImpl() { - override fun getClassifier(name: Name, location: LookupLocation) +class SingleImportScope(private val aliasName: Name, private val descriptors: Collection) : ImportingScope by ImportingScope.Empty { + override fun getDeclaredClassifier(name: Name, location: LookupLocation) = if (name == aliasName) descriptors.filterIsInstance().singleOrNull() else null override fun getPackage(name: Name) = if (name == aliasName) descriptors.filterIsInstance().singleOrNull() else null - override fun getProperties(name: Name, location: LookupLocation) + override fun getDeclaredVariables(name: Name, location: LookupLocation) = if (name == aliasName) descriptors.filterIsInstance() else emptyList() - override fun getFunctions(name: Name, location: LookupLocation) + override fun getDeclaredFunctions(name: Name, location: LookupLocation) = if (name == aliasName) descriptors.filterIsInstance() 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) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt index f224afe1048..be7df976774 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -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 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 collectFromImports( name: Name, - descriptorsSelector: (KtScope, Name) -> Collection + descriptorsSelector: (ImportingScope, Name) -> Collection ): Collection { return storageManager.compute { var descriptors: Collection? = 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 { 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 { 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, name: Name, location: LookupLocation): Collection { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt index f00c9887bb1..860d6e31b5d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt @@ -273,15 +273,26 @@ inline fun 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): 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 } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt index 2181982e84d..0b080e201ba 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ExplicitImportsScope.kt @@ -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) : KtScopeImpl() { - override fun getClassifier(name: Name, location: LookupLocation) = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() +public class ExplicitImportsScope(private val descriptors: Collection) : ImportingScope by ImportingScope.Empty { + override fun getDeclaredClassifier(name: Name, location: LookupLocation) + = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() - override fun getPackage(name: Name)= descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() + override fun getPackage(name: Name) + = descriptors.filter { it.getName() == name }.firstIsInstanceOrNull() - override fun getProperties(name: Name, location: LookupLocation) = descriptors.filter { it.getName() == name }.filterIsInstance() + override fun getDeclaredVariables(name: Name, location: LookupLocation) + = descriptors.filter { it.getName() == name }.filterIsInstance() - override fun getFunctions(name: Name, location: LookupLocation) = descriptors.filter { it.getName() == name }.filterIsInstance() + override fun getDeclaredFunctions(name: Name, location: LookupLocation) + = descriptors.filter { it.getName() == name }.filterIsInstance() - 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()) } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt index 611497f1115..a1d21e37d89 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/CodeFragmentAnalyzer.kt @@ -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 } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt index beb6a4e1dcd..806a51a19ea 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt @@ -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 ) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt index 04b87b613cf..847ccb409b3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt @@ -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()