OLD | NEW |
---|---|
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 edit.domain; | 5 library edit.domain; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 | 8 |
9 import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; | 9 import 'package:analysis_server/plugin/edit/assist/assist_core.dart'; |
10 import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; | 10 import 'package:analysis_server/plugin/edit/fix/fix_core.dart'; |
11 import 'package:analysis_server/src/analysis_server.dart'; | 11 import 'package:analysis_server/src/analysis_server.dart'; |
12 import 'package:analysis_server/src/collections.dart'; | 12 import 'package:analysis_server/src/collections.dart'; |
13 import 'package:analysis_server/src/constants.dart'; | 13 import 'package:analysis_server/src/constants.dart'; |
14 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 14 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
15 import 'package:analysis_server/src/services/correction/assist.dart'; | 15 import 'package:analysis_server/src/services/correction/assist.dart'; |
16 import 'package:analysis_server/src/services/correction/fix.dart'; | 16 import 'package:analysis_server/src/services/correction/fix.dart'; |
17 import 'package:analysis_server/src/services/correction/organize_directives.dart '; | 17 import 'package:analysis_server/src/services/correction/organize_directives.dart '; |
18 import 'package:analysis_server/src/services/correction/sort_members.dart'; | 18 import 'package:analysis_server/src/services/correction/sort_members.dart'; |
19 import 'package:analysis_server/src/services/correction/status.dart'; | 19 import 'package:analysis_server/src/services/correction/status.dart'; |
20 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; | 20 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; |
21 import 'package:analysis_server/src/services/search/search_engine.dart'; | 21 import 'package:analysis_server/src/services/search/search_engine.dart'; |
22 import 'package:analyzer/dart/ast/ast.dart'; | 22 import 'package:analyzer/dart/ast/ast.dart'; |
23 import 'package:analyzer/dart/element/element.dart'; | 23 import 'package:analyzer/dart/element/element.dart'; |
24 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine; | 24 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine; |
25 import 'package:analyzer/src/generated/engine.dart' as engine; | 25 import 'package:analyzer/src/generated/engine.dart' as engine; |
26 import 'package:analyzer/src/generated/error.dart' as engine; | 26 import 'package:analyzer/src/generated/error.dart' as engine; |
27 import 'package:analyzer/src/generated/parser.dart' as engine; | 27 import 'package:analyzer/src/generated/parser.dart' as engine; |
28 import 'package:analyzer/src/generated/source.dart'; | 28 import 'package:analyzer/src/generated/source.dart'; |
29 import 'package:analyzer/task/dart.dart'; | |
29 import 'package:dart_style/dart_style.dart'; | 30 import 'package:dart_style/dart_style.dart'; |
30 | 31 |
32 int test_resetCount = 0; | |
33 | |
31 bool test_simulateRefactoringException_change = false; | 34 bool test_simulateRefactoringException_change = false; |
32 bool test_simulateRefactoringException_final = false; | 35 bool test_simulateRefactoringException_final = false; |
33 bool test_simulateRefactoringException_init = false; | 36 bool test_simulateRefactoringException_init = false; |
34 | 37 |
35 bool test_simulateRefactoringReset_afterCreateChange = false; | 38 bool test_simulateRefactoringReset_afterCreateChange = false; |
36 bool test_simulateRefactoringReset_afterFinalConditions = false; | 39 bool test_simulateRefactoringReset_afterFinalConditions = false; |
37 bool test_simulateRefactoringReset_afterInitialConditions = false; | 40 bool test_simulateRefactoringReset_afterInitialConditions = false; |
38 | 41 |
39 /** | 42 /** |
40 * Instances of the class [EditDomainHandler] implement a [RequestHandler] | 43 * Instances of the class [EditDomainHandler] implement a [RequestHandler] |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 * | 372 * |
370 * Once new set of parameters is received, the previous [Refactoring] instance | 373 * Once new set of parameters is received, the previous [Refactoring] instance |
371 * is invalidated and a new one is created and initialized. | 374 * is invalidated and a new one is created and initialized. |
372 */ | 375 */ |
373 class _RefactoringManager { | 376 class _RefactoringManager { |
374 static const List<RefactoringProblem> EMPTY_PROBLEM_LIST = | 377 static const List<RefactoringProblem> EMPTY_PROBLEM_LIST = |
375 const <RefactoringProblem>[]; | 378 const <RefactoringProblem>[]; |
376 | 379 |
377 final AnalysisServer server; | 380 final AnalysisServer server; |
378 final SearchEngine searchEngine; | 381 final SearchEngine searchEngine; |
379 StreamSubscription onAnalysisStartedSubscription; | 382 StreamSubscription subscriptionToReset; |
380 | 383 |
381 RefactoringKind kind; | 384 RefactoringKind kind; |
382 String file; | 385 String file; |
383 int offset; | 386 int offset; |
384 int length; | 387 int length; |
385 Refactoring refactoring; | 388 Refactoring refactoring; |
386 RefactoringFeedback feedback; | 389 RefactoringFeedback feedback; |
387 RefactoringStatus initStatus; | 390 RefactoringStatus initStatus; |
388 RefactoringStatus optionsStatus; | 391 RefactoringStatus optionsStatus; |
389 RefactoringStatus finalStatus; | 392 RefactoringStatus finalStatus; |
390 | 393 |
391 Request request; | 394 Request request; |
392 EditGetRefactoringResult result; | 395 EditGetRefactoringResult result; |
393 | 396 |
394 _RefactoringManager(this.server, this.searchEngine) { | 397 _RefactoringManager(this.server, this.searchEngine) { |
395 onAnalysisStartedSubscription = server.onAnalysisStarted.listen(_reset); | |
396 _reset(); | 398 _reset(); |
397 } | 399 } |
398 | 400 |
399 /** | 401 /** |
400 * Returns `true` if a response for the current request has not yet been sent. | 402 * Returns `true` if a response for the current request has not yet been sent. |
401 */ | 403 */ |
402 bool get hasPendingRequest => request != null; | 404 bool get hasPendingRequest => request != null; |
403 | 405 |
404 bool get _hasFatalError { | 406 bool get _hasFatalError { |
405 return initStatus.hasFatalError || | 407 return initStatus.hasFatalError || |
406 optionsStatus.hasFatalError || | 408 optionsStatus.hasFatalError || |
407 finalStatus.hasFatalError; | 409 finalStatus.hasFatalError; |
408 } | 410 } |
409 | 411 |
410 /** | 412 /** |
411 * Checks if [refactoring] requires options. | 413 * Checks if [refactoring] requires options. |
412 */ | 414 */ |
413 bool get _requiresOptions { | 415 bool get _requiresOptions { |
414 return refactoring is ExtractLocalRefactoring || | 416 return refactoring is ExtractLocalRefactoring || |
415 refactoring is ExtractMethodRefactoring || | 417 refactoring is ExtractMethodRefactoring || |
416 refactoring is InlineMethodRefactoring || | 418 refactoring is InlineMethodRefactoring || |
417 refactoring is MoveFileRefactoring || | 419 refactoring is MoveFileRefactoring || |
418 refactoring is RenameRefactoring; | 420 refactoring is RenameRefactoring; |
419 } | 421 } |
420 | 422 |
421 /** | 423 /** |
422 * Cancels processing of the current request and cleans up. | 424 * Cancels processing of the current request and cleans up. |
423 */ | 425 */ |
424 void cancel() { | 426 void cancel() { |
425 onAnalysisStartedSubscription.cancel(); | 427 subscriptionToReset?.cancel(); |
428 subscriptionToReset = null; | |
426 server.sendResponse(new Response.refactoringRequestCancelled(request)); | 429 server.sendResponse(new Response.refactoringRequestCancelled(request)); |
427 request = null; | 430 request = null; |
428 } | 431 } |
429 | 432 |
430 void getRefactoring(Request _request) { | 433 void getRefactoring(Request _request) { |
431 // prepare for processing the request | 434 // prepare for processing the request |
432 request = _request; | 435 request = _request; |
433 result = new EditGetRefactoringResult( | 436 result = new EditGetRefactoringResult( |
434 EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST); | 437 EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST); |
435 // process the request | 438 // process the request |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 cancel(); | 488 cancel(); |
486 } else { | 489 } else { |
487 server.instrumentationService.logException(exception, stackTrace); | 490 server.instrumentationService.logException(exception, stackTrace); |
488 server.sendResponse( | 491 server.sendResponse( |
489 new Response.serverError(_request, exception, stackTrace)); | 492 new Response.serverError(_request, exception, stackTrace)); |
490 } | 493 } |
491 _reset(); | 494 _reset(); |
492 }); | 495 }); |
493 } | 496 } |
494 | 497 |
498 /** | |
499 * Perform enough analysis to be able to perform refactoring of the given | |
500 * [kind] in the given [file]. | |
501 */ | |
502 Future<Null> _analyzeForRefactoring(String file, RefactoringKind kind) async { | |
503 // "Extract Local" and "Inline Local" refactorings need only local analysis. | |
504 if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE || | |
505 kind == RefactoringKind.INLINE_LOCAL_VARIABLE) { | |
506 ContextSourcePair pair = server.getContextSourcePair(file); | |
507 engine.AnalysisContext context = pair.context; | |
508 Source source = pair.source; | |
509 if (context != null && source != null) { | |
510 if (context.computeResult(source, SOURCE_KIND) == SourceKind.LIBRARY) { | |
511 await context.computeResolvedCompilationUnitAsync(source, source); | |
512 return; | |
513 } | |
514 } | |
515 } | |
516 // A refactoring for which we cannot optimize analysis. | |
517 // So, wait for full analysis. | |
518 await server.onAnalysisComplete; | |
519 } | |
520 | |
495 void _checkForReset_afterCreateChange() { | 521 void _checkForReset_afterCreateChange() { |
496 if (test_simulateRefactoringReset_afterCreateChange) { | 522 if (test_simulateRefactoringReset_afterCreateChange) { |
497 _reset(); | 523 _reset(); |
498 } | 524 } |
499 if (refactoring == null) { | 525 if (refactoring == null) { |
500 throw new _ResetError(); | 526 throw new _ResetError(); |
501 } | 527 } |
502 } | 528 } |
503 | 529 |
504 void _checkForReset_afterFinalConditions() { | 530 void _checkForReset_afterFinalConditions() { |
(...skipping 13 matching lines...) Expand all Loading... | |
518 throw new _ResetError(); | 544 throw new _ResetError(); |
519 } | 545 } |
520 } | 546 } |
521 | 547 |
522 /** | 548 /** |
523 * Initializes this context to perform a refactoring with the specified | 549 * Initializes this context to perform a refactoring with the specified |
524 * parameters. The existing [Refactoring] is reused or created as needed. | 550 * parameters. The existing [Refactoring] is reused or created as needed. |
525 */ | 551 */ |
526 Future _init( | 552 Future _init( |
527 RefactoringKind kind, String file, int offset, int length) async { | 553 RefactoringKind kind, String file, int offset, int length) async { |
528 await server.onAnalysisComplete; | 554 await _analyzeForRefactoring(file, kind); |
529 // check if we can continue with the existing Refactoring instance | 555 // check if we can continue with the existing Refactoring instance |
530 if (this.kind == kind && | 556 if (this.kind == kind && |
531 this.file == file && | 557 this.file == file && |
532 this.offset == offset && | 558 this.offset == offset && |
533 this.length == length) { | 559 this.length == length) { |
534 return; | 560 return; |
535 } | 561 } |
536 _reset(); | 562 _reset(); |
537 this.kind = kind; | 563 this.kind = kind; |
538 this.file = file; | 564 this.file = file; |
539 this.offset = offset; | 565 this.offset = offset; |
540 this.length = length; | 566 this.length = length; |
541 // simulate an exception | 567 // simulate an exception |
542 if (test_simulateRefactoringException_init) { | 568 if (test_simulateRefactoringException_init) { |
543 throw 'A simulated refactoring exception - init.'; | 569 throw 'A simulated refactoring exception - init.'; |
544 } | 570 } |
545 // create a new Refactoring instance | 571 // create a new Refactoring instance |
546 if (kind == RefactoringKind.CONVERT_GETTER_TO_METHOD) { | 572 if (kind == RefactoringKind.CONVERT_GETTER_TO_METHOD) { |
547 List<Element> elements = server.getElementsAtOffset(file, offset); | 573 List<Element> elements = server.getElementsAtOffset(file, offset); |
548 if (elements.isNotEmpty) { | 574 if (elements.isNotEmpty) { |
549 Element element = elements[0]; | 575 Element element = elements[0]; |
550 if (element is ExecutableElement) { | 576 if (element is ExecutableElement) { |
577 _resetOnAnalysisStarted(); | |
551 refactoring = | 578 refactoring = |
552 new ConvertGetterToMethodRefactoring(searchEngine, element); | 579 new ConvertGetterToMethodRefactoring(searchEngine, element); |
553 } | 580 } |
554 } | 581 } |
555 } | 582 } |
556 if (kind == RefactoringKind.CONVERT_METHOD_TO_GETTER) { | 583 if (kind == RefactoringKind.CONVERT_METHOD_TO_GETTER) { |
557 List<Element> elements = server.getElementsAtOffset(file, offset); | 584 List<Element> elements = server.getElementsAtOffset(file, offset); |
558 if (elements.isNotEmpty) { | 585 if (elements.isNotEmpty) { |
559 Element element = elements[0]; | 586 Element element = elements[0]; |
560 if (element is ExecutableElement) { | 587 if (element is ExecutableElement) { |
588 _resetOnAnalysisStarted(); | |
561 refactoring = | 589 refactoring = |
562 new ConvertMethodToGetterRefactoring(searchEngine, element); | 590 new ConvertMethodToGetterRefactoring(searchEngine, element); |
563 } | 591 } |
564 } | 592 } |
565 } | 593 } |
566 if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) { | 594 if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) { |
567 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); | 595 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); |
568 if (units.isNotEmpty) { | 596 if (units.isNotEmpty) { |
597 _resetOnFileResolutionChanged(file); | |
569 refactoring = new ExtractLocalRefactoring(units[0], offset, length); | 598 refactoring = new ExtractLocalRefactoring(units[0], offset, length); |
570 feedback = new ExtractLocalVariableFeedback( | 599 feedback = new ExtractLocalVariableFeedback( |
571 <String>[], <int>[], <int>[], | 600 <String>[], <int>[], <int>[], |
572 coveringExpressionOffsets: <int>[], | 601 coveringExpressionOffsets: <int>[], |
573 coveringExpressionLengths: <int>[]); | 602 coveringExpressionLengths: <int>[]); |
574 } | 603 } |
575 } | 604 } |
576 if (kind == RefactoringKind.EXTRACT_METHOD) { | 605 if (kind == RefactoringKind.EXTRACT_METHOD) { |
577 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); | 606 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); |
578 if (units.isNotEmpty) { | 607 if (units.isNotEmpty) { |
608 _resetOnAnalysisStarted(); | |
579 refactoring = new ExtractMethodRefactoring( | 609 refactoring = new ExtractMethodRefactoring( |
580 searchEngine, units[0], offset, length); | 610 searchEngine, units[0], offset, length); |
581 feedback = new ExtractMethodFeedback(offset, length, '', <String>[], | 611 feedback = new ExtractMethodFeedback(offset, length, '', <String>[], |
582 false, <RefactoringMethodParameter>[], <int>[], <int>[]); | 612 false, <RefactoringMethodParameter>[], <int>[], <int>[]); |
583 } | 613 } |
584 } | 614 } |
585 if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) { | 615 if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) { |
586 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); | 616 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); |
587 if (units.isNotEmpty) { | 617 if (units.isNotEmpty) { |
618 _resetOnFileResolutionChanged(file); | |
588 refactoring = | 619 refactoring = |
589 new InlineLocalRefactoring(searchEngine, units[0], offset); | 620 new InlineLocalRefactoring(searchEngine, units[0], offset); |
590 } | 621 } |
591 } | 622 } |
592 if (kind == RefactoringKind.INLINE_METHOD) { | 623 if (kind == RefactoringKind.INLINE_METHOD) { |
593 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); | 624 List<CompilationUnit> units = server.getResolvedCompilationUnits(file); |
594 if (units.isNotEmpty) { | 625 if (units.isNotEmpty) { |
626 _resetOnAnalysisStarted(); | |
595 refactoring = | 627 refactoring = |
596 new InlineMethodRefactoring(searchEngine, units[0], offset); | 628 new InlineMethodRefactoring(searchEngine, units[0], offset); |
597 } | 629 } |
598 } | 630 } |
599 if (kind == RefactoringKind.MOVE_FILE) { | 631 if (kind == RefactoringKind.MOVE_FILE) { |
632 _resetOnAnalysisStarted(); | |
600 ContextSourcePair contextSource = server.getContextSourcePair(file); | 633 ContextSourcePair contextSource = server.getContextSourcePair(file); |
601 engine.AnalysisContext context = contextSource.context; | 634 engine.AnalysisContext context = contextSource.context; |
602 Source source = contextSource.source; | 635 Source source = contextSource.source; |
603 refactoring = new MoveFileRefactoring( | 636 refactoring = new MoveFileRefactoring( |
604 server.resourceProvider, searchEngine, context, source, file); | 637 server.resourceProvider, searchEngine, context, source, file); |
605 } | 638 } |
606 if (kind == RefactoringKind.RENAME) { | 639 if (kind == RefactoringKind.RENAME) { |
607 List<AstNode> nodes = server.getNodesAtOffset(file, offset); | 640 List<AstNode> nodes = server.getNodesAtOffset(file, offset); |
608 List<Element> elements = server.getElementsOfNodes(nodes); | 641 List<Element> elements = server.getElementsOfNodes(nodes); |
609 if (nodes.isNotEmpty && elements.isNotEmpty) { | 642 if (nodes.isNotEmpty && elements.isNotEmpty) { |
610 AstNode node = nodes[0]; | 643 AstNode node = nodes[0]; |
611 Element element = elements[0]; | 644 Element element = elements[0]; |
612 if (element is FieldFormalParameterElement) { | 645 if (element is FieldFormalParameterElement) { |
613 element = (element as FieldFormalParameterElement).field; | 646 element = (element as FieldFormalParameterElement).field; |
614 } | 647 } |
615 // climb from "Class" in "new Class.named()" to "Class.named" | 648 // climb from "Class" in "new Class.named()" to "Class.named" |
616 if (node.parent is TypeName && node.parent.parent is ConstructorName) { | 649 if (node.parent is TypeName && node.parent.parent is ConstructorName) { |
617 ConstructorName constructor = node.parent.parent; | 650 ConstructorName constructor = node.parent.parent; |
618 node = constructor; | 651 node = constructor; |
619 element = constructor.staticElement; | 652 element = constructor.staticElement; |
620 } | 653 } |
621 // do create the refactoring | 654 // do create the refactoring |
655 _resetOnAnalysisStarted(); | |
622 refactoring = new RenameRefactoring(searchEngine, element); | 656 refactoring = new RenameRefactoring(searchEngine, element); |
623 feedback = | 657 feedback = |
624 new RenameFeedback(node.offset, node.length, 'kind', 'oldName'); | 658 new RenameFeedback(node.offset, node.length, 'kind', 'oldName'); |
625 } | 659 } |
626 } | 660 } |
627 if (refactoring == null) { | 661 if (refactoring == null) { |
628 initStatus = | 662 initStatus = |
629 new RefactoringStatus.fatal('Unable to create a refactoring'); | 663 new RefactoringStatus.fatal('Unable to create a refactoring'); |
630 return; | 664 return; |
631 } | 665 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
669 } | 703 } |
670 } | 704 } |
671 if (refactoring is RenameRefactoring) { | 705 if (refactoring is RenameRefactoring) { |
672 RenameRefactoring refactoring = this.refactoring; | 706 RenameRefactoring refactoring = this.refactoring; |
673 RenameFeedback feedback = this.feedback; | 707 RenameFeedback feedback = this.feedback; |
674 feedback.elementKindName = refactoring.elementKindName; | 708 feedback.elementKindName = refactoring.elementKindName; |
675 feedback.oldName = refactoring.oldName; | 709 feedback.oldName = refactoring.oldName; |
676 } | 710 } |
677 } | 711 } |
678 | 712 |
679 void _reset([engine.AnalysisContext context]) { | 713 void _reset() { |
714 test_resetCount++; | |
680 kind = null; | 715 kind = null; |
681 offset = null; | 716 offset = null; |
682 length = null; | 717 length = null; |
683 refactoring = null; | 718 refactoring = null; |
684 feedback = null; | 719 feedback = null; |
685 initStatus = new RefactoringStatus(); | 720 initStatus = new RefactoringStatus(); |
686 optionsStatus = new RefactoringStatus(); | 721 optionsStatus = new RefactoringStatus(); |
687 finalStatus = new RefactoringStatus(); | 722 finalStatus = new RefactoringStatus(); |
723 subscriptionToReset?.cancel(); | |
724 subscriptionToReset = null; | |
725 } | |
726 | |
727 void _resetOnAnalysisStarted() { | |
728 subscriptionToReset = server.onAnalysisStarted.listen((_) => _reset()); | |
Brian Wilkerson
2016/08/22 23:32:23
Should we assert that `subscriptionToReset` is nul
scheglov
2016/08/23 01:55:28
Well, we need to at least cancel the current subsc
| |
729 } | |
730 | |
731 /** | |
732 * We're performing a refactoring that affects only the given [file]. | |
733 * So, when the [file] resolution is changed, we need to reset refactoring. | |
734 * But when any other file is changed or analyzer, we can continue. | |
735 */ | |
736 void _resetOnFileResolutionChanged(String file) { | |
737 engine.AnalysisContext context = server.getAnalysisContext(file); | |
738 subscriptionToReset = | |
739 context?.onResultChanged(RESOLVED_UNIT)?.listen((event) { | |
740 Source targetSource = event.target.source; | |
741 if (targetSource?.fullName == file) { | |
742 _reset(); | |
743 } | |
744 }); | |
688 } | 745 } |
689 | 746 |
690 void _sendResultResponse() { | 747 void _sendResultResponse() { |
691 // ignore if was cancelled | 748 // ignore if was cancelled |
692 if (request == null) { | 749 if (request == null) { |
693 return; | 750 return; |
694 } | 751 } |
695 // set feedback | 752 // set feedback |
696 result.feedback = feedback; | 753 result.feedback = feedback; |
697 // set problems | 754 // set problems |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
746 } | 803 } |
747 return new RefactoringStatus(); | 804 return new RefactoringStatus(); |
748 } | 805 } |
749 } | 806 } |
750 | 807 |
751 /** | 808 /** |
752 * [_RefactoringManager] throws instances of this class internally to stop | 809 * [_RefactoringManager] throws instances of this class internally to stop |
753 * processing in a manager that was reset. | 810 * processing in a manager that was reset. |
754 */ | 811 */ |
755 class _ResetError {} | 812 class _ResetError {} |
OLD | NEW |