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

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

Issue 1153253004: Issue 23389. Report error in the renamed element be invisible after rename. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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' 9 import 'package:analysis_server/src/protocol_server.dart'
10 hide Element, ElementKind; 10 hide Element, ElementKind;
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/refactoring_internal.da rt'; 15 import 'package:analysis_server/src/services/refactoring/refactoring_internal.da rt';
16 import 'package:analysis_server/src/services/refactoring/rename.dart'; 16 import 'package:analysis_server/src/services/refactoring/rename.dart';
17 import 'package:analysis_server/src/services/search/hierarchy.dart'; 17 import 'package:analysis_server/src/services/search/hierarchy.dart';
18 import 'package:analysis_server/src/services/search/search_engine.dart'; 18 import 'package:analysis_server/src/services/search/search_engine.dart';
19 import 'package:analyzer/src/generated/ast.dart' show Identifier;
19 import 'package:analyzer/src/generated/element.dart'; 20 import 'package:analyzer/src/generated/element.dart';
20 import 'package:analyzer/src/generated/java_core.dart'; 21 import 'package:analyzer/src/generated/java_core.dart';
21 22
22 /** 23 /**
23 * Checks if creating a method with the given [name] in [classElement] will 24 * Checks if creating a method with the given [name] in [classElement] will
24 * cause any conflicts. 25 * cause any conflicts.
25 */ 26 */
26 Future<RefactoringStatus> validateCreateMethod( 27 Future<RefactoringStatus> validateCreateMethod(
27 SearchEngine searchEngine, ClassElement classElement, String name) { 28 SearchEngine searchEngine, ClassElement classElement, String name) {
28 return new _ClassMemberValidator.forCreate(searchEngine, classElement, name) 29 return new _ClassMemberValidator.forCreate(searchEngine, classElement, name)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 potentialEditIds.add(id); 117 potentialEditIds.add(id);
117 return id; 118 return id;
118 } 119 }
119 } 120 }
120 121
121 /** 122 /**
122 * Helper to check if the created or renamed [Element] will cause any conflicts. 123 * Helper to check if the created or renamed [Element] will cause any conflicts.
123 */ 124 */
124 class _ClassMemberValidator { 125 class _ClassMemberValidator {
125 final SearchEngine searchEngine; 126 final SearchEngine searchEngine;
127 final LibraryElement library;
126 final Element element; 128 final Element element;
127 final ClassElement elementClass; 129 final ClassElement elementClass;
128 final ElementKind elementKind; 130 final ElementKind elementKind;
129 final String name; 131 final String name;
130 final bool isRename; 132 final bool isRename;
131 133
134 final RefactoringStatus result = new RefactoringStatus();
132 Set<Element> elements = new Set<Element>(); 135 Set<Element> elements = new Set<Element>();
133 List<SearchMatch> references = <SearchMatch>[]; 136 List<SearchMatch> references = <SearchMatch>[];
134 137
135 _ClassMemberValidator.forCreate( 138 _ClassMemberValidator.forCreate(
136 this.searchEngine, this.elementClass, this.name) 139 this.searchEngine, this.elementClass, this.name)
137 : isRename = false, 140 : isRename = false,
141 library = null,
138 element = null, 142 element = null,
139 elementKind = ElementKind.METHOD; 143 elementKind = ElementKind.METHOD;
140 144
141 _ClassMemberValidator.forRename(this.searchEngine, Element element, this.name) 145 _ClassMemberValidator.forRename(this.searchEngine, Element element, this.name)
142 : isRename = true, 146 : isRename = true,
147 library = element.library,
143 element = element, 148 element = element,
144 elementClass = element.enclosingElement, 149 elementClass = element.enclosingElement,
145 elementKind = element.kind; 150 elementKind = element.kind;
146 151
147 Future<RefactoringStatus> validate() async { 152 Future<RefactoringStatus> validate() async {
148 RefactoringStatus result = new RefactoringStatus();
149 // check if there is a member with "newName" in the same ClassElement 153 // check if there is a member with "newName" in the same ClassElement
150 for (Element newNameMember in getChildren(elementClass, name)) { 154 for (Element newNameMember in getChildren(elementClass, name)) {
151 result.addError(format( 155 result.addError(format(
152 "Class '{0}' already declares {1} with name '{2}'.", 156 "Class '{0}' already declares {1} with name '{2}'.",
153 elementClass.displayName, getElementKindName(newNameMember), 157 elementClass.displayName, getElementKindName(newNameMember),
154 name), newLocation_fromElement(newNameMember)); 158 name), newLocation_fromElement(newNameMember));
155 } 159 }
156 // do chained computations 160 // do chained computations
157 Set<ClassElement> superClasses = getSuperClasses(elementClass); 161 Set<ClassElement> superClasses = getSuperClasses(elementClass);
158 await _prepareReferences(); 162 await _prepareReferences();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 if (isReferenceInLocalRange(localElement, reference)) { 195 if (isReferenceInLocalRange(localElement, reference)) {
192 result.addError(format( 196 result.addError(format(
193 "Usage of renamed {0} will be shadowed by {1} '{2}'.", 197 "Usage of renamed {0} will be shadowed by {1} '{2}'.",
194 elementKind.displayName, getElementKindName(localElement), 198 elementKind.displayName, getElementKindName(localElement),
195 localElement.displayName), newLocation_fromMatch(reference)); 199 localElement.displayName), newLocation_fromMatch(reference));
196 } 200 }
197 } 201 }
198 } 202 }
199 } 203 }
200 } 204 }
205 // visibility
206 if (isRename) {
207 _validateWillBeInvisible();
208 }
201 // done 209 // done
202 return result; 210 return result;
203 } 211 }
204 212
205 /** 213 /**
206 * Fills [elements] with [Element]s to rename. 214 * Fills [elements] with [Element]s to rename.
207 */ 215 */
208 Future _prepareElements() async { 216 Future _prepareElements() async {
209 if (element is ClassMemberElement) { 217 if (element is ClassMemberElement) {
210 elements = await getHierarchyMembers(searchEngine, element); 218 elements = await getHierarchyMembers(searchEngine, element);
211 } else { 219 } else {
212 elements = new Set.from([element]); 220 elements = new Set.from([element]);
213 } 221 }
214 } 222 }
215 223
216 /** 224 /**
217 * Fills [references] with all references to [elements]. 225 * Fills [references] with all references to [elements].
218 */ 226 */
219 Future _prepareReferences() async { 227 Future _prepareReferences() async {
220 if (!isRename) { 228 if (!isRename) {
221 return new Future.value(); 229 return new Future.value();
222 } 230 }
223 await _prepareElements(); 231 await _prepareElements();
224 await Future.forEach(elements, (Element element) async { 232 await Future.forEach(elements, (Element element) async {
225 List<SearchMatch> elementReferences = 233 List<SearchMatch> elementReferences =
226 await searchEngine.searchReferences(element); 234 await searchEngine.searchReferences(element);
227 references.addAll(elementReferences); 235 references.addAll(elementReferences);
228 }); 236 });
229 } 237 }
238
239 /**
240 * Validates if any usage of [element] renamed to [name] will be invisible.
241 */
242 Future _validateWillBeInvisible() async {
243 if (!Identifier.isPrivateName(name)) {
244 return;
245 }
246 for (SearchMatch reference in references) {
247 Element refElement = reference.element;
248 LibraryElement refLibrary = refElement.library;
249 if (refLibrary != library) {
250 String message = format("Renamed {0} will be invisible in '{1}'.",
251 getElementKindName(element), getElementQualifiedName(refLibrary));
252 result.addError(message, newLocation_fromMatch(reference));
253 }
254 }
255 }
230 } 256 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698