From 3322ed6e04fad47d8a0f9ae21aad112edbc0b295 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 15 Aug 2017 19:07:45 +0700 Subject: [PATCH] Implement LazyImportResolver::definitelyDoesNotContainName --- .../kotlin/resolve/lazy/FileScopeFactory.kt | 7 +++++++ .../kotlin/resolve/lazy/LazyImportScope.kt | 18 +++++++++++++++++- .../descriptors/AbstractLazyMemberScope.kt | 2 -- .../resolve/calls/tower/TowerResolver.kt | 2 +- .../java/lazy/descriptors/JvmPackageScope.kt | 8 ++++---- .../descriptors/LazyJavaClassMemberScope.kt | 4 ++-- .../kotlin/resolve/scopes/ResolutionScope.kt | 4 ++++ .../org/jetbrains/kotlin/types/ErrorUtils.java | 10 ++++++++++ .../descriptors/DeserializedClassDescriptor.kt | 4 ++-- 9 files changed, 47 insertions(+), 12 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt index 1f195710a4e..e829cec79dc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt @@ -177,6 +177,7 @@ class FileScopeFactory( parentScope: ImportingScope ): ImportingScope { val scope = packageView.memberScope + val names by lazy(LazyThreadSafetyMode.PUBLICATION) { scope.computeAllNames () } val packageName = packageView.fqName val excludedNames = aliasImportNames.mapNotNull { if (it.parent() == packageName) it.shortName() else null } @@ -219,6 +220,12 @@ class FileScopeFactory( override fun computeImportedNames() = packageView.memberScope.computeAllNames() + override fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean { + if (names?.let { name in it } != false) return false + packageView.memberScope.recordLookup(name, location) + return true + } + override fun toString() = "Scope for current package (${filteringKind.name})" override fun printStructure(p: Printer) { 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 5ea473866b9..63aacd7b718 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.util.collectionUtils.concat import org.jetbrains.kotlin.utils.Printer +import org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable import java.util.* interface IndexedImports { @@ -81,7 +82,7 @@ class LazyImportResolver( val indexedImports: IndexedImports, excludedImportNames: Collection, private val traceForImportResolve: BindingTrace, - private val packageFragment: PackageFragmentDescriptor, + private val packageFragment: PackageFragmentDescriptor?, val deprecationResolver: DeprecationResolver ) : ImportResolver { private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues { @@ -191,6 +192,18 @@ class LazyImportResolver( fun getImportScope(directive: KtImportDirective): ImportingScope { return importedScopesProvider(directive) ?: ImportingScope.Empty } + + val allNames: Set? by lazy(LazyThreadSafetyMode.PUBLICATION) { + indexedImports.imports.flatMapToNullable(hashSetOf()) { getImportScope(it).computeImportedNames() } + } + + fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean { + if (allNames?.let { name in it } != false) return false + indexedImports.importsForName(name).forEach { + getImportScope(it).recordLookup(name, location) + } + return true + } } class LazyImportScope( @@ -269,4 +282,7 @@ class LazyImportScope( p.popIndent() p.println("}") } + + override fun definitelyDoesNotContainName(name: Name, location: LookupLocation) = importResolver.definitelyDoesNotContainName(name, location) + override fun computeImportedNames() = importResolver.allNames } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt index 9d1ac9d11fe..3951107526d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/AbstractLazyMemberScope.kt @@ -219,8 +219,6 @@ protected constructor( return result.toList() } - abstract fun recordLookup(name: Name, from: LookupLocation) - // Do not change this, override in concrete subclasses: // it is very easy to compromise laziness of this class, and fail all the debugging // a generic implementation can't do this properly diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index 9b135248bdd..21139f9557c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -178,7 +178,7 @@ class TowerResolver { } } } - else { + else if (scope.mayFitForName(name, location)) { // functions with no receiver or extension for explicit receiver TowerData.TowerLevel(ImportingScopeBasedTowerLevel(this, scope as ImportingScope)).process()?.let { return it } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt index 9e33002bbb0..2e852f7c490 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt @@ -47,7 +47,7 @@ class JvmPackageScope( } override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { - recordLookup(location, name) + recordLookup(name, location) val javaClassifier = javaScope.getContributedClassifier(name, location) if (javaClassifier != null) return javaClassifier @@ -56,12 +56,12 @@ class JvmPackageScope( } override fun getContributedVariables(name: Name, location: LookupLocation): Collection { - recordLookup(location, name) + recordLookup(name, location) return getFromAllScopes(javaScope, kotlinScopes) { it.getContributedVariables(name, location) } } override fun getContributedFunctions(name: Name, location: LookupLocation): Collection { - recordLookup(location, name) + recordLookup(name, location) return getFromAllScopes(javaScope, kotlinScopes) { it.getContributedFunctions(name, location) } } @@ -96,7 +96,7 @@ class JvmPackageScope( p.println("}") } - private fun recordLookup(location: LookupLocation, name: Name) { + override fun recordLookup(name: Name, location: LookupLocation) { c.components.lookupTracker.record(location, packageFragment, name) } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index b5c8efd79b7..a6de88b03b4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -672,8 +672,8 @@ class LazyJavaClassMemberScope( } } - private fun recordLookup(name: Name, from: LookupLocation) { - c.components.lookupTracker.record(from, ownerDescriptor, name) + override fun recordLookup(name: Name, location: LookupLocation) { + c.components.lookupTracker.record(location, ownerDescriptor, name) } override fun toString() = "Lazy Java member scope for " + jClass.fqName diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ResolutionScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ResolutionScope.kt index 8540d49894f..09315421f7f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ResolutionScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/ResolutionScope.kt @@ -41,4 +41,8 @@ interface ResolutionScope { ): Collection fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean = false + + fun recordLookup(name: Name, location: LookupLocation) { + getContributedFunctions(name, location) + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java index 6dc861785bd..0a412f71927 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/ErrorUtils.java @@ -217,6 +217,11 @@ public class ErrorUtils { return emptySet(); } + @Override + public void recordLookup(@NotNull Name name, @NotNull LookupLocation location) { + + } + @NotNull @Override public Collection getContributedDescriptors( @@ -295,6 +300,11 @@ public class ErrorUtils { throw new IllegalStateException(); } + @Override + public void recordLookup(@NotNull Name name, @NotNull LookupLocation location) { + throw new IllegalStateException(); + } + @Override public boolean definitelyDoesNotContainName(@NotNull Name name, @NotNull LookupLocation location) { return false; diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index ff802785fc7..0014c9e96ba 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -294,8 +294,8 @@ class DeserializedClassDescriptor( result.addAll(classDescriptor.enumEntries?.all().orEmpty()) } - private fun recordLookup(name: Name, from: LookupLocation) { - c.components.lookupTracker.record(from, classDescriptor, name) + override fun recordLookup(name: Name, location: LookupLocation) { + c.components.lookupTracker.record(location, classDescriptor, name) } }