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;
|
package org.jetbrains.jet.lang.resolve.lazy;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
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.InnerClassesScopeWrapper;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -101,61 +98,21 @@ public class ResolveSession {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
|
public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) {
|
||||||
|
if (classOrObject.getParent() instanceof JetClassObject) {
|
||||||
|
return getClassObjectDescriptor((JetClassObject) classOrObject.getParent());
|
||||||
|
}
|
||||||
JetScope resolutionScope = getInjector().getScopeProvider().getResolutionScopeForDeclaration((JetDeclaration) classOrObject);
|
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;
|
return (ClassDescriptor) classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<DeclarationDescriptor> getDescriptorsForDeclarations(Collection<PsiElement> declarationsOrFiles) {
|
/*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) {
|
||||||
final List<DeclarationDescriptor> descriptors = Lists.newArrayList();
|
LazyClassDescriptor classDescriptor = (LazyClassDescriptor) getClassDescriptor(PsiTreeUtil.getParentOfType(classObject, JetClass.class));
|
||||||
for (PsiElement declarationOrFile : declarationsOrFiles) {
|
LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor();
|
||||||
declarationOrFile.accept(new JetVisitorVoid() {
|
assert classObjectDescriptor != null : "Class object is declared, but is null for " + classDescriptor;
|
||||||
@Override
|
return classObjectDescriptor;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -199,4 +156,78 @@ public class ResolveSession {
|
|||||||
assert classDescriptor instanceof LazyClassDescriptor : "Trying to resolve a member of a non-lazily loaded class: " + element;
|
assert classDescriptor instanceof LazyClassDescriptor : "Trying to resolve a member of a non-lazily loaded class: " + element;
|
||||||
return (LazyClassDescriptor) classDescriptor;
|
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.PsiElement;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.NamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.*;
|
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;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -71,33 +70,11 @@ public class ScopeProvider {
|
|||||||
resolveSession.getInjector().getQualifiedExpressionResolver());
|
resolveSession.getInjector().getQualifiedExpressionResolver());
|
||||||
writableScope.importScope(packageDescriptor.getMemberScope());
|
writableScope.importScope(packageDescriptor.getMemberScope());
|
||||||
|
|
||||||
// TODO: imports
|
|
||||||
|
|
||||||
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
|
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
|
||||||
// TODO: Cache
|
// TODO: Cache
|
||||||
return writableScope;
|
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
|
@NotNull
|
||||||
public JetScope getResolutionScopeForDeclaration(@NotNull JetDeclaration jetDeclaration) {
|
public JetScope getResolutionScopeForDeclaration(@NotNull JetDeclaration jetDeclaration) {
|
||||||
PsiElement immediateParent = jetDeclaration.getParent();
|
PsiElement immediateParent = jetDeclaration.getParent();
|
||||||
@@ -108,19 +85,16 @@ public class ScopeProvider {
|
|||||||
JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(jetDeclaration, JetDeclaration.class);
|
JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(jetDeclaration, JetDeclaration.class);
|
||||||
if (parentDeclaration instanceof JetClassOrObject) {
|
if (parentDeclaration instanceof JetClassOrObject) {
|
||||||
JetClassOrObject classOrObject = (JetClassOrObject) parentDeclaration;
|
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 {
|
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