Order the computations in LazyTopDownAnalyzer

- First, all class descriptors are created
- Then, all functions and properties
- Then the rest
This commit is contained in:
Andrey Breslav
2014-04-14 19:47:29 +04:00
parent b017b87093
commit fef2968e1d
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.name.FqName;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -90,36 +91,20 @@ public class LazyTopDownAnalyzer {
final TopDownAnalysisContext c = new TopDownAnalysisContext(topDownAnalysisParameters);
final Multimap<FqName, JetElement> topLevelFqNames = HashMultimap.create();
final List<JetProperty> properties = new ArrayList<JetProperty>();
final List<JetNamedFunction> functions = new ArrayList<JetNamedFunction>();
// fill in the context
for (PsiElement declaration : declarations) {
declaration.accept(
new JetVisitorVoid() {
private void registerDeclarations(@NotNull List<JetDeclaration> declarations) {
for (JetDeclaration jetDeclaration : declarations) {
jetDeclaration.accept(this);
}
}
private void registerTopLevelFqName(
@NotNull JetNamedDeclaration declaration,
@NotNull DeclarationDescriptor descriptor
) {
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
FqName fqName = declaration.getFqName();
if (fqName != null) {
topLevelFqNames.put(fqName, declaration);
}
}
}
private void registerScope(@Nullable JetDeclaration declaration) {
if (declaration == null) return;
c.registerDeclaringScope(
declaration,
resolveSession.getScopeProvider().getResolutionScopeForDeclaration(declaration)
);
}
@Override
public void visitDeclaration(@NotNull JetDeclaration dcl) {
throw new IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText());
@@ -146,22 +131,15 @@ public class LazyTopDownAnalyzer {
topLevelFqNames.put(file.getPackageFqName(), packageDirective);
}
resolveAndCheckImports(file, resolveSession);
}
private void resolveAndCheckImports(@NotNull JetFile file, @NotNull ResolveSession resolveSession) {
LazyImportScope fileScope = resolveSession.getScopeProvider().getExplicitImportsScopeForFile(file);
fileScope.forceResolveAllContents();
}
private void visitClassOrObject(@NotNull JetClassOrObject classOrObject) {
ClassDescriptorWithResolutionScopes descriptor = ForceResolveUtil.forceResolveAllContents(
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject)
);
ClassDescriptorWithResolutionScopes descriptor =
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject);
c.getDeclaredClasses().put(classOrObject, descriptor);
registerDeclarations(classOrObject.getDeclarations());
registerTopLevelFqName(classOrObject, descriptor);
registerTopLevelFqName(topLevelFqNames, classOrObject, descriptor);
checkManyClassObjects(classOrObject);
}
@@ -215,47 +193,121 @@ public class LazyTopDownAnalyzer {
@Override
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
registerScope(initializer);
registerScope(c, resolveSession, initializer);
}
@Override
public void visitNamedFunction(@NotNull JetNamedFunction function) {
c.getFunctions().put(
function,
ForceResolveUtil.forceResolveAllContents(
(SimpleFunctionDescriptor) resolveSession.resolveToDescriptor(function)
)
);
registerScope(function);
functions.add(function);
}
@Override
public void visitProperty(@NotNull JetProperty property) {
PropertyDescriptor descriptor = ForceResolveUtil.forceResolveAllContents(
(PropertyDescriptor) resolveSession.resolveToDescriptor(property)
);
c.getProperties().put(property, descriptor);
registerTopLevelFqName(property, descriptor);
registerScope(property);
registerScope(property.getGetter());
registerScope(property.getSetter());
properties.add(property);
}
}
);
}
createFunctionDescriptors(c, resolveSession, functions);
createPropertyDescriptors(c, resolveSession, topLevelFqNames, properties);
forceResolveAllClasses(c);
declarationResolver.checkRedeclarationsInPackages(resolveSession, topLevelFqNames);
declarationResolver.checkRedeclarationsInInnerClassNames(c);
overrideResolver.check(c);
resolveImportsInAllFiles(c, resolveSession);
overloadResolver.process(c);
bodyResolver.resolveBodies(c);
return c;
}
private static void resolveImportsInAllFiles(TopDownAnalysisContext c, ResolveSession resolveSession) {
for (JetFile file : c.getFiles()) {
resolveAndCheckImports(file, resolveSession);
}
for (JetScript script : c.getScripts().keySet()) {
resolveAndCheckImports((JetFile) script.getContainingFile(), resolveSession);
}
}
private static void forceResolveAllClasses(TopDownAnalysisContext c) {
for (ClassDescriptorWithResolutionScopes classDescriptor : c.getAllClasses()) {
ForceResolveUtil.forceResolveAllContents(classDescriptor);
}
}
private static void createPropertyDescriptors(
TopDownAnalysisContext c,
ResolveSession resolveSession,
Multimap<FqName, JetElement> topLevelFqNames,
List<JetProperty> properties
) {
for (JetProperty property : properties) {
PropertyDescriptor descriptor = (PropertyDescriptor) resolveSession.resolveToDescriptor(property);
c.getProperties().put(property, descriptor);
registerTopLevelFqName(topLevelFqNames, property, descriptor);
registerScope(c, resolveSession, property);
registerScope(c, resolveSession, property.getGetter());
registerScope(c, resolveSession, property.getSetter());
}
}
private static void createFunctionDescriptors(
TopDownAnalysisContext c,
ResolveSession resolveSession,
List<JetNamedFunction> functions
) {
for (JetNamedFunction function : functions) {
c.getFunctions().put(
function,
(SimpleFunctionDescriptor) resolveSession.resolveToDescriptor(function)
);
registerScope(c, resolveSession, function);
}
}
private static void resolveAndCheckImports(@NotNull JetFile file, @NotNull ResolveSession resolveSession) {
LazyImportScope fileScope = resolveSession.getScopeProvider().getExplicitImportsScopeForFile(file);
fileScope.forceResolveAllContents();
}
private static void registerScope(
@NotNull TopDownAnalysisContext c,
@NotNull ResolveSession resolveSession,
@Nullable JetDeclaration declaration
) {
if (declaration == null) return;
c.registerDeclaringScope(
declaration,
resolveSession.getScopeProvider().getResolutionScopeForDeclaration(declaration)
);
}
private static void registerTopLevelFqName(
@NotNull Multimap<FqName, JetElement> topLevelFqNames,
@NotNull JetNamedDeclaration declaration,
@NotNull DeclarationDescriptor descriptor
) {
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
FqName fqName = declaration.getFqName();
if (fqName != null) {
topLevelFqNames.put(fqName, declaration);
}
}
}
}