more DI in top down analysis

This commit is contained in:
Stepan Koltsov
2012-03-14 21:47:29 +04:00
parent 7a6f18c14a
commit fecc98af8c
11 changed files with 265 additions and 122 deletions
@@ -145,7 +145,7 @@ public class AnalyzerFacadeForJVM {
public static BindingContext analyzeFilesWithJavaIntegration(Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
return AnalyzingUtils.analyzeFilesWithGivenTrace(
AnalyzingUtils.analyzeFilesWithGivenTrace(
project,
JavaBridgeConfiguration.createJavaBridgeConfiguration(project, bindingTraceContext, DefaultModuleConfiguration.createStandardConfiguration(project)),
files,
@@ -153,6 +153,7 @@ public class AnalyzerFacadeForJVM {
flowDataTraceFactory,
bindingTraceContext
);
return bindingTraceContext.getBindingContext();
}
public static BindingContext shallowAnalyzeFiles(Collection<JetFile> files) {
@@ -18,12 +18,13 @@
package org.jetbrains.jet.di;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext;
import org.jetbrains.jet.lang.resolve.BodyResolver;
import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer;
import org.jetbrains.jet.lang.resolve.DeclarationsChecker;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
@@ -39,7 +40,7 @@ import org.jetbrains.jet.lang.resolve.OverloadResolver;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
@@ -49,25 +50,29 @@ import org.jetbrains.annotations.NotNull;
public class InjectorForTopDownAnalyzer {
private TopDownAnalyzer topDownAnalyzer;
private TopDownAnalysisContext topDownAnalysisContext;
private BodyResolver bodyResolver;
private ControlFlowAnalyzer controlFlowAnalyzer;
private DeclarationsChecker declarationsChecker;
private DescriptorResolver descriptorResolver;
private final Project project;
private final TopDownAnalysisParameters topDownAnalysisParameters;
public InjectorForTopDownAnalyzer(
@NotNull Project project,
@NotNull TopDownAnalysisContext topDownAnalysisContext,
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
@NotNull ModuleConfiguration moduleConfiguration,
@NotNull ModuleDescriptor moduleDescriptor,
JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory
) {
this.topDownAnalyzer = new TopDownAnalyzer();
this.topDownAnalysisContext = new TopDownAnalysisContext();
this.bodyResolver = new BodyResolver();
this.controlFlowAnalyzer = new ControlFlowAnalyzer();
this.declarationsChecker = new DeclarationsChecker();
this.descriptorResolver = new DescriptorResolver();
this.project = project;
this.topDownAnalysisParameters = topDownAnalysisParameters;
DeclarationResolver declarationResolver = new DeclarationResolver();
AnnotationResolver annotationResolver = new AnnotationResolver();
CallResolver callResolver = new CallResolver();
@@ -80,19 +85,30 @@ public class InjectorForTopDownAnalyzer {
OverrideResolver overrideResolver = new OverrideResolver();
TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver();
this.topDownAnalyzer.setBodyResolver(bodyResolver);
this.topDownAnalyzer.setConfiguration(moduleConfiguration);
this.topDownAnalyzer.setContext(topDownAnalysisContext);
this.topDownAnalyzer.setControlFlowAnalyzer(controlFlowAnalyzer);
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
this.topDownAnalyzer.setDeclarationsChecker(declarationsChecker);
this.topDownAnalyzer.setDelegationResolver(delegationResolver);
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
this.topDownAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.topDownAnalyzer.setTypeHierarchyResolver(typeHierarchyResolver);
this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setCallResolver(callResolver);
this.bodyResolver.setContext(topDownAnalysisContext);
this.bodyResolver.setDescriptorResolver(descriptorResolver);
this.bodyResolver.setExpressionTypingServices(expressionTypingServices);
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.controlFlowAnalyzer.setContext(topDownAnalysisContext);
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.declarationsChecker.setContext(topDownAnalysisContext);
@@ -129,6 +145,7 @@ public class InjectorForTopDownAnalyzer {
overloadResolver.setContext(topDownAnalysisContext);
overrideResolver.setContext(topDownAnalysisContext);
overrideResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
typeHierarchyResolver.setConfiguration(moduleConfiguration);
typeHierarchyResolver.setContext(topDownAnalysisContext);
@@ -142,6 +159,10 @@ public class InjectorForTopDownAnalyzer {
return this.topDownAnalyzer;
}
public TopDownAnalysisContext getTopDownAnalysisContext() {
return this.topDownAnalysisContext;
}
public BodyResolver getBodyResolver() {
return this.bodyResolver;
}
@@ -162,4 +183,8 @@ public class InjectorForTopDownAnalyzer {
return this.project;
}
public TopDownAnalysisParameters getTopDownAnalysisParameters() {
return this.topDownAnalysisParameters;
}
}
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
@@ -26,16 +25,10 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeAdapter;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import java.util.ArrayList;
import java.util.Collection;
@@ -91,10 +84,11 @@ public class AnalyzingUtils {
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
return analyzeFilesWithGivenTrace(project, configuration, files, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext);
analyzeFilesWithGivenTrace(project, configuration, files, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext);
return bindingTraceContext.getBindingContext();
}
public static BindingContext analyzeFilesWithGivenTrace(
public static void analyzeFilesWithGivenTrace(
@NotNull Project project,
@NotNull final ModuleConfiguration configuration,
@NotNull Collection<JetFile> files,
@@ -102,45 +96,7 @@ public class AnalyzingUtils {
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull BindingTraceContext bindingTraceContext) {
final ModuleDescriptor owner = new ModuleDescriptor("<module>");
final WritableScope scope = new WritableScopeImpl(
JetScope.EMPTY, owner,
new TraceBasedRedeclarationHandler(bindingTraceContext)).setDebugName("Root scope in analyzeNamespace");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
// Import the lang package
scope.importScope(JetStandardLibrary.getInstance().getLibraryScope());
// Import a scope that contains all top-level namespaces that come from dependencies
// This makes the namespaces visible at all, does not import themselves
scope.importScope(new JetScopeAdapter(JetScope.EMPTY) {
@Override
public NamespaceDescriptor getNamespace(@NotNull String name) {
// Is it a top-level namespace coming from the dependencies?
NamespaceDescriptor topLevelNamespaceFromConfiguration = configuration.getTopLevelNamespace(name);
if (topLevelNamespaceFromConfiguration != null) {
return topLevelNamespaceFromConfiguration;
}
// Should be null, we are delegating to EMPTY
return super.getNamespace(name);
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
List<DeclarationDescriptor> allDescriptors = Lists.newArrayList();
configuration.addAllTopLevelNamespacesTo(allDescriptors);
return allDescriptors;
}
});
// dummy builder is used because "root" is module descriptor,
// namespaces added to module explicitly in
TopDownAnalyzer.process(project, bindingTraceContext, scope,
new NamespaceLikeBuilderDummy(), owner, files, filesToAnalyzeCompletely, flowDataTraceFactory, configuration);
return bindingTraceContext.getBindingContext();
TopDownAnalyzer.doAnalyzeFilesWithGivenTrace(project, configuration, files, filesToAnalyzeCompletely, flowDataTraceFactory, bindingTraceContext);
}
}
@@ -55,6 +55,8 @@ public class BodyResolver {
@NotNull
private TopDownAnalysisContext context;
@NotNull
private TopDownAnalysisParameters topDownAnalysisParameters;
@NotNull
private DescriptorResolver descriptorResolver;
@NotNull
private ExpressionTypingServices expressionTypingServices;
@@ -67,6 +69,11 @@ public class BodyResolver {
this.context = context;
}
@Inject
public void setTopDownAnalysisParameters(@NotNull TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
}
@Inject
public void setDescriptorResolver(@NotNull DescriptorResolver descriptorResolver) {
this.descriptorResolver = descriptorResolver;
@@ -97,7 +104,7 @@ public class BodyResolver {
resolveSecondaryConstructorBodies();
resolveFunctionBodies();
if (!context.isDeclaredLocally()) {
if (!topDownAnalysisParameters.isDeclaredLocally()) {
computeDeferredTypes();
}
}
@@ -35,10 +35,16 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
* @author svtk
*/
public class ControlFlowAnalyzer {
private TopDownAnalysisParameters topDownAnalysisParameters;
private TopDownAnalysisContext context;
private JetControlFlowDataTraceFactory flowDataTraceFactory;
@Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
}
@Inject
public void setContext(TopDownAnalysisContext context) {
this.context = context;
@@ -83,7 +89,7 @@ public class ControlFlowAnalyzer {
private void checkClassOrObject(JetClassOrObject klass) {
// A pseudocode of class initialization corresponds to a class
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, (JetExpression) klass, flowDataTraceFactory, context.getTrace());
flowInformationProvider.markUninitializedVariables((JetElement) klass, context.isDeclaredLocally());
flowInformationProvider.markUninitializedVariables((JetElement) klass, topDownAnalysisParameters.isDeclaredLocally());
}
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
@@ -107,7 +113,7 @@ public class ControlFlowAnalyzer {
// Property accessor is checked through initialization of a class check (at 'checkClassOrObject')
boolean isPropertyAccessor = function instanceof JetPropertyAccessor;
flowInformationProvider.markUninitializedVariables(function.asElement(), context.isDeclaredLocally() || isPropertyAccessor);
flowInformationProvider.markUninitializedVariables(function.asElement(), topDownAnalysisParameters.isDeclaredLocally() || isPropertyAccessor);
flowInformationProvider.markUnusedVariables(function.asElement());
@@ -45,6 +45,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.DELEGATED;
public class OverrideResolver {
private TopDownAnalysisContext context;
private TopDownAnalysisParameters topDownAnalysisParameters;
@Inject
@@ -52,6 +53,11 @@ public class OverrideResolver {
this.context = context;
}
@Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
}
public void process() {
@@ -213,7 +219,7 @@ public class OverrideResolver {
}
protected void checkOverridesInAClass(MutableClassDescriptor classDescriptor, JetClassOrObject klass) {
if (context.analyzingBootstrapLibrary()) return;
if (topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) return;
// Check overrides for internal consistency
for (CallableMemberDescriptor member : classDescriptor.getCallableMembers()) {
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import javax.inject.Inject;
import java.io.PrintStream;
import java.util.Map;
import java.util.Set;
@@ -41,7 +42,7 @@ import java.util.Set;
*/
public class TopDownAnalysisContext {
private final ObservableBindingTrace trace;
private ObservableBindingTrace trace;
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
@@ -54,40 +55,19 @@ public class TopDownAnalysisContext {
private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
private final Set<PropertyDescriptor> primaryConstructorParameterProperties = Sets.newHashSet();
private final Predicate<PsiFile> analyzeCompletely;
private StringBuilder debugOutput;
private final boolean analyzingBootstrapLibrary;
private boolean declaredLocally;
private final InjectorForTopDownAnalyzer injector;
public TopDownAnalysisContext(
final Project project,
final BindingTrace trace,
Predicate<PsiFile> analyzeCompletely,
@NotNull final ModuleConfiguration configuration,
@NotNull final ModuleDescriptor moduleDescriptor,
boolean declaredLocally,
boolean analyzingBootstrapLibrary,
@Nullable final JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory) {
private TopDownAnalysisParameters topDownAnalysisParameters;
if (analyzingBootstrapLibrary == (jetControlFlowDataTraceFactory != null)) {
throw new IllegalStateException(
"jetControlFlowDataTraceFactory must not be passed when analyzingBootstrapLibrary and vice versa");
}
this.injector = new InjectorForTopDownAnalyzer(project, this, configuration, moduleDescriptor, jetControlFlowDataTraceFactory);
this.trace = new ObservableBindingTrace(trace);
this.analyzeCompletely = analyzeCompletely;
this.declaredLocally = declaredLocally;
this.analyzingBootstrapLibrary = analyzingBootstrapLibrary;
@Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
this.trace = new ObservableBindingTrace(topDownAnalysisParameters.getTrace());
}
public InjectorForTopDownAnalyzer getInjector() {
return injector;
}
public void debug(Object message) {
if (debugOutput != null) {
@@ -107,13 +87,9 @@ public class TopDownAnalysisContext {
}
}
public boolean analyzingBootstrapLibrary() {
return analyzingBootstrapLibrary;
}
public boolean completeAnalysisNeeded(@NotNull PsiElement element) {
PsiFile containingFile = element.getContainingFile();
boolean result = containingFile != null && analyzeCompletely.apply(containingFile);
boolean result = containingFile != null && topDownAnalysisParameters.getAnalyzeCompletely().apply(containingFile);
if (!result) {
debug(containingFile);
}
@@ -161,8 +137,4 @@ public class TopDownAnalysisContext {
return functions;
}
public boolean isDeclaredLocally() {
return declaredLocally;
}
}
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* Various junk that cannot be placed into context (yet).
*
* @author Stepan Koltsov
*/
public class TopDownAnalysisParameters {
@NotNull
private final Predicate<PsiFile> analyzeCompletely;
private final boolean analyzingBootstrapLibrary;
private final boolean declaredLocally;
@NotNull
private final BindingTrace trace;
public TopDownAnalysisParameters(
@NotNull Predicate<PsiFile> analyzeCompletely,
boolean analyzingBootstrapLibrary,
boolean declaredLocally,
@NotNull BindingTrace trace) {
this.analyzeCompletely = analyzeCompletely;
this.analyzingBootstrapLibrary = analyzingBootstrapLibrary;
this.declaredLocally = declaredLocally;
this.trace = trace;
}
@NotNull
public Predicate<PsiFile> getAnalyzeCompletely() {
return analyzeCompletely;
}
public boolean isAnalyzingBootstrapLibrary() {
return analyzingBootstrapLibrary;
}
public boolean isDeclaredLocally() {
return declaredLocally;
}
@NotNull
public BindingTrace getTrace() {
return trace;
}
}
@@ -18,10 +18,12 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzer;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*;
@@ -29,8 +31,11 @@ import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeAdapter;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import javax.inject.Inject;
import java.util.ArrayList;
@@ -53,7 +58,18 @@ public class TopDownAnalyzer {
private OverrideResolver overrideResolver;
@NotNull
private OverloadResolver overloadResolver;
@NotNull
private TopDownAnalysisParameters topDownAnalysisParameters;
@NotNull
private TopDownAnalysisContext context;
@NotNull
private ModuleConfiguration configuration;
@NotNull
private ModuleDescriptor moduleDescriptor;
private BodyResolver bodyResolver;
private ControlFlowAnalyzer controlFlowAnalyzer;
private DeclarationsChecker declarationsChecker;
@Inject
public void setDeclarationResolver(@NotNull DeclarationResolver declarationResolver) {
@@ -80,23 +96,45 @@ public class TopDownAnalyzer {
this.overloadResolver = overloadResolver;
}
@Inject
public void setTopDownAnalysisParameters(@NotNull TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
}
@Inject
public void setContext(@NotNull TopDownAnalysisContext context) {
this.context = context;
}
@Inject
public void setConfiguration(@NotNull ModuleConfiguration configuration) {
this.configuration = configuration;
}
@Inject
public void setModuleDescriptor(@NotNull ModuleDescriptor moduleDescriptor) {
this.moduleDescriptor = moduleDescriptor;
}
@Inject
public void setBodyResolver(BodyResolver bodyResolver) {
this.bodyResolver = bodyResolver;
}
@Inject
public void setControlFlowAnalyzer(ControlFlowAnalyzer controlFlowAnalyzer) {
this.controlFlowAnalyzer = controlFlowAnalyzer;
}
@Inject
public void setDeclarationsChecker(DeclarationsChecker declarationsChecker) {
this.declarationsChecker = declarationsChecker;
}
public static void process(
@NotNull Project project,
@NotNull BindingTrace trace,
@NotNull JetScope outerScope,
@NotNull NamespaceLikeBuilder owner,
@NotNull ModuleDescriptor moduleDescriptor,
@NotNull Collection<JetFile> files,
@NotNull Predicate<PsiFile> analyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull ModuleConfiguration configuration
) {
process(project, trace, outerScope, moduleDescriptor, owner, files, analyzeCompletely, flowDataTraceFactory, configuration, false);
}
private static void process(
@NotNull Project project,
@NotNull BindingTrace trace,
@NotNull JetScope outerScope,
@@ -107,13 +145,17 @@ public class TopDownAnalyzer {
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull ModuleConfiguration configuration,
boolean declaredLocally) {
TopDownAnalysisContext context = new TopDownAnalysisContext(project, trace, analyzeCompletely, configuration, moduleDescriptor, declaredLocally, false, flowDataTraceFactory);
context.getInjector().getTopDownAnalyzer().doProcess(context, outerScope, owner, declarations);
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(analyzeCompletely, false, declaredLocally, trace);
InjectorForTopDownAnalyzer injector = new InjectorForTopDownAnalyzer(project, topDownAnalysisParameters, configuration, moduleDescriptor, flowDataTraceFactory);
injector.getTopDownAnalyzer().doProcess(outerScope, owner, declarations);
}
private void doProcess(
TopDownAnalysisContext context, JetScope outerScope,
public void doProcess(
JetScope outerScope,
NamespaceLikeBuilder owner,
Collection<? extends PsiElement> declarations) {
// context.enableDebugOutput();
@@ -124,14 +166,14 @@ public class TopDownAnalyzer {
delegationResolver.process();
overrideResolver.process();
lockScopes(context);
lockScopes();
overloadResolver.process();
if (!context.analyzingBootstrapLibrary()) {
context.getInjector().getBodyResolver().resolveBehaviorDeclarationBodies();
context.getInjector().getControlFlowAnalyzer().process();
context.getInjector().getDeclarationsChecker().process();
if (!topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) {
bodyResolver.resolveBehaviorDeclarationBodies();
controlFlowAnalyzer.process();
declarationsChecker.process();
}
context.debug("Exit");
@@ -139,7 +181,7 @@ public class TopDownAnalyzer {
}
private static void lockScopes(TopDownAnalysisContext context) {
private void lockScopes() {
for (MutableClassDescriptor mutableClassDescriptor : context.getClasses().values()) {
mutableClassDescriptor.lockScopes();
}
@@ -157,7 +199,17 @@ public class TopDownAnalyzer {
@NotNull WritableScope outerScope,
@NotNull NamespaceDescriptorImpl standardLibraryNamespace,
@NotNull List<JetFile> files) {
TopDownAnalysisContext context = new TopDownAnalysisContext(project, trace, Predicates.<PsiFile>alwaysFalse(), ModuleConfiguration.EMPTY, JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, false, true, null);
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(Predicates.<PsiFile>alwaysFalse(), true, false, trace);
InjectorForTopDownAnalyzer injector = new InjectorForTopDownAnalyzer(
project, topDownAnalysisParameters, ModuleConfiguration.EMPTY,
JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, null);
injector.getTopDownAnalyzer().doProcessStandardLibraryNamespace(outerScope, standardLibraryNamespace, files);
}
private void doProcessStandardLibraryNamespace(
WritableScope outerScope, NamespaceDescriptorImpl standardLibraryNamespace, List<JetFile> files) {
ArrayList<JetDeclaration> toAnalyze = new ArrayList<JetDeclaration>();
for(JetFile file : files) {
context.getNamespaceDescriptors().put(file, standardLibraryNamespace);
@@ -166,7 +218,7 @@ public class TopDownAnalyzer {
}
// context.getDeclaringScopes().put(file, outerScope);
context.getInjector().getTopDownAnalyzer().doProcess(context, outerScope, standardLibraryNamespace, toAnalyze);
doProcess(outerScope, standardLibraryNamespace, toAnalyze);
}
public static void processObject(
@@ -213,6 +265,58 @@ public class TopDownAnalyzer {
}, Collections.<PsiElement>singletonList(object), Predicates.equalTo(object.getContainingFile()), JetControlFlowDataTraceFactory.EMPTY, ModuleConfiguration.EMPTY, true);
}
public static void doAnalyzeFilesWithGivenTrace(Project project, final ModuleConfiguration configuration, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely, JetControlFlowDataTraceFactory flowDataTraceFactory, BindingTraceContext bindingTraceContext) {
final ModuleDescriptor owner = new ModuleDescriptor("<module>");
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
filesToAnalyzeCompletely, false, false, bindingTraceContext);
InjectorForTopDownAnalyzer injector = new InjectorForTopDownAnalyzer(
project, topDownAnalysisParameters, configuration, owner, flowDataTraceFactory);
injector.getTopDownAnalyzer().doAnalyzeFilesWithGivenTrance2(files);
}
private void doAnalyzeFilesWithGivenTrance2(Collection<JetFile> files) {
final WritableScope scope = new WritableScopeImpl(
JetScope.EMPTY, moduleDescriptor,
new TraceBasedRedeclarationHandler(topDownAnalysisParameters.getTrace())).setDebugName("Root scope in analyzeNamespace");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
// Import the lang package
scope.importScope(JetStandardLibrary.getInstance().getLibraryScope());
// Import a scope that contains all top-level namespaces that come from dependencies
// This makes the namespaces visible at all, does not import themselves
scope.importScope(new JetScopeAdapter(JetScope.EMPTY) {
@Override
public NamespaceDescriptor getNamespace(@NotNull String name) {
// Is it a top-level namespace coming from the dependencies?
NamespaceDescriptor topLevelNamespaceFromConfiguration = configuration.getTopLevelNamespace(name);
if (topLevelNamespaceFromConfiguration != null) {
return topLevelNamespaceFromConfiguration;
}
// Should be null, we are delegating to EMPTY
return super.getNamespace(name);
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
List<DeclarationDescriptor> allDescriptors = Lists.newArrayList();
configuration.addAllTopLevelNamespacesTo(allDescriptors);
return allDescriptors;
}
});
// dummy builder is used because "root" is module descriptor,
// namespaces added to module explicitly in
doProcess(scope, new NamespaceLikeBuilderDummy(), files);
}
}
@@ -45,6 +45,7 @@ public class AllInjectorsGenerator {
// Fields
generator.addPublicField(TopDownAnalyzer.class);
generator.addPublicField(TopDownAnalysisContext.class);
generator.addPublicField(BodyResolver.class);
generator.addPublicField(ControlFlowAnalyzer.class);
generator.addPublicField(DeclarationsChecker.class);
@@ -52,7 +53,7 @@ public class AllInjectorsGenerator {
// Parameters
generator.addPublicParameter(Project.class);
generator.addParameter(TopDownAnalysisContext.class);
generator.addPublicParameter(TopDownAnalysisParameters.class);
generator.addParameter(ModuleConfiguration.class);
generator.addParameter(ModuleDescriptor.class);
generator.addParameter(JetControlFlowDataTraceFactory.class, false);
@@ -94,7 +94,7 @@ public final class AnalyzerFacadeForJS {
public static BindingContext analyzeNamespace(@NotNull JetFile file) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
Project project = file.getProject();
return AnalyzingUtils.analyzeFilesWithGivenTrace(
AnalyzingUtils.analyzeFilesWithGivenTrace(
project,
JsConfiguration.jsLibConfiguration(project),
Collections.singletonList(file),
@@ -102,6 +102,7 @@ public final class AnalyzerFacadeForJS {
JetControlFlowDataTraceFactory.EMPTY,
bindingTraceContext
);
return bindingTraceContext.getBindingContext();
}
private static final class JsConfiguration implements ModuleConfiguration {