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.correction.change; | 5 library services.correction.change; |
6 | 6 |
7 import 'package:analysis_services/constants.dart'; | 7 import 'package:analysis_services/constants.dart'; |
8 import 'package:analysis_services/json.dart'; | 8 import 'package:analysis_services/json.dart'; |
9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
| 10 import 'package:collection/collection.dart'; |
10 | 11 |
11 | 12 |
12 /** | 13 /** |
13 * A description of a single change to one or more files. | 14 * A description of a single change to one or more files. |
14 */ | 15 */ |
15 class Change implements HasToJson { | 16 class Change implements HasToJson { |
16 /** | 17 /** |
17 * A textual description of the change to be applied. | 18 * A textual description of the change to be applied. |
18 */ | 19 */ |
19 final String message; | 20 final String message; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 EDITS: objectToJson(fileEdits), | 81 EDITS: objectToJson(fileEdits), |
81 LINKED_EDIT_GROUPS: objectToJson(linkedEditGroups) | 82 LINKED_EDIT_GROUPS: objectToJson(linkedEditGroups) |
82 }; | 83 }; |
83 if (selection != null) { | 84 if (selection != null) { |
84 json[SELECTION] = selection.toJson(); | 85 json[SELECTION] = selection.toJson(); |
85 } | 86 } |
86 return json; | 87 return json; |
87 } | 88 } |
88 | 89 |
89 @override | 90 @override |
90 String toString() => | 91 String toString() => 'Change(message=$message, edits=$fileEdits, ' |
91 'Change(message=$message, edits=$fileEdits, ' | 92 'linkedEditGroups=$linkedEditGroups, selection=$selection)'; |
92 'linkedEditGroups=$linkedEditGroups, selection=$selection)'; | |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 /** | 96 /** |
97 * A description of a single change to a single file. | 97 * A description of a single change to a single file. |
98 */ | 98 */ |
99 class Edit implements HasToJson { | 99 class Edit implements HasToJson { |
100 /** | 100 /** |
101 * The offset of the region to be modified. | 101 * The offset of the region to be modified. |
102 */ | 102 */ |
103 final int offset; | 103 final int offset; |
104 | 104 |
105 /** | 105 /** |
106 * The length of the region to be modified. | 106 * The length of the region to be modified. |
107 */ | 107 */ |
108 final int length; | 108 final int length; |
109 | 109 |
110 /** | 110 /** |
111 * The text that is to replace the specified region in the original text. | 111 * The text that is to replace the specified region in the original text. |
112 */ | 112 */ |
113 final String replacement; | 113 final String replacement; |
114 | 114 |
115 Edit(this.offset, this.length, this.replacement); | 115 Edit(this.offset, this.length, this.replacement); |
116 | 116 |
117 Edit.range(SourceRange range, String replacement) : this( | 117 Edit.range(SourceRange range, String replacement) : this(range.offset, |
118 range.offset, | 118 range.length, replacement); |
119 range.length, | |
120 replacement); | |
121 | 119 |
122 /** | 120 /** |
123 * The offset of a character immediately after the region to be modified. | 121 * The offset of a character immediately after the region to be modified. |
124 */ | 122 */ |
125 int get end => offset + length; | 123 int get end => offset + length; |
126 | 124 |
127 bool operator ==(other) { | 125 bool operator ==(other) { |
128 if (other is Edit) { | 126 if (other is Edit) { |
129 return other.offset == offset && | 127 return other.offset == offset && other.length == length && |
130 other.length == length && | |
131 other.replacement == replacement; | 128 other.replacement == replacement; |
132 } | 129 } |
133 return false; | 130 return false; |
134 } | 131 } |
135 | 132 |
136 @override | 133 @override |
137 Map<String, Object> toJson() { | 134 Map<String, Object> toJson() { |
138 return { | 135 return { |
139 OFFSET: offset, | 136 OFFSET: offset, |
140 LENGTH: length, | 137 LENGTH: length, |
141 REPLACEMENT: replacement | 138 REPLACEMENT: replacement |
142 }; | 139 }; |
143 } | 140 } |
144 | 141 |
145 @override | 142 @override |
146 String toString() => | 143 String toString() => |
147 "Edit(offset=$offset, length=$length, replacement=:>$replacement<:)"; | 144 "Edit(offset=$offset, length=$length, replacement=:>$replacement<:)"; |
| 145 |
| 146 /** |
| 147 * Get the result of applying the edit to the given [code]. |
| 148 */ |
| 149 String apply(String code) => code.substring(0, offset) + replacement + |
| 150 code.substring(end); |
| 151 |
| 152 /** |
| 153 * Get the result of applying a set of [edits] to the given [code]. Edits |
| 154 * are applied in the order they appear in [edits]. |
| 155 */ |
| 156 static String applySequence(String code, Iterable<Edit> edits) { |
| 157 edits.forEach((Edit edit) { |
| 158 code = edit.apply(code); |
| 159 }); |
| 160 return code; |
| 161 } |
| 162 |
| 163 /** |
| 164 * Get the result of applying a set of [edits] to the given [code]. Edits |
| 165 * are applied in the order of decreasing offset. |
| 166 */ |
| 167 static String applySorted(String code, Iterable<Edit> edits) { |
| 168 List<Edit> sortedEdits = edits.toList(); |
| 169 mergeSort(sortedEdits, compare: (a, b) => a.offset - b.offset); |
| 170 return Edit.applySequence(code, sortedEdits.reversed); |
| 171 } |
148 } | 172 } |
149 | 173 |
150 | 174 |
151 /** | 175 /** |
152 * A description of a set of changes to a single file. | 176 * A description of a set of changes to a single file. |
153 */ | 177 */ |
154 class FileEdit implements HasToJson { | 178 class FileEdit implements HasToJson { |
155 /** | 179 /** |
156 * The file to be modified. | 180 * The file to be modified. |
157 */ | 181 */ |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 Map<String, Object> toJson() { | 234 Map<String, Object> toJson() { |
211 return { | 235 return { |
212 ID: id, | 236 ID: id, |
213 LENGTH: length, | 237 LENGTH: length, |
214 POSITIONS: objectToJson(positions), | 238 POSITIONS: objectToJson(positions), |
215 SUGGESTIONS: objectToJson(suggestions) | 239 SUGGESTIONS: objectToJson(suggestions) |
216 }; | 240 }; |
217 } | 241 } |
218 | 242 |
219 @override | 243 @override |
220 String toString() => | 244 String toString() => 'LinkedEditGroup(id=$id, length=$length, ' |
221 'LinkedEditGroup(id=$id, length=$length, ' | 245 'positions=$positions, suggestions=$suggestions)'; |
222 'positions=$positions, suggestions=$suggestions)'; | |
223 } | 246 } |
224 | 247 |
225 | 248 |
226 /** | 249 /** |
227 * A suggestion of a value that could be used to replace all of the linked edit | 250 * A suggestion of a value that could be used to replace all of the linked edit |
228 * regions in a [LinkedEditGroup]. | 251 * regions in a [LinkedEditGroup]. |
229 */ | 252 */ |
230 class LinkedEditSuggestion implements HasToJson { | 253 class LinkedEditSuggestion implements HasToJson { |
231 final LinkedEditSuggestionKind kind; | 254 final LinkedEditSuggestionKind kind; |
232 final String value; | 255 final String value; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 Map<String, Object> toJson() { | 319 Map<String, Object> toJson() { |
297 return { | 320 return { |
298 FILE: file, | 321 FILE: file, |
299 OFFSET: offset | 322 OFFSET: offset |
300 }; | 323 }; |
301 } | 324 } |
302 | 325 |
303 @override | 326 @override |
304 String toString() => 'Position(file=$file, offset=$offset)'; | 327 String toString() => 'Position(file=$file, offset=$offset)'; |
305 } | 328 } |
OLD | NEW |