resolveToDescriptor() supported for:
* classes * functions * class objects * type parameters * packages
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user