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 a004d71d22e..bc65cdb7f9b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -29,9 +29,6 @@ import org.jetbrains.kotlin.resolve.PlatformTypesMappedToKotlinChecker import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.LookupMode 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.resolve.scopes.JetScopeSelectorUtil.ScopeByNameSelector import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.utils.Printer import java.util.HashSet @@ -146,8 +143,7 @@ class LazyImportResolver( val importedReference = importDirective.getImportedReference() if (importedReference == null || resolvedTo == null) return - val aliasName = JetPsiUtil.getAliasName(importDirective) - if (aliasName == null) return + val aliasName = JetPsiUtil.getAliasName(importDirective) ?: return if (resolvedTo.size() != 1) return @@ -169,7 +165,7 @@ class LazyImportResolver( public fun selectSingleFromImports( name: Name, lookupMode: LookupMode, - descriptorSelector: ScopeByNameSelector + descriptorSelector: (JetScope, Name) -> D? ): D? { fun compute(): D? { val imports = indexedImports.importsForName(name) @@ -180,7 +176,7 @@ class LazyImportResolver( var target: D? = null for (directive in imports) { - val resolved = descriptorSelector.get(getImportScope(directive, lookupMode), name) ?: continue + val resolved = descriptorSelector(getImportScope(directive, lookupMode), name) ?: continue if (target != null && target != resolved) return null // ambiguity target = resolved } @@ -192,7 +188,7 @@ class LazyImportResolver( public fun collectFromImports( name: Name, lookupMode: LookupMode, - descriptorsSelector: ScopeByNameMultiSelector + descriptorsSelector: (JetScope, Name) -> Collection ): Collection { return resolveSession.getStorageManager().compute { val descriptors = HashSet() @@ -202,7 +198,7 @@ class LazyImportResolver( throw IllegalStateException("Recursion while resolving many imports: " + directive.getText()) } - descriptors.addAll(descriptorsSelector.get(getImportScope(directive, lookupMode), name)) + descriptors.addAll(descriptorsSelector(getImportScope(directive, lookupMode), name)) } descriptors @@ -231,40 +227,36 @@ class LazyImportScope( INVISIBLE_CLASSES } - private val classifierDescriptorSelector = object : ScopeByNameSelector { - override fun get(scope: JetScope, name: Name): ClassifierDescriptor? { - val descriptor = JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR.get(scope, name) - return if (descriptor != null && filter(descriptor as ClassDescriptor/*no type parameter can be imported*/)) descriptor else null - } - - private fun filter(descriptor: ClassDescriptor): Boolean { - if (filteringKind == FilteringKind.ALL) return true - val visibility = descriptor.getVisibility() - val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES - if (!visibility.mustCheckInImports()) return includeVisible - return Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, importResolver.packageView) == includeVisible - } + fun isClassVisible(descriptor: ClassDescriptor): Boolean { + if (filteringKind == FilteringKind.ALL) return true + val visibility = descriptor.getVisibility() + val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES + if (!visibility.mustCheckInImports()) return includeVisible + return Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, importResolver.packageView) == includeVisible } override fun getClassifier(name: Name): ClassifierDescriptor? { - return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, classifierDescriptorSelector) + return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES) { scope, name -> + val descriptor = scope.getClassifier(name) + if (descriptor != null && isClassVisible(descriptor as ClassDescriptor/*no type parameter can be imported*/)) descriptor else null + } } override fun getPackage(name: Name): PackageViewDescriptor? { if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return null - return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR) + return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES) { scope, name -> scope.getPackage(name) } } override fun getProperties(name: Name): Collection { if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf() - return importResolver.collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR) + return importResolver.collectFromImports(name, LookupMode.EVERYTHING) { scope, name -> scope.getProperties(name) } } override fun getLocalVariable(name: Name) = null override fun getFunctions(name: Name): Collection { if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf() - return importResolver.collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR) + return importResolver.collectFromImports(name, LookupMode.EVERYTHING) { scope, name -> scope.getFunctions(name) } } override fun getDeclarationsByLabel(labelName: Name): Collection = listOf() diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt index 40cfa1e6622..729e165e52f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ChainedScope.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.Printer import java.util.* -import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.* public open class ChainedScope( private val containingDeclaration: DeclarationDescriptor?/* it's nullable as a hack for TypeUtils.intersect() */, @@ -30,20 +29,42 @@ public open class ChainedScope( private val scopeChain = scopes.clone() private var implicitReceiverHierarchy: List? = null + private inline fun getFirstMatch(callback: (JetScope) -> T): T { + // NOTE: This is performance-sensitive; please don't replace with map().firstOrNull() + for (scope in scopeChain) { + val result = callback(scope) + if (result != null) return result + } + return null + } + + private inline fun getFromAllScopes(callback: (JetScope) -> Collection): Set { + if (scopeChain.isEmpty()) return emptySet() + var result: MutableSet? = null + for (scope in scopeChain) { + val fromScope = callback(scope) + if (result == null) { + result = LinkedHashSet() + } + result.addAll(fromScope) + } + return result ?: emptySet() + } + override fun getClassifier(name: Name): ClassifierDescriptor? - = getFirstMatch(scopeChain, name, CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR) + = getFirstMatch { it.getClassifier(name) } override fun getPackage(name: Name): PackageViewDescriptor? - = getFirstMatch(scopeChain, name, PACKAGE_SCOPE_SELECTOR) + = getFirstMatch { it.getPackage(name) } override fun getProperties(name: Name): Set - = getFromAllScopes(scopeChain, name, NAMED_PROPERTIES_SCOPE_SELECTOR) + = getFromAllScopes { it.getProperties(name) } override fun getLocalVariable(name: Name): VariableDescriptor? - = getFirstMatch(scopeChain, name, VARIABLE_DESCRIPTOR_SCOPE_SELECTOR) + = getFirstMatch { it.getLocalVariable(name) } override fun getFunctions(name: Name): Set - = getFromAllScopes(scopeChain, name, NAMED_FUNCTION_SCOPE_SELECTOR) + = getFromAllScopes { it.getFunctions(name) } override fun getImplicitReceiversHierarchy(): List { if (implicitReceiverHierarchy == null) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeSelectorUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeSelectorUtil.java deleted file mode 100644 index 24847a0c1c2..00000000000 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/JetScopeSelectorUtil.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.scopes; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.name.Name; - -import java.util.*; - -public class JetScopeSelectorUtil { - private JetScopeSelectorUtil() { - } - - public interface ScopeByNameSelector { - @Nullable - D get(@NotNull JetScope scope, @NotNull Name name); - } - - public interface ScopeByNameMultiSelector { - @NotNull - Collection get(JetScope scope, Name name); - } - - @NotNull - public static Collection collect(Collection scopes, ScopeByNameMultiSelector selector, Name name) { - Set descriptors = new HashSet(); - - for (JetScope scope : scopes) { - descriptors.addAll(selector.get(scope, name)); - } - - return descriptors; - } - - public static final ScopeByNameSelector CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR = - new ScopeByNameSelector() { - @Nullable - @Override - public ClassifierDescriptor get(@NotNull JetScope scope, @NotNull Name name) { - return scope.getClassifier(name); - } - }; - - public static final ScopeByNameSelector PACKAGE_SCOPE_SELECTOR = - new ScopeByNameSelector() { - @Nullable - @Override - public PackageViewDescriptor get(@NotNull JetScope scope, @NotNull Name name) { - return scope.getPackage(name); - } - }; - - public static final ScopeByNameSelector VARIABLE_DESCRIPTOR_SCOPE_SELECTOR = - new ScopeByNameSelector() { - @Nullable - @Override - public VariableDescriptor get(@NotNull JetScope scope, @NotNull Name name) { - return scope.getLocalVariable(name); - } - }; - - public static final ScopeByNameMultiSelector NAMED_FUNCTION_SCOPE_SELECTOR = - new ScopeByNameMultiSelector() { - @NotNull - @Override - public Collection get(@NotNull JetScope scope, @NotNull Name name) { - return scope.getFunctions(name); - } - }; - - public static final ScopeByNameMultiSelector NAMED_PROPERTIES_SCOPE_SELECTOR = - new ScopeByNameMultiSelector() { - @NotNull - @Override - public Collection get(@NotNull JetScope scope, @NotNull Name name) { - return scope.getProperties(name); - } - }; - - @Nullable - public static D getFirstMatch( - @NotNull JetScope[] scopes, - @NotNull Name name, - @NotNull ScopeByNameSelector descriptorSelector - ) { - for (JetScope scope : scopes) { - D descriptor = descriptorSelector.get(scope, name); - - if (descriptor != null) { - return descriptor; - } - } - - return null; - } - - @NotNull - public static Set getFromAllScopes( - @NotNull JetScope[] scopes, - @NotNull Name name, - @NotNull ScopeByNameMultiSelector descriptorsSelector - ) { - if (scopes.length == 0) return Collections.emptySet(); - - Set descriptors = new LinkedHashSet(); - for (JetScope jetScope : scopes) { - descriptors.addAll(descriptorsSelector.get(jetScope, name)); - } - - return descriptors; - } -}