| OLD | NEW |
| 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_local; | 5 library services.src.refactoring.inline_local; |
| 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.dart' hide Element; |
| 10 import 'package:analysis_server/src/services/correction/status.dart'; | 10 import 'package:analysis_server/src/services/correction/status.dart'; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 const String _TOKEN_SEPARATOR = "\uFFFF"; | 22 const String _TOKEN_SEPARATOR = "\uFFFF"; |
| 23 | 23 |
| 24 | 24 |
| 25 /** | 25 /** |
| 26 * [InlineLocalRefactoring] implementation. | 26 * [InlineLocalRefactoring] implementation. |
| 27 */ | 27 */ |
| 28 class InlineLocalRefactoringImpl extends RefactoringImpl implements | 28 class InlineLocalRefactoringImpl extends RefactoringImpl implements |
| 29 InlineLocalRefactoring { | 29 InlineLocalRefactoring { |
| 30 final SearchEngine searchEngine; | 30 final SearchEngine searchEngine; |
| 31 final CompilationUnit unit; | 31 final CompilationUnit unit; |
| 32 final LocalVariableElement element; | 32 final int offset; |
| 33 String file; | 33 String file; |
| 34 CorrectionUtils utils; | 34 CorrectionUtils utils; |
| 35 | 35 |
| 36 Element _variableElement; |
| 36 VariableDeclaration _variableNode; | 37 VariableDeclaration _variableNode; |
| 37 List<SearchMatch> _references; | 38 List<SearchMatch> _references; |
| 38 | 39 |
| 39 InlineLocalRefactoringImpl(this.searchEngine, this.unit, this.element) { | 40 InlineLocalRefactoringImpl(this.searchEngine, this.unit, this.offset) { |
| 40 file = unit.element.source.fullName; | 41 file = unit.element.source.fullName; |
| 41 utils = new CorrectionUtils(unit); | 42 utils = new CorrectionUtils(unit); |
| 42 } | 43 } |
| 43 | 44 |
| 44 @override | 45 @override |
| 45 String get refactoringName => 'Inline Local Variable'; | 46 String get refactoringName => 'Inline Local Variable'; |
| 46 | 47 |
| 47 @override | 48 @override |
| 48 int get referenceCount { | 49 int get referenceCount { |
| 49 return _references.length; | 50 return _references.length; |
| 50 } | 51 } |
| 51 | 52 |
| 52 @override | 53 @override |
| 53 Future<RefactoringStatus> checkFinalConditions() { | 54 Future<RefactoringStatus> checkFinalConditions() { |
| 54 RefactoringStatus result = new RefactoringStatus(); | 55 RefactoringStatus result = new RefactoringStatus(); |
| 55 return new Future.value(result); | 56 return new Future.value(result); |
| 56 } | 57 } |
| 57 | 58 |
| 58 @override | 59 @override |
| 59 Future<RefactoringStatus> checkInitialConditions() { | 60 Future<RefactoringStatus> checkInitialConditions() { |
| 60 RefactoringStatus result = new RefactoringStatus(); | 61 RefactoringStatus result = new RefactoringStatus(); |
| 61 // prepare variable | 62 // prepare variable |
| 62 { | 63 { |
| 63 AstNode elementNode = utils.findNode(element.nameOffset); | 64 AstNode offsetNode = new NodeLocator.con1(offset).searchWithin(unit); |
| 64 _variableNode = elementNode != null ? | 65 if (offsetNode is SimpleIdentifier) { |
| 65 elementNode.getAncestor((node) => node is VariableDeclaration) : | 66 Element element = offsetNode.staticElement; |
| 66 null; | 67 if (element is LocalVariableElement) { |
| 68 _variableElement = element; |
| 69 _variableNode = element.node; |
| 70 } |
| 71 } |
| 72 } |
| 73 if (_variableNode == null) { |
| 74 result = new RefactoringStatus.fatal( |
| 75 'Local variable declaration or reference must be selected to activate
this refactoring.'); |
| 76 return new Future.value(result); |
| 67 } | 77 } |
| 68 // should be normal variable declaration statement | 78 // should be normal variable declaration statement |
| 69 if (_variableNode.parent is! VariableDeclarationList || | 79 if (_variableNode.parent is! VariableDeclarationList || |
| 70 _variableNode.parent.parent is! VariableDeclarationStatement || | 80 _variableNode.parent.parent is! VariableDeclarationStatement || |
| 71 _variableNode.parent.parent.parent is! Block) { | 81 _variableNode.parent.parent.parent is! Block) { |
| 72 result = new RefactoringStatus.fatal( | 82 result = new RefactoringStatus.fatal( |
| 73 'Local variable declared in ' | 83 'Local variable declared in ' |
| 74 'statement should be selected to activate this refactoring.'); | 84 'statement should be selected to activate this refactoring.'); |
| 75 return new Future.value(result); | 85 return new Future.value(result); |
| 76 } | 86 } |
| 77 // should have initializer at declaration | 87 // should have initializer at declaration |
| 78 if (_variableNode.initializer == null) { | 88 if (_variableNode.initializer == null) { |
| 79 String message = format( | 89 String message = format( |
| 80 "Local variable '{0}' is not initialized at declaration.", | 90 "Local variable '{0}' is not initialized at declaration.", |
| 81 element.displayName); | 91 _variableElement.displayName); |
| 82 result = | 92 result = |
| 83 new RefactoringStatus.fatal(message, new Location.fromNode(_variableNo
de)); | 93 new RefactoringStatus.fatal(message, new Location.fromNode(_variableNo
de)); |
| 84 return new Future.value(result); | 94 return new Future.value(result); |
| 85 } | 95 } |
| 86 // prepare references | 96 // prepare references |
| 87 return searchEngine.searchReferences(element).then((references) { | 97 return searchEngine.searchReferences(_variableElement).then((references) { |
| 88 this._references = references; | 98 this._references = references; |
| 89 // should not have assignments | 99 // should not have assignments |
| 90 for (SearchMatch reference in _references) { | 100 for (SearchMatch reference in _references) { |
| 91 if (reference.kind != MatchKind.READ) { | 101 if (reference.kind != MatchKind.READ) { |
| 92 String message = format( | 102 String message = format( |
| 93 "Local variable '{0}' is assigned more than once.", | 103 "Local variable '{0}' is assigned more than once.", |
| 94 [element.displayName]); | 104 [_variableElement.displayName]); |
| 95 return new RefactoringStatus.fatal( | 105 return new RefactoringStatus.fatal( |
| 96 message, | 106 message, |
| 97 new Location.fromMatch(reference)); | 107 new Location.fromMatch(reference)); |
| 98 } | 108 } |
| 99 } | 109 } |
| 100 // done | 110 // done |
| 101 return result; | 111 return result; |
| 102 }); | 112 }); |
| 103 } | 113 } |
| 104 | 114 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 */ | 167 */ |
| 158 bool _isIdentifierStringInterpolation(AstNode parent) { | 168 bool _isIdentifierStringInterpolation(AstNode parent) { |
| 159 if (parent is InterpolationExpression) { | 169 if (parent is InterpolationExpression) { |
| 160 InterpolationExpression element = parent; | 170 InterpolationExpression element = parent; |
| 161 return element.beginToken.type == | 171 return element.beginToken.type == |
| 162 TokenType.STRING_INTERPOLATION_IDENTIFIER; | 172 TokenType.STRING_INTERPOLATION_IDENTIFIER; |
| 163 } | 173 } |
| 164 return false; | 174 return false; |
| 165 } | 175 } |
| 166 } | 176 } |
| OLD | NEW |