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

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

Issue 694373002: Support for inlining methods when some arguments are missing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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/inline_method_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.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_server.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';
20 import 'package:analyzer/src/generated/element.dart'; 20 import 'package:analyzer/src/generated/element.dart';
21 import 'package:analyzer/src/generated/source.dart'; 21 import 'package:analyzer/src/generated/source.dart';
22 import 'package:analyzer/src/generated/utilities_dart.dart';
22 23
23 24
24 /** 25 /**
25 * Returns the [SourceRange] to find conflicting locals in. 26 * Returns the [SourceRange] to find conflicting locals in.
26 */ 27 */
27 SourceRange _getLocalsConflictingRange(AstNode node) { 28 SourceRange _getLocalsConflictingRange(AstNode node) {
28 // maybe Block 29 // maybe Block
29 Block block = node.getAncestor((node) => node is Block); 30 Block block = node.getAncestor((node) => node is Block);
30 if (block != null) { 31 if (block != null) {
31 int offset = node.offset; 32 int offset = node.offset;
32 int endOffset = block.end; 33 int endOffset = block.end;
33 return rangeStartEnd(offset, endOffset); 34 return rangeStartEnd(offset, endOffset);
34 } 35 }
35 // maybe whole executable 36 // maybe whole executable
36 AstNode executableNode = getEnclosingExecutableNode(node); 37 AstNode executableNode = getEnclosingExecutableNode(node);
37 if (executableNode != null) { 38 if (executableNode != null) {
38 return rangeNode(executableNode); 39 return rangeNode(executableNode);
39 } 40 }
40 // not a part of a declaration with locals 41 // not a part of a declaration with locals
41 return SourceRange.EMPTY; 42 return SourceRange.EMPTY;
42 } 43 }
43 44
44 45
45 /** 46 /**
46 * Returns the source which should replace given invocation with given 47 * Returns the source which should replace given invocation with given
47 * arguments. 48 * arguments.
48 */ 49 */
49 String _getMethodSourceForInvocation(_SourcePart part, CorrectionUtils utils, 50 String _getMethodSourceForInvocation(RefactoringStatus status, _SourcePart part,
50 AstNode contextNode, Expression targetExpression, List<Expression> arguments ) { 51 CorrectionUtils utils, AstNode contextNode, Expression targetExpression,
52 List<Expression> arguments) {
51 // prepare edits to replace parameters with arguments 53 // prepare edits to replace parameters with arguments
52 List<SourceEdit> edits = <SourceEdit>[]; 54 List<SourceEdit> edits = <SourceEdit>[];
53 part._parameters.forEach( 55 part._parameters.forEach(
54 (ParameterElement parameter, List<_ParameterOccurrence> occurrences) { 56 (ParameterElement parameter, List<_ParameterOccurrence> occurrences) {
55 // prepare argument 57 // prepare argument
56 Expression argument = null; 58 Expression argument = null;
57 for (Expression arg in arguments) { 59 for (Expression arg in arguments) {
58 if (arg.bestParameterElement == parameter) { 60 if (arg.bestParameterElement == parameter) {
59 argument = arg; 61 argument = arg;
60 break; 62 break;
61 } 63 }
62 } 64 }
63 if (argument is NamedExpression) { 65 if (argument is NamedExpression) {
64 argument = (argument as NamedExpression).expression; 66 argument = (argument as NamedExpression).expression;
65 } 67 }
66 int argumentPrecedence = getExpressionPrecedence(argument); 68 // prepare argument properties
67 String argumentSource = utils.getNodeText(argument); 69 int argumentPrecedence;
70 String argumentSource;
71 if (argument != null) {
72 argumentPrecedence = getExpressionPrecedence(argument);
73 argumentSource = utils.getNodeText(argument);
74 } else {
75 // report about a missing required parameter
76 if (parameter.parameterKind == ParameterKind.REQUIRED) {
77 status.addError(
78 'No argument for the parameter "${parameter.name}".',
79 newLocation_fromNode(contextNode));
80 return;
81 }
82 // an optional parameter
83 argumentPrecedence = -1000;
84 argumentSource = parameter.defaultValueCode;
85 if (argumentSource == null) {
86 argumentSource = 'null';
87 }
88 }
68 // replace all occurrences of this parameter 89 // replace all occurrences of this parameter
69 for (_ParameterOccurrence occurrence in occurrences) { 90 for (_ParameterOccurrence occurrence in occurrences) {
70 SourceRange range = occurrence.range; 91 SourceRange range = occurrence.range;
71 // prepare argument source to apply at this occurrence 92 // prepare argument source to apply at this occurrence
72 String occurrenceArgumentSource; 93 String occurrenceArgumentSource;
73 if (argumentPrecedence < occurrence.parentPrecedence) { 94 if (argumentPrecedence < occurrence.parentPrecedence) {
74 occurrenceArgumentSource = "(${argumentSource})"; 95 occurrenceArgumentSource = "($argumentSource)";
75 } else { 96 } else {
76 occurrenceArgumentSource = argumentSource; 97 occurrenceArgumentSource = argumentSource;
77 } 98 }
78 // do replace 99 // do replace
79 edits.add(newSourceEdit_range(range, occurrenceArgumentSource)); 100 edits.add(newSourceEdit_range(range, occurrenceArgumentSource));
80 } 101 }
81 }); 102 });
82 // replace static field "qualifier" with invocation target 103 // replace static field "qualifier" with invocation target
83 part._staticFieldQualifiers.forEach( 104 part._staticFieldQualifiers.forEach(
84 (String className, List<SourceRange> ranges) { 105 (String className, List<SourceRange> ranges) {
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 status.addError( 502 status.addError(
482 'Cannot inline cascade invocation.', 503 'Cannot inline cascade invocation.',
483 newLocation_fromNode(usage)); 504 newLocation_fromNode(usage));
484 } 505 }
485 // can we inline method body into "methodUsage" block? 506 // can we inline method body into "methodUsage" block?
486 if (_canInlineBody(usage)) { 507 if (_canInlineBody(usage)) {
487 // insert non-return statements 508 // insert non-return statements
488 if (ref._methodStatementsPart != null) { 509 if (ref._methodStatementsPart != null) {
489 // prepare statements source for invocation 510 // prepare statements source for invocation
490 String source = _getMethodSourceForInvocation( 511 String source = _getMethodSourceForInvocation(
512 status,
491 ref._methodStatementsPart, 513 ref._methodStatementsPart,
492 _refUtils, 514 _refUtils,
493 usage, 515 usage,
494 target, 516 target,
495 arguments); 517 arguments);
496 source = _refUtils.replaceSourceIndent( 518 source = _refUtils.replaceSourceIndent(
497 source, 519 source,
498 ref._methodStatementsPart._prefix, 520 ref._methodStatementsPart._prefix,
499 _refPrefix); 521 _refPrefix);
500 // do insert 522 // do insert
501 SourceRange range = rangeStartLength(_refLineRange, 0); 523 SourceRange range = rangeStartLength(_refLineRange, 0);
502 SourceEdit edit = newSourceEdit_range(range, source); 524 SourceEdit edit = newSourceEdit_range(range, source);
503 _addRefEdit(edit); 525 _addRefEdit(edit);
504 } 526 }
505 // replace invocation with return expression 527 // replace invocation with return expression
506 if (ref._methodExpressionPart != null) { 528 if (ref._methodExpressionPart != null) {
507 // prepare expression source for invocation 529 // prepare expression source for invocation
508 String source = _getMethodSourceForInvocation( 530 String source = _getMethodSourceForInvocation(
531 status,
509 ref._methodExpressionPart, 532 ref._methodExpressionPart,
510 _refUtils, 533 _refUtils,
511 usage, 534 usage,
512 target, 535 target,
513 arguments); 536 arguments);
514 if (getExpressionPrecedence(ref._methodExpression) < 537 if (getExpressionPrecedence(ref._methodExpression) <
515 getExpressionParentPrecedence(usage)) { 538 getExpressionParentPrecedence(usage)) {
516 source = "(${source})"; 539 source = "(${source})";
517 } 540 }
518 // do replace 541 // do replace
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 } 826 }
804 827
805 void _addVariable(SimpleIdentifier node) { 828 void _addVariable(SimpleIdentifier node) {
806 VariableElement variableElement = getLocalVariableElement(node); 829 VariableElement variableElement = getLocalVariableElement(node);
807 if (variableElement != null) { 830 if (variableElement != null) {
808 SourceRange nodeRange = rangeNode(node); 831 SourceRange nodeRange = rangeNode(node);
809 result.addVariable(variableElement, nodeRange); 832 result.addVariable(variableElement, nodeRange);
810 } 833 }
811 } 834 }
812 } 835 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/services/refactoring/inline_method_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698