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

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

Issue 628293004: Remove references to Engine classes from protocol.dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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.refactoring.inline_method; 5 library services.src.refactoring.inline_method;
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_server.dart' hide Element;
10 import 'package:analysis_server/src/services/correction/source_range.dart'; 10 import 'package:analysis_server/src/services/correction/source_range.dart';
11 import 'package:analysis_server/src/services/correction/status.dart'; 11 import 'package:analysis_server/src/services/correction/status.dart';
12 import 'package:analysis_server/src/services/correction/strings.dart'; 12 import 'package:analysis_server/src/services/correction/strings.dart';
13 import 'package:analysis_server/src/services/correction/util.dart'; 13 import 'package:analysis_server/src/services/correction/util.dart';
14 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; 14 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
15 import 'package:analysis_server/src/services/refactoring/refactoring_internal.da rt'; 15 import 'package:analysis_server/src/services/refactoring/refactoring_internal.da rt';
16 import 'package:analysis_server/src/services/search/element_visitors.dart'; 16 import 'package:analysis_server/src/services/search/element_visitors.dart';
17 import 'package:analysis_server/src/services/search/hierarchy.dart'; 17 import 'package:analysis_server/src/services/search/hierarchy.dart';
18 import 'package:analysis_server/src/services/search/search_engine.dart'; 18 import 'package:analysis_server/src/services/search/search_engine.dart';
19 import 'package:analyzer/src/generated/ast.dart'; 19 import 'package:analyzer/src/generated/ast.dart';
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 for (_ParameterOccurrence occurrence in occurrences) { 69 for (_ParameterOccurrence occurrence in occurrences) {
70 SourceRange range = occurrence.range; 70 SourceRange range = occurrence.range;
71 // prepare argument source to apply at this occurrence 71 // prepare argument source to apply at this occurrence
72 String occurrenceArgumentSource; 72 String occurrenceArgumentSource;
73 if (argumentPrecedence < occurrence.parentPrecedence) { 73 if (argumentPrecedence < occurrence.parentPrecedence) {
74 occurrenceArgumentSource = "(${argumentSource})"; 74 occurrenceArgumentSource = "(${argumentSource})";
75 } else { 75 } else {
76 occurrenceArgumentSource = argumentSource; 76 occurrenceArgumentSource = argumentSource;
77 } 77 }
78 // do replace 78 // do replace
79 edits.add(new SourceEdit.range(range, occurrenceArgumentSource)); 79 edits.add(newSourceEdit_range(range, occurrenceArgumentSource));
80 } 80 }
81 }); 81 });
82 // replace static field "qualifier" with invocation target 82 // replace static field "qualifier" with invocation target
83 part._staticFieldQualifiers.forEach( 83 part._staticFieldQualifiers.forEach(
84 (String className, List<SourceRange> ranges) { 84 (String className, List<SourceRange> ranges) {
85 for (SourceRange range in ranges) { 85 for (SourceRange range in ranges) {
86 edits.add(new SourceEdit.range(range, className + '.')); 86 edits.add(newSourceEdit_range(range, className + '.'));
87 } 87 }
88 }); 88 });
89 // replace instance field "qualifier" with invocation target 89 // replace instance field "qualifier" with invocation target
90 if (targetExpression != null) { 90 if (targetExpression != null) {
91 String targetSource = utils.getNodeText(targetExpression) + '.'; 91 String targetSource = utils.getNodeText(targetExpression) + '.';
92 for (SourceRange qualifierRange in part._instanceFieldQualifiers) { 92 for (SourceRange qualifierRange in part._instanceFieldQualifiers) {
93 edits.add(new SourceEdit.range(qualifierRange, targetSource)); 93 edits.add(newSourceEdit_range(qualifierRange, targetSource));
94 } 94 }
95 } 95 }
96 // prepare edits to replace conflicting variables 96 // prepare edits to replace conflicting variables
97 Set<String> conflictingNames = _getNamesConflictingAt(contextNode); 97 Set<String> conflictingNames = _getNamesConflictingAt(contextNode);
98 part._variables.forEach((VariableElement variable, List<SourceRange> ranges) { 98 part._variables.forEach((VariableElement variable, List<SourceRange> ranges) {
99 String originalName = variable.displayName; 99 String originalName = variable.displayName;
100 // prepare unique name 100 // prepare unique name
101 String uniqueName; 101 String uniqueName;
102 { 102 {
103 uniqueName = originalName; 103 uniqueName = originalName;
104 int uniqueIndex = 2; 104 int uniqueIndex = 2;
105 while (conflictingNames.contains(uniqueName)) { 105 while (conflictingNames.contains(uniqueName)) {
106 uniqueName = originalName + uniqueIndex.toString(); 106 uniqueName = originalName + uniqueIndex.toString();
107 uniqueIndex++; 107 uniqueIndex++;
108 } 108 }
109 } 109 }
110 // update references, if name was change 110 // update references, if name was change
111 if (uniqueName != originalName) { 111 if (uniqueName != originalName) {
112 for (SourceRange range in ranges) { 112 for (SourceRange range in ranges) {
113 edits.add(new SourceEdit.range(range, uniqueName)); 113 edits.add(newSourceEdit_range(range, uniqueName));
114 } 114 }
115 } 115 }
116 }); 116 });
117 // prepare source with applied arguments 117 // prepare source with applied arguments
118 edits.sort((SourceEdit a, SourceEdit b) => b.offset - a.offset); 118 edits.sort((SourceEdit a, SourceEdit b) => b.offset - a.offset);
119 return SourceEdit.applySequence(part._source, edits); 119 return SourceEdit.applySequence(part._source, edits);
120 } 120 }
121 121
122 122
123 /** 123 /**
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 result.addError('All references must be inlined to remove the source.'); 232 result.addError('All references must be inlined to remove the source.');
233 } 233 }
234 // prepare changes 234 // prepare changes
235 for (_ReferenceProcessor processor in _referenceProcessors) { 235 for (_ReferenceProcessor processor in _referenceProcessors) {
236 processor._process(result); 236 processor._process(result);
237 } 237 }
238 // delete method 238 // delete method
239 if (deleteSource && inlineAll) { 239 if (deleteSource && inlineAll) {
240 SourceRange methodRange = rangeNode(_methodNode); 240 SourceRange methodRange = rangeNode(_methodNode);
241 SourceRange linesRange = _methodUtils.getLinesRange(methodRange); 241 SourceRange linesRange = _methodUtils.getLinesRange(methodRange);
242 change.addElementEdit( 242 doSourceChange_addElementEdit(
243 change,
243 _methodElement, 244 _methodElement,
244 new SourceEdit.range(linesRange, '')); 245 newSourceEdit_range(linesRange, ''));
245 } 246 }
246 // done 247 // done
247 return new Future.value(result); 248 return new Future.value(result);
248 } 249 }
249 250
250 @override 251 @override
251 Future<RefactoringStatus> checkInitialConditions() { 252 Future<RefactoringStatus> checkInitialConditions() {
252 RefactoringStatus result = new RefactoringStatus(); 253 RefactoringStatus result = new RefactoringStatus();
253 // prepare method information 254 // prepare method information
254 result.addStatus(_prepareMethod()); 255 result.addStatus(_prepareMethod());
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 Statement refStatement = _node.getAncestor((node) => node is Statement); 422 Statement refStatement = _node.getAncestor((node) => node is Statement);
422 if (refStatement != null) { 423 if (refStatement != null) {
423 _refLineRange = _refUtils.getLinesRangeStatements([refStatement]); 424 _refLineRange = _refUtils.getLinesRangeStatements([refStatement]);
424 _refPrefix = _refUtils.getNodePrefix(refStatement); 425 _refPrefix = _refUtils.getNodePrefix(refStatement);
425 } else { 426 } else {
426 _refLineRange = null; 427 _refLineRange = null;
427 _refPrefix = _refUtils.getLinePrefix(_node.offset); 428 _refPrefix = _refUtils.getLinePrefix(_node.offset);
428 } 429 }
429 } 430 }
430 431
432 void _addRefEdit(SourceEdit edit) {
433 doSourceChange_addElementEdit(ref.change, refElement, edit);
434 }
435
431 bool _canInlineBody(AstNode usage) { 436 bool _canInlineBody(AstNode usage) {
432 // no statements, usually just expression 437 // no statements, usually just expression
433 if (ref._methodStatementsPart == null) { 438 if (ref._methodStatementsPart == null) {
434 // empty method, inline as closure 439 // empty method, inline as closure
435 if (ref._methodExpressionPart == null) { 440 if (ref._methodExpressionPart == null) {
436 return false; 441 return false;
437 } 442 }
438 // OK, just expression 443 // OK, just expression
439 return true; 444 return true;
440 } 445 }
(...skipping 27 matching lines...) Expand all
468 // not in block, cannot inline body 473 // not in block, cannot inline body
469 return false; 474 return false;
470 } 475 }
471 476
472 void _inlineMethodInvocation(RefactoringStatus status, Expression usage, 477 void _inlineMethodInvocation(RefactoringStatus status, Expression usage,
473 bool cascaded, Expression target, List<Expression> arguments) { 478 bool cascaded, Expression target, List<Expression> arguments) {
474 // we don't support cascade 479 // we don't support cascade
475 if (cascaded) { 480 if (cascaded) {
476 status.addError( 481 status.addError(
477 'Cannot inline cascade invocation.', 482 'Cannot inline cascade invocation.',
478 new Location.fromNode(usage)); 483 newLocation_fromNode(usage));
479 } 484 }
480 // can we inline method body into "methodUsage" block? 485 // can we inline method body into "methodUsage" block?
481 if (_canInlineBody(usage)) { 486 if (_canInlineBody(usage)) {
482 // insert non-return statements 487 // insert non-return statements
483 if (ref._methodStatementsPart != null) { 488 if (ref._methodStatementsPart != null) {
484 // prepare statements source for invocation 489 // prepare statements source for invocation
485 String source = _getMethodSourceForInvocation( 490 String source = _getMethodSourceForInvocation(
486 ref._methodStatementsPart, 491 ref._methodStatementsPart,
487 _refUtils, 492 _refUtils,
488 usage, 493 usage,
489 target, 494 target,
490 arguments); 495 arguments);
491 source = _refUtils.replaceSourceIndent( 496 source = _refUtils.replaceSourceIndent(
492 source, 497 source,
493 ref._methodStatementsPart._prefix, 498 ref._methodStatementsPart._prefix,
494 _refPrefix); 499 _refPrefix);
495 // do insert 500 // do insert
496 SourceRange range = rangeStartLength(_refLineRange, 0); 501 SourceRange range = rangeStartLength(_refLineRange, 0);
497 SourceEdit edit = new SourceEdit.range(range, source); 502 SourceEdit edit = newSourceEdit_range(range, source);
498 _addRefEdit(edit); 503 _addRefEdit(edit);
499 } 504 }
500 // replace invocation with return expression 505 // replace invocation with return expression
501 if (ref._methodExpressionPart != null) { 506 if (ref._methodExpressionPart != null) {
502 // prepare expression source for invocation 507 // prepare expression source for invocation
503 String source = _getMethodSourceForInvocation( 508 String source = _getMethodSourceForInvocation(
504 ref._methodExpressionPart, 509 ref._methodExpressionPart,
505 _refUtils, 510 _refUtils,
506 usage, 511 usage,
507 target, 512 target,
508 arguments); 513 arguments);
509 if (getExpressionPrecedence(ref._methodExpression) < 514 if (getExpressionPrecedence(ref._methodExpression) <
510 getExpressionParentPrecedence(usage)) { 515 getExpressionParentPrecedence(usage)) {
511 source = "(${source})"; 516 source = "(${source})";
512 } 517 }
513 // do replace 518 // do replace
514 SourceRange methodUsageRange = rangeNode(usage); 519 SourceRange methodUsageRange = rangeNode(usage);
515 SourceEdit edit = new SourceEdit.range(methodUsageRange, source); 520 SourceEdit edit = newSourceEdit_range(methodUsageRange, source);
516 _addRefEdit(edit); 521 _addRefEdit(edit);
517 } else { 522 } else {
518 SourceEdit edit = new SourceEdit.range(_refLineRange, ""); 523 SourceEdit edit = newSourceEdit_range(_refLineRange, "");
519 _addRefEdit(edit); 524 _addRefEdit(edit);
520 } 525 }
521 return; 526 return;
522 } 527 }
523 // inline as closure invocation 528 // inline as closure invocation
524 String source; 529 String source;
525 { 530 {
526 source = ref._methodUtils.getRangeText( 531 source = ref._methodUtils.getRangeText(
527 rangeStartEnd(ref._methodParameters.leftParenthesis, ref._methodNode)) ; 532 rangeStartEnd(ref._methodParameters.leftParenthesis, ref._methodNode)) ;
528 String methodPrefix = 533 String methodPrefix =
529 ref._methodUtils.getLinePrefix(ref._methodNode.offset); 534 ref._methodUtils.getLinePrefix(ref._methodNode.offset);
530 source = _refUtils.replaceSourceIndent(source, methodPrefix, _refPrefix); 535 source = _refUtils.replaceSourceIndent(source, methodPrefix, _refPrefix);
531 source = source.trim(); 536 source = source.trim();
532 } 537 }
533 // do insert 538 // do insert
534 SourceRange range = rangeNode(_node); 539 SourceRange range = rangeNode(_node);
535 SourceEdit edit = new SourceEdit.range(range, source); 540 SourceEdit edit = newSourceEdit_range(range, source);
536 _addRefEdit(edit); 541 _addRefEdit(edit);
537 } 542 }
538 543
539 void _process(RefactoringStatus status) { 544 void _process(RefactoringStatus status) {
540 AstNode nodeParent = _node.parent; 545 AstNode nodeParent = _node.parent;
541 // may be only single place should be inlined 546 // may be only single place should be inlined
542 if (!_shouldProcess()) { 547 if (!_shouldProcess()) {
543 return; 548 return;
544 } 549 }
545 // may be invocation of inline method 550 // may be invocation of inline method
546 if (nodeParent is MethodInvocation) { 551 if (nodeParent is MethodInvocation) {
547 MethodInvocation invocation = nodeParent; 552 MethodInvocation invocation = nodeParent;
548 Expression target = invocation.target; 553 Expression target = invocation.target;
549 List<Expression> arguments = invocation.argumentList.arguments; 554 List<Expression> arguments = invocation.argumentList.arguments;
550 _inlineMethodInvocation( 555 _inlineMethodInvocation(
551 status, 556 status,
552 invocation, 557 invocation,
553 invocation.isCascaded, 558 invocation.isCascaded,
554 target, 559 target,
555 arguments); 560 arguments);
556 } else { 561 } else {
557 // cannot inline reference to method: var v = new A().method; 562 // cannot inline reference to method: var v = new A().method;
558 if (ref._methodElement is MethodElement) { 563 if (ref._methodElement is MethodElement) {
559 status.addFatalError( 564 status.addFatalError(
560 'Cannot inline class method reference.', 565 'Cannot inline class method reference.',
561 new Location.fromNode(_node)); 566 newLocation_fromNode(_node));
562 return; 567 return;
563 } 568 }
564 // PropertyAccessorElement 569 // PropertyAccessorElement
565 if (ref._methodElement is PropertyAccessorElement) { 570 if (ref._methodElement is PropertyAccessorElement) {
566 Expression usage = _node; 571 Expression usage = _node;
567 Expression target = null; 572 Expression target = null;
568 bool cascade = false; 573 bool cascade = false;
569 if (nodeParent is PrefixedIdentifier) { 574 if (nodeParent is PrefixedIdentifier) {
570 PrefixedIdentifier propertyAccess = nodeParent; 575 PrefixedIdentifier propertyAccess = nodeParent;
571 usage = propertyAccess; 576 usage = propertyAccess;
(...skipping 24 matching lines...) Expand all
596 rangeStartEnd(ref._methodParameters.leftParenthesis, ref._methodNode )); 601 rangeStartEnd(ref._methodParameters.leftParenthesis, ref._methodNode ));
597 String methodPrefix = 602 String methodPrefix =
598 ref._methodUtils.getLinePrefix(ref._methodNode.offset); 603 ref._methodUtils.getLinePrefix(ref._methodNode.offset);
599 source = 604 source =
600 _refUtils.replaceSourceIndent(source, methodPrefix, _refPrefix); 605 _refUtils.replaceSourceIndent(source, methodPrefix, _refPrefix);
601 source = source.trim(); 606 source = source.trim();
602 source = removeEnd(source, ';'); 607 source = removeEnd(source, ';');
603 } 608 }
604 // do insert 609 // do insert
605 SourceRange range = rangeNode(_node); 610 SourceRange range = rangeNode(_node);
606 SourceEdit edit = new SourceEdit.range(range, source); 611 SourceEdit edit = newSourceEdit_range(range, source);
607 _addRefEdit(edit); 612 _addRefEdit(edit);
608 } 613 }
609 } 614 }
610 615
611 void _addRefEdit(SourceEdit edit) {
612 ref.change.addElementEdit(refElement, edit);
613 }
614
615 bool _shouldProcess() { 616 bool _shouldProcess() {
616 if (!ref.inlineAll) { 617 if (!ref.inlineAll) {
617 SourceRange parentRange = rangeNode(_node); 618 SourceRange parentRange = rangeNode(_node);
618 return parentRange.contains(ref.offset); 619 return parentRange.contains(ref.offset);
619 } 620 }
620 return true; 621 return true;
621 } 622 }
622 } 623 }
623 624
624 class _ReturnsValidatorVisitor extends RecursiveAstVisitor { 625 class _ReturnsValidatorVisitor extends RecursiveAstVisitor {
625 final RefactoringStatus result; 626 final RefactoringStatus result;
626 int _numReturns = 0; 627 int _numReturns = 0;
627 628
628 _ReturnsValidatorVisitor(this.result); 629 _ReturnsValidatorVisitor(this.result);
629 630
630 @override 631 @override
631 visitReturnStatement(ReturnStatement node) { 632 visitReturnStatement(ReturnStatement node) {
632 _numReturns++; 633 _numReturns++;
633 if (_numReturns == 2) { 634 if (_numReturns == 2) {
634 result.addError('Ambiguous return value.', new Location.fromNode(node)); 635 result.addError('Ambiguous return value.', newLocation_fromNode(node));
635 } 636 }
636 } 637 }
637 } 638 }
638 639
639 /** 640 /**
640 * Information about the source of a method being inlined. 641 * Information about the source of a method being inlined.
641 */ 642 */
642 class _SourcePart { 643 class _SourcePart {
643 /** 644 /**
644 * The base for all [SourceRange]s. 645 * The base for all [SourceRange]s.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 } 803 }
803 804
804 void _addVariable(SimpleIdentifier node) { 805 void _addVariable(SimpleIdentifier node) {
805 VariableElement variableElement = getLocalVariableElement(node); 806 VariableElement variableElement = getLocalVariableElement(node);
806 if (variableElement != null) { 807 if (variableElement != null) {
807 SourceRange nodeRange = rangeNode(node); 808 SourceRange nodeRange = rangeNode(node);
808 result.addVariable(variableElement, nodeRange); 809 result.addVariable(variableElement, nodeRange);
809 } 810 }
810 } 811 }
811 } 812 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698