| 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_local; | 5 library services.src.refactoring.rename_local; |
| 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 import 'package:analysis_server/src/services/correction/status.dart'; | 10 import 'package:analysis_server/src/services/correction/status.dart'; |
| 11 import 'package:analysis_server/src/services/correction/util.dart'; | 11 import 'package:analysis_server/src/services/correction/util.dart'; |
| 12 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart
'; | 12 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart
'; |
| 13 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; | 13 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; |
| 14 import 'package:analysis_server/src/services/refactoring/rename.dart'; | 14 import 'package:analysis_server/src/services/refactoring/rename.dart'; |
| 15 import 'package:analysis_server/src/services/search/hierarchy.dart'; | 15 import 'package:analysis_server/src/services/search/hierarchy.dart'; |
| 16 import 'package:analysis_server/src/services/search/search_engine.dart'; | 16 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| 17 import 'package:analyzer/src/generated/ast.dart'; | 17 import 'package:analyzer/src/generated/ast.dart'; |
| 18 import 'package:analyzer/src/generated/element.dart'; | 18 import 'package:analyzer/src/generated/element.dart'; |
| 19 import 'package:analyzer/src/generated/source.dart'; | 19 import 'package:analyzer/src/generated/source.dart'; |
| 20 | 20 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 21 | 21 |
| 22 /** | 22 /** |
| 23 * A [Refactoring] for renaming [LocalElement]s. | 23 * A [Refactoring] for renaming [LocalElement]s. |
| 24 */ | 24 */ |
| 25 class RenameLocalRefactoringImpl extends RenameRefactoringImpl { | 25 class RenameLocalRefactoringImpl extends RenameRefactoringImpl { |
| 26 Set<LocalElement> elements = new Set<LocalElement>(); |
| 27 |
| 26 RenameLocalRefactoringImpl(SearchEngine searchEngine, LocalElement element) | 28 RenameLocalRefactoringImpl(SearchEngine searchEngine, LocalElement element) |
| 27 : super(searchEngine, element); | 29 : super(searchEngine, element); |
| 28 | 30 |
| 29 @override | 31 @override |
| 30 LocalElement get element => super.element as LocalElement; | 32 LocalElement get element => super.element as LocalElement; |
| 31 | 33 |
| 32 @override | 34 @override |
| 33 String get refactoringName { | 35 String get refactoringName { |
| 34 if (element is ParameterElement) { | 36 if (element is ParameterElement) { |
| 35 return "Rename Parameter"; | 37 return "Rename Parameter"; |
| 36 } | 38 } |
| 37 if (element is FunctionElement) { | 39 if (element is FunctionElement) { |
| 38 return "Rename Local Function"; | 40 return "Rename Local Function"; |
| 39 } | 41 } |
| 40 return "Rename Local Variable"; | 42 return "Rename Local Variable"; |
| 41 } | 43 } |
| 42 | 44 |
| 43 @override | 45 @override |
| 44 Future<RefactoringStatus> checkFinalConditions() { | 46 Future<RefactoringStatus> checkFinalConditions() async { |
| 45 RefactoringStatus result = new RefactoringStatus(); | 47 RefactoringStatus result = new RefactoringStatus(); |
| 48 // prepare all elements (usually one) |
| 49 await _prepareElements(); |
| 46 // checks the resolved CompilationUnit(s) | 50 // checks the resolved CompilationUnit(s) |
| 47 Source unitSource = element.source; | 51 for (LocalElement element in elements) { |
| 48 List<Source> librarySources = context.getLibrariesContaining(unitSource); | 52 Source unitSource = element.source; |
| 49 for (Source librarySource in librarySources) { | 53 List<Source> librarySources = context.getLibrariesContaining(unitSource); |
| 50 _analyzePossibleConflicts_inLibrary(result, unitSource, librarySource); | 54 for (Source librarySource in librarySources) { |
| 55 _analyzePossibleConflicts_inLibrary( |
| 56 result, |
| 57 unitSource, |
| 58 librarySource, |
| 59 element); |
| 60 } |
| 51 } | 61 } |
| 52 return new Future.value(result); | 62 // done |
| 63 return result; |
| 53 } | 64 } |
| 54 | 65 |
| 55 @override | 66 @override |
| 56 RefactoringStatus checkNewName() { | 67 RefactoringStatus checkNewName() { |
| 57 RefactoringStatus result = super.checkNewName(); | 68 RefactoringStatus result = super.checkNewName(); |
| 58 if (element is LocalVariableElement) { | 69 if (element is LocalVariableElement) { |
| 59 result.addStatus(validateVariableName(newName)); | 70 result.addStatus(validateVariableName(newName)); |
| 60 } else if (element is ParameterElement) { | 71 } else if (element is ParameterElement) { |
| 61 result.addStatus(validateParameterName(newName)); | 72 result.addStatus(validateParameterName(newName)); |
| 62 } else if (element is FunctionElement) { | 73 } else if (element is FunctionElement) { |
| 63 result.addStatus(validateFunctionName(newName)); | 74 result.addStatus(validateFunctionName(newName)); |
| 64 } | 75 } |
| 65 return result; | 76 return result; |
| 66 } | 77 } |
| 67 | 78 |
| 68 @override | 79 @override |
| 69 Future fillChange() { | 80 Future fillChange() async { |
| 70 addDeclarationEdit(element); | 81 for (Element element in elements) { |
| 71 return searchEngine.searchReferences(element).then(addReferenceEdits); | 82 addDeclarationEdit(element); |
| 83 await searchEngine.searchReferences(element).then(addReferenceEdits); |
| 84 } |
| 72 } | 85 } |
| 73 | 86 |
| 74 void _analyzePossibleConflicts_inLibrary(RefactoringStatus result, | 87 void _analyzePossibleConflicts_inLibrary(RefactoringStatus result, |
| 75 Source unitSource, Source librarySource) { | 88 Source unitSource, Source librarySource, LocalElement element) { |
| 76 // prepare resolved unit | 89 // prepare resolved unit |
| 77 CompilationUnit unit = null; | 90 CompilationUnit unit = null; |
| 78 try { | 91 try { |
| 79 unit = context.resolveCompilationUnit2(unitSource, librarySource); | 92 unit = context.resolveCompilationUnit2(unitSource, librarySource); |
| 80 } catch (e) { | 93 } catch (e) {} |
| 81 } | |
| 82 if (unit == null) { | 94 if (unit == null) { |
| 83 return; | 95 return; |
| 84 } | 96 } |
| 85 // check for conflicts in the unit | 97 // check for conflicts in the unit |
| 86 SourceRange elementRange = element.visibleRange; | 98 SourceRange elementRange = element.visibleRange; |
| 87 unit.accept(new _ConflictValidatorVisitor(this, result, elementRange)); | 99 unit.accept(new _ConflictValidatorVisitor(this, result, elementRange)); |
| 88 } | 100 } |
| 101 |
| 102 /** |
| 103 * Fills [elements] with [Element]s to rename. |
| 104 */ |
| 105 Future _prepareElements() async { |
| 106 Element enclosing = element.enclosingElement; |
| 107 if (enclosing is MethodElement && |
| 108 element is ParameterElement && |
| 109 (element as ParameterElement).parameterKind == ParameterKind.NAMED) { |
| 110 // prepare hierarchy methods |
| 111 Set<ClassMemberElement> methods = |
| 112 await getHierarchyMembers(searchEngine, enclosing); |
| 113 // add named parameter from each method |
| 114 for (ClassMemberElement method in methods) { |
| 115 if (method is MethodElement) { |
| 116 for (ParameterElement parameter in method.parameters) { |
| 117 if (parameter.parameterKind == ParameterKind.NAMED && |
| 118 parameter.name == element.name) { |
| 119 elements.add(parameter); |
| 120 } |
| 121 } |
| 122 } |
| 123 } |
| 124 } else { |
| 125 elements = new Set.from([element]); |
| 126 } |
| 127 } |
| 89 } | 128 } |
| 90 | 129 |
| 91 | |
| 92 class _ConflictValidatorVisitor extends RecursiveAstVisitor { | 130 class _ConflictValidatorVisitor extends RecursiveAstVisitor { |
| 93 final RenameLocalRefactoringImpl refactoring; | 131 final RenameLocalRefactoringImpl refactoring; |
| 94 final RefactoringStatus result; | 132 final RefactoringStatus result; |
| 95 final SourceRange elementRange; | 133 final SourceRange elementRange; |
| 96 final Set<Element> conflictingLocals = new Set<Element>(); | 134 final Set<Element> conflictingLocals = new Set<Element>(); |
| 97 | 135 |
| 98 _ConflictValidatorVisitor(this.refactoring, this.result, this.elementRange); | 136 _ConflictValidatorVisitor(this.refactoring, this.result, this.elementRange); |
| 99 | 137 |
| 100 @override | 138 @override |
| 101 visitSimpleIdentifier(SimpleIdentifier node) { | 139 visitSimpleIdentifier(SimpleIdentifier node) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 128 '"$nameElementSourceName" will be shadowed by renamed $refKind.'
; | 166 '"$nameElementSourceName" will be shadowed by renamed $refKind.'
; |
| 129 result.addError(message, newLocation_fromNode(node)); | 167 result.addError(message, newLocation_fromNode(node)); |
| 130 } | 168 } |
| 131 } | 169 } |
| 132 } | 170 } |
| 133 | 171 |
| 134 static bool _isNamedExpressionName(SimpleIdentifier node) { | 172 static bool _isNamedExpressionName(SimpleIdentifier node) { |
| 135 return node.parent is Label && node.parent.parent is NamedExpression; | 173 return node.parent is Label && node.parent.parent is NamedExpression; |
| 136 } | 174 } |
| 137 } | 175 } |
| OLD | NEW |