Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(822)

Unified Diff: pkg/analyzer/lib/src/dart/analysis/analysis_impl.dart

Issue 2679073003: Compute constants in non-task analyzer. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/dart/analysis/analysis_impl.dart
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_impl.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_impl.dart
index 3ca5096fbd3de09c426931d8758e4ec3547c00c2..4b656beda81c0d3998e7dffe9e57b39e4df979ff 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_impl.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_impl.dart
@@ -10,6 +10,8 @@ import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/constant/evaluation.dart';
+import 'package:analyzer/src/dart/constant/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -23,6 +25,7 @@ import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/strong/checker.dart';
+import 'package:front_end/src/dependency_walker.dart';
import 'package:front_end/src/scanner/reader.dart';
/**
@@ -43,6 +46,7 @@ class AnalyzerImpl {
final Map<FileState, ErrorReporter> _errorReporters = {};
final List<UsedImportedElements> usedImportedElementsList = [];
final List<UsedLocalElements> usedLocalElementsList = [];
+ final List<ConstantEvaluationTarget> _constants = [];
AnalyzerImpl(
this.analysisOptions, this.sourceFactory, this.fsState, this.store);
@@ -76,6 +80,8 @@ class AnalyzerImpl {
_resolveFile(analysisContext, library, file, unit);
});
+ _computeConstants();
+
units.forEach((file, unit) {
LibraryElement libraryElement = unit.element.library;
{
@@ -106,12 +112,115 @@ class AnalyzerImpl {
return results;
}
+ /**
+ * Compute [_constants] in all units.
+ */
+ void _computeConstants() {
+ ConstantEvaluationEngine evaluationEngine = new ConstantEvaluationEngine(
+ analysisContext.typeProvider, analysisContext.declaredVariables,
+ typeSystem: analysisContext.typeSystem);
+
+ List<_ConstantNode> nodes = [];
+ Map<ConstantEvaluationTarget, _ConstantNode> nodeMap = {};
+ for (ConstantEvaluationTarget constant in _constants) {
+ var node = new _ConstantNode(evaluationEngine, nodeMap, constant);
+ nodes.add(node);
+ nodeMap[constant] = node;
+ }
+
+ for (_ConstantNode node in nodes) {
+ if (!node.isEvaluated) {
+ new _ConstantWalker(evaluationEngine).walk(node);
+ }
+ }
+ }
+
void _computeVerifyErrorsAndHints(AnalysisContext analysisContext,
FileState libraryFile, FileState file, CompilationUnit unit) {
RecordingErrorListener errorListener = _getErrorListener(file);
CompilationUnitElement unitElement = unit.element;
LibraryElement libraryElement = unitElement.library;
+ //
+ // Use the ErrorVerifier to compute errors.
+ //
+ List<PendingError> pendingErrors;
+ {
+ RequiredConstantsComputer computer =
+ new RequiredConstantsComputer(file.source);
+ unit.accept(computer);
+ pendingErrors = computer.pendingErrors;
+ List<ConstantEvaluationTarget> requiredConstants =
+ computer.requiredConstants;
+ }
+
+ if (analysisOptions.strongMode) {
+ AnalysisOptionsImpl options = analysisOptions as AnalysisOptionsImpl;
+ CodeChecker checker = new CodeChecker(
+ typeProvider,
+ new StrongTypeSystemImpl(typeProvider,
+ implicitCasts: options.implicitCasts,
+ nonnullableTypes: options.nonnullableTypes),
+ errorListener,
+ options);
+ checker.visitCompilationUnit(unit);
+ }
+
+ var errorReporter = _getErrorReporter(file);
+
+ //
+ // Validate the directives.
+ //
+ _validateUriBasedDirectives(file, unit);
+
+ //
+ // Use the ConstantVerifier to compute errors.
+ //
+ ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter,
+ libraryElement, typeProvider, analysisContext.declaredVariables);
+ unit.accept(constantVerifier);
+
+ //
+ // Use the ErrorVerifier to compute errors.
+ //
+ ErrorVerifier errorVerifier = new ErrorVerifier(
+ errorReporter,
+ libraryElement,
+ typeProvider,
+ new InheritanceManager(libraryElement),
+ analysisOptions.enableSuperMixins);
+ unit.accept(errorVerifier);
+
+ //
+ // Convert the pending errors into actual errors.
+ //
+ for (PendingError pendingError in pendingErrors) {
+ errorListener.onError(pendingError.toAnalysisError());
+ }
+
+ //
+ // Find dead code.
+ //
+ unit.accept(new DeadCodeVerifier(errorReporter,
+ typeSystem: analysisContext.typeSystem));
+
+ // Dart2js analysis.
+ if (analysisOptions.dart2jsHint) {
+ unit.accept(new Dart2JSVerifier(errorReporter));
+ }
+
+ InheritanceManager inheritanceManager = new InheritanceManager(
+ libraryElement,
+ includeAbstractFromSuperclasses: true);
+
+ unit.accept(new BestPracticesVerifier(
+ errorReporter, typeProvider, libraryElement, inheritanceManager,
+ typeSystem: analysisContext.typeSystem));
+
+ unit.accept(new OverrideVerifier(errorReporter, inheritanceManager));
+
+ new ToDoFinder(errorReporter).findIn(unit);
+
// Verify imports.
{
ImportsVerifier verifier = new ImportsVerifier();
@@ -180,8 +289,11 @@ class AnalyzerImpl {
void _resolveFile(AnalysisContext analysisContext, FileState library,
FileState file, CompilationUnit unit) {
if (!file.exists) {
- var unitElement = new CompilationUnitElementImpl(file.source.shortName);
+ Source source = file.source;
+ var unitElement = new CompilationUnitElementImpl(source.shortName);
var libraryElement = new LibraryElementImpl(analysisContext, null, -1, 0);
+ unitElement.source = source;
+ unitElement.librarySource = source;
libraryElement.definingCompilationUnit = unitElement;
unit.element = unitElement;
return;
@@ -238,87 +350,14 @@ class AnalyzerImpl {
unit.accept(new ResolverVisitor(
libraryElement, unitElement.source, typeProvider, errorListener));
- // TODO(scheglov) RESOLVED_UNIT12: compute constants
-
//
- // Use the ErrorVerifier to compute errors.
+ // Find constants to compute.
//
- List<PendingError> pendingErrors;
{
- RequiredConstantsComputer computer =
- new RequiredConstantsComputer(file.source);
- unit.accept(computer);
- pendingErrors = computer.pendingErrors;
- List<ConstantEvaluationTarget> requiredConstants =
- computer.requiredConstants;
- }
-
- if (analysisOptions.strongMode) {
- AnalysisOptionsImpl options = analysisOptions as AnalysisOptionsImpl;
- CodeChecker checker = new CodeChecker(
- typeProvider,
- new StrongTypeSystemImpl(typeProvider,
- implicitCasts: options.implicitCasts,
- nonnullableTypes: options.nonnullableTypes),
- errorListener,
- options);
- checker.visitCompilationUnit(unit);
- }
-
- var errorReporter = _getErrorReporter(file);
-
- //
- // Validate the directives.
- //
- _validateUriBasedDirectives(file, unit);
-
- //
- // Use the ConstantVerifier to compute errors.
- //
- ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter,
- libraryElement, typeProvider, analysisContext.declaredVariables);
- unit.accept(constantVerifier);
-
- //
- // Use the ErrorVerifier to compute errors.
- //
- ErrorVerifier errorVerifier = new ErrorVerifier(
- errorReporter,
- libraryElement,
- typeProvider,
- new InheritanceManager(libraryElement),
- analysisOptions.enableSuperMixins);
- unit.accept(errorVerifier);
-
- //
- // Convert the pending errors into actual errors.
- //
- for (PendingError pendingError in pendingErrors) {
- errorListener.onError(pendingError.toAnalysisError());
+ ConstantFinder constantFinder = new ConstantFinder();
+ unit.accept(constantFinder);
+ _constants.addAll(constantFinder.constantsToCompute);
}
-
- //
- // Find dead code.
- //
- unit.accept(new DeadCodeVerifier(errorReporter,
- typeSystem: analysisContext.typeSystem));
-
- // Dart2js analysis.
- if (analysisOptions.dart2jsHint) {
- unit.accept(new Dart2JSVerifier(errorReporter));
- }
-
- InheritanceManager inheritanceManager = new InheritanceManager(
- libraryElement,
- includeAbstractFromSuperclasses: true);
-
- unit.accept(new BestPracticesVerifier(
- errorReporter, typeProvider, libraryElement, inheritanceManager,
- typeSystem: analysisContext.typeSystem));
-
- unit.accept(new OverrideVerifier(errorReporter, inheritanceManager));
-
- new ToDoFinder(errorReporter).findIn(unit);
}
/**
@@ -440,6 +479,60 @@ class UnitAnalysisResult {
}
/**
+ * [Node] that is used to compute constants in dependency order.
+ */
+class _ConstantNode extends Node<_ConstantNode> {
+ final ConstantEvaluationEngine evaluationEngine;
+ final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap;
+ final ConstantEvaluationTarget constant;
+
+ List<_ConstantNode> _dependencies = null;
+
+ bool isEvaluated = false;
+
+ _ConstantNode(this.evaluationEngine, this.nodeMap, this.constant);
+
+ @override
+ List<_ConstantNode> computeDependencies() {
+ if (_dependencies == null) {
+ List<ConstantEvaluationTarget> targets = [];
+ evaluationEngine.computeDependencies(constant, targets.add);
+ _dependencies = targets.map(_getNode).toList();
+ }
+ return _dependencies;
+ }
+
+ _ConstantNode _getNode(ConstantEvaluationTarget constant) {
+ return nodeMap.putIfAbsent(
+ constant, () => new _ConstantNode(evaluationEngine, nodeMap, constant));
+ }
+}
+
+/**
+ * [DependencyWalker] for computing constants and detecting cycles.
+ */
+class _ConstantWalker extends DependencyWalker<_ConstantNode> {
+ final ConstantEvaluationEngine evaluationEngine;
+
+ _ConstantWalker(this.evaluationEngine);
+
+ @override
+ void evaluate(_ConstantNode node) {
+ evaluationEngine.computeConstantValue(node.constant);
+ node.isEvaluated = true;
+ }
+
+ @override
+ void evaluateScc(List<_ConstantNode> scc) {
+ var constantsInCycle = scc.map((node) => node.constant);
+ for (_ConstantNode node in scc) {
+ evaluationEngine.generateCycleError(constantsInCycle, node.constant);
+ node.isEvaluated = true;
+ }
+ }
+}
+
+/**
* [ContentCache] wrapper around [FileContentOverlay].
*/
class _ContentCacheWrapper implements ContentCache {
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698