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

Side by Side Diff: pkg/analysis_server/lib/src/services/correction/util.dart

Issue 526583002: 'Inline Method' refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
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.correction.util; 5 library services.src.correction.util;
6 6
7 import 'dart:math'; 7 import 'dart:math';
8 8
9 import 'package:analysis_server/src/protocol.dart' show SourceEdit; 9 import 'package:analysis_server/src/protocol.dart' show SourceEdit;
10 import 'package:analysis_server/src/services/correction/source_range.dart'; 10 import 'package:analysis_server/src/services/correction/source_range.dart';
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 ElementKind kind = element.kind; 87 ElementKind kind = element.kind;
88 if (kind == ElementKind.FIELD || kind == ElementKind.METHOD) { 88 if (kind == ElementKind.FIELD || kind == ElementKind.METHOD) {
89 return '${element.enclosingElement.displayName}.${element.displayName}'; 89 return '${element.enclosingElement.displayName}.${element.displayName}';
90 } else { 90 } else {
91 return element.displayName; 91 return element.displayName;
92 } 92 }
93 } 93 }
94 94
95 95
96 /** 96 /**
97 * If the given [AstNode] is in a [ClassDeclaration], returns the
98 * [ClassElement]. Otherwise returns `null`.
99 */
100 ClassElement getEnclosingClassElement(AstNode node) {
101 ClassDeclaration enclosingClassNode =
102 node.getAncestor((node) => node is ClassDeclaration);
103 if (enclosingClassNode != null) {
104 return enclosingClassNode.element;
105 }
106 return null;
107 }
108
109
110
111 /**
97 * Returns a class or an unit member enclosing the given [node]. 112 * Returns a class or an unit member enclosing the given [node].
98 */ 113 */
99 AstNode getEnclosingClassOrUnitMember(AstNode node) { 114 AstNode getEnclosingClassOrUnitMember(AstNode node) {
100 AstNode member = node; 115 AstNode member = node;
101 while (node != null) { 116 while (node != null) {
102 if (node is ClassDeclaration) { 117 if (node is ClassDeclaration) {
103 return member; 118 return member;
104 } 119 }
105 if (node is CompilationUnit) { 120 if (node is CompilationUnit) {
106 return member; 121 return member;
107 } 122 }
108 member = node; 123 member = node;
109 node = node.parent; 124 node = node.parent;
110 } 125 }
111 return null; 126 return null;
112 } 127 }
113 128
114
115
116 /** 129 /**
117 * @return the [ExecutableElement] of the enclosing executable [AstNode]. 130 * @return the [ExecutableElement] of the enclosing executable [AstNode].
118 */ 131 */
119 ExecutableElement getEnclosingExecutableElement(AstNode node) { 132 ExecutableElement getEnclosingExecutableElement(AstNode node) {
120 while (node != null) { 133 while (node != null) {
121 if (node is FunctionDeclaration) { 134 if (node is FunctionDeclaration) {
122 return node.element; 135 return node.element;
123 } 136 }
124 if (node is ConstructorDeclaration) { 137 if (node is ConstructorDeclaration) {
125 return node.element; 138 return node.element;
126 } 139 }
127 if (node is MethodDeclaration) { 140 if (node is MethodDeclaration) {
128 return node.element; 141 return node.element;
129 } 142 }
130 node = node.parent; 143 node = node.parent;
131 } 144 }
132 return null; 145 return null;
133 } 146 }
134 147
148
135 /** 149 /**
136 * @return the enclosing executable [AstNode]. 150 * @return the enclosing executable [AstNode].
137 */ 151 */
138 AstNode getEnclosingExecutableNode(AstNode node) { 152 AstNode getEnclosingExecutableNode(AstNode node) {
139 while (node != null) { 153 while (node != null) {
140 if (node is FunctionDeclaration) { 154 if (node is FunctionDeclaration) {
141 return node; 155 return node;
142 } 156 }
143 if (node is ConstructorDeclaration) { 157 if (node is ConstructorDeclaration) {
144 return node; 158 return node;
(...skipping 26 matching lines...) Expand all
171 * Returns the precedence of [node] it is an [Expression], negative otherwise. 185 * Returns the precedence of [node] it is an [Expression], negative otherwise.
172 */ 186 */
173 int getExpressionPrecedence(AstNode node) { 187 int getExpressionPrecedence(AstNode node) {
174 if (node is Expression) { 188 if (node is Expression) {
175 return node.precedence; 189 return node.precedence;
176 } 190 }
177 return -1000; 191 return -1000;
178 } 192 }
179 193
180 194
195
181 /** 196 /**
182 * Returns the namespace of the given [ImportElement]. 197 * Returns the namespace of the given [ImportElement].
183 */ 198 */
184 Map<String, Element> getImportNamespace(ImportElement imp) { 199 Map<String, Element> getImportNamespace(ImportElement imp) {
185 NamespaceBuilder builder = new NamespaceBuilder(); 200 NamespaceBuilder builder = new NamespaceBuilder();
186 Namespace namespace = builder.createImportNamespaceForDirective(imp); 201 Namespace namespace = builder.createImportNamespaceForDirective(imp);
187 return namespace.definedNames; 202 return namespace.definedNames;
188 } 203 }
189 204
190 205
206 /**
207 * Returns the line prefix from the given source, i.e. basically just a
208 * whitespace prefix of the given [String].
209 */
210 String getLinesPrefix(String lines) {
Brian Wilkerson 2014/08/31 15:59:56 Should "lines" be "line"?
scheglov 2014/08/31 16:43:23 Acknowledged.
211 int index = 0;
212 while (index < lines.length) {
213 int c = lines.codeUnitAt(index);
214 if (!isWhitespace(c)) {
215 break;
216 }
217 index++;
218 }
219 return lines.substring(0, index);
220 }
221
191 222
192 /** 223 /**
193 * @return the [LocalVariableElement] or [ParameterElement] if given 224 * @return the [LocalVariableElement] or [ParameterElement] if given
194 * [SimpleIdentifier] is the reference to local variable or parameter, o r 225 * [SimpleIdentifier] is the reference to local variable or parameter, o r
195 * <code>null</code> in the other case. 226 * <code>null</code> in the other case.
196 */ 227 */
197 VariableElement getLocalOrParameterVariableElement(SimpleIdentifier node) { 228 VariableElement getLocalOrParameterVariableElement(SimpleIdentifier node) {
198 Element element = node.staticElement; 229 Element element = node.staticElement;
199 if (element is LocalVariableElement) { 230 if (element is LocalVariableElement) {
200 return element; 231 return element;
(...skipping 10 matching lines...) Expand all
211 * local variable, or <code>null</code> in the other case. 242 * local variable, or <code>null</code> in the other case.
212 */ 243 */
213 LocalVariableElement getLocalVariableElement(SimpleIdentifier node) { 244 LocalVariableElement getLocalVariableElement(SimpleIdentifier node) {
214 Element element = node.staticElement; 245 Element element = node.staticElement;
215 if (element is LocalVariableElement) { 246 if (element is LocalVariableElement) {
216 return element; 247 return element;
217 } 248 }
218 return null; 249 return null;
219 } 250 }
220 251
221
222 /** 252 /**
223 * @return the nearest common ancestor [AstNode] of the given [AstNode]s. 253 * @return the nearest common ancestor [AstNode] of the given [AstNode]s.
224 */ 254 */
225 AstNode getNearestCommonAncestor(List<AstNode> nodes) { 255 AstNode getNearestCommonAncestor(List<AstNode> nodes) {
226 // may be no nodes 256 // may be no nodes
227 if (nodes.isEmpty) { 257 if (nodes.isEmpty) {
228 return null; 258 return null;
229 } 259 }
230 // prepare parents 260 // prepare parents
231 List<List<AstNode>> parents = []; 261 List<List<AstNode>> parents = [];
232 for (AstNode node in nodes) { 262 for (AstNode node in nodes) {
233 parents.add(getParents(node)); 263 parents.add(getParents(node));
234 } 264 }
235 // find min length 265 // find min length
236 int minLength = 1 << 20; 266 int minLength = 1 << 20;
237 for (List<AstNode> parentList in parents) { 267 for (List<AstNode> parentList in parents) {
238 minLength = min(minLength, parentList.length); 268 minLength = min(minLength, parentList.length);
239 } 269 }
240 // find deepest parent 270 // find deepest parent
241 int i = 0; 271 int i = 0;
242 for ( ; i < minLength; i++) { 272 for ( ; i < minLength; i++) {
243 if (!allListsIdentical(parents, i)) { 273 if (!allListsIdentical(parents, i)) {
244 break; 274 break;
245 } 275 }
246 } 276 }
247 return parents[0][i - 1]; 277 return parents[0][i - 1];
248 } 278 }
249 279
280 /**
281 * Returns the [Expression] qualifier if given node is the name part of a
282 * [PropertyAccess] or a [PrefixedIdentifier]. Maybe `null`.
283 */
284 Expression getNodeQualifier(SimpleIdentifier node) {
285 AstNode parent = node.parent;
286 if (parent is PropertyAccess) {
287 PropertyAccess propertyAccess = parent;
288 if (identical(propertyAccess.propertyName, node)) {
289 return propertyAccess.target;
290 }
291 }
292 if (parent is PrefixedIdentifier) {
293 PrefixedIdentifier prefixed = parent;
294 if (identical(prefixed.identifier, node)) {
295 return prefixed.prefix;
296 }
297 }
298 return null;
299 }
300
301
302 /**
303 * Returns the [ParameterElement] if the given [SimpleIdentifier] is a reference
304 * to a parameter, or `null` in the other case.
305 */
306 ParameterElement getParameterElement(SimpleIdentifier node) {
307 Element element = node.staticElement;
308 if (element is ParameterElement) {
309 return element;
310 }
311 return null;
312 }
313
250 314
251 /** 315 /**
252 * @return parent [AstNode]s from [CompilationUnit] (at index "0") to the given one. 316 * @return parent [AstNode]s from [CompilationUnit] (at index "0") to the given one.
253 */ 317 */
254 List<AstNode> getParents(AstNode node) { 318 List<AstNode> getParents(AstNode node) {
255 // prepare number of parents 319 // prepare number of parents
256 int numParents = 0; 320 int numParents = 0;
257 { 321 {
258 AstNode current = node.parent; 322 AstNode current = node.parent;
259 while (current != null) { 323 while (current != null) {
260 numParents++; 324 numParents++;
261 current = current.parent; 325 current = current.parent;
262 } 326 }
263 } 327 }
264 // fill array of parents 328 // fill array of parents
265 List<AstNode> parents = new List<AstNode>(numParents); 329 List<AstNode> parents = new List<AstNode>(numParents);
266 AstNode current = node.parent; 330 AstNode current = node.parent;
267 int index = numParents; 331 int index = numParents;
268 while (current != null) { 332 while (current != null) {
269 parents[--index] = current; 333 parents[--index] = current;
270 current = current.parent; 334 current = current.parent;
271 } 335 }
272 return parents; 336 return parents;
273 } 337 }
274 338
339
340 /**
341 * Returns a [PropertyAccessorElement] if the given [SimpleIdentifier] is a
342 * reference to a property, or `null` in the other case.
343 */
344 PropertyAccessorElement getPropertyAccessorElement(SimpleIdentifier node) {
345 Element element = node.staticElement;
346 if (element is PropertyAccessorElement) {
347 return element;
348 }
349 return null;
350 }
351
352
275 /** 353 /**
276 * If given [AstNode] is name of qualified property extraction, returns target f rom which 354 * If given [AstNode] is name of qualified property extraction, returns target f rom which
277 * this property is extracted. Otherwise `null`. 355 * this property is extracted. Otherwise `null`.
278 */ 356 */
279 Expression getQualifiedPropertyTarget(AstNode node) { 357 Expression getQualifiedPropertyTarget(AstNode node) {
280 AstNode parent = node.parent; 358 AstNode parent = node.parent;
281 if (parent is PrefixedIdentifier) { 359 if (parent is PrefixedIdentifier) {
282 PrefixedIdentifier prefixed = parent; 360 PrefixedIdentifier prefixed = parent;
283 if (prefixed.identifier == node) { 361 if (prefixed.identifier == node) {
284 return parent.prefix; 362 return parent.prefix;
285 } 363 }
286 } 364 }
287 if (parent is PropertyAccess) { 365 if (parent is PropertyAccess) {
288 PropertyAccess access = parent; 366 PropertyAccess access = parent;
289 if (access.propertyName == node) { 367 if (access.propertyName == node) {
290 return access.realTarget; 368 return access.realTarget;
291 } 369 }
292 } 370 }
293 return null; 371 return null;
294 } 372 }
295 373
374
296 /** 375 /**
297 * Returns the given [Statement] if not a [Block], or the first child 376 * Returns the given [Statement] if not a [Block], or the first child
298 * [Statement] if a [Block], or `null` if more than one child. 377 * [Statement] if a [Block], or `null` if more than one child.
299 */ 378 */
300 Statement getSingleStatement(Statement statement) { 379 Statement getSingleStatement(Statement statement) {
301 if (statement is Block) { 380 if (statement is Block) {
302 List<Statement> blockStatements = statement.statements; 381 List<Statement> blockStatements = statement.statements;
303 if (blockStatements.length != 1) { 382 if (blockStatements.length != 1) {
304 return null; 383 return null;
305 } 384 }
(...skipping 26 matching lines...) Expand all
332 /** 411 /**
333 * Checks if the given [Element]'s display name equals to the given name. 412 * Checks if the given [Element]'s display name equals to the given name.
334 */ 413 */
335 bool hasDisplayName(Element element, String name) { 414 bool hasDisplayName(Element element, String name) {
336 if (element == null) { 415 if (element == null) {
337 return false; 416 return false;
338 } 417 }
339 return element.displayName == name; 418 return element.displayName == name;
340 } 419 }
341 420
421 /**
422 * Returns `true` if the given [PropertyAccessorElement] is an accessor of
423 * some [FieldElement].
424 */
425 bool isFieldAccessorElement(PropertyAccessorElement accessor) {
426 return accessor != null &&
427 accessor.variable is FieldElement &&
428 accessor.variable.enclosingElement is ClassElement;
Brian Wilkerson 2014/08/31 15:59:56 Do we have field elements whose parent is not a cl
scheglov 2014/08/31 16:43:23 Yes, we do. Although we are not interested in it f
429 }
430
342 431
343 /** 432 /**
344 * @return <code>true</code> if given [DartNode] is left hand side of assignment , or 433 * @return <code>true</code> if given [DartNode] is left hand side of assignment , or
345 * declaration of the variable. 434 * declaration of the variable.
346 */ 435 */
347 bool isLeftHandOfAssignment(SimpleIdentifier node) { 436 bool isLeftHandOfAssignment(SimpleIdentifier node) {
348 if (node.inSetterContext()) { 437 if (node.inSetterContext()) {
349 return true; 438 return true;
350 } 439 }
351 return node.parent is VariableDeclaration && 440 return node.parent is VariableDeclaration &&
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 */ 495 */
407 SourceEdit createIndentEdit(SourceRange range, String oldIndent, 496 SourceEdit createIndentEdit(SourceRange range, String oldIndent,
408 String newIndent) { 497 String newIndent) {
409 String newSource = replaceSourceRangeIndent(range, oldIndent, newIndent); 498 String newSource = replaceSourceRangeIndent(range, oldIndent, newIndent);
410 return new SourceEdit(range.offset, range.length, newSource); 499 return new SourceEdit(range.offset, range.length, newSource);
411 } 500 }
412 501
413 /** 502 /**
414 * Returns the [AstNode] that encloses the given offset. 503 * Returns the [AstNode] that encloses the given offset.
415 */ 504 */
416 AstNode findNode(int offset) => new NodeLocator.con1(offset).searchWithin(unit ); 505 AstNode findNode(int offset) =>
506 new NodeLocator.con1(offset).searchWithin(unit);
417 507
418 /** 508 /**
419 * Returns the actual type source of the given [Expression], may be `null` 509 * Returns the actual type source of the given [Expression], may be `null`
420 * if can not be resolved, should be treated as the `dynamic` type. 510 * if can not be resolved, should be treated as the `dynamic` type.
421 */ 511 */
422 String getExpressionTypeSource(Expression expression) { 512 String getExpressionTypeSource(Expression expression) {
423 if (expression == null) { 513 if (expression == null) {
424 return null; 514 return null;
425 } 515 }
426 DartType type = expression.bestType; 516 DartType type = expression.bestType;
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 } 1309 }
1220 1310
1221 /** 1311 /**
1222 * @return <code>true</code> if given [Token]s contain only single [Token] wit h given 1312 * @return <code>true</code> if given [Token]s contain only single [Token] wit h given
1223 * [TokenType]. 1313 * [TokenType].
1224 */ 1314 */
1225 static bool hasOnly(List<Token> tokens, TokenType type) => 1315 static bool hasOnly(List<Token> tokens, TokenType type) =>
1226 tokens.length == 1 && tokens[0].type == type; 1316 tokens.length == 1 && tokens[0].type == type;
1227 } 1317 }
1228 1318
1319
1229 /** 1320 /**
1230 * A container with a source and its precedence. 1321 * A container with a source and its precedence.
1231 */ 1322 */
1232 class _InvertedCondition { 1323 class _InvertedCondition {
1233 final int _precedence; 1324 final int _precedence;
1234 1325
1235 final String _source; 1326 final String _source;
1236 1327
1237 _InvertedCondition(this._precedence, this._source); 1328 _InvertedCondition(this._precedence, this._source);
1238 1329
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 1369
1279 @override 1370 @override
1280 Object visitExpression(Expression node) { 1371 Object visitExpression(Expression node) {
1281 if (node is BinaryExpression && node.operator.type == groupOperatorType) { 1372 if (node is BinaryExpression && node.operator.type == groupOperatorType) {
1282 return super.visitNode(node); 1373 return super.visitNode(node);
1283 } 1374 }
1284 operands.add(node); 1375 operands.add(node);
1285 return null; 1376 return null;
1286 } 1377 }
1287 } 1378 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698