| 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; | 5 library services.src.refactoring; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; |
| 8 | 9 |
| 10 import 'package:analysis_server/src/protocol.dart' hide Element; |
| 9 import 'package:analysis_server/src/services/correction/status.dart'; | 11 import 'package:analysis_server/src/services/correction/status.dart'; |
| 10 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; | 12 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; |
| 13 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| 14 import 'package:analyzer/src/generated/element.dart'; |
| 15 import 'package:analyzer/src/generated/source.dart'; |
| 11 | 16 |
| 12 | 17 |
| 13 /** | 18 /** |
| 19 * When a [Source] (a file) is used in more than one context, [SearchEngine] |
| 20 * will return separate [SearchMatch]s for each context. But in rename |
| 21 * refactorings we want to update each [Source] only once. |
| 22 */ |
| 23 List<SourceReference> getSourceReferences(List<SearchMatch> matches) { |
| 24 var uniqueReferences = new HashMap<SourceReference, SourceReference>(); |
| 25 for (SearchMatch match in matches) { |
| 26 Element element = match.element; |
| 27 String file = element.source.fullName; |
| 28 SourceRange range = match.sourceRange; |
| 29 SourceReference newReference = |
| 30 new SourceReference(file, range, element, match.isResolved, match.isQual
ified); |
| 31 SourceReference oldReference = uniqueReferences[newReference]; |
| 32 if (oldReference == null) { |
| 33 uniqueReferences[newReference] = newReference; |
| 34 oldReference = newReference; |
| 35 } |
| 36 } |
| 37 return uniqueReferences.keys.toList(); |
| 38 } |
| 39 |
| 40 |
| 41 /** |
| 14 * Abstract implementation of [Refactoring]. | 42 * Abstract implementation of [Refactoring]. |
| 15 */ | 43 */ |
| 16 abstract class RefactoringImpl implements Refactoring { | 44 abstract class RefactoringImpl implements Refactoring { |
| 17 final List<String> potentialEditIds = <String>[]; | 45 final List<String> potentialEditIds = <String>[]; |
| 18 | 46 |
| 19 @override | 47 @override |
| 20 Future<RefactoringStatus> checkAllConditions() { | 48 Future<RefactoringStatus> checkAllConditions() { |
| 21 RefactoringStatus result = new RefactoringStatus(); | 49 RefactoringStatus result = new RefactoringStatus(); |
| 22 return checkInitialConditions().then((status) { | 50 return checkInitialConditions().then((status) { |
| 23 result.addStatus(status); | 51 result.addStatus(status); |
| 24 if (result.hasFatalError) { | 52 if (result.hasFatalError) { |
| 25 return result; | 53 return result; |
| 26 } | 54 } |
| 27 return checkFinalConditions().then((status) { | 55 return checkFinalConditions().then((status) { |
| 28 result.addStatus(status); | 56 result.addStatus(status); |
| 29 return result; | 57 return result; |
| 30 }); | 58 }); |
| 31 }); | 59 }); |
| 32 } | 60 } |
| 33 } | 61 } |
| 62 |
| 63 |
| 64 /** |
| 65 * The [SourceRange] in some [Source]. |
| 66 */ |
| 67 class SourceReference { |
| 68 final String file; |
| 69 final SourceRange range; |
| 70 final Element element; |
| 71 final bool isResolved; |
| 72 final bool isQualified; |
| 73 |
| 74 SourceReference(this.file, this.range, this.element, this.isResolved, |
| 75 this.isQualified); |
| 76 |
| 77 @override |
| 78 int get hashCode { |
| 79 int hash = file.hashCode; |
| 80 hash = ((hash << 16) & 0xFFFFFFFF) + range.hashCode; |
| 81 return hash; |
| 82 } |
| 83 |
| 84 @override |
| 85 bool operator ==(Object other) { |
| 86 if (identical(other, this)) { |
| 87 return true; |
| 88 } |
| 89 if (other is SourceReference) { |
| 90 return other.file == file && other.range == range; |
| 91 } |
| 92 return false; |
| 93 } |
| 94 |
| 95 /** |
| 96 * Adds the [SourceEdit] to replace this reference. |
| 97 */ |
| 98 void addEdit(SourceChange change, String newText, {String id}) { |
| 99 SourceEdit edit = createEdit(newText, id: id); |
| 100 change.addElementEdit(element, edit); |
| 101 } |
| 102 |
| 103 /** |
| 104 * Returns the [SourceEdit] to replace this reference. |
| 105 */ |
| 106 SourceEdit createEdit(String newText, {String id}) { |
| 107 return new SourceEdit.range(range, newText, id: id); |
| 108 } |
| 109 |
| 110 @override |
| 111 String toString() => '${file}@${range}'; |
| 112 } |
| OLD | NEW |