Implement LazyImportResolver::definitelyDoesNotContainName

This commit is contained in:
Denis Zharkov
2017-08-15 19:07:45 +07:00
parent 6e766634c1
commit 3322ed6e04
9 changed files with 47 additions and 12 deletions
@@ -177,6 +177,7 @@ class FileScopeFactory(
parentScope: ImportingScope parentScope: ImportingScope
): ImportingScope { ): ImportingScope {
val scope = packageView.memberScope val scope = packageView.memberScope
val names by lazy(LazyThreadSafetyMode.PUBLICATION) { scope.computeAllNames () }
val packageName = packageView.fqName val packageName = packageView.fqName
val excludedNames = aliasImportNames.mapNotNull { if (it.parent() == packageName) it.shortName() else null } 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 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 toString() = "Scope for current package (${filteringKind.name})"
override fun printStructure(p: Printer) { override fun printStructure(p: Printer) {
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.collectionUtils.concat import org.jetbrains.kotlin.util.collectionUtils.concat
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable
import java.util.* import java.util.*
interface IndexedImports { interface IndexedImports {
@@ -81,7 +82,7 @@ class LazyImportResolver(
val indexedImports: IndexedImports, val indexedImports: IndexedImports,
excludedImportNames: Collection<FqName>, excludedImportNames: Collection<FqName>,
private val traceForImportResolve: BindingTrace, private val traceForImportResolve: BindingTrace,
private val packageFragment: PackageFragmentDescriptor, private val packageFragment: PackageFragmentDescriptor?,
val deprecationResolver: DeprecationResolver val deprecationResolver: DeprecationResolver
) : ImportResolver { ) : ImportResolver {
private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues { private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues {
@@ -191,6 +192,18 @@ class LazyImportResolver(
fun getImportScope(directive: KtImportDirective): ImportingScope { fun getImportScope(directive: KtImportDirective): ImportingScope {
return importedScopesProvider(directive) ?: ImportingScope.Empty return importedScopesProvider(directive) ?: ImportingScope.Empty
} }
val allNames: Set<Name>? 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( class LazyImportScope(
@@ -269,4 +282,7 @@ class LazyImportScope(
p.popIndent() p.popIndent()
p.println("}") p.println("}")
} }
override fun definitelyDoesNotContainName(name: Name, location: LookupLocation) = importResolver.definitelyDoesNotContainName(name, location)
override fun computeImportedNames() = importResolver.allNames
} }
@@ -219,8 +219,6 @@ protected constructor(
return result.toList() return result.toList()
} }
abstract fun recordLookup(name: Name, from: LookupLocation)
// Do not change this, override in concrete subclasses: // Do not change this, override in concrete subclasses:
// it is very easy to compromise laziness of this class, and fail all the debugging // it is very easy to compromise laziness of this class, and fail all the debugging
// a generic implementation can't do this properly // a generic implementation can't do this properly
@@ -178,7 +178,7 @@ class TowerResolver {
} }
} }
} }
else { else if (scope.mayFitForName(name, location)) {
// functions with no receiver or extension for explicit receiver // functions with no receiver or extension for explicit receiver
TowerData.TowerLevel(ImportingScopeBasedTowerLevel(this, scope as ImportingScope)).process()?.let { return it } TowerData.TowerLevel(ImportingScopeBasedTowerLevel(this, scope as ImportingScope)).process()?.let { return it }
} }
@@ -47,7 +47,7 @@ class JvmPackageScope(
} }
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
recordLookup(location, name) recordLookup(name, location)
val javaClassifier = javaScope.getContributedClassifier(name, location) val javaClassifier = javaScope.getContributedClassifier(name, location)
if (javaClassifier != null) return javaClassifier if (javaClassifier != null) return javaClassifier
@@ -56,12 +56,12 @@ class JvmPackageScope(
} }
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> { override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
recordLookup(location, name) recordLookup(name, location)
return getFromAllScopes(javaScope, kotlinScopes) { it.getContributedVariables(name, location) } return getFromAllScopes(javaScope, kotlinScopes) { it.getContributedVariables(name, location) }
} }
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> { override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
recordLookup(location, name) recordLookup(name, location)
return getFromAllScopes(javaScope, kotlinScopes) { it.getContributedFunctions(name, location) } return getFromAllScopes(javaScope, kotlinScopes) { it.getContributedFunctions(name, location) }
} }
@@ -96,7 +96,7 @@ class JvmPackageScope(
p.println("}") p.println("}")
} }
private fun recordLookup(location: LookupLocation, name: Name) { override fun recordLookup(name: Name, location: LookupLocation) {
c.components.lookupTracker.record(location, packageFragment, name) c.components.lookupTracker.record(location, packageFragment, name)
} }
} }
@@ -672,8 +672,8 @@ class LazyJavaClassMemberScope(
} }
} }
private fun recordLookup(name: Name, from: LookupLocation) { override fun recordLookup(name: Name, location: LookupLocation) {
c.components.lookupTracker.record(from, ownerDescriptor, name) c.components.lookupTracker.record(location, ownerDescriptor, name)
} }
override fun toString() = "Lazy Java member scope for " + jClass.fqName override fun toString() = "Lazy Java member scope for " + jClass.fqName
@@ -41,4 +41,8 @@ interface ResolutionScope {
): Collection<DeclarationDescriptor> ): Collection<DeclarationDescriptor>
fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean = false fun definitelyDoesNotContainName(name: Name, location: LookupLocation): Boolean = false
fun recordLookup(name: Name, location: LookupLocation) {
getContributedFunctions(name, location)
}
} }
@@ -217,6 +217,11 @@ public class ErrorUtils {
return emptySet(); return emptySet();
} }
@Override
public void recordLookup(@NotNull Name name, @NotNull LookupLocation location) {
}
@NotNull @NotNull
@Override @Override
public Collection<DeclarationDescriptor> getContributedDescriptors( public Collection<DeclarationDescriptor> getContributedDescriptors(
@@ -295,6 +300,11 @@ public class ErrorUtils {
throw new IllegalStateException(); throw new IllegalStateException();
} }
@Override
public void recordLookup(@NotNull Name name, @NotNull LookupLocation location) {
throw new IllegalStateException();
}
@Override @Override
public boolean definitelyDoesNotContainName(@NotNull Name name, @NotNull LookupLocation location) { public boolean definitelyDoesNotContainName(@NotNull Name name, @NotNull LookupLocation location) {
return false; return false;
@@ -294,8 +294,8 @@ class DeserializedClassDescriptor(
result.addAll(classDescriptor.enumEntries?.all().orEmpty()) result.addAll(classDescriptor.enumEntries?.all().orEmpty())
} }
private fun recordLookup(name: Name, from: LookupLocation) { override fun recordLookup(name: Name, location: LookupLocation) {
c.components.lookupTracker.record(from, classDescriptor, name) c.components.lookupTracker.record(location, classDescriptor, name)
} }
} }