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

Side by Side Diff: pkg/analysis_server/lib/src/services/refactoring/extract_local.dart

Issue 568333003: Issue 18895. Convert an expression function body into the block function body when Extract Local. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tweak for target Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/refactoring/extract_local_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 String declarationSource = '$keyword $name = '; 122 String declarationSource = '$keyword $name = ';
123 SourceEdit edit = 123 SourceEdit edit =
124 new SourceEdit(singleExpression.offset, 0, declarationSource); 124 new SourceEdit(singleExpression.offset, 0, declarationSource);
125 change.addEdit(file, edit); 125 change.addEdit(file, edit);
126 return new Future.value(change); 126 return new Future.value(change);
127 } 127 }
128 // add variable declaration 128 // add variable declaration
129 { 129 {
130 String declarationSource; 130 String declarationSource;
131 if (stringLiteralPart != null) { 131 if (stringLiteralPart != null) {
132 declarationSource = "var ${name} = '${stringLiteralPart}';"; 132 declarationSource = "var $name = '$stringLiteralPart';";
133 } else { 133 } else {
134 String keyword = _declarationKeyword; 134 String keyword = _declarationKeyword;
135 String initializerSource = utils.getRangeText(selectionRange); 135 String initializerSource = utils.getRangeText(selectionRange);
136 declarationSource = "${keyword} ${name} = ${initializerSource};"; 136 declarationSource = "$keyword $name = $initializerSource;";
137 } 137 }
138 String eol = utils.endOfLine;
138 // prepare location for declaration 139 // prepare location for declaration
139 Statement targetStatement = _findTargetStatement(occurrences); 140 AstNode target_;
140 String prefix = utils.getNodePrefix(targetStatement); 141 {
142 List<AstNode> nodes = _findNodes(occurrences);
143 AstNode commonParent = getNearestCommonAncestor(nodes);
144 if (commonParent is Block) {
145 List<AstNode> firstParents = getParents(nodes[0]);
146 int commonIndex = firstParents.indexOf(commonParent);
147 target_ = firstParents[commonIndex + 1];
148 } else {
149 target_ = _getEnclosingExpressionBody(commonParent);
150 if (target_ == null) {
151 target_ = commonParent.getAncestor((node) => node is Statement);
152 }
153 }
154 }
155 AstNode target = target_;
141 // insert variable declaration 156 // insert variable declaration
142 String eol = utils.endOfLine; 157 if (target is Statement) {
143 SourceEdit edit = new SourceEdit( 158 String prefix = utils.getNodePrefix(target);
144 targetStatement.offset, 159 SourceEdit edit =
145 0, 160 new SourceEdit(target.offset, 0, declarationSource + eol + prefix);
146 '${declarationSource}${eol}${prefix}'); 161 change.addEdit(file, edit);
147 change.addEdit(file, edit); 162 } else if (target is ExpressionFunctionBody) {
163 String prefix = utils.getNodePrefix(target.parent);
164 String indent = utils.getIndent(1);
165 String declStatement = prefix + indent + declarationSource + eol;
166 String exprStatement = prefix + indent + 'return ';
167 Expression expr = target.expression;
168 change.addEdit(
169 file,
170 new SourceEdit(
171 target.offset,
172 expr.offset - target.offset,
173 '{' + eol + declStatement + exprStatement));
174 change.addEdit(
175 file,
176 new SourceEdit(expr.end, 0, ';' + eol + prefix + '}'));
177 }
148 } 178 }
149 // prepare replacement 179 // prepare replacement
150 String occurrenceReplacement = name; 180 String occurrenceReplacement = name;
151 if (stringLiteralPart != null) { 181 if (stringLiteralPart != null) {
152 occurrenceReplacement = "\${$name}"; 182 occurrenceReplacement = "\${$name}";
153 } 183 }
154 // replace occurrences with variable reference 184 // replace occurrences with variable reference
155 for (SourceRange range in occurrences) { 185 for (SourceRange range in occurrences) {
156 SourceEdit edit = new SourceEdit.range(range, occurrenceReplacement); 186 SourceEdit edit = new SourceEdit.range(range, occurrenceReplacement);
157 change.addEdit(file, edit); 187 change.addEdit(file, edit);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 List<AstNode> _findNodes(List<SourceRange> ranges) { 264 List<AstNode> _findNodes(List<SourceRange> ranges) {
235 List<AstNode> nodes = <AstNode>[]; 265 List<AstNode> nodes = <AstNode>[];
236 for (SourceRange range in ranges) { 266 for (SourceRange range in ranges) {
237 AstNode node = new NodeLocator.con1(range.offset).searchWithin(unit); 267 AstNode node = new NodeLocator.con1(range.offset).searchWithin(unit);
238 nodes.add(node); 268 nodes.add(node);
239 } 269 }
240 return nodes; 270 return nodes;
241 } 271 }
242 272
243 /** 273 /**
244 * Returns the [Statement] such that variable declaration added before it is 274 * Returns the [ExpressionFunctionBody] that encloses [node], or `null`
245 * visible at all given occurrences. 275 * if [node] is not enclosed with an [ExpressionFunctionBody].
246 */ 276 */
247 Statement _findTargetStatement(List<SourceRange> occurrences) { 277 ExpressionFunctionBody _getEnclosingExpressionBody(AstNode node) {
248 List<AstNode> nodes = _findNodes(occurrences); 278 while (node != null) {
249 List<AstNode> firstParents = getParents(nodes[0]); 279 if (node is Statement) {
250 AstNode commonParent = getNearestCommonAncestor(nodes); 280 return null;
251 if (commonParent is Block) { 281 }
252 int commonIndex = firstParents.indexOf(commonParent); 282 if (node is ExpressionFunctionBody) {
253 return firstParents[commonIndex + 1] as Statement; 283 return node;
254 } else { 284 }
255 return commonParent.getAncestor((node) => node is Statement); 285 node = node.parent;
256 } 286 }
287 return null;
257 } 288 }
258 289
259 /** 290 /**
260 * Checks if it is OK to extract the node with the given [SourceRange]. 291 * Checks if it is OK to extract the node with the given [SourceRange].
261 */ 292 */
262 bool _isExtractable(SourceRange range) { 293 bool _isExtractable(SourceRange range) {
263 _ExtractExpressionAnalyzer analyzer = new _ExtractExpressionAnalyzer(range); 294 _ExtractExpressionAnalyzer analyzer = new _ExtractExpressionAnalyzer(range);
264 utils.unit.accept(analyzer); 295 utils.unit.accept(analyzer);
265 return analyzer.status.isOK; 296 return analyzer.status.isOK;
266 } 297 }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 Token startToken = nodeTokens[startTokenIndex]; 559 Token startToken = nodeTokens[startTokenIndex];
529 Token endToken = nodeTokens[endTokenIndex]; 560 Token endToken = nodeTokens[endTokenIndex];
530 // add occurrence range 561 // add occurrence range
531 int occuStart = nodeOffset + startToken.offset; 562 int occuStart = nodeOffset + startToken.offset;
532 int occuEnd = nodeOffset + endToken.end; 563 int occuEnd = nodeOffset + endToken.end;
533 SourceRange occuRange = rangeStartEnd(occuStart, occuEnd); 564 SourceRange occuRange = rangeStartEnd(occuStart, occuEnd);
534 _addOccurrence(occuRange); 565 _addOccurrence(occuRange);
535 } 566 }
536 } 567 }
537 } 568 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/refactoring/extract_local_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698