resolveToDescriptor() supported for:

* classes
* functions
* class objects
* type parameters
* packages
This commit is contained in:
Andrey Breslav
2012-06-13 18:38:33 +04:00
parent 2cd7d8505a
commit 743cff4161
2 changed files with 97 additions and 92 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.jet.lang.resolve.lazy;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -35,9 +34,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author abreslav
@@ -101,61 +98,21 @@ public class ResolveSession {
@NotNull
public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
if (classOrObject.getParent() instanceof JetClassObject) {
return getClassObjectDescriptor((JetClassObject) classOrObject.getParent());
}
JetScope resolutionScope = getInjector().getScopeProvider().getResolutionScopeForDeclaration((JetDeclaration) classOrObject);
ClassifierDescriptor classifier = resolutionScope.getClassifier(classOrObject.getNameAsName());
Name name = classOrObject.getNameAsName();
assert name != null : "Name is null for " + classOrObject + " " + classOrObject.getText();
ClassifierDescriptor classifier = resolutionScope.getClassifier(name);
return (ClassDescriptor) classifier;
}
public Collection<DeclarationDescriptor> getDescriptorsForDeclarations(Collection<PsiElement> declarationsOrFiles) {
final List<DeclarationDescriptor> descriptors = Lists.newArrayList();
for (PsiElement declarationOrFile : declarationsOrFiles) {
declarationOrFile.accept(new JetVisitorVoid() {
@Override
public void visitJetFile(JetFile file) {
JetNamespaceHeader header = file.getNamespaceHeader();
if (header == null) {
throw new UnsupportedOperationException("Lazy resolve is not supported for scripts");
}
NamespaceDescriptor packageDescriptor = getPackageDescriptorByFqName(new FqName(header.getQualifiedName()));
if (packageDescriptor == null) {
throw new IllegalStateException("Package descriptor not found for: " + header.getQualifiedName());
}
JetScope packageMemberScope = packageDescriptor.getMemberScope();
for (JetDeclaration declaration : file.getDeclarations()) {
collectDescriptors(packageMemberScope, declaration);
}
}
@Override
public void visitDeclaration(JetDeclaration dcl) {
JetScope scope = injector.getScopeProvider().getResolutionScopeForDeclaration(dcl);
collectDescriptors(scope, dcl);
}
private void collectDescriptors(JetScope outerScope, JetDeclaration declaration) {
if (declaration instanceof JetClass) {
JetClass jetClass = (JetClass) declaration;
descriptors.add(outerScope.getClassifier(jetClass.getNameAsSafeName()));
}
else if (declaration instanceof JetFunction) {
JetFunction jetFunction = (JetFunction) declaration;
Set<FunctionDescriptor> functionDescriptors = outerScope.getFunctions(jetFunction.getNameAsSafeName());
descriptors.addAll(functionDescriptors);
}
else if (declaration instanceof JetProperty) {
JetProperty jetProperty = (JetProperty) declaration;
Set<VariableDescriptor> functionDescriptors = outerScope.getProperties(jetProperty.getNameAsSafeName());
descriptors.addAll(functionDescriptors);
}
else if (declaration instanceof JetObjectDeclaration) {
JetObjectDeclaration jetObjectDeclaration = (JetObjectDeclaration) declaration;
descriptors.addAll(outerScope.getProperties(jetObjectDeclaration.getNameAsSafeName()));
descriptors.add(outerScope.getObjectDescriptor(jetObjectDeclaration.getNameAsSafeName()));
}
}
});
}
return descriptors;
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class));
LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor();
assert classObjectDescriptor != null : "Class object is declared, but is null for " + classDescriptor;
return classObjectDescriptor;
}
@NotNull
@@ -199,4 +156,78 @@ public class ResolveSession {
assert classDescriptor instanceof LazyClassDescriptor : "Trying to resolve a member of a non-lazily loaded class: " + element;
return (LazyClassDescriptor) classDescriptor;
}
@NotNull
public DeclarationDescriptor resolveToDescriptor(JetDeclaration declaration) {
return declaration.accept(new JetVisitor<DeclarationDescriptor, Void>() {
@Override
public DeclarationDescriptor visitClass(JetClass klass, Void data) {
return getClassDescriptor(klass);
}
@Override
public DeclarationDescriptor visitObjectDeclaration(JetObjectDeclaration declaration, Void data) {
PsiElement parent = declaration.getParent();
if (parent instanceof JetClassObject) {
JetClassObject jetClassObject = (JetClassObject) parent;
return resolveToDescriptor(jetClassObject);
}
return getClassDescriptor(declaration);
}
@Override
public DeclarationDescriptor visitClassObject(JetClassObject classObject, Void data) {
DeclarationDescriptor containingDeclaration =
getInjector().getScopeProvider().getResolutionScopeForDeclaration(classObject).getContainingDeclaration();
return ((ClassDescriptor) containingDeclaration).getClassObjectDescriptor();
}
@Override
public DeclarationDescriptor visitTypeParameter(JetTypeParameter parameter, Void data) {
JetTypeParameterListOwner ownerElement = PsiTreeUtil.getParentOfType(parameter, JetTypeParameterListOwner.class);
DeclarationDescriptor ownerDescriptor = resolveToDescriptor(ownerElement);
List<TypeParameterDescriptor> typeParameters;
Name name = parameter.getNameAsName();
if (ownerDescriptor instanceof CallableDescriptor) {
CallableDescriptor callableDescriptor = (CallableDescriptor) ownerDescriptor;
typeParameters = callableDescriptor.getTypeParameters();
}
else if (ownerDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) ownerDescriptor;
typeParameters = classDescriptor.getTypeConstructor().getParameters();
}
else {
throw new IllegalStateException("Unknown owner kind for a type parameter: " + ownerDescriptor);
}
for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
if (typeParameterDescriptor.getName().equals(name)) {
return typeParameterDescriptor;
}
}
throw new IllegalStateException("Type parameter " + name + " not found for " + ownerDescriptor);
}
@Override
public DeclarationDescriptor visitNamedFunction(JetNamedFunction function, Void data) {
JetScope scopeForDeclaration = getInjector().getScopeProvider().getResolutionScopeForDeclaration(function);
scopeForDeclaration.getFunctions(function.getNameAsName());
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
}
@Override
public DeclarationDescriptor visitProperty(JetProperty property, Void data) {
JetScope scopeForDeclaration = getInjector().getScopeProvider().getResolutionScopeForDeclaration(property);
scopeForDeclaration.getProperties(property.getNameAsName());
return getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
}
@Override
public DeclarationDescriptor visitJetElement(JetElement element, Void data) {
throw new IllegalArgumentException("Unsupported declaration type: " + element);
}
}, null);
}
}
@@ -20,15 +20,14 @@ import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import java.util.List;
@@ -71,33 +70,11 @@ public class ScopeProvider {
resolveSession.getInjector().getQualifiedExpressionResolver());
writableScope.importScope(packageDescriptor.getMemberScope());
// TODO: imports
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
// TODO: Cache
return writableScope;
}
@NotNull
public JetScope getScopeForClassMemberResolution(@NotNull JetClassOrObject classOrObject) {
// TODO: cache
ClassDescriptor classDescriptor = resolveSession.getClassDescriptor(classOrObject);
JetScope memberScope = classDescriptor.getDefaultType().getMemberScope();
JetScope outerScope = getResolutionScopeForDeclaration((JetDeclaration) classOrObject);
WritableScope typeParametersScope = new WritableScopeImpl(
JetScope.EMPTY, classDescriptor, RedeclarationHandler.DO_NOTHING, "scope for class member resolution");
for (TypeParameterDescriptor typeParameterDescriptor : classDescriptor.getTypeConstructor().getParameters()) {
typeParametersScope.addClassifierDescriptor(typeParameterDescriptor);
}
return new ChainedScope(classDescriptor, memberScope, typeParametersScope, outerScope);
}
public JetScope getScopeForClassSupertypeResolution(JetClassOrObject declaration) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
public JetScope getResolutionScopeForDeclaration(@NotNull JetDeclaration jetDeclaration) {
PsiElement immediateParent = jetDeclaration.getParent();
@@ -108,19 +85,16 @@ public class ScopeProvider {
JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(jetDeclaration, JetDeclaration.class);
if (parentDeclaration instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) parentDeclaration;
return getScopeForClassMemberResolution(classOrObject);
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) resolveSession.getClassDescriptor(classOrObject);
return classDescriptor.getScopeForMemberDeclarationResolution();
}
else if (parentDeclaration instanceof JetClassObject) {
JetClassObject classObject = (JetClassObject) parentDeclaration;
LazyClassDescriptor classObjectDescriptor = resolveSession.getClassObjectDescriptor(classObject);
return classObjectDescriptor.getScopeForMemberDeclarationResolution();
}
else {
throw new IllegalStateException("Don't call this method for local declarations: " + jetDeclaration);
throw new IllegalStateException("Don't call this method for local declarations: " + jetDeclaration + " " + jetDeclaration.getText());
}
}
public ClassDescriptor buildLazyClassDescriptor(DeclarationDescriptor declaration, Name name, JetScope outerScope) {
throw new UnsupportedOperationException(); // TODO
}
public NamespaceDescriptor buildLazyPackageDescriptor(DeclarationDescriptor declaration,
Name name) {
throw new UnsupportedOperationException(); // TODO
}
}