| 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 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 10 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 String declarationSource; | 133 String declarationSource; |
| 134 if (stringLiteralPart != null) { | 134 if (stringLiteralPart != null) { |
| 135 declarationSource = "var $name = '$stringLiteralPart';"; | 135 declarationSource = "var $name = '$stringLiteralPart';"; |
| 136 } else { | 136 } else { |
| 137 String keyword = _declarationKeyword; | 137 String keyword = _declarationKeyword; |
| 138 String initializerSource = utils.getRangeText(selectionRange); | 138 String initializerSource = utils.getRangeText(selectionRange); |
| 139 declarationSource = "$keyword $name = $initializerSource;"; | 139 declarationSource = "$keyword $name = $initializerSource;"; |
| 140 } | 140 } |
| 141 String eol = utils.endOfLine; | 141 String eol = utils.endOfLine; |
| 142 // prepare location for declaration | 142 // prepare location for declaration |
| 143 AstNode target_; | 143 AstNode target = _findDeclarationTarget(occurrences); |
| 144 { | |
| 145 List<AstNode> nodes = _findNodes(occurrences); | |
| 146 AstNode commonParent = getNearestCommonAncestor(nodes); | |
| 147 if (commonParent is Block) { | |
| 148 List<AstNode> firstParents = getParents(nodes[0]); | |
| 149 int commonIndex = firstParents.indexOf(commonParent); | |
| 150 target_ = firstParents[commonIndex + 1]; | |
| 151 } else { | |
| 152 target_ = _getEnclosingExpressionBody(commonParent); | |
| 153 if (target_ == null) { | |
| 154 target_ = commonParent.getAncestor((node) => node is Statement); | |
| 155 } | |
| 156 } | |
| 157 } | |
| 158 AstNode target = target_; | |
| 159 // insert variable declaration | 144 // insert variable declaration |
| 160 if (target is Statement) { | 145 if (target is Statement) { |
| 161 String prefix = utils.getNodePrefix(target); | 146 String prefix = utils.getNodePrefix(target); |
| 162 SourceEdit edit = | 147 SourceEdit edit = |
| 163 new SourceEdit(target.offset, 0, declarationSource + eol + prefix); | 148 new SourceEdit(target.offset, 0, declarationSource + eol + prefix); |
| 164 doSourceChange_addElementEdit(change, unitElement, edit); | 149 doSourceChange_addElementEdit(change, unitElement, edit); |
| 165 } else if (target is ExpressionFunctionBody) { | 150 } else if (target is ExpressionFunctionBody) { |
| 166 String prefix = utils.getNodePrefix(target.parent); | 151 String prefix = utils.getNodePrefix(target.parent); |
| 167 String indent = utils.getIndent(1); | 152 String indent = utils.getIndent(1); |
| 168 String declStatement = prefix + indent + declarationSource + eol; | 153 String declStatement = prefix + indent + declarationSource + eol; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 if (elementId != null) { | 292 if (elementId != null) { |
| 308 tokenString += '-$elementId'; | 293 tokenString += '-$elementId'; |
| 309 } | 294 } |
| 310 } | 295 } |
| 311 // done | 296 // done |
| 312 return tokenString; | 297 return tokenString; |
| 313 }).join(_TOKEN_SEPARATOR); | 298 }).join(_TOKEN_SEPARATOR); |
| 314 } | 299 } |
| 315 | 300 |
| 316 /** | 301 /** |
| 302 * Return the [AstNode] to defined the variable before. |
| 303 * It should be accessible by all the given [occurrences]. |
| 304 */ |
| 305 AstNode _findDeclarationTarget(List<SourceRange> occurrences) { |
| 306 List<AstNode> nodes = _findNodes(occurrences); |
| 307 AstNode commonParent = getNearestCommonAncestor(nodes); |
| 308 // Block |
| 309 if (commonParent is Block) { |
| 310 List<AstNode> firstParents = getParents(nodes[0]); |
| 311 int commonIndex = firstParents.indexOf(commonParent); |
| 312 return firstParents[commonIndex + 1]; |
| 313 } |
| 314 // ExpressionFunctionBody |
| 315 AstNode expressionBody = _getEnclosingExpressionBody(commonParent); |
| 316 if (expressionBody != null) { |
| 317 return expressionBody; |
| 318 } |
| 319 // single Statement |
| 320 AstNode target = commonParent.getAncestor((node) => node is Statement); |
| 321 while (target.parent is! Block) { |
| 322 target = target.parent; |
| 323 } |
| 324 return target; |
| 325 } |
| 326 |
| 327 /** |
| 317 * Returns [AstNode]s at the offsets of the given [SourceRange]s. | 328 * Returns [AstNode]s at the offsets of the given [SourceRange]s. |
| 318 */ | 329 */ |
| 319 List<AstNode> _findNodes(List<SourceRange> ranges) { | 330 List<AstNode> _findNodes(List<SourceRange> ranges) { |
| 320 List<AstNode> nodes = <AstNode>[]; | 331 List<AstNode> nodes = <AstNode>[]; |
| 321 for (SourceRange range in ranges) { | 332 for (SourceRange range in ranges) { |
| 322 AstNode node = new NodeLocator.con1(range.offset).searchWithin(unit); | 333 AstNode node = new NodeLocator.con1(range.offset).searchWithin(unit); |
| 323 nodes.add(node); | 334 nodes.add(node); |
| 324 } | 335 } |
| 325 return nodes; | 336 return nodes; |
| 326 } | 337 } |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 | 640 |
| 630 _TokenLocalElementVisitor(this.map); | 641 _TokenLocalElementVisitor(this.map); |
| 631 | 642 |
| 632 visitSimpleIdentifier(SimpleIdentifier node) { | 643 visitSimpleIdentifier(SimpleIdentifier node) { |
| 633 Element element = node.staticElement; | 644 Element element = node.staticElement; |
| 634 if (element is LocalVariableElement) { | 645 if (element is LocalVariableElement) { |
| 635 map[node.token] = element; | 646 map[node.token] = element; |
| 636 } | 647 } |
| 637 } | 648 } |
| 638 } | 649 } |
| OLD | NEW |