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

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

Issue 3007493002: Remove most of the remaining references to AnalysisContext (Closed)
Patch Set: Created 3 years, 4 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
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 import 'dart:math'; 5 import 'dart:math';
6 6
7 import 'package:analysis_server/src/protocol_server.dart' 7 import 'package:analysis_server/src/protocol_server.dart'
8 show doSourceChange_addElementEdit; 8 show doSourceChange_addElementEdit;
9 import 'package:analysis_server/src/services/correction/strings.dart'; 9 import 'package:analysis_server/src/services/correction/strings.dart';
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 if (i == uriList.length - 1) { 119 if (i == uriList.length - 1) {
120 importCode = importCode + desc.suffix; 120 importCode = importCode + desc.suffix;
121 } 121 }
122 doSourceChange_addElementEdit( 122 doSourceChange_addElementEdit(
123 change, targetLibrary, new SourceEdit(offset, 0, importCode)); 123 change, targetLibrary, new SourceEdit(offset, 0, importCode));
124 } 124 }
125 } 125 }
126 } 126 }
127 127
128 /** 128 /**
129 * @return <code>true</code> if given [List]s are identical at given position.
130 */
131 bool allListsIdentical(List<List> lists, int position) {
132 Object element = lists[0][position];
133 for (List list in lists) {
134 if (list[position] != element) {
135 return false;
136 }
137 }
138 return true;
139 }
140
141 /**
142 * Climbs up [PrefixedIdentifier] and [PropertyAccess] nodes that include [node] . 129 * Climbs up [PrefixedIdentifier] and [PropertyAccess] nodes that include [node] .
143 */ 130 */
144 Expression climbPropertyAccess(AstNode node) { 131 Expression climbPropertyAccess(AstNode node) {
145 while (true) { 132 while (true) {
146 AstNode parent = node.parent; 133 AstNode parent = node.parent;
147 if (parent is PrefixedIdentifier && parent.identifier == node) { 134 if (parent is PrefixedIdentifier && parent.identifier == node) {
148 node = parent; 135 node = parent;
149 continue; 136 continue;
150 } 137 }
151 if (parent is PropertyAccess && parent.propertyName == node) { 138 if (parent is PropertyAccess && parent.propertyName == node) {
152 node = parent; 139 node = parent;
153 continue; 140 continue;
154 } 141 }
155 return node; 142 return node;
156 } 143 }
157 } 144 }
158 145
159 /** 146 /**
160 * Returns the EOL to use for the given [code].
161 */
162 String getCodeEndOfLine(String code) {
163 if (code.contains('\r\n')) {
164 return '\r\n';
165 }
166 return '\n';
167 }
168
169 /**
170 * TODO(scheglov) replace with nodes once there will be [CompilationUnit.getComm ents]. 147 * TODO(scheglov) replace with nodes once there will be [CompilationUnit.getComm ents].
171 * 148 *
172 * Returns [SourceRange]s of all comments in [unit]. 149 * Returns [SourceRange]s of all comments in [unit].
173 */ 150 */
174 List<SourceRange> getCommentRanges(CompilationUnit unit) { 151 List<SourceRange> getCommentRanges(CompilationUnit unit) {
175 List<SourceRange> ranges = <SourceRange>[]; 152 List<SourceRange> ranges = <SourceRange>[];
176 Token token = unit.beginToken; 153 Token token = unit.beginToken;
177 while (token != null && token.type != TokenType.EOF) { 154 while (token != null && token.type != TokenType.EOF) {
178 Token commentToken = token.precedingComments; 155 Token commentToken = token.precedingComments;
179 while (commentToken != null) { 156 while (commentToken != null) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 if (node is CompilationUnit) { 249 if (node is CompilationUnit) {
273 return member; 250 return member;
274 } 251 }
275 member = node; 252 member = node;
276 node = node.parent; 253 node = node.parent;
277 } 254 }
278 return null; 255 return null;
279 } 256 }
280 257
281 /** 258 /**
282 * @return the [ExecutableElement] of the enclosing executable [AstNode]. 259 * Return the [ExecutableElement] of the enclosing executable [AstNode].
283 */ 260 */
284 ExecutableElement getEnclosingExecutableElement(AstNode node) { 261 ExecutableElement getEnclosingExecutableElement(AstNode node) {
285 while (node != null) { 262 while (node != null) {
286 if (node is FunctionDeclaration) { 263 if (node is FunctionDeclaration) {
287 return node.element; 264 return node.element;
288 } 265 }
289 if (node is ConstructorDeclaration) { 266 if (node is ConstructorDeclaration) {
290 return node.element; 267 return node.element;
291 } 268 }
292 if (node is MethodDeclaration) { 269 if (node is MethodDeclaration) {
293 return node.element; 270 return node.element;
294 } 271 }
295 node = node.parent; 272 node = node.parent;
296 } 273 }
297 return null; 274 return null;
298 } 275 }
299 276
300 /** 277 /**
301 * @return the enclosing executable [AstNode]. 278 * Return the enclosing executable [AstNode].
302 */ 279 */
303 AstNode getEnclosingExecutableNode(AstNode node) { 280 AstNode getEnclosingExecutableNode(AstNode node) {
304 while (node != null) { 281 while (node != null) {
305 if (node is FunctionDeclaration) { 282 if (node is FunctionDeclaration) {
306 return node; 283 return node;
307 } 284 }
308 if (node is ConstructorDeclaration) { 285 if (node is ConstructorDeclaration) {
309 return node; 286 return node;
310 } 287 }
311 if (node is MethodDeclaration) { 288 if (node is MethodDeclaration) {
312 return node; 289 return node;
313 } 290 }
314 node = node.parent; 291 node = node.parent;
315 } 292 }
316 return null; 293 return null;
317 } 294 }
318 295
319 /** 296 /**
320 * Returns [getExpressionPrecedence] for the parent of [node], 297 * Returns [getExpressionPrecedence] for the parent of [node], or `0` if the
321 * or `0` if the parent node is [ParenthesizedExpression]. 298 * parent node is a [ParenthesizedExpression].
322 * 299 *
323 * The reason is that `(expr)` is always executed after `expr`. 300 * The reason is that `(expr)` is always executed after `expr`.
324 */ 301 */
325 int getExpressionParentPrecedence(AstNode node) { 302 int getExpressionParentPrecedence(AstNode node) {
326 AstNode parent = node.parent; 303 AstNode parent = node.parent;
327 if (parent is ParenthesizedExpression) { 304 if (parent is ParenthesizedExpression) {
328 return 0; 305 return 0;
329 } else if (parent is IndexExpression && parent.index == node) { 306 } else if (parent is IndexExpression && parent.index == node) {
330 return 0; 307 return 0;
331 } else if (parent is AssignmentExpression && 308 } else if (parent is AssignmentExpression &&
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 int c = line.codeUnitAt(index); 364 int c = line.codeUnitAt(index);
388 if (!isWhitespace(c)) { 365 if (!isWhitespace(c)) {
389 break; 366 break;
390 } 367 }
391 index++; 368 index++;
392 } 369 }
393 return line.substring(0, index); 370 return line.substring(0, index);
394 } 371 }
395 372
396 /** 373 /**
397 * @return the [LocalVariableElement] or [ParameterElement] if given 374 * Return the [LocalVariableElement] if given [node] is a reference to a local
398 * [SimpleIdentifier] is the reference to local variable or parameter, o r 375 * variable, or `null` in the other case.
399 * <code>null</code> in the other case.
400 */
401 VariableElement getLocalOrParameterVariableElement(SimpleIdentifier node) {
402 Element element = node.staticElement;
403 if (element is LocalVariableElement) {
404 return element;
405 }
406 if (element is ParameterElement) {
407 return element;
408 }
409 return null;
410 }
411
412 /**
413 * @return the [LocalVariableElement] if given [SimpleIdentifier] is the referen ce to
414 * local variable, or <code>null</code> in the other case.
415 */ 376 */
416 LocalVariableElement getLocalVariableElement(SimpleIdentifier node) { 377 LocalVariableElement getLocalVariableElement(SimpleIdentifier node) {
417 Element element = node.staticElement; 378 Element element = node.staticElement;
418 if (element is LocalVariableElement) { 379 if (element is LocalVariableElement) {
419 return element; 380 return element;
420 } 381 }
421 return null; 382 return null;
422 } 383 }
423 384
424 /** 385 /**
425 * @return the nearest common ancestor [AstNode] of the given [AstNode]s. 386 * Return the nearest common ancestor of the given [nodes].
426 */ 387 */
427 AstNode getNearestCommonAncestor(List<AstNode> nodes) { 388 AstNode getNearestCommonAncestor(List<AstNode> nodes) {
428 // may be no nodes 389 // may be no nodes
429 if (nodes.isEmpty) { 390 if (nodes.isEmpty) {
430 return null; 391 return null;
431 } 392 }
432 // prepare parents 393 // prepare parents
433 List<List<AstNode>> parents = []; 394 List<List<AstNode>> parents = [];
434 for (AstNode node in nodes) { 395 for (AstNode node in nodes) {
435 parents.add(getParents(node)); 396 parents.add(getParents(node));
436 } 397 }
437 // find min length 398 // find min length
438 int minLength = 1 << 20; 399 int minLength = 1 << 20;
439 for (List<AstNode> parentList in parents) { 400 for (List<AstNode> parentList in parents) {
440 minLength = min(minLength, parentList.length); 401 minLength = min(minLength, parentList.length);
441 } 402 }
442 // find deepest parent 403 // find deepest parent
443 int i = 0; 404 int i = 0;
444 for (; i < minLength; i++) { 405 for (; i < minLength; i++) {
445 if (!allListsIdentical(parents, i)) { 406 if (!_allListsIdentical(parents, i)) {
446 break; 407 break;
447 } 408 }
448 } 409 }
449 return parents[0][i - 1]; 410 return parents[0][i - 1];
450 } 411 }
451 412
452 /** 413 /**
453 * Returns the [Expression] qualifier if given node is the name part of a 414 * Returns the [Expression] qualifier if given [node] is the name part of a
454 * [PropertyAccess] or a [PrefixedIdentifier]. Maybe `null`. 415 * [PropertyAccess] or a [PrefixedIdentifier]. Maybe `null`.
455 */ 416 */
456 Expression getNodeQualifier(SimpleIdentifier node) { 417 Expression getNodeQualifier(SimpleIdentifier node) {
457 AstNode parent = node.parent; 418 AstNode parent = node.parent;
458 if (parent is MethodInvocation && identical(parent.methodName, node)) { 419 if (parent is MethodInvocation && identical(parent.methodName, node)) {
459 return parent.target; 420 return parent.target;
460 } 421 }
461 if (parent is PropertyAccess && identical(parent.propertyName, node)) { 422 if (parent is PropertyAccess && identical(parent.propertyName, node)) {
462 return parent.target; 423 return parent.target;
463 } 424 }
464 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { 425 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
465 return parent.prefix; 426 return parent.prefix;
466 } 427 }
467 return null; 428 return null;
468 } 429 }
469 430
470 /** 431 /**
471 * Returns the [ParameterElement] if the given [SimpleIdentifier] is a reference 432 * Returns the [ParameterElement] if the given [node] is a reference to a
472 * to a parameter, or `null` in the other case. 433 * parameter, or `null` in the other case.
473 */ 434 */
474 ParameterElement getParameterElement(SimpleIdentifier node) { 435 ParameterElement getParameterElement(SimpleIdentifier node) {
475 Element element = node.staticElement; 436 Element element = node.staticElement;
476 if (element is ParameterElement) { 437 if (element is ParameterElement) {
477 return element; 438 return element;
478 } 439 }
479 return null; 440 return null;
480 } 441 }
481 442
482 /** 443 /**
483 * @return parent [AstNode]s from [CompilationUnit] (at index "0") to the given one. 444 * Return parent [AstNode]s from compilation unit (at index "0") to the given
445 * [node].
484 */ 446 */
485 List<AstNode> getParents(AstNode node) { 447 List<AstNode> getParents(AstNode node) {
486 // prepare number of parents 448 // prepare number of parents
487 int numParents = 0; 449 int numParents = 0;
488 { 450 {
489 AstNode current = node.parent; 451 AstNode current = node.parent;
490 while (current != null) { 452 while (current != null) {
491 numParents++; 453 numParents++;
492 current = current.parent; 454 current = current.parent;
493 } 455 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 AnalysisContext context = unitElement.context; 493 AnalysisContext context = unitElement.context;
532 Source source = unitElement.source; 494 Source source = unitElement.source;
533 CompilationUnit unit = context.parseCompilationUnit(source); 495 CompilationUnit unit = context.parseCompilationUnit(source);
534 if (unit.element == null) { 496 if (unit.element == null) {
535 unit.element = unitElement; 497 unit.element = unitElement;
536 } 498 }
537 return unit; 499 return unit;
538 } 500 }
539 501
540 /** 502 /**
541 * Returns a [PropertyAccessorElement] if the given [SimpleIdentifier] is a 503 * If given [node] is name of qualified property extraction, returns target from
542 * reference to a property, or `null` in the other case. 504 * which this property is extracted, otherwise `null`.
543 */
544 PropertyAccessorElement getPropertyAccessorElement(SimpleIdentifier node) {
545 Element element = node.staticElement;
546 if (element is PropertyAccessorElement) {
547 return element;
548 }
549 return null;
550 }
551
552 /**
553 * If given [AstNode] is name of qualified property extraction, returns target f rom which
554 * this property is extracted. Otherwise `null`.
555 */ 505 */
556 Expression getQualifiedPropertyTarget(AstNode node) { 506 Expression getQualifiedPropertyTarget(AstNode node) {
557 AstNode parent = node.parent; 507 AstNode parent = node.parent;
558 if (parent is PrefixedIdentifier) { 508 if (parent is PrefixedIdentifier) {
559 PrefixedIdentifier prefixed = parent; 509 PrefixedIdentifier prefixed = parent;
560 if (prefixed.identifier == node) { 510 if (prefixed.identifier == node) {
561 return parent.prefix; 511 return parent.prefix;
562 } 512 }
563 } 513 }
564 if (parent is PropertyAccess) { 514 if (parent is PropertyAccess) {
565 PropertyAccess access = parent; 515 PropertyAccess access = parent;
566 if (access.propertyName == node) { 516 if (access.propertyName == node) {
567 return access.realTarget; 517 return access.realTarget;
568 } 518 }
569 } 519 }
570 return null; 520 return null;
571 } 521 }
572 522
573 /** 523 /**
574 * Returns the given [Statement] if not a [Block], or the first child 524 * Returns the given [statement] if not a block, or the first child statement if
575 * [Statement] if a [Block], or `null` if more than one child. 525 * a block, or `null` if more than one child.
576 */ 526 */
577 Statement getSingleStatement(Statement statement) { 527 Statement getSingleStatement(Statement statement) {
578 if (statement is Block) { 528 if (statement is Block) {
579 List<Statement> blockStatements = statement.statements; 529 List<Statement> blockStatements = statement.statements;
580 if (blockStatements.length != 1) { 530 if (blockStatements.length != 1) {
581 return null; 531 return null;
582 } 532 }
583 return blockStatements[0]; 533 return blockStatements[0];
584 } 534 }
585 return statement; 535 return statement;
586 } 536 }
587 537
588 /** 538 /**
589 * Returns the [String] content of the given [Source]. 539 * Returns the given [statement] if not a block, or all the children statements
590 */ 540 * if a block.
591 String getSourceContent(AnalysisContext context, Source source) {
592 return context.getContents(source).data;
593 }
594
595 /**
596 * Returns the given [Statement] if not a [Block], or all the children
597 * [Statement]s if a [Block].
598 */ 541 */
599 List<Statement> getStatements(Statement statement) { 542 List<Statement> getStatements(Statement statement) {
600 if (statement is Block) { 543 if (statement is Block) {
601 return statement.statements; 544 return statement.statements;
602 } 545 }
603 return [statement]; 546 return [statement];
604 } 547 }
605 548
606 /** 549 /**
607 * Checks if the given [Element]'s display name equals to the given name. 550 * Checks if the given [element]'s display name equals to the given [name].
608 */ 551 */
609 bool hasDisplayName(Element element, String name) { 552 bool hasDisplayName(Element element, String name) {
610 if (element == null) { 553 if (element == null) {
611 return false; 554 return false;
612 } 555 }
613 return element.displayName == name; 556 return element.displayName == name;
614 } 557 }
615 558
616 /** 559 /**
617 * Checks if the given [PropertyAccessorElement] is an accessor of a
618 * [FieldElement].
619 */
620 bool isFieldAccessorElement(PropertyAccessorElement accessor) {
621 return accessor != null && accessor.variable is FieldElement;
622 }
623
624 /**
625 * Checks if given [DartNode] is the left hand side of an assignment, or a 560 * Checks if given [DartNode] is the left hand side of an assignment, or a
626 * declaration of a variable. 561 * declaration of a variable.
627 */ 562 */
628 bool isLeftHandOfAssignment(SimpleIdentifier node) { 563 bool isLeftHandOfAssignment(SimpleIdentifier node) {
629 if (node.inSetterContext()) { 564 if (node.inSetterContext()) {
630 return true; 565 return true;
631 } 566 }
632 return node.parent is VariableDeclaration && 567 return node.parent is VariableDeclaration &&
633 (node.parent as VariableDeclaration).name == node; 568 (node.parent as VariableDeclaration).name == node;
634 } 569 }
635 570
636 /** 571 /**
637 * @return `true` if the given [SimpleIdentifier] is the name of the 572 * Return `true` if the given [node] is the name of a [NamedExpression].
638 * [NamedExpression].
639 */ 573 */
640 bool isNamedExpressionName(SimpleIdentifier node) { 574 bool isNamedExpressionName(SimpleIdentifier node) {
641 AstNode parent = node.parent; 575 AstNode parent = node.parent;
642 if (parent is Label) { 576 if (parent is Label) {
643 Label label = parent; 577 Label label = parent;
644 if (identical(label.label, node)) { 578 if (identical(label.label, node)) {
645 AstNode parent2 = label.parent; 579 AstNode parent2 = label.parent;
646 if (parent2 is NamedExpression) { 580 if (parent2 is NamedExpression) {
647 return identical(parent2.name, label); 581 return identical(parent2.name, label);
648 } 582 }
649 } 583 }
650 } 584 }
651 return false; 585 return false;
652 } 586 }
653 587
654 /** 588 /**
655 * If the given [expression] is the `expression` property of a [NamedExpression] 589 * If the given [expression] is the `expression` property of a [NamedExpression]
656 * then returns this [NamedExpression]. Otherwise returns [expression]. 590 * then returns this [NamedExpression], otherwise returns [expression].
657 */ 591 */
658 Expression stepUpNamedExpression(Expression expression) { 592 Expression stepUpNamedExpression(Expression expression) {
659 if (expression != null) { 593 if (expression != null) {
660 AstNode parent = expression.parent; 594 AstNode parent = expression.parent;
661 if (parent is NamedExpression && parent.expression == expression) { 595 if (parent is NamedExpression && parent.expression == expression) {
662 return parent; 596 return parent;
663 } 597 }
664 } 598 }
665 return expression; 599 return expression;
666 } 600 }
667 601
668 /** 602 /**
603 * Return `true` if the given [lists] are identical at the given [position].
604 */
605 bool _allListsIdentical(List<List> lists, int position) {
606 Object element = lists[0][position];
607 for (List list in lists) {
608 if (list[position] != element) {
609 return false;
610 }
611 }
612 return true;
613 }
614
615 /**
669 * This exception is thrown to cancel the current correction operation, 616 * This exception is thrown to cancel the current correction operation,
670 * such as quick assist or quick fix because an inconsistency was detected. 617 * such as quick assist or quick fix because an inconsistency was detected.
671 * These inconsistencies may happen as a part of normal workflow, e.g. because 618 * These inconsistencies may happen as a part of normal workflow, e.g. because
672 * a resource was deleted, or an analysis result was invalidated. 619 * a resource was deleted, or an analysis result was invalidated.
673 */ 620 */
674 class CancelCorrectionException { 621 class CancelCorrectionException {
675 final Object exception; 622 final Object exception;
676 CancelCorrectionException({this.exception}); 623 CancelCorrectionException({this.exception});
677 } 624 }
678 625
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 @override 1503 @override
1557 visitSimpleIdentifier(SimpleIdentifier node) { 1504 visitSimpleIdentifier(SimpleIdentifier node) {
1558 if (node.inDeclarationContext()) { 1505 if (node.inDeclarationContext()) {
1559 Element element = node.staticElement; 1506 Element element = node.staticElement;
1560 if (element is LocalElement) { 1507 if (element is LocalElement) {
1561 elements.add(element); 1508 elements.add(element);
1562 } 1509 }
1563 } 1510 }
1564 } 1511 }
1565 } 1512 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698