Chromium Code Reviews| Index: pkg/analysis_server/lib/src/services/refactoring/inline_local.dart |
| diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart |
| index f44274d030f8eafa6f1a4f76f55377a45c9e2f24..debaed6303b01e7d9c12c43ff0e366e123ce5c5c 100644 |
| --- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart |
| +++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart |
| @@ -7,6 +7,7 @@ library services.src.refactoring.inline_local; |
| import 'dart:async'; |
| import 'package:analysis_server/src/protocol_server.dart' hide Element; |
| +import 'package:analysis_server/src/services/correction/source_range.dart'; |
| import 'package:analysis_server/src/services/correction/status.dart'; |
| import 'package:analysis_server/src/services/correction/util.dart'; |
| import 'package:analysis_server/src/services/refactoring/refactoring.dart'; |
| @@ -135,17 +136,51 @@ class InlineLocalRefactoringImpl extends RefactoringImpl implements |
| } |
| // prepare initializer |
| Expression initializer = _variableNode.initializer; |
| - String initializerSource = utils.getNodeText(initializer); |
| + String initializerCode = utils.getNodeText(initializer); |
| int initializerPrecedence = getExpressionPrecedence(initializer); |
| // replace references |
| for (SearchMatch reference in _references) { |
| SourceRange range = reference.sourceRange; |
| - String sourceForReference = |
| - _getSourceForReference(range, initializerSource, initializerPrecedence); |
| + // prepare context |
| + int offset = range.offset; |
| + AstNode node = utils.findNode(offset); |
| + AstNode parent = node.parent; |
| + // prepare code |
| + String codeForReference; |
| + if (parent is InterpolationExpression) { |
| + StringInterpolation target = parent.parent; |
| + if (initializer is SingleStringLiteral && |
| + !initializer.isRaw && |
| + initializer.isSingleQuoted == target.isSingleQuoted && |
| + (initializer.isSingleQuoted || target.isMultiline)) { |
|
Paul Berry
2014/10/07 17:12:39
I think you mean (!initializer.isMultiline || targ
scheglov
2014/10/07 17:22:06
Ouch!
Thank you for catching this.
Test added and
|
| + range = rangeNode(parent); |
| + // unwrap the literal being inlined |
| + int initOffset = initializer.contentsOffset; |
| + int initLength = initializer.contentsEnd - initOffset; |
| + codeForReference = utils.getText(initOffset, initLength); |
| + // drop leading multiline EOL |
| + if (initializer.isMultiline) { |
| + if (codeForReference.startsWith('\n')) { |
| + codeForReference = codeForReference.substring(1); |
| + } else if (codeForReference.startsWith('\r\n')) { |
| + codeForReference = codeForReference.substring(2); |
| + } |
| + } |
| + } else if (_shouldBeExpressionInterpolation(parent, initializer)) { |
| + codeForReference = '{$initializerCode}'; |
| + } else { |
| + codeForReference = initializerCode; |
| + } |
| + } else if (initializerPrecedence < getExpressionParentPrecedence(node)) { |
| + codeForReference = '($initializerCode)'; |
| + } else { |
| + codeForReference = initializerCode; |
| + } |
| + // do replace |
| doSourceChange_addElementEdit( |
| change, |
| unitElement, |
| - newSourceEdit_range(range, sourceForReference)); |
| + newSourceEdit_range(range, codeForReference)); |
| } |
| // done |
| return new Future.value(change); |
| @@ -154,37 +189,10 @@ class InlineLocalRefactoringImpl extends RefactoringImpl implements |
| @override |
| bool requiresPreview() => false; |
| - /** |
| - * Returns the source which should be used to replace the reference with the |
| - * given [SourceRange]. |
| - * |
| - * [range] - the [SourceRange] of the reference. |
| - * [source] - the source of the initializer, to be inserted at [range]. |
| - * [precedence] - the precedence of the initializer [source]. |
| - */ |
| - String _getSourceForReference(SourceRange range, String source, |
| - int precedence) { |
| - int offset = range.offset; |
| - AstNode node = utils.findNode(offset); |
| - AstNode parent = node.parent; |
| - if (_isIdentifierStringInterpolation(parent)) { |
| - return '{${source}}'; |
| - } |
| - if (precedence < getExpressionParentPrecedence(node)) { |
| - return '(${source})'; |
| - } |
| - return source; |
| - } |
| - |
| - /** |
| - * Checks if the given node is a string interpolation in form `$name`. |
| - */ |
| - bool _isIdentifierStringInterpolation(AstNode parent) { |
| - if (parent is InterpolationExpression) { |
| - InterpolationExpression element = parent; |
| - return element.beginToken.type == |
| - TokenType.STRING_INTERPOLATION_IDENTIFIER; |
| - } |
| - return false; |
| + static bool _shouldBeExpressionInterpolation(InterpolationExpression target, |
| + Expression expression) { |
| + TokenType targetType = target.beginToken.type; |
| + return targetType == TokenType.STRING_INTERPOLATION_IDENTIFIER && |
| + expression is! SimpleIdentifier; |
| } |
| } |