TopDownAnalyzer supports lazy mode

This commit is contained in:
Andrey Breslav
2014-03-12 15:14:37 +04:00
parent 3f09b0e030
commit fd9cb59841
5 changed files with 156 additions and 11 deletions
@@ -187,6 +187,8 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
this.topDownAnalyzer.setPackageFragmentProvider(mutablePackageFragmentProvider);
this.topDownAnalyzer.setScriptHeaderResolver(scriptHeaderResolver);
this.topDownAnalyzer.setTrace(bindingTrace);
this.topDownAnalyzer.setTypeHierarchyResolver(typeHierarchyResolver);
javaClassFinder.setProject(project);
@@ -145,6 +145,8 @@ public class InjectorForTopDownAnalyzerBasic {
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
this.topDownAnalyzer.setPackageFragmentProvider(mutablePackageFragmentProvider);
this.topDownAnalyzer.setScriptHeaderResolver(scriptHeaderResolver);
this.topDownAnalyzer.setTrace(bindingTrace);
this.topDownAnalyzer.setTypeHierarchyResolver(typeHierarchyResolver);
bodyResolver.setAnnotationResolver(annotationResolver);
@@ -61,6 +61,10 @@ public class OverrideResolver {
//all created fake descriptors are stored to resolve visibility on them later
generateOverridesAndDelegation(c);
check(c);
}
public void check(@NotNull TopDownAnalysisContext c) {
checkVisibility(c);
checkOverrides(c);
checkParameterOverridesForAllClasses(c);
@@ -19,30 +19,41 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicates;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.context.GlobalContextImpl;
import org.jetbrains.jet.di.InjectorForLazyResolve;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
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.WritableScope;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.storage.LockBasedStorageManager;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.*;
public class TopDownAnalyzer {
public static boolean LAZY;
static {
LAZY = "true".equals(System.getProperty("lazy.tda"));
}
@NotNull
private BindingTrace trace;
@NotNull
private DeclarationResolver declarationResolver;
@NotNull
@@ -57,6 +68,13 @@ public class TopDownAnalyzer {
private MutablePackageFragmentProvider packageFragmentProvider;
@NotNull
private BodyResolver bodyResolver;
@NotNull
private ScriptHeaderResolver scriptHeaderResolver;
@Inject
public void setTrace(@NotNull BindingTrace trace) {
this.trace = trace;
}
@Inject
public void setDeclarationResolver(@NotNull DeclarationResolver declarationResolver) {
@@ -93,8 +111,13 @@ public class TopDownAnalyzer {
this.bodyResolver = bodyResolver;
}
@Inject
public void setScriptHeaderResolver(@NotNull ScriptHeaderResolver scriptHeaderResolver) {
this.scriptHeaderResolver = scriptHeaderResolver;
}
public void doProcess(
@NotNull TopDownAnalysisContext c,
@NotNull final TopDownAnalysisContext c,
@NotNull JetScope outerScope,
@NotNull PackageLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations
@@ -102,11 +125,113 @@ public class TopDownAnalyzer {
// c.enableDebugOutput();
c.debug("Enter");
typeHierarchyResolver.process(c, outerScope, owner, declarations);
declarationResolver.process(c);
overrideResolver.process(c);
if (LAZY && !c.getTopDownAnalysisParameters().isDeclaredLocally()) {
final ResolveSession resolveSession = new InjectorForLazyResolve(
declarations.iterator().next().getProject(), // TODO
new GlobalContextImpl((LockBasedStorageManager) c.getStorageManager(), c.getExceptionTracker()), // TODO
(ModuleDescriptorImpl) moduleDescriptor, // TODO
new FileBasedDeclarationProviderFactory(c.getStorageManager(), getFiles(declarations)),
trace
).getResolveSession();
lockScopes(c);
// 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 registerScope(@Nullable JetDeclaration declaration, @NotNull JetDeclaration anchorForScope) {
if (declaration == null) return;
c.registerDeclaringScope(
declaration,
resolveSession.getScopeProvider().getResolutionScopeForDeclaration(anchorForScope)
);
}
@Override
public void visitDeclaration(@NotNull JetDeclaration dcl) {
throw new IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText());
}
@Override
public void visitJetFile(@NotNull JetFile file) {
if (file.isScript()) {
JetScript script = file.getScript();
assert script != null;
scriptHeaderResolver.processScriptHierarchy(c, script, resolveSession.getScopeProvider().getFileScope(file));
}
else {
registerDeclarations(file.getDeclarations());
}
}
private void visitClassOrObject(@NotNull JetClassOrObject classOrObject) {
c.getClasses().put(
classOrObject,
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject)
);
registerDeclarations(classOrObject.getDeclarations());
}
@Override
public void visitClass(@NotNull JetClass klass) {
visitClassOrObject(klass);
}
@Override
public void visitClassObject(@NotNull JetClassObject classObject) {
visitClassOrObject(classObject.getObjectDeclaration());
}
@Override
public void visitEnumEntry(@NotNull JetEnumEntry enumEntry) {
visitClassOrObject(enumEntry);
}
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
visitClassOrObject(declaration);
}
@Override
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
registerScope(initializer, initializer);
}
@Override
public void visitNamedFunction(@NotNull JetNamedFunction function) {
c.getFunctions().put(
function,
(SimpleFunctionDescriptor) resolveSession.resolveToDescriptor(function)
);
registerScope(function, function);
}
@Override
public void visitProperty(@NotNull JetProperty property) {
c.getProperties().put(
property,
(PropertyDescriptor) resolveSession.resolveToDescriptor(property)
);
registerScope(property, property);
registerScope(property.getGetter(), property);
registerScope(property.getSetter(), property);
}
}
);
}
overrideResolver.check(c);
}
else {
typeHierarchyResolver.process(c, outerScope, owner, declarations);
declarationResolver.process(c);
overrideResolver.process(c);
lockScopes(c);
}
overloadResolver.process(c);
@@ -118,6 +243,16 @@ public class TopDownAnalyzer {
c.printDebugOutput(System.out);
}
private static Collection<JetFile> getFiles(Collection<? extends PsiElement> declarations) {
return new LinkedHashSet<JetFile>(KotlinPackage.map(declarations, new Function1<PsiElement, JetFile>() {
@Nullable
@Override
public JetFile invoke(PsiElement element) {
return (JetFile) element.getContainingFile();
}
}));
}
private void lockScopes(@NotNull TopDownAnalysisContext c) {
for (ClassDescriptorWithResolutionScopes mutableClassDescriptor : c.getClasses().values()) {
((MutableClassDescriptor) mutableClassDescriptor).lockScopes();
@@ -145,6 +145,8 @@ public class InjectorForTopDownAnalyzerForJs {
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
this.topDownAnalyzer.setPackageFragmentProvider(mutablePackageFragmentProvider);
this.topDownAnalyzer.setScriptHeaderResolver(scriptHeaderResolver);
this.topDownAnalyzer.setTrace(bindingTrace);
this.topDownAnalyzer.setTypeHierarchyResolver(typeHierarchyResolver);
bodyResolver.setAnnotationResolver(annotationResolver);