diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index a52f7ca03d6..eae2a3d1dac 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -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 getDescriptorsForDeclarations(Collection declarationsOrFiles) { - final List 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 functionDescriptors = outerScope.getFunctions(jetFunction.getNameAsSafeName()); - descriptors.addAll(functionDescriptors); - } - else if (declaration instanceof JetProperty) { - JetProperty jetProperty = (JetProperty) declaration; - Set 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() { + @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 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); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index 12149b12431..f7a1d3594da 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -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 - } }