| 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.rename_unit_member; | 5 library services.src.refactoring.rename_unit_member; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol_server.dart' show | 9 import 'package:analysis_server/src/protocol_server.dart' |
| 10 newLocation_fromElement, newLocation_fromMatch; | 10 show newLocation_fromElement, newLocation_fromMatch; |
| 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/util.dart'; | 12 import 'package:analysis_server/src/services/correction/util.dart'; |
| 13 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart
'; | 13 import 'package:analysis_server/src/services/refactoring/naming_conventions.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/rename.dart'; | 15 import 'package:analysis_server/src/services/refactoring/rename.dart'; |
| 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/search_engine.dart'; | 17 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| 18 import 'package:analyzer/src/generated/element.dart'; | 18 import 'package:analyzer/src/generated/element.dart'; |
| 19 import 'package:analyzer/src/generated/java_core.dart'; | 19 import 'package:analyzer/src/generated/java_core.dart'; |
| 20 | 20 |
| 21 | |
| 22 /** | 21 /** |
| 23 * Checks if creating a top-level function with the given [name] in [library] | 22 * Checks if creating a top-level function with the given [name] in [library] |
| 24 * will cause any conflicts. | 23 * will cause any conflicts. |
| 25 */ | 24 */ |
| 26 Future<RefactoringStatus> validateCreateFunction(SearchEngine searchEngine, | 25 Future<RefactoringStatus> validateCreateFunction( |
| 27 LibraryElement library, String name) { | 26 SearchEngine searchEngine, LibraryElement library, String name) { |
| 28 return new _RenameUnitMemberValidator.forCreate( | 27 return new _RenameUnitMemberValidator.forCreate( |
| 29 searchEngine, | 28 searchEngine, library, ElementKind.FUNCTION, name).validate(); |
| 30 library, | |
| 31 ElementKind.FUNCTION, | |
| 32 name).validate(); | |
| 33 } | 29 } |
| 34 | 30 |
| 35 | |
| 36 /** | 31 /** |
| 37 * Checks if creating a top-level function with the given [name] in [element] | 32 * Checks if creating a top-level function with the given [name] in [element] |
| 38 * will cause any conflicts. | 33 * will cause any conflicts. |
| 39 */ | 34 */ |
| 40 Future<RefactoringStatus> validateRenameTopLevel(SearchEngine searchEngine, | 35 Future<RefactoringStatus> validateRenameTopLevel( |
| 41 Element element, String name) { | 36 SearchEngine searchEngine, Element element, String name) { |
| 42 return new _RenameUnitMemberValidator.forRename( | 37 return new _RenameUnitMemberValidator.forRename(searchEngine, element, name) |
| 43 searchEngine, | 38 .validate(); |
| 44 element, | |
| 45 name).validate(); | |
| 46 } | 39 } |
| 47 | 40 |
| 48 | |
| 49 /** | 41 /** |
| 50 * A [Refactoring] for renaming compilation unit member [Element]s. | 42 * A [Refactoring] for renaming compilation unit member [Element]s. |
| 51 */ | 43 */ |
| 52 class RenameUnitMemberRefactoringImpl extends RenameRefactoringImpl { | 44 class RenameUnitMemberRefactoringImpl extends RenameRefactoringImpl { |
| 53 RenameUnitMemberRefactoringImpl(SearchEngine searchEngine, Element element) | 45 RenameUnitMemberRefactoringImpl(SearchEngine searchEngine, Element element) |
| 54 : super(searchEngine, element); | 46 : super(searchEngine, element); |
| 55 | 47 |
| 56 @override | 48 @override |
| 57 String get refactoringName { | 49 String get refactoringName { |
| 58 if (element is FunctionElement) { | 50 if (element is FunctionElement) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 elements.add(element); | 100 elements.add(element); |
| 109 } | 101 } |
| 110 // update each element | 102 // update each element |
| 111 return Future.forEach(elements, (Element element) { | 103 return Future.forEach(elements, (Element element) { |
| 112 addDeclarationEdit(element); | 104 addDeclarationEdit(element); |
| 113 return searchEngine.searchReferences(element).then(addReferenceEdits); | 105 return searchEngine.searchReferences(element).then(addReferenceEdits); |
| 114 }); | 106 }); |
| 115 } | 107 } |
| 116 } | 108 } |
| 117 | 109 |
| 118 | |
| 119 /** | 110 /** |
| 120 * Helper to check if the created or renamed [Element] will cause any conflicts. | 111 * Helper to check if the created or renamed [Element] will cause any conflicts. |
| 121 */ | 112 */ |
| 122 class _RenameUnitMemberValidator { | 113 class _RenameUnitMemberValidator { |
| 123 final SearchEngine searchEngine; | 114 final SearchEngine searchEngine; |
| 124 LibraryElement library; | 115 LibraryElement library; |
| 125 Element element; | 116 Element element; |
| 126 ElementKind elementKind; | 117 ElementKind elementKind; |
| 127 final String name; | 118 final String name; |
| 128 final bool isRename; | 119 final bool isRename; |
| 129 | 120 |
| 130 final RefactoringStatus result = new RefactoringStatus(); | 121 final RefactoringStatus result = new RefactoringStatus(); |
| 131 | 122 |
| 132 _RenameUnitMemberValidator.forCreate(this.searchEngine, this.library, | 123 _RenameUnitMemberValidator.forCreate( |
| 133 this.elementKind, this.name) | 124 this.searchEngine, this.library, this.elementKind, this.name) |
| 134 : isRename = false; | 125 : isRename = false; |
| 135 | 126 |
| 136 _RenameUnitMemberValidator.forRename(this.searchEngine, this.element, | 127 _RenameUnitMemberValidator.forRename( |
| 137 this.name) | 128 this.searchEngine, this.element, this.name) |
| 138 : isRename = true { | 129 : isRename = true { |
| 139 library = element.getAncestor((e) => e is LibraryElement); | 130 library = element.getAncestor((e) => e is LibraryElement); |
| 140 elementKind = element.kind; | 131 elementKind = element.kind; |
| 141 } | 132 } |
| 142 | 133 |
| 143 Future<RefactoringStatus> validate() async { | 134 Future<RefactoringStatus> validate() async { |
| 144 _validateWillConflict(); | 135 _validateWillConflict(); |
| 145 if (isRename) { | 136 if (isRename) { |
| 146 await _validateWillBeShadowed(); | 137 await _validateWillBeShadowed(); |
| 147 } | 138 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 } | 173 } |
| 183 List<SearchMatch> references = await searchEngine.searchReferences(element); | 174 List<SearchMatch> references = await searchEngine.searchReferences(element); |
| 184 for (SearchMatch reference in references) { | 175 for (SearchMatch reference in references) { |
| 185 Element refElement = reference.element; | 176 Element refElement = reference.element; |
| 186 ClassElement refClass = refElement.getAncestor((e) => e is ClassElement); | 177 ClassElement refClass = refElement.getAncestor((e) => e is ClassElement); |
| 187 if (refClass != null) { | 178 if (refClass != null) { |
| 188 visitChildren(refClass, (shadow) { | 179 visitChildren(refClass, (shadow) { |
| 189 if (hasDisplayName(shadow, name)) { | 180 if (hasDisplayName(shadow, name)) { |
| 190 String message = format( | 181 String message = format( |
| 191 "Reference to renamed {0} will be shadowed by {1} '{2}'.", | 182 "Reference to renamed {0} will be shadowed by {1} '{2}'.", |
| 192 getElementKindName(element), | 183 getElementKindName(element), getElementKindName(shadow), |
| 193 getElementKindName(shadow), | |
| 194 getElementQualifiedName(shadow)); | 184 getElementQualifiedName(shadow)); |
| 195 result.addError(message, newLocation_fromElement(shadow)); | 185 result.addError(message, newLocation_fromElement(shadow)); |
| 196 } | 186 } |
| 197 }); | 187 }); |
| 198 } | 188 } |
| 199 } | 189 } |
| 200 } | 190 } |
| 201 | 191 |
| 202 /** | 192 /** |
| 203 * Validates if [element] renamed to [name] will conflict with another | 193 * Validates if [element] renamed to [name] will conflict with another |
| 204 * top-level [Element] in the same library. | 194 * top-level [Element] in the same library. |
| 205 */ | 195 */ |
| 206 void _validateWillConflict() { | 196 void _validateWillConflict() { |
| 207 visitLibraryTopLevelElements(library, (element) { | 197 visitLibraryTopLevelElements(library, (element) { |
| 208 if (hasDisplayName(element, name)) { | 198 if (hasDisplayName(element, name)) { |
| 209 String message = format( | 199 String message = format("Library already declares {0} with name '{1}'.", |
| 210 "Library already declares {0} with name '{1}'.", | 200 getElementKindName(element), name); |
| 211 getElementKindName(element), | |
| 212 name); | |
| 213 result.addError(message, newLocation_fromElement(element)); | 201 result.addError(message, newLocation_fromElement(element)); |
| 214 } | 202 } |
| 215 }); | 203 }); |
| 216 } | 204 } |
| 217 | 205 |
| 218 /** | 206 /** |
| 219 * Validates if renamed [element] will shadow any [Element] named [name]. | 207 * Validates if renamed [element] will shadow any [Element] named [name]. |
| 220 */ | 208 */ |
| 221 Future _validateWillShadow() async { | 209 Future _validateWillShadow() async { |
| 222 List<SearchMatch> declarations = | 210 List<SearchMatch> declarations = |
| (...skipping 13 matching lines...) Expand all Loading... |
| 236 ClassElement refClass = | 224 ClassElement refClass = |
| 237 refElement.getAncestor((e) => e is ClassElement); | 225 refElement.getAncestor((e) => e is ClassElement); |
| 238 if (refClass == declaringClass) { | 226 if (refClass == declaringClass) { |
| 239 continue; | 227 continue; |
| 240 } | 228 } |
| 241 // ignore if not visible | 229 // ignore if not visible |
| 242 if (!_isVisibleAt(element, memberReference)) { | 230 if (!_isVisibleAt(element, memberReference)) { |
| 243 continue; | 231 continue; |
| 244 } | 232 } |
| 245 // OK, reference will be shadowed be the element being renamed | 233 // OK, reference will be shadowed be the element being renamed |
| 246 String message = format( | 234 String message = format(isRename |
| 247 isRename ? | 235 ? "Renamed {0} will shadow {1} '{2}'." |
| 248 "Renamed {0} will shadow {1} '{2}'." : | 236 : "Created {0} will shadow {1} '{2}'.", elementKind.displayName, |
| 249 "Created {0} will shadow {1} '{2}'.", | 237 getElementKindName(member), getElementQualifiedName(member)); |
| 250 elementKind.displayName, | |
| 251 getElementKindName(member), | |
| 252 getElementQualifiedName(member)); | |
| 253 result.addError(message, newLocation_fromMatch(memberReference)); | 238 result.addError(message, newLocation_fromMatch(memberReference)); |
| 254 } | 239 } |
| 255 } | 240 } |
| 256 } | 241 } |
| 257 } | 242 } |
| OLD | NEW |