| 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_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/protocol2.dart' show SourceEdit; | 9 import 'package:analysis_server/src/protocol2.dart' show SourceEdit; |
| 10 import 'package:analysis_server/src/services/correction/change.dart'; | 10 import 'package:analysis_server/src/services/correction/change.dart'; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 return "Rename Type Parameter"; | 34 return "Rename Type Parameter"; |
| 35 } | 35 } |
| 36 if (element is FieldElement) { | 36 if (element is FieldElement) { |
| 37 return "Rename Field"; | 37 return "Rename Field"; |
| 38 } | 38 } |
| 39 return "Rename Method"; | 39 return "Rename Method"; |
| 40 } | 40 } |
| 41 | 41 |
| 42 @override | 42 @override |
| 43 Future<RefactoringStatus> checkFinalConditions() { | 43 Future<RefactoringStatus> checkFinalConditions() { |
| 44 _validator = new _RenameClassMemberValidator( | 44 _validator = |
| 45 searchEngine, | 45 new _RenameClassMemberValidator(searchEngine, element, newName); |
| 46 element, | |
| 47 newName); | |
| 48 return _validator.validate(); | 46 return _validator.validate(); |
| 49 } | 47 } |
| 50 | 48 |
| 51 @override | 49 @override |
| 52 Future<RefactoringStatus> checkInitialConditions() { | 50 Future<RefactoringStatus> checkInitialConditions() { |
| 53 RefactoringStatus result = new RefactoringStatus(); | 51 RefactoringStatus result = new RefactoringStatus(); |
| 54 if (element is MethodElement && (element as MethodElement).isOperator) { | 52 if (element is MethodElement && (element as MethodElement).isOperator) { |
| 55 result.addFatalError('Cannot rename operator.'); | 53 result.addFatalError('Cannot rename operator.'); |
| 56 } | 54 } |
| 57 return new Future.value(result); | 55 return new Future.value(result); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 continue; | 99 continue; |
| 102 } | 100 } |
| 103 // check the element being renamed is accessible | 101 // check the element being renamed is accessible |
| 104 { | 102 { |
| 105 LibraryElement whereLibrary = reference.element.library; | 103 LibraryElement whereLibrary = reference.element.library; |
| 106 if (!element.isAccessibleIn(whereLibrary)) { | 104 if (!element.isAccessibleIn(whereLibrary)) { |
| 107 continue; | 105 continue; |
| 108 } | 106 } |
| 109 } | 107 } |
| 110 // add edit | 108 // add edit |
| 111 SourceEdit edit = createReferenceEdit(reference, newName, | 109 SourceEdit edit = |
| 112 id: _newPotentialId()); | 110 createReferenceEdit(reference, newName, id: _newPotentialId()); |
| 113 change.addEdit(reference.file, edit); | 111 change.addEdit(reference.file, edit); |
| 114 } | 112 } |
| 115 }).then((_) => change); | 113 }).then((_) => change); |
| 116 } | 114 } |
| 117 | 115 |
| 118 String _newPotentialId() { | 116 String _newPotentialId() { |
| 119 String id = potentialEditIds.length.toString(); | 117 String id = potentialEditIds.length.toString(); |
| 120 potentialEditIds.add(id); | 118 potentialEditIds.add(id); |
| 121 return id; | 119 return id; |
| 122 } | 120 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 144 RefactoringStatus result = new RefactoringStatus(); | 142 RefactoringStatus result = new RefactoringStatus(); |
| 145 ClassElement elementClass = element.enclosingElement; | 143 ClassElement elementClass = element.enclosingElement; |
| 146 // check if there is a member with "newName" in the same ClassElement | 144 // check if there is a member with "newName" in the same ClassElement |
| 147 for (Element newNameMember in getChildren(elementClass, newName)) { | 145 for (Element newNameMember in getChildren(elementClass, newName)) { |
| 148 result.addError( | 146 result.addError( |
| 149 format( | 147 format( |
| 150 "Class '{0}' already declares {1} with name '{2}'.", | 148 "Class '{0}' already declares {1} with name '{2}'.", |
| 151 elementClass.displayName, | 149 elementClass.displayName, |
| 152 getElementKindName(newNameMember), | 150 getElementKindName(newNameMember), |
| 153 newName), | 151 newName), |
| 154 new RefactoringStatusContext.forElement(newNameMember)); | 152 createLocation_forElement(newNameMember)); |
| 155 } | 153 } |
| 156 // do chained computations | 154 // do chained computations |
| 157 Set<ClassElement> superClasses = getSuperClasses(elementClass); | 155 Set<ClassElement> superClasses = getSuperClasses(elementClass); |
| 158 Set<ClassElement> subClasses; | 156 Set<ClassElement> subClasses; |
| 159 return _prepareReferences().then((_) { | 157 return _prepareReferences().then((_) { |
| 160 return getSubClasses(searchEngine, elementClass).then((_subs) { | 158 return getSubClasses(searchEngine, elementClass).then((_subs) { |
| 161 subClasses = _subs; | 159 subClasses = _subs; |
| 162 }); | 160 }); |
| 163 }).then((_) { | 161 }).then((_) { |
| 164 // check shadowing in hierarchy | 162 // check shadowing in hierarchy |
| 165 return searchEngine.searchElementDeclarations(newName).then((decls) { | 163 return searchEngine.searchElementDeclarations(newName).then((decls) { |
| 166 for (SearchMatch decl in decls) { | 164 for (SearchMatch decl in decls) { |
| 167 Element nameElement = getSyntheticAccessorVariable(decl.element); | 165 Element nameElement = getSyntheticAccessorVariable(decl.element); |
| 168 Element nameClass = nameElement.enclosingElement; | 166 Element nameClass = nameElement.enclosingElement; |
| 169 // renamed Element shadows member of superclass | 167 // renamed Element shadows member of superclass |
| 170 if (superClasses.contains(nameClass)) { | 168 if (superClasses.contains(nameClass)) { |
| 171 result.addError( | 169 result.addError( |
| 172 format( | 170 format( |
| 173 "Renamed {0} will shadow {1} '{2}'.", | 171 "Renamed {0} will shadow {1} '{2}'.", |
| 174 getElementKindName(element), | 172 getElementKindName(element), |
| 175 getElementKindName(nameElement), | 173 getElementKindName(nameElement), |
| 176 getElementQualifiedName(nameElement)), | 174 getElementQualifiedName(nameElement)), |
| 177 new RefactoringStatusContext.forElement(nameElement)); | 175 createLocation_forElement(nameElement)); |
| 178 } | 176 } |
| 179 // renamed Element is shadowed by member of subclass | 177 // renamed Element is shadowed by member of subclass |
| 180 if (subClasses.contains(nameClass)) { | 178 if (subClasses.contains(nameClass)) { |
| 181 result.addError( | 179 result.addError( |
| 182 format( | 180 format( |
| 183 "Renamed {0} will be shadowed by {1} '{2}'.", | 181 "Renamed {0} will be shadowed by {1} '{2}'.", |
| 184 getElementKindName(element), | 182 getElementKindName(element), |
| 185 getElementKindName(nameElement), | 183 getElementKindName(nameElement), |
| 186 getElementQualifiedName(nameElement)), | 184 getElementQualifiedName(nameElement)), |
| 187 new RefactoringStatusContext.forElement(nameElement)); | 185 createLocation_forElement(nameElement)); |
| 188 } | 186 } |
| 189 // renamed Element is shadowed by local | 187 // renamed Element is shadowed by local |
| 190 if (nameElement is LocalElement) { | 188 if (nameElement is LocalElement) { |
| 191 LocalElement localElement = nameElement; | 189 LocalElement localElement = nameElement; |
| 192 ClassElement enclosingClass = | 190 ClassElement enclosingClass = |
| 193 nameElement.getAncestor((element) => element is ClassElement); | 191 nameElement.getAncestor((element) => element is ClassElement); |
| 194 if (enclosingClass == elementClass || | 192 if (enclosingClass == elementClass || |
| 195 subClasses.contains(enclosingClass)) { | 193 subClasses.contains(enclosingClass)) { |
| 196 for (SearchMatch reference in references) { | 194 for (SearchMatch reference in references) { |
| 197 if (isReferenceInLocalRange(localElement, reference)) { | 195 if (isReferenceInLocalRange(localElement, reference)) { |
| 198 result.addError( | 196 result.addError( |
| 199 format( | 197 format( |
| 200 "Usage of renamed {0} will be shadowed by {1} '{2}'.", | 198 "Usage of renamed {0} will be shadowed by {1} '{2}'.", |
| 201 getElementKindName(element), | 199 getElementKindName(element), |
| 202 getElementKindName(localElement), | 200 getElementKindName(localElement), |
| 203 localElement.displayName), | 201 localElement.displayName), |
| 204 new RefactoringStatusContext.forMatch(reference)); | 202 createLocation_forMatch(reference)); |
| 205 } | 203 } |
| 206 } | 204 } |
| 207 } | 205 } |
| 208 } | 206 } |
| 209 } | 207 } |
| 210 }); | 208 }); |
| 211 }).then((_) => result); | 209 }).then((_) => result); |
| 212 } | 210 } |
| 213 | 211 |
| 214 /** | 212 /** |
| (...skipping 18 matching lines...) Expand all Loading... |
| 233 Future _prepareReferences() { | 231 Future _prepareReferences() { |
| 234 return _prepareElements().then((_) { | 232 return _prepareElements().then((_) { |
| 235 return Future.forEach(elements, (Element element) { | 233 return Future.forEach(elements, (Element element) { |
| 236 return searchEngine.searchReferences(element).then((references) { | 234 return searchEngine.searchReferences(element).then((references) { |
| 237 this.references.addAll(references); | 235 this.references.addAll(references); |
| 238 }); | 236 }); |
| 239 }); | 237 }); |
| 240 }); | 238 }); |
| 241 } | 239 } |
| 242 } | 240 } |
| OLD | NEW |