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

Side by Side Diff: pkg/analysis_server/lib/src/services/refactoring/rename_unit_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
« no previous file with comments | « pkg/analysis_server/lib/src/services/refactoring/rename_import.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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' show
10 newLocation_fromElement, newLocation_fromMatch; 10 newLocation_fromElement, newLocation_fromMatch;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 this.elementKind, this.name) 133 this.elementKind, this.name)
134 : isRename = false; 134 : isRename = false;
135 135
136 _RenameUnitMemberValidator.forRename(this.searchEngine, this.element, 136 _RenameUnitMemberValidator.forRename(this.searchEngine, this.element,
137 this.name) 137 this.name)
138 : isRename = true { 138 : isRename = true {
139 library = element.getAncestor((e) => e is LibraryElement); 139 library = element.getAncestor((e) => e is LibraryElement);
140 elementKind = element.kind; 140 elementKind = element.kind;
141 } 141 }
142 142
143 Future<RefactoringStatus> validate() { 143 Future<RefactoringStatus> validate() async {
144 _validateWillConflict(); 144 _validateWillConflict();
145 List<Future> futures = <Future>[];
146 if (isRename) { 145 if (isRename) {
147 futures.add(_validateWillBeShadowed()); 146 await _validateWillBeShadowed();
148 } 147 }
149 futures.add(_validateWillShadow()); 148 await _validateWillShadow();
150 return Future.wait(futures).then((_) { 149 return result;
151 return result;
152 });
153 } 150 }
154 151
155 /** 152 /**
156 * Returns `true` if [element] is visible at the given [SearchMatch]. 153 * Returns `true` if [element] is visible at the given [SearchMatch].
157 */ 154 */
158 bool _isVisibleAt(Element element, SearchMatch at) { 155 bool _isVisibleAt(Element element, SearchMatch at) {
159 LibraryElement atLibrary = at.element.library; 156 LibraryElement atLibrary = at.element.library;
160 // may be the same library 157 // may be the same library
161 if (library == atLibrary) { 158 if (library == atLibrary) {
162 return true; 159 return true;
163 } 160 }
164 // check imports 161 // check imports
165 for (ImportElement importElement in atLibrary.imports) { 162 for (ImportElement importElement in atLibrary.imports) {
166 // ignore if imported with prefix 163 // ignore if imported with prefix
167 if (importElement.prefix != null) { 164 if (importElement.prefix != null) {
168 continue; 165 continue;
169 } 166 }
170 // check imported elements 167 // check imported elements
171 if (getImportNamespace(importElement).containsValue(element)) { 168 if (getImportNamespace(importElement).containsValue(element)) {
172 return true; 169 return true;
173 } 170 }
174 } 171 }
175 // no, it is not visible 172 // no, it is not visible
176 return false; 173 return false;
177 } 174 }
178 175
179 /** 176 /**
180 * Validates if any usage of [element] renamed to [name] will be shadowed. 177 * Validates if any usage of [element] renamed to [name] will be shadowed.
181 */ 178 */
182 Future _validateWillBeShadowed() { 179 Future _validateWillBeShadowed() async {
183 if (!isRename) { 180 if (!isRename) {
184 return new Future.value(); 181 return;
185 } 182 }
186 return searchEngine.searchReferences(element).then((references) { 183 List<SearchMatch> references = await searchEngine.searchReferences(element);
187 for (SearchMatch reference in references) { 184 for (SearchMatch reference in references) {
188 Element refElement = reference.element; 185 Element refElement = reference.element;
189 ClassElement refClass = 186 ClassElement refClass = refElement.getAncestor((e) => e is ClassElement);
190 refElement.getAncestor((e) => e is ClassElement); 187 if (refClass != null) {
191 if (refClass != null) { 188 visitChildren(refClass, (shadow) {
192 visitChildren(refClass, (shadow) { 189 if (hasDisplayName(shadow, name)) {
193 if (hasDisplayName(shadow, name)) { 190 String message = format(
194 String message = format( 191 "Reference to renamed {0} will be shadowed by {1} '{2}'.",
195 "Reference to renamed {0} will be shadowed by {1} '{2}'.", 192 getElementKindName(element),
196 getElementKindName(element), 193 getElementKindName(shadow),
197 getElementKindName(shadow), 194 getElementQualifiedName(shadow));
198 getElementQualifiedName(shadow)); 195 result.addError(message, newLocation_fromElement(shadow));
199 result.addError(message, newLocation_fromElement(shadow)); 196 }
200 } 197 });
201 });
202 }
203 } 198 }
204 }); 199 }
205 } 200 }
206 201
207 /** 202 /**
208 * Validates if [element] renamed to [name] will conflict with another 203 * Validates if [element] renamed to [name] will conflict with another
209 * top-level [Element] in the same library. 204 * top-level [Element] in the same library.
210 */ 205 */
211 void _validateWillConflict() { 206 void _validateWillConflict() {
212 visitLibraryTopLevelElements(library, (element) { 207 visitLibraryTopLevelElements(library, (element) {
213 if (hasDisplayName(element, name)) { 208 if (hasDisplayName(element, name)) {
214 String message = format( 209 String message = format(
215 "Library already declares {0} with name '{1}'.", 210 "Library already declares {0} with name '{1}'.",
216 getElementKindName(element), 211 getElementKindName(element),
217 name); 212 name);
218 result.addError(message, newLocation_fromElement(element)); 213 result.addError(message, newLocation_fromElement(element));
219 } 214 }
220 }); 215 });
221 } 216 }
222 217
223 /** 218 /**
224 * Validates if renamed [element] will shadow any [Element] named [name]. 219 * Validates if renamed [element] will shadow any [Element] named [name].
225 */ 220 */
226 Future _validateWillShadow() { 221 Future _validateWillShadow() async {
227 return searchEngine.searchMemberDeclarations(name).then((declarations) { 222 List<SearchMatch> declarations =
228 return Future.forEach(declarations, (SearchMatch declaration) { 223 await searchEngine.searchMemberDeclarations(name);
229 Element member = declaration.element; 224 for (SearchMatch declaration in declarations) {
230 ClassElement declaringClass = member.enclosingElement; 225 Element member = declaration.element;
231 return searchEngine.searchReferences(member).then((memberReferences) { 226 ClassElement declaringClass = member.enclosingElement;
232 for (SearchMatch memberReference in memberReferences) { 227 List<SearchMatch> memberReferences =
233 Element refElement = memberReference.element; 228 await searchEngine.searchReferences(member);
234 // cannot be shadowed if qualified 229 for (SearchMatch memberReference in memberReferences) {
235 if (memberReference.isQualified) { 230 Element refElement = memberReference.element;
236 continue; 231 // cannot be shadowed if qualified
237 } 232 if (memberReference.isQualified) {
238 // cannot be shadowed if declared in the same class as reference 233 continue;
239 ClassElement refClass = 234 }
240 refElement.getAncestor((e) => e is ClassElement); 235 // cannot be shadowed if declared in the same class as reference
241 if (refClass == declaringClass) { 236 ClassElement refClass =
242 continue; 237 refElement.getAncestor((e) => e is ClassElement);
243 } 238 if (refClass == declaringClass) {
244 // ignore if not visible 239 continue;
245 if (!_isVisibleAt(element, memberReference)) { 240 }
246 continue; 241 // ignore if not visible
247 } 242 if (!_isVisibleAt(element, memberReference)) {
248 // OK, reference will be shadowed be the element being renamed 243 continue;
249 String message = format( 244 }
250 isRename ? 245 // OK, reference will be shadowed be the element being renamed
251 "Renamed {0} will shadow {1} '{2}'." : 246 String message = format(
252 "Created {0} will shadow {1} '{2}'.", 247 isRename ?
253 elementKind.displayName, 248 "Renamed {0} will shadow {1} '{2}'." :
254 getElementKindName(member), 249 "Created {0} will shadow {1} '{2}'.",
255 getElementQualifiedName(member)); 250 elementKind.displayName,
256 result.addError(message, newLocation_fromMatch(memberReference)); 251 getElementKindName(member),
257 } 252 getElementQualifiedName(member));
258 }); 253 result.addError(message, newLocation_fromMatch(memberReference));
259 }); 254 }
260 }); 255 }
261 } 256 }
262 } 257 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/services/refactoring/rename_import.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698