| 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 services.src.refactoring.extract_local; | 5 library services.src.refactoring.extract_local; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol.dart' hide Element; | 9 import 'package:analysis_server/src/protocol.dart' hide Element; |
| 10 import 'package:analysis_server/src/services/correction/name_suggestion.dart'; | 10 import 'package:analysis_server/src/services/correction/name_suggestion.dart'; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 | 29 |
| 30 /** | 30 /** |
| 31 * [ExtractLocalRefactoring] implementation. | 31 * [ExtractLocalRefactoring] implementation. |
| 32 */ | 32 */ |
| 33 class ExtractLocalRefactoringImpl extends RefactoringImpl implements | 33 class ExtractLocalRefactoringImpl extends RefactoringImpl implements |
| 34 ExtractLocalRefactoring { | 34 ExtractLocalRefactoring { |
| 35 final CompilationUnit unit; | 35 final CompilationUnit unit; |
| 36 final int selectionOffset; | 36 final int selectionOffset; |
| 37 final int selectionLength; | 37 final int selectionLength; |
| 38 CompilationUnitElement unitElement; |
| 38 String file; | 39 String file; |
| 39 SourceRange selectionRange; | 40 SourceRange selectionRange; |
| 40 CorrectionUtils utils; | 41 CorrectionUtils utils; |
| 41 | 42 |
| 42 String name; | 43 String name; |
| 43 bool extractAll = true; | 44 bool extractAll = true; |
| 44 final List<String> names = <String>[]; | 45 final List<String> names = <String>[]; |
| 45 final List<int> offsets = <int>[]; | 46 final List<int> offsets = <int>[]; |
| 46 final List<int> lengths = <int>[]; | 47 final List<int> lengths = <int>[]; |
| 47 | 48 |
| 48 Expression rootExpression; | 49 Expression rootExpression; |
| 49 Expression singleExpression; | 50 Expression singleExpression; |
| 50 bool wholeStatementExpression = false; | 51 bool wholeStatementExpression = false; |
| 51 String stringLiteralPart; | 52 String stringLiteralPart; |
| 52 final List<SourceRange> occurrences = <SourceRange>[]; | 53 final List<SourceRange> occurrences = <SourceRange>[]; |
| 53 final Set<String> excludedVariableNames = new Set<String>(); | 54 final Set<String> excludedVariableNames = new Set<String>(); |
| 54 | 55 |
| 55 ExtractLocalRefactoringImpl(this.unit, this.selectionOffset, | 56 ExtractLocalRefactoringImpl(this.unit, this.selectionOffset, |
| 56 this.selectionLength) { | 57 this.selectionLength) { |
| 57 file = unit.element.source.fullName; | 58 unitElement = unit.element; |
| 58 selectionRange = new SourceRange(selectionOffset, selectionLength); | 59 selectionRange = new SourceRange(selectionOffset, selectionLength); |
| 59 utils = new CorrectionUtils(unit); | 60 utils = new CorrectionUtils(unit); |
| 60 } | 61 } |
| 61 | 62 |
| 62 @override | 63 @override |
| 63 String get refactoringName => 'Extract Local Variable'; | 64 String get refactoringName => 'Extract Local Variable'; |
| 64 | 65 |
| 65 String get _declarationKeyword { | 66 String get _declarationKeyword { |
| 66 if (_isPartOfConstantExpression(rootExpression)) { | 67 if (_isPartOfConstantExpression(rootExpression)) { |
| 67 return "const"; | 68 return "const"; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 } else { | 116 } else { |
| 116 occurrences = [selectionRange]; | 117 occurrences = [selectionRange]; |
| 117 } | 118 } |
| 118 // If the whole expression of a statement is selected, like '1 + 2', | 119 // If the whole expression of a statement is selected, like '1 + 2', |
| 119 // then convert it into a variable declaration statement. | 120 // then convert it into a variable declaration statement. |
| 120 if (wholeStatementExpression && occurrences.length == 1) { | 121 if (wholeStatementExpression && occurrences.length == 1) { |
| 121 String keyword = _declarationKeyword; | 122 String keyword = _declarationKeyword; |
| 122 String declarationSource = '$keyword $name = '; | 123 String declarationSource = '$keyword $name = '; |
| 123 SourceEdit edit = | 124 SourceEdit edit = |
| 124 new SourceEdit(singleExpression.offset, 0, declarationSource); | 125 new SourceEdit(singleExpression.offset, 0, declarationSource); |
| 125 change.addEdit(file, edit); | 126 addElementSourceChange(change, unitElement, edit); |
| 126 return new Future.value(change); | 127 return new Future.value(change); |
| 127 } | 128 } |
| 128 // add variable declaration | 129 // add variable declaration |
| 129 { | 130 { |
| 130 String declarationSource; | 131 String declarationSource; |
| 131 if (stringLiteralPart != null) { | 132 if (stringLiteralPart != null) { |
| 132 declarationSource = "var $name = '$stringLiteralPart';"; | 133 declarationSource = "var $name = '$stringLiteralPart';"; |
| 133 } else { | 134 } else { |
| 134 String keyword = _declarationKeyword; | 135 String keyword = _declarationKeyword; |
| 135 String initializerSource = utils.getRangeText(selectionRange); | 136 String initializerSource = utils.getRangeText(selectionRange); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 151 target_ = commonParent.getAncestor((node) => node is Statement); | 152 target_ = commonParent.getAncestor((node) => node is Statement); |
| 152 } | 153 } |
| 153 } | 154 } |
| 154 } | 155 } |
| 155 AstNode target = target_; | 156 AstNode target = target_; |
| 156 // insert variable declaration | 157 // insert variable declaration |
| 157 if (target is Statement) { | 158 if (target is Statement) { |
| 158 String prefix = utils.getNodePrefix(target); | 159 String prefix = utils.getNodePrefix(target); |
| 159 SourceEdit edit = | 160 SourceEdit edit = |
| 160 new SourceEdit(target.offset, 0, declarationSource + eol + prefix); | 161 new SourceEdit(target.offset, 0, declarationSource + eol + prefix); |
| 161 change.addEdit(file, edit); | 162 addElementSourceChange(change, unitElement, edit); |
| 162 } else if (target is ExpressionFunctionBody) { | 163 } else if (target is ExpressionFunctionBody) { |
| 163 String prefix = utils.getNodePrefix(target.parent); | 164 String prefix = utils.getNodePrefix(target.parent); |
| 164 String indent = utils.getIndent(1); | 165 String indent = utils.getIndent(1); |
| 165 String declStatement = prefix + indent + declarationSource + eol; | 166 String declStatement = prefix + indent + declarationSource + eol; |
| 166 String exprStatement = prefix + indent + 'return '; | 167 String exprStatement = prefix + indent + 'return '; |
| 167 Expression expr = target.expression; | 168 Expression expr = target.expression; |
| 168 change.addEdit( | 169 addElementSourceChange( |
| 169 file, | 170 change, |
| 171 unitElement, |
| 170 new SourceEdit( | 172 new SourceEdit( |
| 171 target.offset, | 173 target.offset, |
| 172 expr.offset - target.offset, | 174 expr.offset - target.offset, |
| 173 '{' + eol + declStatement + exprStatement)); | 175 '{' + eol + declStatement + exprStatement)); |
| 174 change.addEdit( | 176 addElementSourceChange( |
| 175 file, | 177 change, |
| 178 unitElement, |
| 176 new SourceEdit(expr.end, 0, ';' + eol + prefix + '}')); | 179 new SourceEdit(expr.end, 0, ';' + eol + prefix + '}')); |
| 177 } | 180 } |
| 178 } | 181 } |
| 179 // prepare replacement | 182 // prepare replacement |
| 180 String occurrenceReplacement = name; | 183 String occurrenceReplacement = name; |
| 181 if (stringLiteralPart != null) { | 184 if (stringLiteralPart != null) { |
| 182 occurrenceReplacement = "\${$name}"; | 185 occurrenceReplacement = "\${$name}"; |
| 183 } | 186 } |
| 184 // replace occurrences with variable reference | 187 // replace occurrences with variable reference |
| 185 for (SourceRange range in occurrences) { | 188 for (SourceRange range in occurrences) { |
| 186 SourceEdit edit = new SourceEdit.range(range, occurrenceReplacement); | 189 SourceEdit edit = new SourceEdit.range(range, occurrenceReplacement); |
| 187 change.addEdit(file, edit); | 190 addElementSourceChange(change, unitElement, edit); |
| 188 } | 191 } |
| 189 // done | 192 // done |
| 190 return new Future.value(change); | 193 return new Future.value(change); |
| 191 } | 194 } |
| 192 | 195 |
| 193 @override | 196 @override |
| 194 bool requiresPreview() => false; | 197 bool requiresPreview() => false; |
| 195 | 198 |
| 196 /** | 199 /** |
| 197 * Checks if [selectionRange] selects [Expression] which can be extracted, and | 200 * Checks if [selectionRange] selects [Expression] which can be extracted, and |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 Token startToken = nodeTokens[startTokenIndex]; | 562 Token startToken = nodeTokens[startTokenIndex]; |
| 560 Token endToken = nodeTokens[endTokenIndex]; | 563 Token endToken = nodeTokens[endTokenIndex]; |
| 561 // add occurrence range | 564 // add occurrence range |
| 562 int occuStart = nodeOffset + startToken.offset; | 565 int occuStart = nodeOffset + startToken.offset; |
| 563 int occuEnd = nodeOffset + endToken.end; | 566 int occuEnd = nodeOffset + endToken.end; |
| 564 SourceRange occuRange = rangeStartEnd(occuStart, occuEnd); | 567 SourceRange occuRange = rangeStartEnd(occuStart, occuEnd); |
| 565 _addOccurrence(occuRange); | 568 _addOccurrence(occuRange); |
| 566 } | 569 } |
| 567 } | 570 } |
| 568 } | 571 } |
| OLD | NEW |