- Out of block modification strategy for Kotlin block expression

- Separate project analysis for IDEA needs: headers + bodies
This commit is contained in:
Nikolay Krasko
2012-05-27 17:39:56 +04:00
parent e38aac1dce
commit e946a0f908
23 changed files with 516 additions and 227 deletions
@@ -31,8 +31,6 @@ import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
import org.jetbrains.jet.cli.common.messages.PrintingMessageCollector;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.k2js.analyze.AnalyzerFacadeForJS;
import org.jetbrains.k2js.config.Config;
import org.jetbrains.k2js.config.EcmaVersion;
@@ -110,9 +108,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments, K2JSCompile
analyzerWithCompilerReport.analyzeAndReport(new Function0<AnalyzeExhaust>() {
@Override
public AnalyzeExhaust invoke() {
BindingContext context = AnalyzerFacadeForJS
.analyzeFiles(sources, Predicates.<PsiFile>alwaysTrue(), config);
return AnalyzeExhaust.success(context, JetStandardLibrary.getInstance());
return AnalyzerFacadeForJS.analyzeFiles(sources, Predicates.<PsiFile>alwaysTrue(), config);
}
}, sources);
return analyzerWithCompilerReport.hasErrors();
@@ -17,44 +17,16 @@
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.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
import org.jetbrains.jet.lang.resolve.java.PsiClassFinderForJvm;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.DelegationResolver;
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
import org.jetbrains.jet.lang.resolve.OverloadResolver;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer;
import com.intellij.openapi.project.Project;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
@@ -149,18 +121,15 @@ public class InjectorForTopDownAnalyzerForJvm {
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.bodyResolver.setTrace(observableBindingTrace);
this.controlFlowAnalyzer.setContext(topDownAnalysisContext);
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
this.declarationsChecker.setContext(topDownAnalysisContext);
this.declarationsChecker.setTrace(observableBindingTrace);
this.descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -27,10 +27,7 @@ import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
@@ -56,7 +53,21 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
return analyzeFilesWithJavaIntegration(project, files, filesToAnalyzeCompletely, flowDataTraceFactory,
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR));
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR), true);
}
@NotNull
@Override
public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
@NotNull Predicate<PsiFile> filesForBodiesResolve,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull BindingTrace headersTraceContext,
@NotNull BodiesResolveContext bodiesResolveContext
) {
return analyzeBodiesInFilesWithJavaIntegration(
project, filesForBodiesResolve, flowDataTraceFactory,
compilerDependenciesForProduction(CompilerSpecialMode.REGULAR),
headersTraceContext, bodiesResolveContext);
}
public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors(
@@ -82,6 +93,16 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies) {
return analyzeFilesWithJavaIntegration(
project, files, filesToAnalyzeCompletely,
flowDataTraceFactory, compilerDependencies, false);
}
public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Collection<JetFile> files, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies,
boolean storeContextForBodiesResolve) {
BindingTraceContext bindingTraceContext = new BindingTraceContext();
final ModuleDescriptor owner = new ModuleDescriptor(Name.special("<module>"));
@@ -89,17 +110,42 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
filesToAnalyzeCompletely, false, false);
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
project, topDownAnalysisParameters,
new ObservableBindingTrace(bindingTraceContext), owner, flowDataTraceFactory,
compilerDependencies);
try {
injector.getTopDownAnalyzer().analyzeFiles(files);
BodiesResolveContext bodiesResolveContext = storeContextForBodiesResolve ?
new CachedBodiesResolveContext(injector.getTopDownAnalysisContext()) :
null;
return AnalyzeExhaust.success(bindingTraceContext.getBindingContext(), JetStandardLibrary.getInstance(), bodiesResolveContext);
} finally {
injector.destroy();
}
}
return AnalyzeExhaust.success(bindingTraceContext.getBindingContext(), JetStandardLibrary.getInstance());
public static AnalyzeExhaust analyzeBodiesInFilesWithJavaIntegration(
Project project, Predicate<PsiFile> filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull CompilerDependencies compilerDependencies,
@NotNull BindingTrace traceContext,
@NotNull BodiesResolveContext bodiesResolveContext) {
final ModuleDescriptor owner = new ModuleDescriptor(Name.special("<module>"));
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
filesToAnalyzeCompletely, false, false);
bodiesResolveContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
project, topDownAnalysisParameters,
new ObservableBindingTrace(traceContext), owner, flowDataTraceFactory,
compilerDependencies);
try {
injector.getTopDownAnalyzer().doProcessForBodies(bodiesResolveContext);
return AnalyzeExhaust.success(traceContext.getBindingContext(), JetStandardLibrary.getInstance());
} finally {
injector.destroy();
}
@@ -19,6 +19,7 @@ package org.jetbrains.jet.analyzer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
/**
@@ -30,19 +31,33 @@ public class AnalyzeExhaust {
private final JetStandardLibrary standardLibrary;
private final Throwable error;
@Nullable
private final BodiesResolveContext bodiesResolveContext;
private AnalyzeExhaust(@NotNull BindingContext bindingContext,
@Nullable JetStandardLibrary standardLibrary, @Nullable Throwable error) {
@Nullable JetStandardLibrary standardLibrary, @Nullable BodiesResolveContext bodiesResolveContext, @Nullable Throwable error) {
this.bindingContext = bindingContext;
this.standardLibrary = standardLibrary;
this.error = error;
this.bodiesResolveContext = bodiesResolveContext;
}
public static AnalyzeExhaust success(@NotNull BindingContext bindingContext, @NotNull JetStandardLibrary standardLibrary) {
return new AnalyzeExhaust(bindingContext, standardLibrary, null);
return new AnalyzeExhaust(bindingContext, standardLibrary, null, null);
}
public static AnalyzeExhaust success(@NotNull BindingContext bindingContext, @NotNull JetStandardLibrary standardLibrary,
BodiesResolveContext bodiesResolveContext) {
return new AnalyzeExhaust(bindingContext, standardLibrary, bodiesResolveContext, null);
}
public static AnalyzeExhaust error(@NotNull BindingContext bindingContext, @NotNull Throwable error) {
return new AnalyzeExhaust(bindingContext, null, error);
return new AnalyzeExhaust(bindingContext, null, null, error);
}
@Nullable
public BodiesResolveContext getBodiesResolveContext() {
return bodiesResolveContext;
}
@NotNull
@@ -22,6 +22,8 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
import java.util.Collection;
@@ -35,4 +37,11 @@ public interface AnalyzerFacade {
@NotNull Collection<JetFile> files,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory);
@NotNull
AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
@NotNull Predicate<PsiFile> filesForBodiesResolve,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@NotNull BindingTrace traceContext,
@NotNull BodiesResolveContext bodiesResolveContext);
}
@@ -17,38 +17,16 @@
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.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.resolve.DeclarationResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.resolve.ImportsResolver;
import org.jetbrains.jet.lang.resolve.DelegationResolver;
import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl;
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.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.ObservableBindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.ModuleConfiguration;
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.ModuleDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadingConflictResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */
@@ -131,18 +109,15 @@ public class InjectorForTopDownAnalyzerBasic {
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.bodyResolver.setTrace(observableBindingTrace);
this.controlFlowAnalyzer.setContext(topDownAnalysisContext);
this.controlFlowAnalyzer.setFlowDataTraceFactory(jetControlFlowDataTraceFactory);
this.controlFlowAnalyzer.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.controlFlowAnalyzer.setTrace(observableBindingTrace);
this.declarationsChecker.setContext(topDownAnalysisContext);
this.declarationsChecker.setTrace(observableBindingTrace);
this.descriptorResolver.setAnnotationResolver(annotationResolver);
@@ -16,10 +16,10 @@
package org.jetbrains.jet.lang.psi;
import com.google.common.collect.Lists;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifiableCodeBlock;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetTokens;
@@ -30,11 +30,16 @@ import java.util.List;
/**
* @author max
*/
public class JetBlockExpression extends JetExpression implements JetStatementExpression {
public class JetBlockExpression extends JetExpression implements JetStatementExpression, PsiModifiableCodeBlock {
public JetBlockExpression(@NotNull ASTNode node) {
super(node);
}
@Override
public boolean shouldChangeModificationCount(PsiElement place) {
return JetModifiableBlockHelper.shouldChangeModificationCount(place);
}
@Override
public void accept(@NotNull JetVisitorVoid visitor) {
visitor.visitBlockExpression(this);
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lexer.JetToken;
@@ -30,6 +31,7 @@ public abstract class JetDeclaration extends JetExpression implements JetModifie
}
@Override
@Nullable
public JetModifierList getModifierList() {
return (JetModifierList) findChildByType(JetNodeTypes.MODIFIER_LIST);
}
@@ -42,7 +42,7 @@ public class JetElement extends ASTWrapperPsiElement {
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public static @interface IfNotParsed {}
public @interface IfNotParsed {}
@NotNull
@Override
@@ -0,0 +1,54 @@
/*
* 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.psi;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
/**
* @author Nikolay Krasko
*/
public final class JetModifiableBlockHelper {
private JetModifiableBlockHelper() {
}
// TODO: Need tests for this method
// TODO: Consider for FUNCTION_LITERALS
public static boolean shouldChangeModificationCount(PsiElement place) {
JetDeclaration declaration = PsiTreeUtil.getParentOfType(place, JetDeclaration.class, true);
if (declaration != null) {
if (declaration instanceof JetNamedFunction) {
JetNamedFunction function = (JetNamedFunction) declaration;
if (function.hasDeclaredReturnType() || function.hasBlockBody()) {
return false;
}
return shouldChangeModificationCount(function);
}
else if (declaration instanceof JetProperty) {
JetProperty property = (JetProperty) declaration;
if (property.getPropertyTypeRef() != null) {
return false;
}
return shouldChangeModificationCount(property);
}
}
return true;
}
}
@@ -0,0 +1,44 @@
/*
* 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.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import java.util.Map;
/**
* @author Nikolay Krasko
*/
public interface BodiesResolveContext {
Map<JetClass, MutableClassDescriptor> getClasses();
Map<JetObjectDeclaration, MutableClassDescriptor> getObjects();
Map<JetSecondaryConstructor, ConstructorDescriptor> getConstructors();
Map<JetProperty, PropertyDescriptor> getProperties();
Map<JetNamedFunction, SimpleFunctionDescriptor> getFunctions();
Map<JetDeclaration, JetScope> getDeclaringScopes();
Map<JetScript, ScriptDescriptor> getScripts();
Map<JetScript, WritableScope> getScriptScopes();
void setTopDownAnalysisParameters(TopDownAnalysisParameters parameters);
boolean completeAnalysisNeeded(@NotNull PsiElement element);
}
@@ -55,7 +55,7 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
*/
public class BodyResolver {
@NotNull
private TopDownAnalysisContext context;
private BodiesResolveContext context;
@NotNull
private TopDownAnalysisParameters topDownAnalysisParameters;
@NotNull
@@ -67,12 +67,6 @@ public class BodyResolver {
@NotNull
private ObservableBindingTrace trace;
@Inject
public void setContext(@NotNull TopDownAnalysisContext context) {
this.context = context;
}
@Inject
public void setTopDownAnalysisParameters(@NotNull TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
@@ -98,9 +92,9 @@ public class BodyResolver {
this.trace = trace;
}
public void resolveBehaviorDeclarationBodies() {
public void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext bodiesResolveContext) {
// Initialize context
context = bodiesResolveContext;
resolveDelegationSpecifierLists();
resolveClassAnnotations();
@@ -0,0 +1,111 @@
/*
* 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.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import java.util.Collections;
import java.util.Map;
/**
* A storage for the part of {@see TopDownAnalysisContext} collected during headers analysis that will be used during resolution of
* bodies
*
* @author Nikolay Krasko
*/
public class CachedBodiesResolveContext implements BodiesResolveContext {
private final Map<JetClass, MutableClassDescriptor> classes;
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects;
private final Map<JetSecondaryConstructor, ConstructorDescriptor> constructors;
private final Map<JetProperty, PropertyDescriptor> properties;
private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions;
private final Map<JetDeclaration, JetScope> declaringScopes;
private final Map<JetScript, ScriptDescriptor> scripts;
private final Map<JetScript, WritableScope> scriptScopes;
private @NotNull TopDownAnalysisParameters topDownAnalysisParameters;
public CachedBodiesResolveContext(TopDownAnalysisContext context) {
classes = Collections.unmodifiableMap(context.getClasses());
objects = Collections.unmodifiableMap(context.getObjects());
constructors = Collections.unmodifiableMap(context.getConstructors());
properties = Collections.unmodifiableMap(context.getProperties());
functions = Collections.unmodifiableMap(context.getFunctions());
declaringScopes = Collections.unmodifiableMap(context.getDeclaringScopes());
scripts = Collections.unmodifiableMap(context.getScripts());
scriptScopes = Collections.unmodifiableMap(context.getScriptScopes());
topDownAnalysisParameters = context.getTopDownAnalysisParameters();
}
@Override
public Map<JetClass, MutableClassDescriptor> getClasses() {
return classes;
}
@Override
public Map<JetObjectDeclaration, MutableClassDescriptor> getObjects() {
return objects;
}
@Override
public Map<JetSecondaryConstructor, ConstructorDescriptor> getConstructors() {
return constructors;
}
@Override
public Map<JetProperty, PropertyDescriptor> getProperties() {
return properties;
}
@Override
public Map<JetNamedFunction, SimpleFunctionDescriptor> getFunctions() {
return functions;
}
@Override
public Map<JetDeclaration, JetScope> getDeclaringScopes() {
return declaringScopes;
}
@Override
public Map<JetScript, ScriptDescriptor> getScripts() {
return scripts;
}
@Override
public Map<JetScript, WritableScope> getScriptScopes() {
return scriptScopes;
}
@Override
public void setTopDownAnalysisParameters(@NotNull TopDownAnalysisParameters parameters) {
topDownAnalysisParameters = parameters;
}
@Override
public boolean completeAnalysisNeeded(@NotNull PsiElement element) {
PsiFile containingFile = element.getContainingFile();
return containingFile != null && topDownAnalysisParameters.getAnalyzeCompletely().apply(containingFile);
}
}
@@ -36,21 +36,14 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
*/
public class ControlFlowAnalyzer {
private TopDownAnalysisParameters topDownAnalysisParameters;
private TopDownAnalysisContext context;
private BindingTrace trace;
private JetControlFlowDataTraceFactory flowDataTraceFactory;
@Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
}
@Inject
public void setContext(TopDownAnalysisContext context) {
this.context = context;
}
@Inject
public void setTrace(BindingTrace trace) {
this.trace = trace;
@@ -61,43 +54,42 @@ public class ControlFlowAnalyzer {
this.flowDataTraceFactory = flowDataTraceFactory;
}
public void process() {
for (JetClass aClass : context.getClasses().keySet()) {
if (!context.completeAnalysisNeeded(aClass)) continue;
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) {
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
checkClassOrObject(aClass);
}
for (JetObjectDeclaration objectDeclaration : context.getObjects().keySet()) {
if (!context.completeAnalysisNeeded(objectDeclaration)) continue;
for (JetObjectDeclaration objectDeclaration : bodiesResolveContext.getObjects().keySet()) {
if (!bodiesResolveContext.completeAnalysisNeeded(objectDeclaration)) continue;
checkClassOrObject(objectDeclaration);
}
for (Map.Entry<JetNamedFunction, SimpleFunctionDescriptor> entry : context.getFunctions().entrySet()) {
for (Map.Entry<JetNamedFunction, SimpleFunctionDescriptor> entry : bodiesResolveContext.getFunctions().entrySet()) {
JetNamedFunction function = entry.getKey();
SimpleFunctionDescriptor functionDescriptor = entry.getValue();
if (!context.completeAnalysisNeeded(function)) continue;
if (!bodiesResolveContext.completeAnalysisNeeded(function)) continue;
final JetType expectedReturnType = !function.hasBlockBody() && !function.hasDeclaredReturnType()
? NO_EXPECTED_TYPE
: functionDescriptor.getReturnType();
checkFunction(function, expectedReturnType);
}
for (JetSecondaryConstructor constructor : this.context.getConstructors().keySet()) {
if (!context.completeAnalysisNeeded(constructor)) continue;
for (JetSecondaryConstructor constructor : bodiesResolveContext.getConstructors().keySet()) {
if (!bodiesResolveContext.completeAnalysisNeeded(constructor)) continue;
checkFunction(constructor, JetStandardClasses.getUnitType());
}
for (Map.Entry<JetProperty, PropertyDescriptor> entry : context.getProperties().entrySet()) {
for (Map.Entry<JetProperty, PropertyDescriptor> entry : bodiesResolveContext.getProperties().entrySet()) {
JetProperty property = entry.getKey();
if (!context.completeAnalysisNeeded(property)) continue;
if (!bodiesResolveContext.completeAnalysisNeeded(property)) continue;
PropertyDescriptor propertyDescriptor = entry.getValue();
checkProperty(property, propertyDescriptor);
}
}
private void checkClassOrObject(JetClassOrObject klass) {
// A pseudocode of class initialization corresponds to a class
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, (JetExpression) klass, flowDataTraceFactory, trace);
flowInformationProvider.markUninitializedVariables((JetElement) klass, topDownAnalysisParameters.isDeclaredLocally());
}
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
for (JetPropertyAccessor accessor : property.getAccessors()) {
PropertyAccessorDescriptor accessorDescriptor = accessor.isGetter()
@@ -44,60 +44,50 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE;
* @author svtk
*/
public class DeclarationsChecker {
@NotNull
private TopDownAnalysisContext context;
@NotNull
private BindingTrace trace;
@Inject
public void setContext(@NotNull TopDownAnalysisContext context) {
this.context = context;
}
@Inject
public void setTrace(@NotNull BindingTrace trace) {
this.trace = trace;
}
public void process() {
Map<JetClass, MutableClassDescriptor> classes = context.getClasses();
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
Map<JetClass, MutableClassDescriptor> classes = bodiesResolveContext.getClasses();
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
JetClass aClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
if (!context.completeAnalysisNeeded(aClass)) continue;
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
checkClass(aClass, classDescriptor);
checkModifiers(aClass.getModifierList(), classDescriptor);
}
Map<JetObjectDeclaration, MutableClassDescriptor> objects = context.getObjects();
Map<JetObjectDeclaration, MutableClassDescriptor> objects = bodiesResolveContext.getObjects();
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
JetObjectDeclaration objectDeclaration = entry.getKey();
MutableClassDescriptor objectDescriptor = entry.getValue();
if (!context.completeAnalysisNeeded(objectDeclaration)) continue;
if (!bodiesResolveContext.completeAnalysisNeeded(objectDeclaration)) continue;
checkObject(objectDeclaration, objectDescriptor);
}
Map<JetNamedFunction, SimpleFunctionDescriptor> functions = context.getFunctions();
Map<JetNamedFunction, SimpleFunctionDescriptor> functions = bodiesResolveContext.getFunctions();
for (Map.Entry<JetNamedFunction, SimpleFunctionDescriptor> entry : functions.entrySet()) {
JetNamedFunction function = entry.getKey();
SimpleFunctionDescriptor functionDescriptor = entry.getValue();
if (!context.completeAnalysisNeeded(function)) continue;
if (!bodiesResolveContext.completeAnalysisNeeded(function)) continue;
checkFunction(function, functionDescriptor);
checkModifiers(function.getModifierList(), functionDescriptor);
}
Map<JetProperty, PropertyDescriptor> properties = context.getProperties();
Map<JetProperty, PropertyDescriptor> properties = bodiesResolveContext.getProperties();
for (Map.Entry<JetProperty, PropertyDescriptor> entry : properties.entrySet()) {
JetProperty property = entry.getKey();
PropertyDescriptor propertyDescriptor = entry.getValue();
if (!context.completeAnalysisNeeded(property)) continue;
if (!bodiesResolveContext.completeAnalysisNeeded(property)) continue;
checkProperty(property, propertyDescriptor);
checkModifiers(property.getModifierList(), propertyDescriptor);
}
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.util.slicedmap.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -36,7 +37,9 @@ public class DelegatingBindingTrace implements BindingTrace {
private final BindingContext bindingContext = new BindingContext() {
@Override
public Collection<Diagnostic> getDiagnostics() {
return diagnostics;
ArrayList<Diagnostic> mergedDiagnostics = new ArrayList<Diagnostic>(diagnostics);
mergedDiagnostics.addAll(parentContext.getDiagnostics());
return mergedDiagnostics;
}
@Override
@@ -79,9 +82,10 @@ public class DelegatingBindingTrace implements BindingTrace {
assert value != null;
if (value.equals(true)) return value;
}
else {
if (value != null) return value;
else if (value != null) {
return value;
}
return parentContext.get(slice, key);
}
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -33,7 +32,7 @@ import java.util.Map;
/**
* @author abreslav
*/
public class TopDownAnalysisContext {
public class TopDownAnalysisContext implements BodiesResolveContext {
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
@@ -62,13 +61,15 @@ public class TopDownAnalysisContext {
private TopDownAnalysisParameters topDownAnalysisParameters;
@Override
@Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
this.topDownAnalysisParameters = topDownAnalysisParameters;
}
public TopDownAnalysisParameters getTopDownAnalysisParameters() {
return topDownAnalysisParameters;
}
public void debug(Object message) {
if (debugOutput != null) {
@@ -76,6 +77,7 @@ public class TopDownAnalysisContext {
}
}
@SuppressWarnings("UnusedDeclaration")
/*package*/ void enableDebugOutput() {
if (debugOutput == null) {
debugOutput = new StringBuilder();
@@ -88,6 +90,7 @@ public class TopDownAnalysisContext {
}
}
@Override
public boolean completeAnalysisNeeded(@NotNull PsiElement element) {
PsiFile containingFile = element.getContainingFile();
boolean result = containingFile != null && topDownAnalysisParameters.getAnalyzeCompletely().apply(containingFile);
@@ -97,10 +100,12 @@ public class TopDownAnalysisContext {
return result;
}
@Override
public Map<JetClass, MutableClassDescriptor> getClasses() {
return classes;
}
@Override
public Map<JetObjectDeclaration, MutableClassDescriptor> getObjects() {
return objects;
}
@@ -123,11 +128,13 @@ public class TopDownAnalysisContext {
return namespaceDescriptors;
}
@Override
@NotNull
public Map<JetScript, ScriptDescriptor> getScripts() {
return scripts;
}
@Override
@NotNull
public Map<JetScript, WritableScope> getScriptScopes() {
return scriptScopes;
@@ -137,18 +144,22 @@ public class TopDownAnalysisContext {
return primaryConstructorParameterProperties;
}
@Override
public Map<JetSecondaryConstructor, ConstructorDescriptor> getConstructors() {
return constructors;
}
@Override
public Map<JetProperty, PropertyDescriptor> getProperties() {
return properties;
}
@Override
public Map<JetDeclaration, JetScope> getDeclaringScopes() {
return declaringScopes;
}
@Override
public Map<JetNamedFunction, SimpleFunctionDescriptor> getFunctions() {
return functions;
}
@@ -136,7 +136,6 @@ public class TopDownAnalyzer {
this.declarationsChecker = declarationsChecker;
}
public void doProcess(
JetScope outerScope,
NamespaceLikeBuilder owner,
@@ -154,15 +153,18 @@ public class TopDownAnalyzer {
overloadResolver.process();
if (!topDownAnalysisParameters.isAnalyzingBootstrapLibrary()) {
bodyResolver.resolveBehaviorDeclarationBodies();
controlFlowAnalyzer.process();
declarationsChecker.process();
doProcessForBodies(context);
}
context.debug("Exit");
context.printDebugOutput(System.out);
}
public void doProcessForBodies(BodiesResolveContext bodiesResolveContext) {
bodyResolver.resolveBehaviorDeclarationBodies(bodiesResolveContext);
controlFlowAnalyzer.process(bodiesResolveContext);
declarationsChecker.process(bodiesResolveContext);
}
private void lockScopes() {
for (MutableClassDescriptor mutableClassDescriptor : context.getClasses().values()) {