| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |