| Index: pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
|
| diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
|
| index 6080479a09d14f7fa36e027073b89e5303d204ad..06b88c0d01bd92033d368cb2445a1697be2ff547 100644
|
| --- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
|
| +++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
|
| @@ -192,13 +192,27 @@ class _ClassMemberValidator {
|
| newLocation_fromElement(elementClass));
|
| }
|
| }
|
| - // check shadowing in hierarchy
|
| + // usage of the renamed Element is shadowed by a local element
|
| + {
|
| + _MatchShadowedByLocal conflict = _getShadowingLocalElement();
|
| + if (conflict != null) {
|
| + LocalElement localElement = conflict.localElement;
|
| + result.addError(
|
| + format(
|
| + "Usage of renamed {0} will be shadowed by {1} '{2}'.",
|
| + elementKind.displayName,
|
| + getElementKindName(localElement),
|
| + localElement.displayName),
|
| + newLocation_fromMatch(conflict.match));
|
| + }
|
| + }
|
| + // check shadowing in the hierarchy
|
| List<SearchMatch> declarations =
|
| - await searchEngine.searchElementDeclarations(name);
|
| + await searchEngine.searchMemberDeclarations(name);
|
| for (SearchMatch declaration in declarations) {
|
| Element nameElement = getSyntheticAccessorVariable(declaration.element);
|
| Element nameClass = nameElement.enclosingElement;
|
| - // renamed Element shadows member of superclass
|
| + // the renamed Element shadows a member of a superclass
|
| if (superClasses.contains(nameClass)) {
|
| result.addError(
|
| format(
|
| @@ -210,7 +224,7 @@ class _ClassMemberValidator {
|
| getElementQualifiedName(nameElement)),
|
| newLocation_fromElement(nameElement));
|
| }
|
| - // renamed Element is shadowed by member of subclass
|
| + // the renamed Element is shadowed by a member of a subclass
|
| if (isRename && subClasses.contains(nameClass)) {
|
| result.addError(
|
| format(
|
| @@ -220,26 +234,6 @@ class _ClassMemberValidator {
|
| getElementQualifiedName(nameElement)),
|
| newLocation_fromElement(nameElement));
|
| }
|
| - // renamed Element is shadowed by local
|
| - if (nameElement is LocalElement) {
|
| - LocalElement localElement = nameElement;
|
| - ClassElement enclosingClass =
|
| - nameElement.getAncestor((element) => element is ClassElement);
|
| - if (enclosingClass == elementClass ||
|
| - subClasses.contains(enclosingClass)) {
|
| - for (SearchMatch reference in references) {
|
| - if (isReferenceInLocalRange(localElement, reference)) {
|
| - result.addError(
|
| - format(
|
| - "Usage of renamed {0} will be shadowed by {1} '{2}'.",
|
| - elementKind.displayName,
|
| - getElementKindName(localElement),
|
| - localElement.displayName),
|
| - newLocation_fromMatch(reference));
|
| - }
|
| - }
|
| - }
|
| - }
|
| }
|
| // visibility
|
| if (isRename) {
|
| @@ -249,6 +243,31 @@ class _ClassMemberValidator {
|
| return result;
|
| }
|
|
|
| + _MatchShadowedByLocal _getShadowingLocalElement() {
|
| + for (SearchMatch match in references) {
|
| + // qualified reference cannot be shadowed by a local element
|
| + if (match.isQualified) {
|
| + continue;
|
| + }
|
| + // check local elements of the enclosing executable
|
| + Element containingElement = match.element;
|
| + if (containingElement is ExecutableElement) {
|
| + Iterable<LocalElement> localElements = <Iterable<LocalElement>>[
|
| + containingElement.functions,
|
| + containingElement.localVariables,
|
| + containingElement.parameters
|
| + ].expand((Iterable<LocalElement> x) => x);
|
| + for (LocalElement localElement in localElements) {
|
| + if (localElement.displayName == name &&
|
| + localElement.visibleRange.intersects(match.sourceRange)) {
|
| + return new _MatchShadowedByLocal(match, localElement);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| /**
|
| * Fills [elements] with [Element]s to rename.
|
| */
|
| @@ -293,3 +312,10 @@ class _ClassMemberValidator {
|
| }
|
| }
|
| }
|
| +
|
| +class _MatchShadowedByLocal {
|
| + final SearchMatch match;
|
| + final LocalElement localElement;
|
| +
|
| + _MatchShadowedByLocal(this.match, this.localElement);
|
| +}
|
|
|