Simplify ResolveSessionUtils and LazyResolveBasedCache

This commit is contained in:
Alexander Udalov
2015-02-09 21:11:23 +03:00
parent 1e8d8d0a99
commit 745ac7355b
2 changed files with 33 additions and 81 deletions
@@ -39,14 +39,7 @@ public class LazyResolveBasedCache() : JavaResolverCache {
}
override fun getClassResolvedFromSource(fqName: FqName): ClassDescriptor? {
val descriptor = traceBasedCache.getClassResolvedFromSource(fqName)
if (descriptor != null) return descriptor
return resolveSession.findInPackageFragments(fqName) { packageFragmentDescriptor ->
ResolveSessionUtils.findByQualifiedName(
packageFragmentDescriptor.getMemberScope(),
fqName.tail(packageFragmentDescriptor.fqName))
}
return traceBasedCache.getClassResolvedFromSource(fqName) ?: findInPackageFragments(fqName)
}
override fun recordMethod(method: JavaMethod, descriptor: SimpleFunctionDescriptor) {
@@ -60,34 +53,25 @@ public class LazyResolveBasedCache() : JavaResolverCache {
override fun recordField(field: JavaField, descriptor: PropertyDescriptor) {
traceBasedCache.recordField(field, descriptor)
}
override fun recordClass(javaClass: JavaClass, descriptor: ClassDescriptor) {
traceBasedCache.recordClass(javaClass, descriptor)
}
private fun <T: Any> ResolveSession.findInPackageFragments(fqName: FqName, find: (PackageFragmentDescriptor) -> T?): T? {
var result: T? = null
(if (fqName.isRoot()) fqName else fqName.parent()).each { (parentFqName: FqName) : Boolean ->
val packageDescriptor = resolveSession.getPackageFragment(parentFqName)
if (packageDescriptor == null) {
return@each false // Stop iteration
}
private fun findInPackageFragments(fullFqName: FqName): ClassDescriptor? {
var fqName = if (fullFqName.isRoot()) fullFqName else fullFqName.parent()
val findResult = find(packageDescriptor)
if (findResult != null) {
result = findResult
return@each false // Stop iteration
}
while (true) {
val packageDescriptor = resolveSession.getPackageFragment(fqName)
if (packageDescriptor == null) break
true // Continue search
val result = ResolveSessionUtils.findByQualifiedName(packageDescriptor.getMemberScope(), fullFqName.tail(fqName))
if (result != null) return result
if (fqName.isRoot()) break
fqName = fqName.parent()
}
return result
}
tailRecursive
private fun FqName.each(operation: (FqName) -> Boolean) {
if (operation(this) && !isRoot()) {
parent().each(operation)
}
return null
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.lazy;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
@@ -33,9 +32,9 @@ import org.jetbrains.kotlin.psi.JetNamedDeclaration;
import org.jetbrains.kotlin.psi.JetNamedDeclarationUtil;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class ResolveSessionUtils {
@@ -43,84 +42,53 @@ public class ResolveSessionUtils {
}
@NotNull
public static Collection<ClassDescriptor> getClassDescriptorsByFqName(@NotNull ModuleDescriptor moduleDescriptor, @NotNull FqName fqName) {
return getClassOrObjectDescriptorsByFqName(moduleDescriptor, fqName, Predicates.<ClassDescriptor>alwaysTrue());
public static Collection<ClassDescriptor> getClassDescriptorsByFqName(@NotNull ModuleDescriptor module, @NotNull FqName fqName) {
return getClassOrObjectDescriptorsByFqName(module, fqName, Predicates.<ClassDescriptor>alwaysTrue());
}
@NotNull
public static Collection<ClassDescriptor> getClassOrObjectDescriptorsByFqName(
@NotNull ModuleDescriptor moduleDescriptor,
@NotNull ModuleDescriptor module,
@NotNull FqName fqName,
@NotNull Predicate<ClassDescriptor> filter
) {
if (fqName.isRoot()) return Collections.emptyList();
Collection<ClassDescriptor> classDescriptors = Lists.newArrayList();
Collection<ClassDescriptor> result = new ArrayList<ClassDescriptor>(1);
FqName packageFqName = fqName.parent();
while (true) {
PackageViewDescriptor packageDescriptor = moduleDescriptor.getPackage(packageFqName);
PackageViewDescriptor packageDescriptor = module.getPackage(packageFqName);
if (packageDescriptor != null) {
FqName classInPackagePath = NamePackage.tail(fqName, packageFqName);
ClassDescriptor classDescriptor = findByQualifiedName(packageDescriptor.getMemberScope(), classInPackagePath, filter);
if (classDescriptor != null) {
classDescriptors.add(classDescriptor);
FqName relativeClassFqName = NamePackage.tail(fqName, packageFqName);
ClassDescriptor classDescriptor = findByQualifiedName(packageDescriptor.getMemberScope(), relativeClassFqName);
if (classDescriptor != null && filter.apply(classDescriptor)) {
result.add(classDescriptor);
}
}
if (packageFqName.isRoot()) {
break;
}
else {
packageFqName = packageFqName.parent();
}
packageFqName = packageFqName.parent();
}
return classDescriptors;
return result;
}
@Nullable
public static ClassDescriptor findByQualifiedName(@NotNull JetScope packageScope, @NotNull FqName path) {
return findByQualifiedName(packageScope, path, Predicates.<ClassDescriptor>alwaysTrue());
}
@Nullable
private static ClassDescriptor findByQualifiedName(
@NotNull JetScope jetScope,
@NotNull FqName path,
@NotNull Predicate<ClassDescriptor> filter
) {
public static ClassDescriptor findByQualifiedName(@NotNull JetScope outerScope, @NotNull FqName path) {
if (path.isRoot()) return null;
if (NamePackage.isOneSegmentFQN(path)) {
Name shortName = path.shortName();
ClassifierDescriptor classifier = jetScope.getClassifier(shortName);
if (classifier instanceof ClassDescriptor) {
ClassDescriptor resultDescriptor = (ClassDescriptor) classifier;
if (filter.apply(resultDescriptor)) {
return resultDescriptor;
}
}
return null;
JetScope scope = outerScope;
for (Name name : path.pathSegments()) {
ClassifierDescriptor classifier = scope.getClassifier(name);
if (!(classifier instanceof ClassDescriptor)) return null;
scope = ((ClassDescriptor) classifier).getUnsubstitutedInnerClassesScope();
}
List<Name> pathSegments = path.pathSegments();
Name firstName = pathSegments.get(0);
ClassifierDescriptor classifier = jetScope.getClassifier(firstName);
if (classifier instanceof ClassDescriptor) {
return findByQualifiedName(
((ClassDescriptor) classifier).getUnsubstitutedInnerClassesScope(),
new FqName(path.asString().substring(firstName.asString().length() + 1)),
filter
);
}
// TODO: search in class object
return null;
return (ClassDescriptor) scope.getContainingDeclaration();
}
@NotNull