Chromium Code Reviews| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library services.src.correction.assist; | 8 library services.src.correction.assist; |
| 9 | 9 |
| 10 import 'dart:collection'; | |
| 11 | |
| 10 import 'package:analysis_services/correction/assist.dart'; | 12 import 'package:analysis_services/correction/assist.dart'; |
| 11 import 'package:analysis_services/correction/change.dart'; | 13 import 'package:analysis_services/correction/change.dart'; |
| 12 import 'package:analysis_services/search/hierarchy.dart'; | 14 import 'package:analysis_services/search/hierarchy.dart'; |
| 13 import 'package:analysis_services/search/search_engine.dart'; | 15 import 'package:analysis_services/search/search_engine.dart'; |
| 14 import 'package:analysis_services/src/correction/name_suggestion.dart'; | 16 import 'package:analysis_services/src/correction/name_suggestion.dart'; |
| 15 import 'package:analysis_services/src/correction/source_buffer.dart'; | 17 import 'package:analysis_services/src/correction/source_buffer.dart'; |
| 16 import 'package:analysis_services/src/correction/source_range.dart'; | 18 import 'package:analysis_services/src/correction/source_range.dart'; |
| 17 import 'package:analysis_services/src/correction/util.dart'; | 19 import 'package:analysis_services/src/correction/util.dart'; |
| 18 import 'package:analyzer/src/generated/ast.dart'; | 20 import 'package:analyzer/src/generated/ast.dart'; |
| 19 import 'package:analyzer/src/generated/element.dart'; | 21 import 'package:analyzer/src/generated/element.dart'; |
| 20 import 'package:analyzer/src/generated/java_core.dart'; | 22 import 'package:analyzer/src/generated/java_core.dart'; |
| 21 import 'package:analyzer/src/generated/scanner.dart'; | 23 import 'package:analyzer/src/generated/scanner.dart'; |
| 22 import 'package:analyzer/src/generated/source.dart'; | 24 import 'package:analyzer/src/generated/source.dart'; |
| 23 import 'package:path/path.dart'; | 25 import 'package:path/path.dart'; |
| 24 | 26 |
| 25 | 27 |
| 28 | |
| 29 typedef _SimpleIdentifierVisitor(SimpleIdentifier node); | |
| 30 | |
| 31 | |
| 26 /** | 32 /** |
| 27 * The computer for Dart assists. | 33 * The computer for Dart assists. |
| 28 */ | 34 */ |
| 29 class AssistProcessor { | 35 class AssistProcessor { |
| 30 final SearchEngine searchEngine; | 36 final SearchEngine searchEngine; |
| 31 final Source source; | 37 final Source source; |
| 32 final String file; | 38 final String file; |
| 33 final CompilationUnit unit; | 39 final CompilationUnit unit; |
| 34 final int selectionOffset; | 40 final int selectionOffset; |
| 35 final int selectionLength; | 41 final int selectionLength; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 _addProposal_assignToLocalVariable(); | 78 _addProposal_assignToLocalVariable(); |
| 73 _addProposal_convertToBlockFunctionBody(); | 79 _addProposal_convertToBlockFunctionBody(); |
| 74 _addProposal_convertToExpressionFunctionBody(); | 80 _addProposal_convertToExpressionFunctionBody(); |
| 75 _addProposal_convertToIsNot_onIs(); | 81 _addProposal_convertToIsNot_onIs(); |
| 76 _addProposal_convertToIsNot_onNot(); | 82 _addProposal_convertToIsNot_onNot(); |
| 77 _addProposal_convertToIsNotEmpty(); | 83 _addProposal_convertToIsNotEmpty(); |
| 78 _addProposal_exchangeOperands(); | 84 _addProposal_exchangeOperands(); |
| 79 _addProposal_extractClassIntoPart(); | 85 _addProposal_extractClassIntoPart(); |
| 80 _addProposal_importAddShow(); | 86 _addProposal_importAddShow(); |
| 81 _addProposal_invertIf(); | 87 _addProposal_invertIf(); |
| 88 _addProposal_joinIfStatementInner(); | |
| 82 _addProposal_joinIfStatementOuter(); | 89 _addProposal_joinIfStatementOuter(); |
| 83 _addProposal_joinVariableDeclaration_onAssignment(); | 90 _addProposal_joinVariableDeclaration_onAssignment(); |
| 84 _addProposal_joinVariableDeclaration_onDeclaration(); | 91 _addProposal_joinVariableDeclaration_onDeclaration(); |
| 85 _addProposal_removeTypeAnnotation(); | 92 _addProposal_removeTypeAnnotation(); |
| 86 _addProposal_replaceConditionalWithIfElse(); | 93 _addProposal_replaceConditionalWithIfElse(); |
| 87 _addProposal_replaceIfElseWithConditional(); | 94 _addProposal_replaceIfElseWithConditional(); |
| 88 _addProposal_splitAndCondition(); | 95 _addProposal_splitAndCondition(); |
| 89 _addProposal_splitVariableDeclaration(); | 96 _addProposal_splitVariableDeclaration(); |
| 90 _addProposal_surroundWith(); | 97 _addProposal_surroundWith(); |
| 91 // done | 98 // done |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 // Change compositeChange = | 545 // Change compositeChange = |
| 539 // new CompositeChange("", [unitChange, createFileChange, libraryChange]) ; | 546 // new CompositeChange("", [unitChange, createFileChange, libraryChange]) ; |
| 540 // _proposals.add( | 547 // _proposals.add( |
| 541 // new ChangeCorrectionProposal( | 548 // new ChangeCorrectionProposal( |
| 542 // compositeChange, | 549 // compositeChange, |
| 543 // AssistKind.EXTRACT_CLASS, | 550 // AssistKind.EXTRACT_CLASS, |
| 544 // [fileName])); | 551 // [fileName])); |
| 545 } | 552 } |
| 546 | 553 |
| 547 void _addProposal_importAddShow() { | 554 void _addProposal_importAddShow() { |
| 548 // TODO(scheglov) implement | 555 // prepare ImportDirective |
| 549 // // prepare ImportDirective | 556 ImportDirective importDirective = |
| 550 // ImportDirective importDirective = | 557 node.getAncestor((node) => node is ImportDirective); |
| 551 // node.getAncestor((node) => node is ImportDirective); | 558 if (importDirective == null) { |
| 552 // if (importDirective == null) { | 559 _coverageMarker(); |
| 553 // return; | 560 return; |
| 554 // } | 561 } |
| 555 // // there should be no existing combinators | 562 // there should be no existing combinators |
| 556 // if (!importDirective.combinators.isEmpty) { | 563 if (importDirective.combinators.isNotEmpty) { |
| 557 // return; | 564 _coverageMarker(); |
| 558 // } | 565 return; |
| 559 // // prepare whole import namespace | 566 } |
| 560 // ImportElement importElement = importDirective.element; | 567 // prepare whole import namespace |
| 561 // Map<String, Element> namespace = | 568 ImportElement importElement = importDirective.element; |
| 562 // getImportNamespace(importElement); | 569 Map<String, Element> namespace = getImportNamespace(importElement); |
| 563 // // prepare names of referenced elements (from this import) | 570 // prepare names of referenced elements (from this import) |
| 564 // Set<String> referencedNames = new Set(); | 571 SplayTreeSet<String> referencedNames = new SplayTreeSet<String>(); |
| 565 // for (Element element in namespace.values) { | 572 _SimpleIdentifierRecursiveAstVisitor visitor = |
| 566 // List<SearchMatch> references = | 573 new _SimpleIdentifierRecursiveAstVisitor((SimpleIdentifier node) { |
| 567 // searchEngine.searchReferences(element, null, null); | 574 Element element = node.staticElement; |
| 568 // for (SearchMatch match in references) { | 575 if (namespace[node.name] == element) { |
| 569 // LibraryElement library = match.element.library; | 576 referencedNames.add(element.displayName); |
| 570 // if (unitLibraryElement == library) { | 577 } |
| 571 // referencedNames.add(element.displayName); | 578 }); |
| 572 // break; | 579 unit.accept(visitor); |
| 573 // } | 580 // ignore if unused |
| 574 // } | 581 if (referencedNames.isEmpty) { |
| 575 // } | 582 _coverageMarker(); |
| 576 // // ignore if unused | 583 return; |
| 577 // if (referencedNames.isEmpty) { | 584 } |
| 578 // return; | 585 // prepare change |
| 579 // } | 586 String sb = " show ${StringUtils.join(referencedNames, ", ")}"; |
| 580 // // prepare change | 587 _addInsertEdit(importDirective.end - 1, sb.toString()); |
|
Brian Wilkerson
2014/08/04 21:13:20
I suspect 'sb' was once an abbreviation of 'String
scheglov
2014/08/04 21:18:55
Done.
| |
| 581 // String sb = " show ${StringUtils.join(referencedNames, ", ")}"; | 588 // add proposal |
| 582 // _addInsertEdit(importDirective.end - 1, sb.toString()); | 589 _addAssist(AssistKind.IMPORT_ADD_SHOW, []); |
| 583 // // add proposal | |
| 584 // _addAssist(AssistKind.IMPORT_ADD_SHOW, []); | |
| 585 } | 590 } |
| 586 | 591 |
| 587 void _addProposal_invertIf() { | 592 void _addProposal_invertIf() { |
| 588 // TODO(scheglov) implement | 593 if (node is! IfStatement) { |
| 589 // if (node is! IfStatement) { | 594 return; |
| 590 // return; | 595 } |
| 591 // } | 596 IfStatement ifStatement = node as IfStatement; |
| 592 // IfStatement ifStatement = node as IfStatement; | 597 Expression condition = ifStatement.condition; |
| 593 // Expression condition = ifStatement.condition; | 598 // should have both "then" and "else" |
| 594 // // should have both "then" and "else" | 599 Statement thenStatement = ifStatement.thenStatement; |
| 595 // Statement thenStatement = ifStatement.thenStatement; | 600 Statement elseStatement = ifStatement.elseStatement; |
| 596 // Statement elseStatement = ifStatement.elseStatement; | 601 if (thenStatement == null || elseStatement == null) { |
| 597 // if (thenStatement == null || elseStatement == null) { | 602 return; |
| 598 // return; | 603 } |
| 599 // } | 604 // prepare source |
| 600 // // prepare source | 605 String invertedCondition = utils.invertCondition(condition); |
| 601 // String invertedCondition = utils.invertCondition(condition); | 606 String thenSource = _getSource(thenStatement); |
| 602 // String thenSource = _getSource(thenStatement); | 607 String elseSource = _getSource(elseStatement); |
| 603 // String elseSource = _getSource(elseStatement); | 608 // do replacements |
| 604 // // do replacements | 609 _addReplaceEdit(rangeNode(condition), invertedCondition); |
| 605 // _addReplaceEdit(rangeNode(condition), invertedCondition); | 610 _addReplaceEdit(rangeNode(thenStatement), elseSource); |
| 606 // _addReplaceEdit(rangeNode(thenStatement), elseSource); | 611 _addReplaceEdit(rangeNode(elseStatement), thenSource); |
| 607 // _addReplaceEdit(rangeNode(elseStatement), thenSource); | 612 // add proposal |
| 608 // // add proposal | 613 _addAssist(AssistKind.INVERT_IF_STATEMENT, []); |
| 609 // _addAssist(AssistKind.INVERT_IF_STATEMENT, []); | |
| 610 } | 614 } |
| 611 | 615 |
| 612 void _addProposal_joinIfStatementInner() { | 616 void _addProposal_joinIfStatementInner() { |
| 613 // TODO(scheglov) implement | 617 // climb up condition to the (supposedly) "if" statement |
| 614 // // climb up condition to the (supposedly) "if" statement | 618 AstNode node = this.node; |
| 615 // AstNode node = this.node; | 619 while (node is Expression) { |
| 616 // while (node is Expression) { | 620 node = node.parent; |
| 617 // node = node.parent; | 621 } |
| 618 // } | 622 // prepare target "if" statement |
| 619 // // prepare target "if" statement | 623 if (node is! IfStatement) { |
| 620 // if (node is! IfStatement) { | 624 _coverageMarker(); |
| 621 // return; | 625 return; |
| 622 // } | 626 } |
| 623 // IfStatement targetIfStatement = node as IfStatement; | 627 IfStatement targetIfStatement = node as IfStatement; |
| 624 // if (targetIfStatement.elseStatement != null) { | 628 if (targetIfStatement.elseStatement != null) { |
| 625 // return; | 629 _coverageMarker(); |
| 626 // } | 630 return; |
| 627 // // prepare inner "if" statement | 631 } |
| 628 // Statement targetThenStatement = targetIfStatement.thenStatement; | 632 // prepare inner "if" statement |
| 629 // Statement innerStatement = | 633 Statement targetThenStatement = targetIfStatement.thenStatement; |
| 630 // CorrectionUtils.getSingleStatement(targetThenStatement); | 634 Statement innerStatement = getSingleStatement(targetThenStatement); |
| 631 // if (innerStatement is! IfStatement) { | 635 if (innerStatement is! IfStatement) { |
| 632 // return; | 636 _coverageMarker(); |
| 633 // } | 637 return; |
| 634 // IfStatement innerIfStatement = innerStatement as IfStatement; | 638 } |
| 635 // if (innerIfStatement.elseStatement != null) { | 639 IfStatement innerIfStatement = innerStatement as IfStatement; |
| 636 // return; | 640 if (innerIfStatement.elseStatement != null) { |
| 637 // } | 641 _coverageMarker(); |
| 638 // // prepare environment | 642 return; |
| 639 // String prefix = utils.getNodePrefix(targetIfStatement); | 643 } |
| 640 // // merge conditions | 644 // prepare environment |
| 641 // String condition; | 645 String prefix = utils.getNodePrefix(targetIfStatement); |
| 642 // { | 646 // merge conditions |
| 643 // Expression targetCondition = targetIfStatement.condition; | 647 String condition; |
| 644 // Expression innerCondition = innerIfStatement.condition; | 648 { |
| 645 // String targetConditionSource = _getSource(targetCondition); | 649 Expression targetCondition = targetIfStatement.condition; |
| 646 // String innerConditionSource = _getSource(innerCondition); | 650 Expression innerCondition = innerIfStatement.condition; |
| 647 // if (_shouldWrapParenthesisBeforeAnd(targetCondition)) { | 651 String targetConditionSource = _getSource(targetCondition); |
| 648 // targetConditionSource = "(${targetConditionSource})"; | 652 String innerConditionSource = _getSource(innerCondition); |
| 649 // } | 653 if (_shouldWrapParenthesisBeforeAnd(targetCondition)) { |
| 650 // if (_shouldWrapParenthesisBeforeAnd(innerCondition)) { | 654 targetConditionSource = "(${targetConditionSource})"; |
| 651 // innerConditionSource = "(${innerConditionSource})"; | 655 } |
| 652 // } | 656 if (_shouldWrapParenthesisBeforeAnd(innerCondition)) { |
| 653 // condition = "${targetConditionSource} && ${innerConditionSource}"; | 657 innerConditionSource = "(${innerConditionSource})"; |
| 654 // } | 658 } |
| 655 // // replace target "if" statement | 659 condition = "${targetConditionSource} && ${innerConditionSource}"; |
| 656 // { | 660 } |
| 657 // Statement innerThenStatement = innerIfStatement.thenStatement; | 661 // replace target "if" statement |
| 658 // List<Statement> innerThenStatements = | 662 { |
| 659 // CorrectionUtils.getStatements(innerThenStatement); | 663 Statement innerThenStatement = innerIfStatement.thenStatement; |
| 660 // SourceRange lineRanges = utils.getLinesRange(innerThenStatements); | 664 List<Statement> innerThenStatements = getStatements(innerThenStatement); |
| 661 // String oldSource = utils.getText3(lineRanges); | 665 SourceRange lineRanges = |
| 662 // String newSource = utils.getIndentSource2(oldSource, false); | 666 utils.getLinesRangeStatements(innerThenStatements); |
| 663 // // TODO(scheglov) | 667 String oldSource = utils.getText3(lineRanges); |
| 664 //// _addReplaceEdit( | 668 String newSource = utils.getIndentSource2(oldSource, false); |
| 665 //// rangeNode(targetIfStatement), | 669 _addReplaceEdit( |
| 666 //// MessageFormat.format( | 670 rangeNode(targetIfStatement), |
| 667 //// "if ({0}) '{'{1}{2}{3}'}'", | 671 "if ($condition) {${eol}${newSource}${prefix}}"); |
| 668 //// [condition, eol, newSource, prefix])); | 672 } |
| 669 // } | 673 // done |
| 670 // // done | 674 _addAssist(AssistKind.JOIN_IF_WITH_INNER, []); |
| 671 // _addAssist(AssistKind.JOIN_IF_WITH_INNER, []); | |
| 672 } | 675 } |
| 673 | 676 |
| 674 void _addProposal_joinIfStatementOuter() { | 677 void _addProposal_joinIfStatementOuter() { |
| 675 // TODO(scheglov) implement | 678 // climb up condition to the (supposedly) "if" statement |
| 676 // // climb up condition to the (supposedly) "if" statement | 679 AstNode node = this.node; |
| 677 // AstNode node = this.node; | 680 while (node is Expression) { |
| 678 // while (node is Expression) { | 681 node = node.parent; |
| 679 // node = node.parent; | 682 } |
| 680 // } | 683 // prepare target "if" statement |
| 681 // // prepare target "if" statement | 684 if (node is! IfStatement) { |
| 682 // if (node is! IfStatement) { | 685 _coverageMarker(); |
| 683 // return; | 686 return; |
| 684 // } | 687 } |
| 685 // IfStatement targetIfStatement = node as IfStatement; | 688 IfStatement targetIfStatement = node as IfStatement; |
| 686 // if (targetIfStatement.elseStatement != null) { | 689 if (targetIfStatement.elseStatement != null) { |
| 687 // return; | 690 _coverageMarker(); |
| 688 // } | 691 return; |
| 689 // // prepare outer "if" statement | 692 } |
| 690 // AstNode parent = targetIfStatement.parent; | 693 // prepare outer "if" statement |
| 691 // if (parent is Block) { | 694 AstNode parent = targetIfStatement.parent; |
| 692 // parent = parent.parent; | 695 if (parent is Block) { |
| 693 // } | 696 parent = parent.parent; |
| 694 // if (parent is! IfStatement) { | 697 } |
| 695 // return; | 698 if (parent is! IfStatement) { |
| 696 // } | 699 _coverageMarker(); |
| 697 // IfStatement outerIfStatement = parent as IfStatement; | 700 return; |
| 698 // if (outerIfStatement.elseStatement != null) { | 701 } |
| 699 // return; | 702 IfStatement outerIfStatement = parent as IfStatement; |
| 700 // } | 703 if (outerIfStatement.elseStatement != null) { |
| 701 // // prepare environment | 704 _coverageMarker(); |
| 702 // String prefix = utils.getNodePrefix(outerIfStatement); | 705 return; |
| 703 // // merge conditions | 706 } |
| 704 // String condition; | 707 // prepare environment |
| 705 // { | 708 String prefix = utils.getNodePrefix(outerIfStatement); |
| 706 // Expression targetCondition = targetIfStatement.condition; | 709 // merge conditions |
| 707 // Expression outerCondition = outerIfStatement.condition; | 710 String condition; |
| 708 // String targetConditionSource = _getSource(targetCondition); | 711 { |
| 709 // String outerConditionSource = _getSource(outerCondition); | 712 Expression targetCondition = targetIfStatement.condition; |
| 710 // if (_shouldWrapParenthesisBeforeAnd(targetCondition)) { | 713 Expression outerCondition = outerIfStatement.condition; |
| 711 // targetConditionSource = "(${targetConditionSource})"; | 714 String targetConditionSource = _getSource(targetCondition); |
| 712 // } | 715 String outerConditionSource = _getSource(outerCondition); |
| 713 // if (_shouldWrapParenthesisBeforeAnd(outerCondition)) { | 716 if (_shouldWrapParenthesisBeforeAnd(targetCondition)) { |
| 714 // outerConditionSource = "(${outerConditionSource})"; | 717 targetConditionSource = "(${targetConditionSource})"; |
| 715 // } | 718 } |
| 716 // condition = "${outerConditionSource} && ${targetConditionSource}"; | 719 if (_shouldWrapParenthesisBeforeAnd(outerCondition)) { |
| 717 // } | 720 outerConditionSource = "(${outerConditionSource})"; |
| 718 // // replace outer "if" statement | 721 } |
| 719 // { | 722 condition = "${outerConditionSource} && ${targetConditionSource}"; |
| 720 // Statement targetThenStatement = targetIfStatement.thenStatement; | 723 } |
| 721 // List<Statement> targetThenStatements = | 724 // replace outer "if" statement |
| 722 // CorrectionUtils.getStatements(targetThenStatement); | 725 { |
| 723 // SourceRange lineRanges = utils.getLinesRange(targetThenStatements); | 726 Statement targetThenStatement = targetIfStatement.thenStatement; |
| 724 // String oldSource = utils.getText3(lineRanges); | 727 List<Statement> targetThenStatements = getStatements(targetThenStatement); |
| 725 // String newSource = utils.getIndentSource2(oldSource, false); | 728 SourceRange lineRanges = |
| 726 // // TODO(scheglov) | 729 utils.getLinesRangeStatements(targetThenStatements); |
| 727 //// _addReplaceEdit( | 730 String oldSource = utils.getText3(lineRanges); |
| 728 //// rangeNode(outerIfStatement), | 731 String newSource = utils.getIndentSource2(oldSource, false); |
| 729 //// MessageFormat.format( | 732 _addReplaceEdit( |
| 730 //// "if ({0}) '{'{1}{2}{3}'}'", | 733 rangeNode(outerIfStatement), |
| 731 //// [condition, eol, newSource, prefix])); | 734 "if ($condition) {${eol}${newSource}${prefix}}"); |
| 732 // } | 735 } |
| 733 // // done | 736 // done |
| 734 // _addAssist(AssistKind.JOIN_IF_WITH_OUTER, []); | 737 _addAssist(AssistKind.JOIN_IF_WITH_OUTER, []); |
| 735 } | 738 } |
| 736 | 739 |
| 737 void _addProposal_joinVariableDeclaration_onAssignment() { | 740 void _addProposal_joinVariableDeclaration_onAssignment() { |
| 738 // check that node is LHS in assignment | 741 // check that node is LHS in assignment |
| 739 if (node is SimpleIdentifier && | 742 if (node is SimpleIdentifier && |
| 740 node.parent is AssignmentExpression && | 743 node.parent is AssignmentExpression && |
| 741 identical((node.parent as AssignmentExpression).leftHandSide, node) && | 744 identical((node.parent as AssignmentExpression).leftHandSide, node) && |
| 742 node.parent.parent is ExpressionStatement) { | 745 node.parent.parent is ExpressionStatement) { |
| 743 } else { | 746 } else { |
| 744 _coverageMarker(); | 747 _coverageMarker(); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1017 src += prefix + '} else {' + eol; | 1020 src += prefix + '} else {' + eol; |
| 1018 src += prefix + indent + 'return $elseSrc;' + eol; | 1021 src += prefix + indent + 'return $elseSrc;' + eol; |
| 1019 src += prefix + '}'; | 1022 src += prefix + '}'; |
| 1020 _addReplaceEdit(rangeNode(statement), src); | 1023 _addReplaceEdit(rangeNode(statement), src); |
| 1021 } | 1024 } |
| 1022 // add proposal | 1025 // add proposal |
| 1023 _addAssist(AssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, []); | 1026 _addAssist(AssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, []); |
| 1024 } | 1027 } |
| 1025 | 1028 |
| 1026 void _addProposal_replaceIfElseWithConditional() { | 1029 void _addProposal_replaceIfElseWithConditional() { |
| 1027 // TODO(scheglov) implement | 1030 // should be "if" |
| 1028 // // should be "if" | 1031 if (node is! IfStatement) { |
| 1029 // if (node is! IfStatement) { | 1032 _coverageMarker(); |
| 1030 // return; | 1033 return; |
| 1031 // } | 1034 } |
| 1032 // IfStatement ifStatement = node as IfStatement; | 1035 IfStatement ifStatement = node as IfStatement; |
| 1033 // // single then/else statements | 1036 // single then/else statements |
| 1034 // Statement thenStatement = | 1037 Statement thenStatement = getSingleStatement(ifStatement.thenStatement); |
| 1035 // CorrectionUtils.getSingleStatement(ifStatement.thenStatement); | 1038 Statement elseStatement = getSingleStatement(ifStatement.elseStatement); |
| 1036 // Statement elseStatement = | 1039 if (thenStatement == null || elseStatement == null) { |
| 1037 // CorrectionUtils.getSingleStatement(ifStatement.elseStatement); | 1040 _coverageMarker(); |
| 1038 // if (thenStatement == null || elseStatement == null) { | 1041 return; |
| 1039 // return; | 1042 } |
| 1040 // } | 1043 // returns |
| 1041 // // returns | 1044 if (thenStatement is ReturnStatement || elseStatement is ReturnStatement) { |
| 1042 // if (thenStatement is ReturnStatement || elseStatement is ReturnStatement) { | 1045 ReturnStatement thenReturn = thenStatement as ReturnStatement; |
| 1043 // ReturnStatement thenReturn = thenStatement as ReturnStatement; | 1046 ReturnStatement elseReturn = elseStatement as ReturnStatement; |
| 1044 // ReturnStatement elseReturn = elseStatement as ReturnStatement; | 1047 String conditionSrc = _getSource(ifStatement.condition); |
| 1045 // // TODO(scheglov) | 1048 String theSrc = _getSource(thenReturn.expression); |
| 1046 //// _addReplaceEdit( | 1049 String elseSrc = _getSource(elseReturn.expression); |
| 1047 //// rangeNode(ifStatement), | 1050 _addReplaceEdit( |
| 1048 //// MessageFormat.format( | 1051 rangeNode(ifStatement), |
| 1049 //// "return {0} ? {1} : {2};", | 1052 'return $conditionSrc ? $theSrc : $elseSrc;'); |
| 1050 //// [ | 1053 } |
| 1051 //// _getSource(ifStatement.condition), | 1054 // assignments -> v = Conditional; |
| 1052 //// _getSource(thenReturn.expression), | 1055 if (thenStatement is ExpressionStatement && |
| 1053 //// _getSource(elseReturn.expression)])); | 1056 elseStatement is ExpressionStatement) { |
| 1054 // } | 1057 Expression thenExpression = thenStatement.expression; |
| 1055 // // assignments -> v = Conditional; | 1058 Expression elseExpression = elseStatement.expression; |
| 1056 // if (thenStatement is ExpressionStatement && | 1059 if (thenExpression is AssignmentExpression && |
| 1057 // elseStatement is ExpressionStatement) { | 1060 elseExpression is AssignmentExpression) { |
| 1058 // Expression thenExpression = thenStatement.expression; | 1061 AssignmentExpression thenAssignment = thenExpression; |
| 1059 // Expression elseExpression = elseStatement.expression; | 1062 AssignmentExpression elseAssignment = elseExpression; |
| 1060 // if (thenExpression is AssignmentExpression && | 1063 String thenTarget = _getSource(thenAssignment.leftHandSide); |
| 1061 // elseExpression is AssignmentExpression) { | 1064 String elseTarget = _getSource(elseAssignment.leftHandSide); |
| 1062 // AssignmentExpression thenAssignment = thenExpression; | 1065 if (thenAssignment.operator.type == TokenType.EQ && |
| 1063 // AssignmentExpression elseAssignment = elseExpression; | 1066 elseAssignment.operator.type == TokenType.EQ && |
| 1064 // String thenTarget = _getSource(thenAssignment.leftHandSide); | 1067 StringUtils.equals(thenTarget, elseTarget)) { |
| 1065 // String elseTarget = _getSource(elseAssignment.leftHandSide); | 1068 String conditionSrc = _getSource(ifStatement.condition); |
| 1066 // if (thenAssignment.operator.type == TokenType.EQ && | 1069 String theSrc = _getSource(thenAssignment.rightHandSide); |
| 1067 // elseAssignment.operator.type == TokenType.EQ && | 1070 String elseSrc = _getSource(elseAssignment.rightHandSide); |
| 1068 // StringUtils.equals(thenTarget, elseTarget)) { | 1071 _addReplaceEdit( |
| 1069 // // TODO(scheglov) | 1072 rangeNode(ifStatement), |
| 1070 //// _addReplaceEdit( | 1073 '$thenTarget = $conditionSrc ? $theSrc : $elseSrc;'); |
| 1071 //// rangeNode(ifStatement), | 1074 } |
| 1072 //// MessageFormat.format( | 1075 } |
| 1073 //// "{0} = {1} ? {2} : {3};", | 1076 } |
| 1074 //// [ | 1077 // add proposal |
| 1075 //// thenTarget, | 1078 _addAssist(AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, []); |
| 1076 //// _getSource(ifStatement.condition), | |
| 1077 //// _getSource(thenAssignment.rightHandSide), | |
| 1078 //// _getSource(elseAssignment.rightHandSide)])); | |
| 1079 // } | |
| 1080 // } | |
| 1081 // } | |
| 1082 // // add proposal | |
| 1083 // _addAssist( | |
| 1084 // AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, | |
| 1085 // []); | |
| 1086 } | 1079 } |
| 1087 | 1080 |
| 1088 void _addProposal_splitAndCondition() { | 1081 void _addProposal_splitAndCondition() { |
| 1089 // TODO(scheglov) implement | 1082 // check that user invokes quick assist on binary expression |
| 1090 // // check that user invokes quick assist on binary expression | 1083 if (node is! BinaryExpression) { |
| 1091 // if (node is! BinaryExpression) { | 1084 _coverageMarker(); |
| 1092 // return; | 1085 return; |
| 1093 // } | 1086 } |
| 1094 // BinaryExpression binaryExpression = node as BinaryExpression; | 1087 BinaryExpression binaryExpression = node as BinaryExpression; |
| 1095 // // prepare operator position | 1088 // prepare operator position |
| 1096 // int offset = | 1089 if (!_isOperatorSelected( |
| 1097 // _isOperatorSelected(binaryExpression, _selectionOffset, _selectionLeng th); | 1090 binaryExpression, |
| 1098 // if (offset == -1) { | 1091 selectionOffset, |
| 1099 // return; | 1092 selectionLength)) { |
| 1100 // } | 1093 _coverageMarker(); |
| 1101 // // should be && | 1094 return; |
| 1102 // if (binaryExpression.operator.type != TokenType.AMPERSAND_AMPERSAND) { | 1095 } |
| 1103 // return; | 1096 // should be && |
| 1104 // } | 1097 if (binaryExpression.operator.type != TokenType.AMPERSAND_AMPERSAND) { |
| 1105 // // prepare "if" | 1098 _coverageMarker(); |
| 1106 // Statement statement = node.getAncestor((node) => node is Statement); | 1099 return; |
| 1107 // if (statement is! IfStatement) { | 1100 } |
| 1108 // return; | 1101 // prepare "if" |
| 1109 // } | 1102 Statement statement = node.getAncestor((node) => node is Statement); |
| 1110 // IfStatement ifStatement = statement as IfStatement; | 1103 if (statement is! IfStatement) { |
| 1111 // // check that binary expression is part of first level && condition of "if " | 1104 _coverageMarker(); |
| 1112 // BinaryExpression condition = binaryExpression; | 1105 return; |
| 1113 // while (condition.parent is BinaryExpression && | 1106 } |
| 1114 // (condition.parent as BinaryExpression).operator.type == | 1107 IfStatement ifStatement = statement as IfStatement; |
| 1115 // TokenType.AMPERSAND_AMPERSAND) { | 1108 // check that binary expression is part of first level && condition of "if" |
| 1116 // condition = condition.parent as BinaryExpression; | 1109 BinaryExpression condition = binaryExpression; |
| 1117 // } | 1110 while (condition.parent is BinaryExpression && |
| 1118 // if (!identical(ifStatement.condition, condition)) { | 1111 (condition.parent as BinaryExpression).operator.type == |
| 1119 // return; | 1112 TokenType.AMPERSAND_AMPERSAND) { |
| 1120 // } | 1113 condition = condition.parent as BinaryExpression; |
| 1121 // // prepare environment | 1114 } |
| 1122 // String prefix = utils.getNodePrefix(ifStatement); | 1115 if (!identical(ifStatement.condition, condition)) { |
| 1123 // String indent = utils.getIndent(1); | 1116 _coverageMarker(); |
| 1124 // // prepare "rightCondition" | 1117 return; |
| 1125 // String rightConditionSource; | 1118 } |
| 1126 // { | 1119 // prepare environment |
| 1127 // SourceRange rightConditionRange = | 1120 String prefix = utils.getNodePrefix(ifStatement); |
| 1128 // rangeStartEnd(binaryExpression.rightOperand, condition); | 1121 String indent = utils.getIndent(1); |
| 1129 // rightConditionSource = _getSource2(rightConditionRange); | 1122 // prepare "rightCondition" |
| 1130 // } | 1123 String rightConditionSource; |
| 1131 // // remove "&& rightCondition" | 1124 { |
| 1132 // _addRemoveEdit( | 1125 SourceRange rightConditionRange = |
| 1133 // rangeEndEnd(binaryExpression.leftOperand, condition)); | 1126 rangeStartEnd(binaryExpression.rightOperand, condition); |
| 1134 // // update "then" statement | 1127 rightConditionSource = _getSource2(rightConditionRange); |
| 1135 // Statement thenStatement = ifStatement.thenStatement; | 1128 } |
| 1136 // Statement elseStatement = ifStatement.elseStatement; | 1129 // remove "&& rightCondition" |
| 1137 // if (thenStatement is Block) { | 1130 _addRemoveEdit(rangeEndEnd(binaryExpression.leftOperand, condition)); |
| 1138 // Block thenBlock = thenStatement; | 1131 // update "then" statement |
| 1139 // SourceRange thenBlockRange = rangeNode(thenBlock); | 1132 Statement thenStatement = ifStatement.thenStatement; |
| 1140 // // insert inner "if" with right part of "condition" | 1133 Statement elseStatement = ifStatement.elseStatement; |
| 1141 // { | 1134 if (thenStatement is Block) { |
| 1142 // String source = | 1135 Block thenBlock = thenStatement; |
| 1143 // "${eol}${prefix}${indent}if (${rightConditionSource}) {"; | 1136 SourceRange thenBlockRange = rangeNode(thenBlock); |
| 1144 // int thenBlockInsideOffset = thenBlockRange.offset + 1; | 1137 // insert inner "if" with right part of "condition" |
| 1145 // _addInsertEdit(thenBlockInsideOffset, source); | 1138 { |
| 1146 // } | 1139 String source = |
| 1147 // // insert closing "}" for inner "if" | 1140 "${eol}${prefix}${indent}if (${rightConditionSource}) {"; |
| 1148 // { | 1141 int thenBlockInsideOffset = thenBlockRange.offset + 1; |
| 1149 // int thenBlockEnd = thenBlockRange.end; | 1142 _addInsertEdit(thenBlockInsideOffset, source); |
| 1150 // String source = "${indent}}"; | 1143 } |
| 1151 // // may be move "else" statements | 1144 // insert closing "}" for inner "if" |
| 1152 // if (elseStatement != null) { | 1145 { |
| 1153 // List<Statement> elseStatements = | 1146 int thenBlockEnd = thenBlockRange.end; |
| 1154 // CorrectionUtils.getStatements(elseStatement); | 1147 String source = "${indent}}"; |
| 1155 // SourceRange elseLinesRange = utils.getLinesRange(elseStatements); | 1148 // may be move "else" statements |
| 1156 // String elseIndentOld = "${prefix}${indent}"; | 1149 if (elseStatement != null) { |
| 1157 // String elseIndentNew = "${elseIndentOld}${indent}"; | 1150 List<Statement> elseStatements = getStatements(elseStatement); |
| 1158 // String newElseSource = | 1151 SourceRange elseLinesRange = |
| 1159 // utils.getIndentSource(elseLinesRange, elseIndentOld, elseIndentN ew); | 1152 utils.getLinesRangeStatements(elseStatements); |
| 1160 // // append "else" block | 1153 String elseIndentOld = "${prefix}${indent}"; |
| 1161 // source += " else {${eol}"; | 1154 String elseIndentNew = "${elseIndentOld}${indent}"; |
| 1162 // source += newElseSource; | 1155 String newElseSource = |
| 1163 // source += "${prefix}${indent}}"; | 1156 utils.getIndentSource(elseLinesRange, elseIndentOld, elseIndentNew ); |
| 1164 // // remove old "else" range | 1157 // append "else" block |
| 1165 // _addRemoveEdit( | 1158 source += " else {${eol}"; |
| 1166 // rangeStartEnd(thenBlockEnd, elseStatement)); | 1159 source += newElseSource; |
| 1167 // } | 1160 source += "${prefix}${indent}}"; |
| 1168 // // insert before outer "then" block "}" | 1161 // remove old "else" range |
| 1169 // source += "${eol}${prefix}"; | 1162 _addRemoveEdit(rangeStartEnd(thenBlockEnd, elseStatement)); |
| 1170 // _addInsertEdit(thenBlockEnd - 1, source); | 1163 } |
| 1171 // } | 1164 // insert before outer "then" block "}" |
| 1172 // } else { | 1165 source += "${eol}${prefix}"; |
| 1173 // // insert inner "if" with right part of "condition" | 1166 _addInsertEdit(thenBlockEnd - 1, source); |
| 1174 // { | 1167 } |
| 1175 // String source = "${eol}${prefix}${indent}if (${rightConditionSource})" ; | 1168 } else { |
| 1176 // _addInsertEdit(ifStatement.rightParenthesis.offset + 1, source); | 1169 // insert inner "if" with right part of "condition" |
| 1177 // } | 1170 { |
| 1178 // // indent "else" statements to correspond inner "if" | 1171 String source = "${eol}${prefix}${indent}if (${rightConditionSource})"; |
| 1179 // if (elseStatement != null) { | 1172 _addInsertEdit(ifStatement.rightParenthesis.offset + 1, source); |
| 1180 // SourceRange elseRange = | 1173 } |
| 1181 // rangeStartEnd(ifStatement.elseKeyword.offset, elseStatement); | 1174 // indent "else" statements to correspond inner "if" |
| 1182 // SourceRange elseLinesRange = utils.getLinesRange2(elseRange); | 1175 if (elseStatement != null) { |
| 1183 // String elseIndentOld = prefix; | 1176 SourceRange elseRange = |
| 1184 // String elseIndentNew = "${elseIndentOld}${indent}"; | 1177 rangeStartEnd(ifStatement.elseKeyword.offset, elseStatement); |
| 1185 // edits.add( | 1178 SourceRange elseLinesRange = utils.getLinesRange(elseRange); |
| 1186 // utils.createIndentEdit(elseLinesRange, elseIndentOld, elseIndentNe w)); | 1179 String elseIndentOld = prefix; |
| 1187 // } | 1180 String elseIndentNew = "${elseIndentOld}${indent}"; |
| 1188 // } | 1181 edits.add( |
| 1189 // // indent "then" statements to correspond inner "if" | 1182 utils.createIndentEdit(elseLinesRange, elseIndentOld, elseIndentNew) ); |
| 1190 // { | 1183 } |
| 1191 // List<Statement> thenStatements = | 1184 } |
| 1192 // CorrectionUtils.getStatements(thenStatement); | 1185 // indent "then" statements to correspond inner "if" |
| 1193 // SourceRange linesRange = utils.getLinesRange(thenStatements); | 1186 { |
| 1194 // String thenIndentOld = "${prefix}${indent}"; | 1187 List<Statement> thenStatements = getStatements(thenStatement); |
| 1195 // String thenIndentNew = "${thenIndentOld}${indent}"; | 1188 SourceRange linesRange = utils.getLinesRangeStatements(thenStatements); |
| 1196 // edits.add( | 1189 String thenIndentOld = "${prefix}${indent}"; |
| 1197 // utils.createIndentEdit(linesRange, thenIndentOld, thenIndentNew)); | 1190 String thenIndentNew = "${thenIndentOld}${indent}"; |
| 1198 // } | 1191 edits.add( |
| 1199 // // add proposal | 1192 utils.createIndentEdit(linesRange, thenIndentOld, thenIndentNew)); |
| 1200 // _addAssist(AssistKind.SPLIT_AND_CONDITION, []); | 1193 } |
| 1194 // add proposal | |
| 1195 _addAssist(AssistKind.SPLIT_AND_CONDITION, []); | |
| 1201 } | 1196 } |
| 1202 | 1197 |
| 1203 void _addProposal_splitVariableDeclaration() { | 1198 void _addProposal_splitVariableDeclaration() { |
| 1204 // TODO(scheglov) implement | 1199 // prepare DartVariableStatement, should be part of Block |
| 1205 // // prepare DartVariableStatement, should be part of Block | 1200 VariableDeclarationStatement statement = |
| 1206 // VariableDeclarationStatement statement = | 1201 node.getAncestor((node) => node is VariableDeclarationStatement); |
| 1207 // node.getAncestor((node) => node is VariableDeclarationStatement); | 1202 if (statement != null && statement.parent is Block) { |
| 1208 // if (statement != null && statement.parent is Block) { | 1203 } else { |
| 1209 // } else { | 1204 _coverageMarker(); |
| 1210 // return; | 1205 return; |
| 1211 // } | 1206 } |
| 1212 // // check that statement declares single variable | 1207 // check that statement declares single variable |
| 1213 // List<VariableDeclaration> variables = statement.variables.variables; | 1208 List<VariableDeclaration> variables = statement.variables.variables; |
| 1214 // if (variables.length != 1) { | 1209 if (variables.length != 1) { |
| 1215 // return; | 1210 _coverageMarker(); |
| 1216 // } | 1211 return; |
| 1217 // VariableDeclaration variable = variables[0]; | 1212 } |
| 1218 // // remove initializer value | 1213 VariableDeclaration variable = variables[0]; |
| 1219 // _addRemoveEdit( | 1214 // prepare initializer |
| 1220 // rangeEndStart(variable.name, statement.semicolon)); | 1215 Expression initializer = variable.initializer; |
| 1221 // // TODO(scheglov) | 1216 if (initializer == null) { |
| 1222 //// // add assignment statement | 1217 _coverageMarker(); |
| 1223 //// String indent = _utils.getNodePrefix(statement); | 1218 return; |
| 1224 //// String assignSource = | 1219 } |
| 1225 //// MessageFormat.format( | 1220 // remove initializer value |
| 1226 //// "{0} = {1};", | 1221 _addRemoveEdit(rangeEndStart(variable.name, statement.semicolon)); |
| 1227 //// [variable.name.name, _getSource(variable.initializer)]); | 1222 // add assignment statement |
| 1228 //// SourceRange assignRange = rangeEndLength(statement, 0); | 1223 String indent = utils.getNodePrefix(statement); |
| 1229 //// _addReplaceEdit(assignRange, "${eol}${indent}${assignSource}"); | 1224 String name = variable.name.name; |
| 1230 //// // add proposal | 1225 String initSrc = _getSource(initializer); |
| 1231 //// _addUnitCorrectionProposal( | 1226 SourceRange assignRange = rangeEndLength(statement, 0); |
| 1232 //// AssistKind.SPLIT_VARIABLE_DECLARATION, | 1227 _addReplaceEdit(assignRange, eol + indent + name + ' = ' + initSrc + ';'); |
| 1233 //// []); | 1228 // add proposal |
| 1229 _addAssist(AssistKind.SPLIT_VARIABLE_DECLARATION, []); | |
| 1234 } | 1230 } |
| 1235 | 1231 |
| 1236 void _addProposal_surroundWith() { | 1232 void _addProposal_surroundWith() { |
| 1237 // TODO(scheglov) implement | 1233 // TODO(scheglov) implement |
| 1238 // // prepare selected statements | 1234 // // prepare selected statements |
| 1239 // List<Statement> selectedStatements; | 1235 // List<Statement> selectedStatements; |
| 1240 // { | 1236 // { |
| 1241 // SourceRange selection = | 1237 // SourceRange selection = |
| 1242 // rangeStartLength(_selectionOffset, _selectionLength); | 1238 // rangeStartLength(_selectionOffset, _selectionLength); |
| 1243 // StatementAnalyzer selectionAnalyzer = | 1239 // StatementAnalyzer selectionAnalyzer = |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1604 _coverageMarker(); | 1600 _coverageMarker(); |
| 1605 return false; | 1601 return false; |
| 1606 } | 1602 } |
| 1607 _coverageMarker(); | 1603 _coverageMarker(); |
| 1608 return true; | 1604 return true; |
| 1609 } | 1605 } |
| 1610 // invalid selection (part of node, etc) | 1606 // invalid selection (part of node, etc) |
| 1611 _coverageMarker(); | 1607 _coverageMarker(); |
| 1612 return false; | 1608 return false; |
| 1613 } | 1609 } |
| 1610 | |
| 1611 /** | |
| 1612 * Checks if the given [Expression] should be wrapped with parenthesis when we | |
| 1613 * want to use it as operand of a logical `and` expression. | |
| 1614 */ | |
| 1615 static bool _shouldWrapParenthesisBeforeAnd(Expression expr) { | |
| 1616 if (expr is BinaryExpression) { | |
| 1617 BinaryExpression binary = expr; | |
| 1618 int precedence = binary.operator.type.precedence; | |
| 1619 return precedence < TokenClass.LOGICAL_AND_OPERATOR.precedence; | |
| 1620 } | |
| 1621 return false; | |
| 1622 } | |
| 1614 } | 1623 } |
| 1624 | |
| 1625 | |
| 1626 class _SimpleIdentifierRecursiveAstVisitor extends RecursiveAstVisitor { | |
| 1627 final _SimpleIdentifierVisitor visitor; | |
| 1628 | |
| 1629 _SimpleIdentifierRecursiveAstVisitor(this.visitor); | |
| 1630 | |
| 1631 @override | |
| 1632 visitSimpleIdentifier(SimpleIdentifier node) { | |
| 1633 visitor(node); | |
| 1634 } | |
| 1635 } | |
| OLD | NEW |