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

Side by Side Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1147853002: Properly handle circular references among constants in the task model. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.task.dart; 5 library analyzer.src.task.dart;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' as math; 8 import 'dart:math' as math;
9 9
10 import 'package:analyzer/src/generated/ast.dart'; 10 import 'package:analyzer/src/generated/ast.dart';
11 import 'package:analyzer/src/generated/constant.dart'; 11 import 'package:analyzer/src/generated/constant.dart';
12 import 'package:analyzer/src/generated/element.dart'; 12 import 'package:analyzer/src/generated/element.dart';
13 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask; 13 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
14 import 'package:analyzer/src/generated/error.dart'; 14 import 'package:analyzer/src/generated/error.dart';
15 import 'package:analyzer/src/generated/error_verifier.dart'; 15 import 'package:analyzer/src/generated/error_verifier.dart';
16 import 'package:analyzer/src/generated/java_engine.dart'; 16 import 'package:analyzer/src/generated/java_engine.dart';
17 import 'package:analyzer/src/generated/parser.dart'; 17 import 'package:analyzer/src/generated/parser.dart';
18 import 'package:analyzer/src/generated/resolver.dart'; 18 import 'package:analyzer/src/generated/resolver.dart';
19 import 'package:analyzer/src/generated/scanner.dart'; 19 import 'package:analyzer/src/generated/scanner.dart';
20 import 'package:analyzer/src/generated/sdk.dart'; 20 import 'package:analyzer/src/generated/sdk.dart';
21 import 'package:analyzer/src/generated/source.dart'; 21 import 'package:analyzer/src/generated/source.dart';
22 import 'package:analyzer/src/task/driver.dart';
22 import 'package:analyzer/src/task/general.dart'; 23 import 'package:analyzer/src/task/general.dart';
23 import 'package:analyzer/src/task/model.dart'; 24 import 'package:analyzer/src/task/model.dart';
24 import 'package:analyzer/task/dart.dart'; 25 import 'package:analyzer/task/dart.dart';
25 import 'package:analyzer/task/general.dart'; 26 import 'package:analyzer/task/general.dart';
26 import 'package:analyzer/task/model.dart'; 27 import 'package:analyzer/task/model.dart';
27 28
28 /** 29 /**
29 * The [ResultCachingPolicy] for ASTs. 30 * The [ResultCachingPolicy] for ASTs.
30 */ 31 */
31 const ResultCachingPolicy AST_CACHING_POLICY = 32 const ResultCachingPolicy AST_CACHING_POLICY =
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 <ResultDescriptor>[CONSTANT_VALUE]); 1779 <ResultDescriptor>[CONSTANT_VALUE]);
1779 1780
1780 ComputeConstantValueTask( 1781 ComputeConstantValueTask(
1781 InternalAnalysisContext context, ConstantEvaluationTarget constant) 1782 InternalAnalysisContext context, ConstantEvaluationTarget constant)
1782 : super(context, constant); 1783 : super(context, constant);
1783 1784
1784 @override 1785 @override
1785 TaskDescriptor get descriptor => DESCRIPTOR; 1786 TaskDescriptor get descriptor => DESCRIPTOR;
1786 1787
1787 @override 1788 @override
1789 bool get handlesDependencyCycles => true;
1790
1791 @override
1788 void internalPerform() { 1792 void internalPerform() {
1789 // 1793 //
1790 // Prepare inputs. 1794 // Prepare inputs.
1791 // 1795 //
1792 // Note: DEPENDENCIES_INPUT is not needed. It is merely a bookkeeping 1796 // Note: DEPENDENCIES_INPUT is not needed. It is merely a bookkeeping
1793 // dependency to ensure that the constants that this constant depends on 1797 // dependency to ensure that the constants that this constant depends on
1794 // are computed first. 1798 // are computed first.
1795 ConstantEvaluationTarget constant = target; 1799 ConstantEvaluationTarget constant = target;
1796 AnalysisContext context = constant.context; 1800 AnalysisContext context = constant.context;
1797 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); 1801 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
1798 // 1802 //
1799 // Compute the value of the constant. 1803 // Compute the value of the constant, or report an error if there was a
1804 // cycle.
1800 // 1805 //
1801 new ConstantEvaluationEngine(typeProvider, context.declaredVariables) 1806 ConstantEvaluationEngine constantEvaluationEngine =
1802 .computeConstantValue(constant); 1807 new ConstantEvaluationEngine(typeProvider, context.declaredVariables);
1808 if (dependencyCycle == null) {
1809 constantEvaluationEngine.computeConstantValue(constant);
1810 } else {
1811 List<ConstantEvaluationTarget> constantsInCycle =
1812 <ConstantEvaluationTarget>[];
1813 for (WorkItem workItem in dependencyCycle) {
1814 if (workItem.descriptor == DESCRIPTOR) {
1815 constantsInCycle.add(workItem.target);
1816 }
1817 }
1818 assert(constantsInCycle.isNotEmpty);
1819 constantEvaluationEngine.generateCycleError(constantsInCycle, constant);
1820 }
1803 // 1821 //
1804 // Record outputs. 1822 // Record outputs.
1805 // 1823 //
1806 outputs[CONSTANT_VALUE] = constant; 1824 outputs[CONSTANT_VALUE] = constant;
1807 } 1825 }
1808 1826
1809 /** 1827 /**
1810 * Return a map from the names of the inputs of this kind of task to the task 1828 * Return a map from the names of the inputs of this kind of task to the task
1811 * input descriptors describing those inputs for a task with the given 1829 * input descriptors describing those inputs for a task with the given
1812 * [target]. 1830 * [target].
(...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after
3237 final Source target; 3255 final Source target;
3238 3256
3239 _ExportSourceClosureTaskInput(this.target); 3257 _ExportSourceClosureTaskInput(this.target);
3240 3258
3241 @override 3259 @override
3242 TaskInputBuilder<List<Source>> createBuilder() => 3260 TaskInputBuilder<List<Source>> createBuilder() =>
3243 new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.EXPORT); 3261 new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.EXPORT);
3244 } 3262 }
3245 3263
3246 /** 3264 /**
3247 * The kind of the source closure to build.
3248 */
3249 enum _SourceClosureKind { IMPORT, EXPORT, IMPORT_EXPORT }
3250
3251 /**
3252 * A [TaskInput] whose value is a list of library sources imported or exported, 3265 * A [TaskInput] whose value is a list of library sources imported or exported,
3253 * directly or indirectly by the target [Source]. 3266 * directly or indirectly by the target [Source].
3254 */ 3267 */
3255 class _ImportExportSourceClosureTaskInput implements TaskInput<List<Source>> { 3268 class _ImportExportSourceClosureTaskInput implements TaskInput<List<Source>> {
3256 final Source target; 3269 final Source target;
3257 3270
3258 _ImportExportSourceClosureTaskInput(this.target); 3271 _ImportExportSourceClosureTaskInput(this.target);
3259 3272
3260 @override 3273 @override
3261 TaskInputBuilder<List<Source>> createBuilder() => 3274 TaskInputBuilder<List<Source>> createBuilder() =>
3262 new _SourceClosureTaskInputBuilder( 3275 new _SourceClosureTaskInputBuilder(
3263 target, _SourceClosureKind.IMPORT_EXPORT); 3276 target, _SourceClosureKind.IMPORT_EXPORT);
3264 } 3277 }
3265 3278
3266 /** 3279 /**
3267 * A [TaskInput] whose value is a list of library sources imported directly 3280 * A [TaskInput] whose value is a list of library sources imported directly
3268 * or indirectly by the target [Source]. 3281 * or indirectly by the target [Source].
3269 */ 3282 */
3270 class _ImportSourceClosureTaskInput implements TaskInput<List<Source>> { 3283 class _ImportSourceClosureTaskInput implements TaskInput<List<Source>> {
3271 final Source target; 3284 final Source target;
3272 3285
3273 _ImportSourceClosureTaskInput(this.target); 3286 _ImportSourceClosureTaskInput(this.target);
3274 3287
3275 @override 3288 @override
3276 TaskInputBuilder<List<Source>> createBuilder() => 3289 TaskInputBuilder<List<Source>> createBuilder() =>
3277 new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.IMPORT); 3290 new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.IMPORT);
3278 } 3291 }
3279 3292
3280 /** 3293 /**
3294 * The kind of the source closure to build.
3295 */
3296 enum _SourceClosureKind { IMPORT, EXPORT, IMPORT_EXPORT }
3297
3298 /**
3281 * A [TaskInputBuilder] to build values for [_ImportSourceClosureTaskInput]. 3299 * A [TaskInputBuilder] to build values for [_ImportSourceClosureTaskInput].
3282 */ 3300 */
3283 class _SourceClosureTaskInputBuilder implements TaskInputBuilder<List<Source>> { 3301 class _SourceClosureTaskInputBuilder implements TaskInputBuilder<List<Source>> {
3284 final _SourceClosureKind kind; 3302 final _SourceClosureKind kind;
3285 final Set<LibraryElement> _libraries = new HashSet<LibraryElement>(); 3303 final Set<LibraryElement> _libraries = new HashSet<LibraryElement>();
3286 final Set<Source> _newSources = new HashSet<Source>(); 3304 final Set<Source> _newSources = new HashSet<Source>();
3287 3305
3288 Source currentTarget; 3306 Source currentTarget;
3289 3307
3290 _SourceClosureTaskInputBuilder(Source librarySource, this.kind) { 3308 _SourceClosureTaskInputBuilder(Source librarySource, this.kind) {
(...skipping 22 matching lines...) Expand all
3313 } 3331 }
3314 } 3332 }
3315 } 3333 }
3316 3334
3317 @override 3335 @override
3318 List<Source> get inputValue { 3336 List<Source> get inputValue {
3319 return _libraries.map((LibraryElement library) => library.source).toList(); 3337 return _libraries.map((LibraryElement library) => library.source).toList();
3320 } 3338 }
3321 3339
3322 @override 3340 @override
3341 void currentValueNotAvailable() {
3342 // Nothing needs to be done. moveNext() will simply go on to the next new
3343 // source.
3344 }
3345
3346 @override
3323 bool moveNext() { 3347 bool moveNext() {
3324 if (_newSources.isEmpty) { 3348 if (_newSources.isEmpty) {
3325 return false; 3349 return false;
3326 } 3350 }
3327 currentTarget = _newSources.first; 3351 currentTarget = _newSources.first;
3328 _newSources.remove(currentTarget); 3352 _newSources.remove(currentTarget);
3329 return true; 3353 return true;
3330 } 3354 }
3331 } 3355 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698