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

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

Issue 913903002: Use async/await in refactorings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 months 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
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.rename_class_member; 5 library services.src.refactoring.rename_class_member;
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 ElementKind; 10 ElementKind;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 if (element is FieldElement) { 75 if (element is FieldElement) {
76 result.addStatus(validateFieldName(newName)); 76 result.addStatus(validateFieldName(newName));
77 } 77 }
78 if (element is MethodElement) { 78 if (element is MethodElement) {
79 result.addStatus(validateMethodName(newName)); 79 result.addStatus(validateMethodName(newName));
80 } 80 }
81 return result; 81 return result;
82 } 82 }
83 83
84 @override 84 @override
85 Future fillChange() { 85 Future fillChange() async {
86 // update declarations 86 // update declarations
87 for (Element renameElement in _validator.elements) { 87 for (Element renameElement in _validator.elements) {
88 if (renameElement.isSynthetic && renameElement is FieldElement) { 88 if (renameElement.isSynthetic && renameElement is FieldElement) {
89 addDeclarationEdit(renameElement.getter); 89 addDeclarationEdit(renameElement.getter);
90 addDeclarationEdit(renameElement.setter); 90 addDeclarationEdit(renameElement.setter);
91 } else { 91 } else {
92 addDeclarationEdit(renameElement); 92 addDeclarationEdit(renameElement);
93 } 93 }
94 } 94 }
95 // update references 95 // update references
96 addReferenceEdits(_validator.references); 96 addReferenceEdits(_validator.references);
97 // potential matches 97 // potential matches
98 return searchEngine.searchMemberReferences(oldName).then((nameMatches) { 98 List<SearchMatch> nameMatches =
99 List<SourceReference> nameRefs = getSourceReferences(nameMatches); 99 await searchEngine.searchMemberReferences(oldName);
100 for (SourceReference reference in nameRefs) { 100 List<SourceReference> nameRefs = getSourceReferences(nameMatches);
101 // ignore resolved reference, we have already updated it 101 for (SourceReference reference in nameRefs) {
102 if (reference.isResolved) { 102 // ignore resolved reference, we have already updated it
103 if (reference.isResolved) {
104 continue;
105 }
106 // check the element being renamed is accessible
107 {
108 LibraryElement whereLibrary = reference.element.library;
109 if (!element.isAccessibleIn(whereLibrary)) {
103 continue; 110 continue;
104 } 111 }
105 // check the element being renamed is accessible
106 {
107 LibraryElement whereLibrary = reference.element.library;
108 if (!element.isAccessibleIn(whereLibrary)) {
109 continue;
110 }
111 }
112 // add edit
113 reference.addEdit(change, newName, id: _newPotentialId());
114 } 112 }
115 }); 113 // add edit
114 reference.addEdit(change, newName, id: _newPotentialId());
115 }
116 } 116 }
117 117
118 String _newPotentialId() { 118 String _newPotentialId() {
119 String id = potentialEditIds.length.toString(); 119 String id = potentialEditIds.length.toString();
120 potentialEditIds.add(id); 120 potentialEditIds.add(id);
121 return id; 121 return id;
122 } 122 }
123 } 123 }
124 124
125 125
(...skipping 16 matching lines...) Expand all
142 : isRename = false, 142 : isRename = false,
143 element = null, 143 element = null,
144 elementKind = ElementKind.METHOD; 144 elementKind = ElementKind.METHOD;
145 145
146 _ClassMemberValidator.forRename(this.searchEngine, Element element, this.name) 146 _ClassMemberValidator.forRename(this.searchEngine, Element element, this.name)
147 : isRename = true, 147 : isRename = true,
148 element = element, 148 element = element,
149 elementClass = element.enclosingElement, 149 elementClass = element.enclosingElement,
150 elementKind = element.kind; 150 elementKind = element.kind;
151 151
152 Future<RefactoringStatus> validate() { 152 Future<RefactoringStatus> validate() async {
153 RefactoringStatus result = new RefactoringStatus(); 153 RefactoringStatus result = new RefactoringStatus();
154 // check if there is a member with "newName" in the same ClassElement 154 // check if there is a member with "newName" in the same ClassElement
155 for (Element newNameMember in getChildren(elementClass, name)) { 155 for (Element newNameMember in getChildren(elementClass, name)) {
156 result.addError( 156 result.addError(
157 format( 157 format(
158 "Class '{0}' already declares {1} with name '{2}'.", 158 "Class '{0}' already declares {1} with name '{2}'.",
159 elementClass.displayName, 159 elementClass.displayName,
160 getElementKindName(newNameMember), 160 getElementKindName(newNameMember),
161 name), 161 name),
162 newLocation_fromElement(newNameMember)); 162 newLocation_fromElement(newNameMember));
163 } 163 }
164 // do chained computations 164 // do chained computations
165 Set<ClassElement> superClasses = getSuperClasses(elementClass); 165 Set<ClassElement> superClasses = getSuperClasses(elementClass);
166 Set<ClassElement> subClasses; 166 await _prepareReferences();
167 return _prepareReferences().then((_) { 167 Set<ClassElement> subClasses =
168 return getSubClasses(searchEngine, elementClass).then((_subs) { 168 await getSubClasses(searchEngine, elementClass);
169 subClasses = _subs; 169 // check shadowing in hierarchy
170 }); 170 List<SearchMatch> declarations =
171 }).then((_) { 171 await searchEngine.searchElementDeclarations(name);
172 // check shadowing in hierarchy 172 for (SearchMatch declaration in declarations) {
173 return searchEngine.searchElementDeclarations(name).then((decls) { 173 Element nameElement = getSyntheticAccessorVariable(declaration.element);
174 for (SearchMatch decl in decls) { 174 Element nameClass = nameElement.enclosingElement;
175 Element nameElement = getSyntheticAccessorVariable(decl.element); 175 // renamed Element shadows member of superclass
176 Element nameClass = nameElement.enclosingElement; 176 if (superClasses.contains(nameClass)) {
177 // renamed Element shadows member of superclass 177 result.addError(
178 if (superClasses.contains(nameClass)) { 178 format(
179 result.addError( 179 isRename ?
180 format( 180 "Renamed {0} will shadow {1} '{2}'." :
181 isRename ? 181 "Created {0} will shadow {1} '{2}'.",
182 "Renamed {0} will shadow {1} '{2}'." : 182 elementKind.displayName,
183 "Created {0} will shadow {1} '{2}'.", 183 getElementKindName(nameElement),
184 elementKind.displayName, 184 getElementQualifiedName(nameElement)),
185 getElementKindName(nameElement), 185 newLocation_fromElement(nameElement));
186 getElementQualifiedName(nameElement)), 186 }
187 newLocation_fromElement(nameElement)); 187 // renamed Element is shadowed by member of subclass
188 } 188 if (isRename && subClasses.contains(nameClass)) {
189 // renamed Element is shadowed by member of subclass 189 result.addError(
190 if (isRename && subClasses.contains(nameClass)) { 190 format(
191 result.addError( 191 "Renamed {0} will be shadowed by {1} '{2}'.",
192 format( 192 elementKind.displayName,
193 "Renamed {0} will be shadowed by {1} '{2}'.", 193 getElementKindName(nameElement),
194 elementKind.displayName, 194 getElementQualifiedName(nameElement)),
195 getElementKindName(nameElement), 195 newLocation_fromElement(nameElement));
196 getElementQualifiedName(nameElement)), 196 }
197 newLocation_fromElement(nameElement)); 197 // renamed Element is shadowed by local
198 } 198 if (nameElement is LocalElement) {
199 // renamed Element is shadowed by local 199 LocalElement localElement = nameElement;
200 if (nameElement is LocalElement) { 200 ClassElement enclosingClass =
201 LocalElement localElement = nameElement; 201 nameElement.getAncestor((element) => element is ClassElement);
202 ClassElement enclosingClass = 202 if (enclosingClass == elementClass ||
203 nameElement.getAncestor((element) => element is ClassElement); 203 subClasses.contains(enclosingClass)) {
204 if (enclosingClass == elementClass || 204 for (SearchMatch reference in references) {
205 subClasses.contains(enclosingClass)) { 205 if (isReferenceInLocalRange(localElement, reference)) {
206 for (SearchMatch reference in references) { 206 result.addError(
207 if (isReferenceInLocalRange(localElement, reference)) { 207 format(
208 result.addError( 208 "Usage of renamed {0} will be shadowed by {1} '{2}'.",
209 format( 209 elementKind.displayName,
210 "Usage of renamed {0} will be shadowed by {1} '{2}'.", 210 getElementKindName(localElement),
211 elementKind.displayName, 211 localElement.displayName),
212 getElementKindName(localElement), 212 newLocation_fromMatch(reference));
213 localElement.displayName),
214 newLocation_fromMatch(reference));
215 }
216 }
217 } 213 }
218 } 214 }
219 } 215 }
220 }); 216 }
221 }).then((_) => result); 217 }
218 // done
219 return result;
222 } 220 }
223 221
224 /** 222 /**
225 * Fills [elements] with [Element]s to rename. 223 * Fills [elements] with [Element]s to rename.
226 */ 224 */
227 Future _prepareElements() { 225 Future _prepareElements() async {
228 if (element is ClassMemberElement) { 226 if (element is ClassMemberElement) {
229 return getHierarchyMembers( 227 elements = await getHierarchyMembers(searchEngine, element);
230 searchEngine,
231 element).then((Set<Element> elements) {
232 this.elements = elements;
233 });
234 } else { 228 } else {
235 elements = new Set.from([element]); 229 elements = new Set.from([element]);
236 return new Future.value();
237 } 230 }
238 } 231 }
239 232
240 /** 233 /**
241 * Fills [references] with all references to [elements]. 234 * Fills [references] with all references to [elements].
242 */ 235 */
243 Future _prepareReferences() { 236 Future _prepareReferences() async {
244 if (!isRename) { 237 if (!isRename) {
245 return new Future.value(); 238 return new Future.value();
246 } 239 }
247 return _prepareElements().then((_) { 240 await _prepareElements();
248 return Future.forEach(elements, (Element element) { 241 await Future.forEach(elements, (Element element) async {
249 return searchEngine.searchReferences(element).then((references) { 242 List<SearchMatch> elementReferences =
250 this.references.addAll(references); 243 await searchEngine.searchReferences(element);
251 }); 244 references.addAll(elementReferences);
252 });
253 }); 245 });
254 } 246 }
255 } 247 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698