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 |