store ResolverScopeData in Java*Scope

This commit is contained in:
Stepan Koltsov
2012-04-07 23:16:48 +04:00
parent 6a68de9a8b
commit 2bc305bddf
4 changed files with 185 additions and 141 deletions
@@ -33,25 +33,17 @@ import java.util.*;
* @author abreslav * @author abreslav
*/ */
public class JavaClassMembersScope extends JavaClassOrPackageScope { public class JavaClassMembersScope extends JavaClassOrPackageScope {
@NotNull
protected final PsiClass psiClass;
private final boolean staticMembers;
private final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap(); private final Map<String, ClassifierDescriptor> classifiers = Maps.newHashMap();
private Collection<DeclarationDescriptor> allDescriptors; private Collection<DeclarationDescriptor> allDescriptors;
public JavaClassMembersScope( public JavaClassMembersScope(
@NotNull ClassOrNamespaceDescriptor classOrNamespaceDescriptor,
@NotNull PsiClass psiClass,
@NotNull JavaSemanticServices semanticServices, @NotNull JavaSemanticServices semanticServices,
boolean staticMembers) { @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) {
super(classOrNamespaceDescriptor, semanticServices, psiClass); super(semanticServices, resolverScopeData);
this.psiClass = psiClass;
this.staticMembers = staticMembers;
}
@Override if (resolverScopeData.psiClass == null) {
protected boolean staticMembers() { throw new IllegalArgumentException("must pass PsiClass here");
return staticMembers; }
} }
@NotNull @NotNull
@@ -90,20 +82,21 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope {
if (allDescriptors == null) { if (allDescriptors == null) {
allDescriptors = Sets.newHashSet(); allDescriptors = Sets.newHashSet();
allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(psiClass, descriptor)); allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(resolverScopeData));
allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(descriptor, psiClass, staticMembers)); allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(resolverScopeData));
allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveInnerClasses(descriptor, psiClass, staticMembers)); allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveInnerClasses(
resolverScopeData.classOrNamespaceDescriptor, resolverScopeData.psiClass, resolverScopeData.staticMembers));
} }
return allDescriptors; return allDescriptors;
} }
private ClassifierDescriptor doGetClassifierDescriptor(String name) { private ClassifierDescriptor doGetClassifierDescriptor(String name) {
// TODO : suboptimal, walk the list only once // TODO : suboptimal, walk the list only once
for (PsiClass innerClass : psiClass.getAllInnerClasses()) { for (PsiClass innerClass : resolverScopeData.psiClass.getAllInnerClasses()) {
if (name.equals(innerClass.getName())) { if (name.equals(innerClass.getName())) {
if (innerClass.hasModifierProperty(PsiModifier.STATIC) != staticMembers) return null; if (innerClass.hasModifierProperty(PsiModifier.STATIC) != resolverScopeData.staticMembers) return null;
ClassDescriptor classDescriptor = semanticServices.getDescriptorResolver() ClassDescriptor classDescriptor = semanticServices.getDescriptorResolver()
.resolveClass(new FqName(innerClass.getQualifiedName()), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN); .resolveClass(new FqName(innerClass.getQualifiedName()), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
if (classDescriptor != null) { if (classDescriptor != null) {
@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl;
import java.util.Collections;
import java.util.Set; import java.util.Set;
/** /**
@@ -33,51 +32,34 @@ import java.util.Set;
*/ */
public abstract class JavaClassOrPackageScope extends JetScopeImpl { public abstract class JavaClassOrPackageScope extends JetScopeImpl {
@NotNull
protected final ClassOrNamespaceDescriptor descriptor;
@NotNull @NotNull
protected final JavaSemanticServices semanticServices; protected final JavaSemanticServices semanticServices;
@Nullable @NotNull
protected final PsiClass psiClass; protected final JavaDescriptorResolver.ResolverScopeData resolverScopeData;
protected JavaClassOrPackageScope(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull JavaSemanticServices semanticServices, protected JavaClassOrPackageScope(
@Nullable PsiClass psiClass) { @NotNull JavaSemanticServices semanticServices,
this.descriptor = descriptor; @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) {
this.semanticServices = semanticServices; this.semanticServices = semanticServices;
this.psiClass = psiClass; this.resolverScopeData = resolverScopeData;
JavaDescriptorResolver.checkPsiClassIsNotJet(psiClass);
} }
@NotNull @NotNull
@Override @Override
public DeclarationDescriptor getContainingDeclaration() { public DeclarationDescriptor getContainingDeclaration() {
return descriptor; return resolverScopeData.classOrNamespaceDescriptor;
} }
protected abstract boolean staticMembers();
@NotNull @NotNull
@Override @Override
public Set<VariableDescriptor> getProperties(@NotNull String name) { public Set<VariableDescriptor> getProperties(@NotNull String name) {
if (psiClass == null) { return semanticServices.getDescriptorResolver().resolveFieldGroupByName(name, resolverScopeData);
return Collections.emptySet();
}
// TODO: cache
return semanticServices.getDescriptorResolver().resolveFieldGroupByName(
descriptor, psiClass, name, staticMembers());
} }
@NotNull @NotNull
@Override @Override
public Set<FunctionDescriptor> getFunctions(@NotNull String name) { public Set<FunctionDescriptor> getFunctions(@NotNull String name) {
return semanticServices.getDescriptorResolver().resolveFunctionGroup(name, resolverScopeData);
if (psiClass == null) {
return Collections.emptySet();
}
return semanticServices.getDescriptorResolver().resolveFunctionGroup(descriptor, psiClass, name, staticMembers());
} }
} }
@@ -21,17 +21,80 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pair;
import com.intellij.psi.*; import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.PsiAnnotationMethod;
import com.intellij.psi.PsiAnnotationParameterList;
import com.intellij.psi.PsiArrayType;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiEllipsisType;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeParameter;
import com.intellij.psi.PsiTypeParameterListOwner;
import jet.typeinfo.TypeInfoVariance; import jet.typeinfo.TypeInfoVariance;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.Modality;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptorLite;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.descriptors.Visibilities;
import org.jetbrains.jet.lang.descriptors.Visibility;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.NamespaceFactory;
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.constants.ByteValue;
import org.jetbrains.jet.lang.resolve.constants.CharValue;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.DoubleValue;
import org.jetbrains.jet.lang.resolve.constants.FloatValue;
import org.jetbrains.jet.lang.resolve.constants.IntValue;
import org.jetbrains.jet.lang.resolve.constants.LongValue;
import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.jet.lang.resolve.constants.ShortValue;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
@@ -40,7 +103,14 @@ import org.jetbrains.jet.rt.signature.JetSignatureReader;
import org.jetbrains.jet.rt.signature.JetSignatureVisitor; import org.jetbrains.jet.rt.signature.JetSignatureVisitor;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* @author abreslav * @author abreslav
@@ -129,9 +199,23 @@ public class JavaDescriptorResolver {
} }
private static abstract class ResolverScopeData { static abstract class ResolverScopeData {
protected boolean kotlin; protected boolean kotlin;
@Nullable
final PsiClass psiClass;
final boolean staticMembers;
@NotNull
final ClassOrNamespaceDescriptor classOrNamespaceDescriptor;
protected ResolverScopeData(@Nullable PsiClass psiClass, boolean staticMembers, @NotNull ClassOrNamespaceDescriptor descriptor) {
checkPsiClassIsNotJet(psiClass);
this.psiClass = psiClass;
this.staticMembers = staticMembers;
classOrNamespaceDescriptor = descriptor;
}
private Map<String, NamedMembers> namedMembersMap; private Map<String, NamedMembers> namedMembersMap;
@NotNull @NotNull
@@ -140,12 +224,13 @@ public class JavaDescriptorResolver {
/** Class with instance members */ /** Class with instance members */
static class ResolverBinaryClassData extends ResolverScopeData { static class ResolverBinaryClassData extends ResolverScopeData {
private final MutableClassDescriptorLite classDescriptor;
ResolverBinaryClassData() { ResolverBinaryClassData(@NotNull PsiClass psiClass, @NotNull MutableClassDescriptorLite classDescriptor) {
super(psiClass, false, classDescriptor);
this.classDescriptor = classDescriptor;
} }
private MutableClassDescriptorLite classDescriptor;
List<TypeParameterDescriptorInitialization> typeParameters; List<TypeParameterDescriptorInitialization> typeParameters;
@NotNull @NotNull
@@ -162,15 +247,16 @@ public class JavaDescriptorResolver {
} }
/** Either package or class with static members */ /** Either package or class with static members */
private static class ResolverNamespaceData extends ResolverScopeData { static class ResolverNamespaceData extends ResolverScopeData {
private NamespaceDescriptor namespaceDescriptor; private final NamespaceDescriptor namespaceDescriptor;
private JavaPackageScope memberScope;
@NotNull ResolverNamespaceData(@Nullable PsiClass psiClass, @NotNull NamespaceDescriptor namespaceDescriptor) {
public NamespaceDescriptor getNamespaceDescriptor() { super(psiClass, true, namespaceDescriptor);
return namespaceDescriptor; this.namespaceDescriptor = namespaceDescriptor;
} }
private JavaPackageScope memberScope;
@NotNull @NotNull
@Override @Override
public List<TypeParameterDescriptor> getTypeParameters() { public List<TypeParameterDescriptor> getTypeParameters() {
@@ -261,11 +347,10 @@ public class JavaDescriptorResolver {
checkPsiClassIsNotJet(psiClass); checkPsiClassIsNotJet(psiClass);
String name = psiClass.getName(); String name = psiClass.getName();
ResolverBinaryClassData classData = new ResolverBinaryClassData();
classDescriptorCache.put(new FqName(psiClass.getQualifiedName()), classData);
ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS; ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS;
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass); ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
classData.classDescriptor = new MutableClassDescriptorLite(containingDeclaration, kind); ResolverBinaryClassData classData = new ResolverBinaryClassData(psiClass, new MutableClassDescriptorLite(containingDeclaration, kind));
classDescriptorCache.put(new FqName(psiClass.getQualifiedName()), classData);
classData.classDescriptor.setName(name); classData.classDescriptor.setName(name);
classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass)); classData.classDescriptor.setAnnotations(resolveAnnotations(psiClass));
@@ -296,7 +381,7 @@ public class JavaDescriptorResolver {
} }
classData.classDescriptor.setModality(modality); classData.classDescriptor.setModality(modality);
classData.classDescriptor.createTypeConstructor(); classData.classDescriptor.createTypeConstructor();
classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false)); classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(semanticServices, classData));
initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName()); initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName());
@@ -433,19 +518,18 @@ public class JavaDescriptorResolver {
checkPsiClassIsNotJet(psiClass); checkPsiClassIsNotJet(psiClass);
ResolverBinaryClassData classData = new ResolverBinaryClassData(); ResolverBinaryClassData classData = new ResolverBinaryClassData(classObjectPsiClass, new MutableClassDescriptorLite(containing, ClassKind.OBJECT));
classData.kotlin = true;
classData.classDescriptor = new MutableClassDescriptorLite(containing, ClassKind.OBJECT);
classDescriptorCache.put(new FqName(classObjectPsiClass.getQualifiedName()), classData); classDescriptorCache.put(new FqName(classObjectPsiClass.getQualifiedName()), classData);
classData.kotlin = true;
classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData.classDescriptor, new ArrayList<TypeParameterDescriptor>(0))); classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData.classDescriptor, new ArrayList<TypeParameterDescriptor>(0)));
classData.classDescriptor.setName(JetPsiUtil.NO_NAME_PROVIDED); // TODO classData.classDescriptor.setName(JetPsiUtil.NO_NAME_PROVIDED); // TODO
classData.classDescriptor.setModality(Modality.FINAL); classData.classDescriptor.setModality(Modality.FINAL);
classData.classDescriptor.setVisibility(containing.getVisibility()); classData.classDescriptor.setVisibility(containing.getVisibility());
classData.classDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0)); classData.classDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
classData.classDescriptor.createTypeConstructor(); classData.classDescriptor.createTypeConstructor();
classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, classObjectPsiClass, semanticServices, false)); classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(semanticServices, classData));
// TODO: wrong: class objects do not need visible constructors // TODO: wrong: class objects do not need visible constructors
ConstructorDescriptorImpl constructor = new ConstructorDescriptorImpl(classData.classDescriptor, new ArrayList<AnnotationDescriptor>(0), true); ConstructorDescriptorImpl constructor = new ConstructorDescriptorImpl(classData.classDescriptor, new ArrayList<AnnotationDescriptor>(0), true);
@@ -829,10 +913,10 @@ public class JavaDescriptorResolver {
trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, ns, false); trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, ns, false);
} }
JavaPackageScope scope = new JavaPackageScope(fqName, ns, semanticServices, psiPackage, psiClass); ResolverNamespaceData namespaceData = new ResolverNamespaceData(psiClass, ns);
JavaPackageScope scope = new JavaPackageScope(fqName, semanticServices, psiPackage, psiClass, namespaceData);
ResolverNamespaceData namespaceData = new ResolverNamespaceData();
namespaceData.namespaceDescriptor = ns;
// TODO: hack // TODO: hack
namespaceData.kotlin = true; namespaceData.kotlin = true;
@@ -871,7 +955,7 @@ public class JavaDescriptorResolver {
return null; return null;
} else { } else {
// TODO: what is GlobalSearchScope // TODO: what is GlobalSearchScope
return semanticServices.getPsiClassFinder().findPsiClass(JavaPackageScope.getQualifiedName(packageFQN, JvmAbi.PACKAGE_CLASS)); return semanticServices.getPsiClassFinder().findPsiClass(packageFQN.child(JvmAbi.PACKAGE_CLASS));
} }
} }
@@ -892,7 +976,6 @@ public class JavaDescriptorResolver {
checkPsiClassIsNotJet(psiClass); checkPsiClassIsNotJet(psiClass);
ResolverNamespaceData namespaceData = new ResolverNamespaceData();
JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor( JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor(
(NamespaceDescriptorParent) resolveParentDescriptor(psiClass), (NamespaceDescriptorParent) resolveParentDescriptor(psiClass),
Collections.<AnnotationDescriptor>emptyList(), // TODO Collections.<AnnotationDescriptor>emptyList(), // TODO
@@ -900,10 +983,10 @@ public class JavaDescriptorResolver {
new FqName(psiClass.getQualifiedName()), new FqName(psiClass.getQualifiedName()),
false false
); );
namespaceData.namespaceDescriptor = ns; ResolverNamespaceData namespaceData = new ResolverNamespaceData(psiClass, ns);
trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespaceData.namespaceDescriptor, true); trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespaceData.namespaceDescriptor, true);
ns.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true)); ns.setMemberScope(new JavaClassMembersScope(semanticServices, namespaceData));
trace.record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor); trace.record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor);
return namespaceData; return namespaceData;
} }
@@ -1010,8 +1093,13 @@ public class JavaDescriptorResolver {
} }
} }
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, String fieldName, boolean staticMembers) { public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull String fieldName, @NotNull ResolverScopeData scopeData) {
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
if (scopeData.psiClass == null) {
return Collections.emptySet();
}
getResolverScopeData(scopeData);
NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName);
if (namedMembers == null) { if (namedMembers == null) {
@@ -1019,7 +1107,8 @@ public class JavaDescriptorResolver {
} }
Set<VariableDescriptor> r = new HashSet<VariableDescriptor>(); Set<VariableDescriptor> r = new HashSet<VariableDescriptor>();
resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, fieldName, "class or namespace " + psiClass.getQualifiedName()); resolveNamedGroupProperties(scopeData.classOrNamespaceDescriptor, scopeData, namedMembers, fieldName,
"class or namespace " + scopeData.psiClass.getQualifiedName());
r.addAll(namedMembers.propertyDescriptors); r.addAll(namedMembers.propertyDescriptors);
@@ -1031,17 +1120,17 @@ public class JavaDescriptorResolver {
} }
@NotNull @NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, boolean staticMembers) { public Set<VariableDescriptor> resolveFieldGroup(@NotNull ResolverScopeData scopeData) {
getResolverScopeData(scopeData);
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
Set<VariableDescriptor> descriptors = Sets.newHashSet(); Set<VariableDescriptor> descriptors = Sets.newHashSet();
Map<String, NamedMembers> membersForProperties = scopeData.namedMembersMap; Map<String, NamedMembers> membersForProperties = scopeData.namedMembersMap;
for (Map.Entry<String, NamedMembers> entry : membersForProperties.entrySet()) { for (Map.Entry<String, NamedMembers> entry : membersForProperties.entrySet()) {
NamedMembers namedMembers = entry.getValue(); NamedMembers namedMembers = entry.getValue();
String propertyName = entry.getKey(); String propertyName = entry.getKey();
resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, propertyName, "class or namespace " + psiClass.getQualifiedName()); resolveNamedGroupProperties(scopeData.classOrNamespaceDescriptor, scopeData, namedMembers, propertyName, "class or namespace " + scopeData.psiClass.getQualifiedName());
descriptors.addAll(namedMembers.propertyDescriptors); descriptors.addAll(namedMembers.propertyDescriptors);
} }
@@ -1079,9 +1168,10 @@ public class JavaDescriptorResolver {
private void resolveNamedGroupProperties( private void resolveNamedGroupProperties(
@NotNull ClassOrNamespaceDescriptor owner, @NotNull ClassOrNamespaceDescriptor owner,
@NotNull ResolverScopeData scopeData, @NotNull ResolverScopeData scopeData,
boolean staticMembers, @NotNull NamedMembers namedMembers, @NotNull String propertyName, @NotNull NamedMembers namedMembers, @NotNull String propertyName,
@NotNull String context @NotNull String context) {
) { getResolverScopeData(scopeData);
if (namedMembers.propertyDescriptors != null) { if (namedMembers.propertyDescriptors != null) {
return; return;
} }
@@ -1306,8 +1396,7 @@ public class JavaDescriptorResolver {
Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet(); Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet();
for (PsiMethodWrapper method : namedMembers.methods) { for (PsiMethodWrapper method : namedMembers.methods) {
FunctionDescriptorImpl function = resolveMethodToFunctionDescriptor(owner, psiClass, FunctionDescriptorImpl function = resolveMethodToFunctionDescriptor(owner, psiClass, method, scopeData);
method);
if (function != null) { if (function != null) {
functionsFromCurrent.add((SimpleFunctionDescriptor) function); functionsFromCurrent.add((SimpleFunctionDescriptor) function);
} }
@@ -1357,42 +1446,28 @@ public class JavaDescriptorResolver {
return r; return r;
} }
private ResolverScopeData getResolverScopeData(@NotNull ClassOrNamespaceDescriptor owner, PsiClassWrapper psiClass) { private void getResolverScopeData(@NotNull ResolverScopeData scopeData) {
// TODO: store scopeData in Java*Scope
ResolverScopeData scopeData;
boolean staticMembers;
if (owner instanceof JavaNamespaceDescriptor) {
scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName());
staticMembers = true;
} else if (owner instanceof ClassDescriptor) {
scopeData = classDescriptorCache.get(new FqName(psiClass.getQualifiedName()));
staticMembers = false;
} else {
throw new IllegalStateException("unknown owner: " + owner.getClass().getName());
}
if (scopeData == null) {
throw new IllegalStateException();
}
if (scopeData.namedMembersMap == null) { if (scopeData.namedMembersMap == null) {
scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin); if (scopeData.psiClass != null) {
scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(new PsiClassWrapper(scopeData.psiClass), scopeData.staticMembers, scopeData.kotlin);
} else {
scopeData.namedMembersMap = Collections.emptyMap();
}
} }
return scopeData;
} }
@NotNull @NotNull
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull PsiClass psiClass, @NotNull String methodName, boolean staticMembers) { public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull String methodName, @NotNull ResolverScopeData scopeData) {
ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass)); getResolverScopeData(scopeData);
Map<String, NamedMembers> namedMembersMap = resolverScopeData.namedMembersMap; Map<String, NamedMembers> namedMembersMap = scopeData.namedMembersMap;
NamedMembers namedMembers = namedMembersMap.get(methodName); NamedMembers namedMembers = namedMembersMap.get(methodName);
if (namedMembers != null && namedMembers.methods != null) { if (namedMembers != null && namedMembers.methods != null) {
TypeSubstitutor typeSubstitutor = typeSubstitutorForGenericSupertypes(resolverScopeData); TypeSubstitutor typeSubstitutor = typeSubstitutorForGenericSupertypes(scopeData);
resolveNamedGroupFunctions(descriptor, psiClass, typeSubstitutor, namedMembers, methodName, resolverScopeData); resolveNamedGroupFunctions(scopeData.classOrNamespaceDescriptor, scopeData.psiClass, typeSubstitutor, namedMembers, methodName, scopeData);
return namedMembers.functionDescriptors; return namedMembers.functionDescriptors;
} else { } else {
@@ -1436,13 +1511,16 @@ public class JavaDescriptorResolver {
} }
@Nullable @Nullable
private FunctionDescriptorImpl resolveMethodToFunctionDescriptor(ClassOrNamespaceDescriptor owner, final PsiClass psiClass, final PsiMethodWrapper method) { private FunctionDescriptorImpl resolveMethodToFunctionDescriptor(
ClassOrNamespaceDescriptor owner, final PsiClass psiClass, final PsiMethodWrapper method,
@NotNull ResolverScopeData scopeData) {
getResolverScopeData(scopeData);
PsiType returnType = method.getReturnType(); PsiType returnType = method.getReturnType();
if (returnType == null) { if (returnType == null) {
return null; return null;
} }
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
boolean kotlin; boolean kotlin;
if (owner instanceof JavaNamespaceDescriptor) { if (owner instanceof JavaNamespaceDescriptor) {
@@ -1580,8 +1658,9 @@ public class JavaDescriptorResolver {
return annotation; return annotation;
} }
public List<FunctionDescriptor> resolveMethods(@NotNull PsiClass psiClass, @NotNull ClassOrNamespaceDescriptor containingDeclaration) { public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) {
ResolverScopeData scopeData = getResolverScopeData(containingDeclaration, new PsiClassWrapper(psiClass));
getResolverScopeData(scopeData);
TypeSubstitutor substitutorForGenericSupertypes = typeSubstitutorForGenericSupertypes(scopeData); TypeSubstitutor substitutorForGenericSupertypes = typeSubstitutorForGenericSupertypes(scopeData);
@@ -1590,7 +1669,7 @@ public class JavaDescriptorResolver {
for (Map.Entry<String, NamedMembers> entry : scopeData.namedMembersMap.entrySet()) { for (Map.Entry<String, NamedMembers> entry : scopeData.namedMembersMap.entrySet()) {
String methodName = entry.getKey(); String methodName = entry.getKey();
NamedMembers namedMembers = entry.getValue(); NamedMembers namedMembers = entry.getValue();
resolveNamedGroupFunctions(containingDeclaration, psiClass, substitutorForGenericSupertypes, namedMembers, methodName, scopeData); resolveNamedGroupFunctions(scopeData.classOrNamespaceDescriptor, scopeData.psiClass, substitutorForGenericSupertypes, namedMembers, methodName, scopeData);
functions.addAll(namedMembers.functionDescriptors); functions.addAll(namedMembers.functionDescriptors);
} }
@@ -1608,8 +1687,8 @@ public class JavaDescriptorResolver {
} }
private TypeSubstitutor typeSubstitutorForGenericSupertypes(ResolverScopeData scopeData) { private TypeSubstitutor typeSubstitutorForGenericSupertypes(ResolverScopeData scopeData) {
if (scopeData instanceof ResolverClassData) { if (scopeData instanceof ResolverBinaryClassData) {
return createSubstitutorForGenericSupertypes(((ResolverClassData)scopeData).getClassDescriptor()); return createSubstitutorForGenericSupertypes(((ResolverBinaryClassData) scopeData).getClassDescriptor());
} else { } else {
return TypeSubstitutor.EMPTY; return TypeSubstitutor.EMPTY;
} }
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiPackage; import com.intellij.psi.PsiPackage;
@@ -46,11 +45,11 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
public JavaPackageScope( public JavaPackageScope(
@NotNull FqName packageFQN, @NotNull FqName packageFQN,
@NotNull NamespaceDescriptor containingDescriptor,
@NotNull JavaSemanticServices semanticServices, @NotNull JavaSemanticServices semanticServices,
@Nullable PsiPackage psiPackage, @Nullable PsiPackage psiPackage,
@Nullable PsiClass psiClass) { @Nullable PsiClass psiClass,
super(containingDescriptor, semanticServices, psiClass); @NotNull JavaDescriptorResolver.ResolverScopeData resolverNamespaceData) {
super(semanticServices, resolverNamespaceData);
this.packageFQN = packageFQN; this.packageFQN = packageFQN;
this.psiPackage = psiPackage; this.psiPackage = psiPackage;
@@ -61,7 +60,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
@Override @Override
public ClassifierDescriptor getClassifier(@NotNull String name) { public ClassifierDescriptor getClassifier(@NotNull String name) {
ClassDescriptor classDescriptor = semanticServices.getDescriptorResolver().resolveClass(getQualifiedName(packageFQN, name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN); ClassDescriptor classDescriptor = semanticServices.getDescriptorResolver().resolveClass(packageFQN.child(name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
if (classDescriptor == null || DescriptorUtils.isObject(classDescriptor)) { if (classDescriptor == null || DescriptorUtils.isObject(classDescriptor)) {
// TODO: this is a big hack against several things that I barely understand myself and cannot explain // TODO: this is a big hack against several things that I barely understand myself and cannot explain
// 1. We should not return objects from this method, and maybe JDR.resolveClass should not return too // 1. We should not return objects from this method, and maybe JDR.resolveClass should not return too
@@ -79,12 +78,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
@Override @Override
public NamespaceDescriptor getNamespace(@NotNull String name) { public NamespaceDescriptor getNamespace(@NotNull String name) {
return semanticServices.getDescriptorResolver().resolveNamespace(getQualifiedName(packageFQN, name), DescriptorSearchRule.INCLUDE_KOTLIN); return semanticServices.getDescriptorResolver().resolveNamespace(packageFQN.child(name), DescriptorSearchRule.INCLUDE_KOTLIN);
}
@Override
protected boolean staticMembers() {
return true;
} }
/** /**
@@ -96,10 +90,10 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
if (allDescriptors == null) { if (allDescriptors == null) {
allDescriptors = Sets.newHashSet(); allDescriptors = Sets.newHashSet();
if (psiClass != null) { if (resolverScopeData.psiClass != null) {
allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(psiClass, descriptor)); allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(resolverScopeData));
allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(descriptor, psiClass, staticMembers())); allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(resolverScopeData));
} }
if (psiPackage != null) { if (psiPackage != null) {
@@ -107,7 +101,8 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
final JavaDescriptorResolver descriptorResolver = semanticServices.getDescriptorResolver(); final JavaDescriptorResolver descriptorResolver = semanticServices.getDescriptorResolver();
for (PsiPackage psiSubPackage : psiPackage.getSubPackages()) { for (PsiPackage psiSubPackage : psiPackage.getSubPackages()) {
NamespaceDescriptor childNs = descriptorResolver.resolveNamespace(new FqName(psiSubPackage.getQualifiedName()), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN); NamespaceDescriptor childNs = descriptorResolver.resolveNamespace(
new FqName(psiSubPackage.getQualifiedName()), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
if (childNs != null) { if (childNs != null) {
allDescriptors.add(childNs); allDescriptors.add(childNs);
} }
@@ -140,9 +135,4 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
return allDescriptors; return allDescriptors;
} }
@NotNull
static FqName getQualifiedName(@NotNull FqName packageFQN, @NotNull String name) {
return packageFQN.child(name);
}
} }