Restructure caches in JavaNamespaceResolver
This commit is contained in:
+33
-22
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java.resolver;
|
package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.PsiClass;
|
||||||
import com.intellij.psi.PsiPackage;
|
import com.intellij.psi.PsiPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -38,13 +39,17 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public final class JavaNamespaceResolver {
|
public final class JavaNamespaceResolver {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final ModuleDescriptor FAKE_ROOT_MODULE = new ModuleDescriptor(JavaDescriptorResolver.JAVA_ROOT);
|
public static final ModuleDescriptor FAKE_ROOT_MODULE = new ModuleDescriptor(JavaDescriptorResolver.JAVA_ROOT);
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<FqName, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
|
private final Map<FqName, JavaPackageScope> resolvedNamespaceCache = Maps.newHashMap();
|
||||||
|
@NotNull
|
||||||
|
private final Set<FqName> unresolvedCache = Sets.newHashSet();
|
||||||
|
|
||||||
private PsiClassFinder psiClassFinder;
|
private PsiClassFinder psiClassFinder;
|
||||||
private BindingTrace trace;
|
private BindingTrace trace;
|
||||||
private JavaSemanticServices javaSemanticServices;
|
private JavaSemanticServices javaSemanticServices;
|
||||||
@@ -75,9 +80,12 @@ public final class JavaNamespaceResolver {
|
|||||||
return searchRule.processFoundInKotlin(kotlinNamespaceDescriptor);
|
return searchRule.processFoundInKotlin(kotlinNamespaceDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolverNamespaceData namespaceData = lookUpCache(qualifiedName);
|
if (unresolvedCache.contains(qualifiedName)) {
|
||||||
if (namespaceData != null) {
|
return null;
|
||||||
return namespaceData.getNamespaceDescriptor();
|
}
|
||||||
|
JavaPackageScope scope = resolvedNamespaceCache.get(qualifiedName);
|
||||||
|
if (scope != null) {
|
||||||
|
return (NamespaceDescriptor) scope.getContainingDeclaration();
|
||||||
}
|
}
|
||||||
|
|
||||||
NamespaceDescriptorParent parentNs = resolveParentNamespace(qualifiedName);
|
NamespaceDescriptorParent parentNs = resolveParentNamespace(qualifiedName);
|
||||||
@@ -103,10 +111,6 @@ public final class JavaNamespaceResolver {
|
|||||||
return scopeData.getNamespaceDescriptor();
|
return scopeData.getNamespaceDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResolverNamespaceData lookUpCache(FqName qualifiedName) {
|
|
||||||
return namespaceDescriptorCacheByFqn.get(qualifiedName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) {
|
public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) {
|
||||||
return resolveNamespace(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
return resolveNamespace(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||||
@@ -145,21 +149,26 @@ public final class JavaNamespaceResolver {
|
|||||||
break lookingForPsi;
|
break lookingForPsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache(fqName, ResolverNamespaceData.NEGATIVE);
|
cache(fqName, null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolverNamespaceData namespaceData = new ResolverNamespaceData(psiClass, psiPackage, fqName, ns);
|
ResolverNamespaceData namespaceData = new ResolverNamespaceData(psiClass, psiPackage, fqName, ns);
|
||||||
|
|
||||||
namespaceData.setMemberScope(new JavaPackageScope(fqName, javaSemanticServices, namespaceData));
|
JavaPackageScope memberScope = new JavaPackageScope(fqName, javaSemanticServices, namespaceData);
|
||||||
|
namespaceData.setMemberScope(memberScope);
|
||||||
|
|
||||||
cache(fqName, namespaceData);
|
cache(fqName, memberScope);
|
||||||
|
|
||||||
return namespaceData;
|
return namespaceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cache(@NotNull FqName fqName, @NotNull ResolverNamespaceData namespaceData) {
|
private void cache(@NotNull FqName fqName, @Nullable JavaPackageScope packageScope) {
|
||||||
ResolverNamespaceData oldValue = namespaceDescriptorCacheByFqn.put(fqName, namespaceData);
|
if (packageScope == null) {
|
||||||
|
unresolvedCache.add(fqName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JavaPackageScope oldValue = resolvedNamespaceCache.put(fqName, packageScope);
|
||||||
if (oldValue != null) {
|
if (oldValue != null) {
|
||||||
throw new IllegalStateException("rewrite at " + fqName);
|
throw new IllegalStateException("rewrite at " + fqName);
|
||||||
}
|
}
|
||||||
@@ -168,19 +177,21 @@ public final class JavaNamespaceResolver {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public JavaPackageScope getJavaPackageScopeForExistingNamespaceDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
public JavaPackageScope getJavaPackageScopeForExistingNamespaceDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor) {
|
||||||
FqName fqName = DescriptorUtils.getFQName(namespaceDescriptor).toSafe();
|
FqName fqName = DescriptorUtils.getFQName(namespaceDescriptor).toSafe();
|
||||||
ResolverNamespaceData resolverNamespaceData = lookUpCache(fqName);
|
if (unresolvedCache.contains(fqName)) {
|
||||||
if (resolverNamespaceData == null) {
|
|
||||||
resolverNamespaceData = createNamespaceResolverScopeData(fqName, namespaceDescriptor);
|
|
||||||
}
|
|
||||||
if (resolverNamespaceData == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (resolverNamespaceData == ResolverNamespaceData.NEGATIVE) {
|
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"This means that we are trying to create a Java package, but have a package with the same FQN defined in Kotlin: " +
|
"This means that we are trying to create a Java package, but have a package with the same FQN defined in Kotlin: " +
|
||||||
fqName);
|
fqName);
|
||||||
}
|
}
|
||||||
JavaPackageScope scope = resolverNamespaceData.getMemberScope();
|
JavaPackageScope alreadyResolvedScope = resolvedNamespaceCache.get(fqName);
|
||||||
|
if (alreadyResolvedScope != null) {
|
||||||
|
return alreadyResolvedScope;
|
||||||
|
}
|
||||||
|
ResolverNamespaceData data;
|
||||||
|
data = createNamespaceResolverScopeData(fqName, namespaceDescriptor);
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JavaPackageScope scope = data.getMemberScope();
|
||||||
if (scope == null) {
|
if (scope == null) {
|
||||||
throw new IllegalStateException("fqn: " + fqName);
|
throw new IllegalStateException("fqn: " + fqName);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user