| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library services.src.refactoring.rename_local; | 8 library services.src.refactoring.rename_local; |
| 9 | 9 |
| 10 import 'dart:async'; |
| 11 |
| 10 import 'package:analysis_services/correction/change.dart'; | 12 import 'package:analysis_services/correction/change.dart'; |
| 11 import 'package:analysis_services/correction/status.dart'; | 13 import 'package:analysis_services/correction/status.dart'; |
| 12 import 'package:analysis_services/refactoring/refactoring.dart'; | 14 import 'package:analysis_services/refactoring/refactoring.dart'; |
| 15 import 'package:analysis_services/search/hierarchy.dart'; |
| 13 import 'package:analysis_services/search/search_engine.dart'; | 16 import 'package:analysis_services/search/search_engine.dart'; |
| 17 import 'package:analysis_services/src/correction/util.dart'; |
| 14 import 'package:analysis_services/src/refactoring/rename.dart'; | 18 import 'package:analysis_services/src/refactoring/rename.dart'; |
| 19 import 'package:analyzer/src/generated/ast.dart'; |
| 15 import 'package:analyzer/src/generated/element.dart'; | 20 import 'package:analyzer/src/generated/element.dart'; |
| 21 import 'package:analyzer/src/generated/source.dart'; |
| 16 | 22 |
| 17 | 23 |
| 18 /** | 24 /** |
| 19 * A [Refactoring] for renaming [LocalElement]s. | 25 * A [Refactoring] for renaming [LocalElement]s. |
| 20 */ | 26 */ |
| 21 class RenameLocalRefactoringImpl extends RenameRefactoringImpl { | 27 class RenameLocalRefactoringImpl extends RenameRefactoringImpl { |
| 22 RenameLocalRefactoringImpl(SearchEngine searchEngine, LocalElement element) : | 28 RenameLocalRefactoringImpl(SearchEngine searchEngine, LocalElement element) : |
| 23 super( | 29 super( |
| 24 searchEngine, | 30 searchEngine, |
| 25 element); | 31 element); |
| 26 | 32 |
| 27 @override | 33 @override |
| 28 LocalElement get element => super.element as LocalElement; | 34 LocalElement get element => super.element as LocalElement; |
| 29 | 35 |
| 30 @override | 36 @override |
| 31 String get refactoringName { | 37 String get refactoringName { |
| 32 if (element is ParameterElement) { | 38 if (element is ParameterElement) { |
| 33 return "Rename Parameter"; | 39 return "Rename Parameter"; |
| 34 } | 40 } |
| 35 if (element is FunctionElement) { | 41 if (element is FunctionElement) { |
| 36 return "Rename Local Function"; | 42 return "Rename Local Function"; |
| 37 } | 43 } |
| 38 return "Rename Local Variable"; | 44 return "Rename Local Variable"; |
| 39 } | 45 } |
| 40 | 46 |
| 41 @override | 47 @override |
| 42 RefactoringStatus checkFinalConditions() { | 48 Future<RefactoringStatus> checkFinalConditions() { |
| 43 // TODO: implement checkFinalConditions | 49 RefactoringStatus result = new RefactoringStatus(); |
| 44 } | 50 // checks the resolved CompilationUnit(s) |
| 45 | 51 Source unitSource = element.source; |
| 46 // TODO: implement refactoringName | 52 List<Source> librarySources = context.getLibrariesContaining(unitSource); |
| 47 @override | 53 for (Source librarySource in librarySources) { |
| 48 Change createChange() { | 54 _analyzePossibleConflicts_inLibrary(result, unitSource, librarySource); |
| 49 // TODO: implement createChange | 55 } |
| 56 return new Future.value(result); |
| 50 } | 57 } |
| 51 | 58 |
| 52 @override | 59 @override |
| 53 bool requiresPreview() { | 60 Future<Change> createChange() { |
| 54 // TODO: implement requiresPreview | 61 Change change = new Change(refactoringName); |
| 62 // update declaration |
| 63 addDeclarationEdit(change, element); |
| 64 // update references |
| 65 return searchEngine.searchReferences(element).then((refMatches) { |
| 66 List<SourceReference> references = getSourceReferences(refMatches); |
| 67 for (SourceReference reference in references) { |
| 68 addReferenceEdit(change, reference); |
| 69 } |
| 70 return change; |
| 71 }); |
| 72 } |
| 73 |
| 74 void _analyzePossibleConflicts_inLibrary(RefactoringStatus result, |
| 75 Source unitSource, Source librarySource) { |
| 76 // prepare resolved unit |
| 77 CompilationUnit unit = null; |
| 78 try { |
| 79 unit = context.resolveCompilationUnit2(unitSource, librarySource); |
| 80 } catch (e) { |
| 81 } |
| 82 if (unit == null) { |
| 83 return; |
| 84 } |
| 85 // check for conflicts in the unit |
| 86 SourceRange elementRange = element.visibleRange; |
| 87 unit.accept(new _ConflictValidatorVisitor(this, result, elementRange)); |
| 55 } | 88 } |
| 56 } | 89 } |
| 90 |
| 91 |
| 92 class _ConflictValidatorVisitor extends RecursiveAstVisitor<Object> { |
| 93 final RenameLocalRefactoringImpl refactoring; |
| 94 final RefactoringStatus result; |
| 95 final SourceRange elementRange; |
| 96 |
| 97 _ConflictValidatorVisitor(this.refactoring, this.result, this.elementRange); |
| 98 |
| 99 @override |
| 100 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 101 Element nodeElement = node.bestElement; |
| 102 String newName = refactoring.newName; |
| 103 if (nodeElement != null && nodeElement.name == newName) { |
| 104 // duplicate declaration |
| 105 if (haveIntersectingRanges(refactoring.element, nodeElement)) { |
| 106 String nodeKind = nodeElement.kind.displayName; |
| 107 String message = "Duplicate ${nodeKind} '$newName'."; |
| 108 result.addError( |
| 109 message, |
| 110 new RefactoringStatusContext.forElement(nodeElement)); |
| 111 return null; |
| 112 } |
| 113 // shadowing referenced element |
| 114 if (elementRange.contains(node.offset) && !node.isQualified) { |
| 115 nodeElement = getSyntheticAccessorVariable(nodeElement); |
| 116 String nodeKind = nodeElement.kind.displayName; |
| 117 String nodeName = getElementQualifiedName(nodeElement); |
| 118 String nameElementSourceName = nodeElement.source.shortName; |
| 119 String refKind = refactoring.element.kind.displayName; |
| 120 String message = |
| 121 'Usage of $nodeKind "$nodeName" declared in ' |
| 122 '"$nameElementSourceName" will be shadowed by renamed $refKind.'
; |
| 123 result.addError(message, new RefactoringStatusContext.forNode(node)); |
| 124 } |
| 125 } |
| 126 return null; |
| 127 } |
| 128 } |
| OLD | NEW |