Order the computations in LazyTopDownAnalyzer
- First, all class descriptors are created - Then, all functions and properties - Then the rest
This commit is contained in:
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -90,36 +91,20 @@ public class LazyTopDownAnalyzer {
|
|||||||
final TopDownAnalysisContext c = new TopDownAnalysisContext(topDownAnalysisParameters);
|
final TopDownAnalysisContext c = new TopDownAnalysisContext(topDownAnalysisParameters);
|
||||||
final Multimap<FqName, JetElement> topLevelFqNames = HashMultimap.create();
|
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
|
// fill in the context
|
||||||
for (PsiElement declaration : declarations) {
|
for (PsiElement declaration : declarations) {
|
||||||
declaration.accept(
|
declaration.accept(
|
||||||
new JetVisitorVoid() {
|
new JetVisitorVoid() {
|
||||||
|
|
||||||
private void registerDeclarations(@NotNull List<JetDeclaration> declarations) {
|
private void registerDeclarations(@NotNull List<JetDeclaration> declarations) {
|
||||||
for (JetDeclaration jetDeclaration : declarations) {
|
for (JetDeclaration jetDeclaration : declarations) {
|
||||||
jetDeclaration.accept(this);
|
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
|
@Override
|
||||||
public void visitDeclaration(@NotNull JetDeclaration dcl) {
|
public void visitDeclaration(@NotNull JetDeclaration dcl) {
|
||||||
throw new IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText());
|
throw new IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText());
|
||||||
@@ -146,22 +131,15 @@ public class LazyTopDownAnalyzer {
|
|||||||
|
|
||||||
topLevelFqNames.put(file.getPackageFqName(), packageDirective);
|
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) {
|
private void visitClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||||
ClassDescriptorWithResolutionScopes descriptor = ForceResolveUtil.forceResolveAllContents(
|
ClassDescriptorWithResolutionScopes descriptor =
|
||||||
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject)
|
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject);
|
||||||
);
|
|
||||||
|
|
||||||
c.getDeclaredClasses().put(classOrObject, descriptor);
|
c.getDeclaredClasses().put(classOrObject, descriptor);
|
||||||
registerDeclarations(classOrObject.getDeclarations());
|
registerDeclarations(classOrObject.getDeclarations());
|
||||||
registerTopLevelFqName(classOrObject, descriptor);
|
registerTopLevelFqName(topLevelFqNames, classOrObject, descriptor);
|
||||||
|
|
||||||
checkManyClassObjects(classOrObject);
|
checkManyClassObjects(classOrObject);
|
||||||
}
|
}
|
||||||
@@ -215,47 +193,121 @@ public class LazyTopDownAnalyzer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
|
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
|
||||||
registerScope(initializer);
|
registerScope(c, resolveSession, initializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitNamedFunction(@NotNull JetNamedFunction function) {
|
public void visitNamedFunction(@NotNull JetNamedFunction function) {
|
||||||
c.getFunctions().put(
|
functions.add(function);
|
||||||
function,
|
|
||||||
ForceResolveUtil.forceResolveAllContents(
|
|
||||||
(SimpleFunctionDescriptor) resolveSession.resolveToDescriptor(function)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
registerScope(function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitProperty(@NotNull JetProperty property) {
|
public void visitProperty(@NotNull JetProperty property) {
|
||||||
PropertyDescriptor descriptor = ForceResolveUtil.forceResolveAllContents(
|
properties.add(property);
|
||||||
(PropertyDescriptor) resolveSession.resolveToDescriptor(property)
|
|
||||||
);
|
|
||||||
|
|
||||||
c.getProperties().put(property, descriptor);
|
|
||||||
registerTopLevelFqName(property, descriptor);
|
|
||||||
|
|
||||||
registerScope(property);
|
|
||||||
registerScope(property.getGetter());
|
|
||||||
registerScope(property.getSetter());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createFunctionDescriptors(c, resolveSession, functions);
|
||||||
|
|
||||||
|
createPropertyDescriptors(c, resolveSession, topLevelFqNames, properties);
|
||||||
|
|
||||||
|
forceResolveAllClasses(c);
|
||||||
|
|
||||||
declarationResolver.checkRedeclarationsInPackages(resolveSession, topLevelFqNames);
|
declarationResolver.checkRedeclarationsInPackages(resolveSession, topLevelFqNames);
|
||||||
declarationResolver.checkRedeclarationsInInnerClassNames(c);
|
declarationResolver.checkRedeclarationsInInnerClassNames(c);
|
||||||
|
|
||||||
overrideResolver.check(c);
|
overrideResolver.check(c);
|
||||||
|
|
||||||
|
resolveImportsInAllFiles(c, resolveSession);
|
||||||
|
|
||||||
overloadResolver.process(c);
|
overloadResolver.process(c);
|
||||||
|
|
||||||
bodyResolver.resolveBodies(c);
|
bodyResolver.resolveBodies(c);
|
||||||
|
|
||||||
|
|
||||||
return 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user