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

Side by Side Diff: pkg/analyzer/lib/src/task/inputs.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.inputs; 5 library analyzer.src.task.inputs;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/task/model.dart'; 9 import 'package:analyzer/task/model.dart';
10 10
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 @override 229 @override
230 void set currentValue(Object value) { 230 void set currentValue(Object value) {
231 if (currentBuilder == null) { 231 if (currentBuilder == null) {
232 throw new StateError( 232 throw new StateError(
233 'Cannot set the result value when there is no current result'); 233 'Cannot set the result value when there is no current result');
234 } 234 }
235 currentBuilder.currentValue = value; 235 currentBuilder.currentValue = value;
236 } 236 }
237 237
238 @override 238 @override
239 void currentValueNotAvailable() {
240 if (currentBuilder == null) {
241 throw new StateError(
242 'Cannot set the result value when there is no current result');
243 }
244 currentBuilder.currentValueNotAvailable();
245 }
246
247 @override
239 bool moveNext() { 248 bool moveNext() {
240 // Prepare base Map. 249 // Prepare base Map.
241 if (baseMap == null) { 250 if (baseMap == null) {
242 if (currentBuilder.moveNext()) { 251 if (currentBuilder.moveNext()) {
243 return true; 252 return true;
244 } 253 }
245 baseMap = currentBuilder.inputValue; 254 baseMap = currentBuilder.inputValue;
255 if (baseMap == null) {
256 // No base map could be computed due to a circular dependency. Use an
257 // empty map so that no further results will be computed.
258 baseMap = {};
259 }
246 keyIterator = baseMap.keys.iterator; 260 keyIterator = baseMap.keys.iterator;
247 // Done with this builder. 261 // Done with this builder.
248 currentBuilder = null; 262 currentBuilder = null;
249 } 263 }
250 // Prepare the next result value. 264 // Prepare the next result value.
251 if (currentBuilder != null) { 265 if (currentBuilder != null) {
252 if (currentBuilder.moveNext()) { 266 if (currentBuilder.moveNext()) {
253 return true; 267 return true;
254 } 268 }
255 // Add the result value for the current Map key/value. 269 // Add the result value for the current Map key/value.
256 E resultValue = currentBuilder.inputValue; 270 E resultValue = currentBuilder.inputValue;
257 inputValue.add(resultValue); 271 if (resultValue != null) {
272 inputValue.add(resultValue);
273 }
258 // Done with this builder. 274 // Done with this builder.
259 currentBuilder = null; 275 currentBuilder = null;
260 } 276 }
261 // Move to the next Map value. 277 // Move to the next Map value.
262 if (valueIterator != null && valueIterator.moveNext()) { 278 if (valueIterator != null && valueIterator.moveNext()) {
263 K key = keyIterator.current; 279 K key = keyIterator.current;
264 V value = valueIterator.current; 280 V value = valueIterator.current;
265 currentBuilder = mapper(key, value).createBuilder(); 281 currentBuilder = mapper(key, value).createBuilder();
266 return moveNext(); 282 return moveNext();
267 } 283 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 * result. 338 * result.
323 */ 339 */
324 static const _AFTER = 1; 340 static const _AFTER = 1;
325 341
326 /** 342 /**
327 * The input being built. 343 * The input being built.
328 */ 344 */
329 final SimpleTaskInput<V> input; 345 final SimpleTaskInput<V> input;
330 346
331 /** 347 /**
332 * The value of the input being built. 348 * The value of the input being built. `null` if the value hasn't been set
349 * yet, or if no result is available ([currentValueNotAvailable] was called).
333 */ 350 */
334 V _resultValue = null; 351 V _resultValue = null;
335 352
336 /** 353 /**
337 * The state of the builder. 354 * The state of the builder.
338 */ 355 */
339 int _state = _BEFORE; 356 int _state = _BEFORE;
340 357
341 /** 358 /**
342 * A flag indicating whether the result value was explicitly set. 359 * A flag indicating whether the result value was explicitly set.
(...skipping 24 matching lines...) Expand all
367 384
368 @override 385 @override
369 V get inputValue { 386 V get inputValue {
370 if (_state != _AFTER) { 387 if (_state != _AFTER) {
371 throw new StateError('Result value has not been created'); 388 throw new StateError('Result value has not been created');
372 } 389 }
373 return _resultValue; 390 return _resultValue;
374 } 391 }
375 392
376 @override 393 @override
394 void currentValueNotAvailable() {
395 if (_state != _AT) {
396 throw new StateError(
397 'Cannot set the result value when there is no current result');
398 }
399 _resultValue = null;
400 _resultSet = true;
401 }
402
403 @override
377 bool moveNext() { 404 bool moveNext() {
378 if (_state == _BEFORE) { 405 if (_state == _BEFORE) {
379 _state = _AT; 406 _state = _AT;
380 return true; 407 return true;
381 } else { 408 } else {
382 if (!_resultSet) { 409 if (!_resultSet) {
383 throw new StateError( 410 throw new StateError(
384 'The value of the current result must be set before moving to the ne xt result.'); 411 'The value of the current result must be set before moving to the ne xt result.');
385 } 412 }
386 _state = _AFTER; 413 _state = _AFTER;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 } 490 }
464 return inputs; 491 return inputs;
465 } 492 }
466 493
467 /** 494 /**
468 * Assuming that there is a current input, return its name. 495 * Assuming that there is a current input, return its name.
469 */ 496 */
470 String get _currentName => inputNames[nameIndex]; 497 String get _currentName => inputNames[nameIndex];
471 498
472 @override 499 @override
500 void currentValueNotAvailable() {
501 if (currentBuilder == null) {
502 throw new StateError(
503 'Cannot set the result value when there is no current result');
504 }
505 currentBuilder.currentValueNotAvailable();
506 }
507
508 @override
473 bool moveNext() { 509 bool moveNext() {
474 if (nameIndex >= inputNames.length) { 510 if (nameIndex >= inputNames.length) {
475 // We have already computed all of the results, so just return false. 511 // We have already computed all of the results, so just return false.
476 return false; 512 return false;
477 } 513 }
478 if (nameIndex < 0) { 514 if (nameIndex < 0) {
479 // This is the first time moveNext has been invoked, so we just determine 515 // This is the first time moveNext has been invoked, so we just determine
480 // whether there are any results to be computed. 516 // whether there are any results to be computed.
481 nameIndex = 0; 517 nameIndex = 0;
482 } else { 518 } else {
483 if (currentBuilder.moveNext()) { 519 if (currentBuilder.moveNext()) {
484 // We are still working on building the value associated with the 520 // We are still working on building the value associated with the
485 // current name. 521 // current name.
486 return true; 522 return true;
487 } 523 }
488 inputs[_currentName] = currentBuilder.inputValue; 524 if (currentBuilder.inputValue != null) {
525 inputs[_currentName] = currentBuilder.inputValue;
526 }
489 nameIndex++; 527 nameIndex++;
490 } 528 }
491 if (nameIndex >= inputNames.length) { 529 if (nameIndex >= inputNames.length) {
492 // There is no next value, so we're done. 530 // There is no next value, so we're done.
493 return false; 531 return false;
494 } 532 }
495 currentBuilder = inputDescriptors[_currentName].createBuilder(); 533 currentBuilder = inputDescriptors[_currentName].createBuilder();
496 // NOTE: This assumes that every builder will require at least one result 534 // NOTE: This assumes that every builder will require at least one result
497 // value to be created. If that assumption is every broken, this method will 535 // value to be created. If that assumption is every broken, this method will
498 // need to be changed to advance until we find a builder that does require 536 // need to be changed to advance until we find a builder that does require
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 } 636 }
599 return _resultValue; 637 return _resultValue;
600 } 638 }
601 639
602 /** 640 /**
603 * The list of values being built. 641 * The list of values being built.
604 */ 642 */
605 C get _resultValue; 643 C get _resultValue;
606 644
607 @override 645 @override
646 void currentValueNotAvailable() {
647 if (currentBuilder == null) {
648 throw new StateError(
649 'Cannot set the result value when there is no current result');
650 }
651 currentBuilder.currentValueNotAvailable();
652 }
653
654 @override
608 bool moveNext() { 655 bool moveNext() {
609 if (currentBuilder == null) { 656 if (currentBuilder == null) {
610 if (_resultValue == null) { 657 if (_resultValue == null) {
611 // This is the first time moveNext has been invoked, so start by 658 // This is the first time moveNext has been invoked, so start by
612 // computing the list of values from which the results will be derived. 659 // computing the list of values from which the results will be derived.
613 currentBuilder = input.baseAccessor.createBuilder(); 660 currentBuilder = input.baseAccessor.createBuilder();
614 return currentBuilder.moveNext(); 661 return currentBuilder.moveNext();
615 } else { 662 } else {
616 // We have already computed all of the results, so just return false. 663 // We have already computed all of the results, so just return false.
617 return false; 664 return false;
618 } 665 }
619 } 666 }
620 if (currentBuilder.moveNext()) { 667 if (currentBuilder.moveNext()) {
621 return true; 668 return true;
622 } 669 }
623 if (_resultValue == null) { 670 if (_resultValue == null) {
624 // We have finished computing the list of values from which the results 671 // We have finished computing the list of values from which the results
625 // will be derived. 672 // will be derived.
626 _baseList = currentBuilder.inputValue; 673 _baseList = currentBuilder.inputValue;
674 if (_baseList == null) {
675 // No base list could be computed due to a circular dependency. Use an
676 // empty list so that no further results will be computed.
677 _baseList = [];
678 }
627 _baseListIndex = 0; 679 _baseListIndex = 0;
628 _initResultValue(); 680 _initResultValue();
629 } else { 681 } else {
630 // We have finished computing one of the elements in the result list. 682 // We have finished computing one of the elements in the result list.
631 _addResultElement(_baseListElement, currentBuilder.inputValue); 683 if (currentBuilder.inputValue != null) {
684 _addResultElement(_baseListElement, currentBuilder.inputValue);
685 }
632 _baseListIndex++; 686 _baseListIndex++;
633 } 687 }
634 if (_baseListIndex >= _baseList.length) { 688 if (_baseListIndex >= _baseList.length) {
635 currentBuilder = null; 689 currentBuilder = null;
636 return false; 690 return false;
637 } 691 }
638 _baseListElement = _baseList[_baseListIndex]; 692 _baseListElement = _baseList[_baseListIndex];
639 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); 693 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder();
640 return currentBuilder.moveNext(); 694 return currentBuilder.moveNext();
641 } 695 }
642 696
643 void _addResultElement(B baseElement, E resultElement); 697 void _addResultElement(B baseElement, E resultElement);
644 void _initResultValue(); 698 void _initResultValue();
645 } 699 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698