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.sort_members; | 5 library services.src.refactoring.sort_members; |
6 | 6 |
7 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element; | 7 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element; |
8 import 'package:analysis_server/src/services/correction/strings.dart'; | 8 import 'package:analysis_server/src/services/correction/strings.dart'; |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | |
11 | 10 |
12 /** | 11 /** |
13 * Sorter for unit/class members. | 12 * Sorter for unit/class members. |
14 */ | 13 */ |
15 class MemberSorter { | 14 class MemberSorter { |
16 static List<_PriorityItem> _PRIORITY_ITEMS = [ | 15 static List<_PriorityItem> _PRIORITY_ITEMS = [ |
17 new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_MAIN, false), | 16 new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_MAIN, false), |
18 new _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, false), | 17 new _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, false), |
19 new _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, true), | 18 new _PriorityItem(false, _MemberKind.UNIT_VARIABLE_CONST, true), |
20 new _PriorityItem(false, _MemberKind.UNIT_VARIABLE, false), | 19 new _PriorityItem(false, _MemberKind.UNIT_VARIABLE, false), |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 153 } |
155 } | 154 } |
156 // do sort | 155 // do sort |
157 _sortAndReorderMembers(members); | 156 _sortAndReorderMembers(members); |
158 } | 157 } |
159 | 158 |
160 /** | 159 /** |
161 * Sorts all [Directive]s. | 160 * Sorts all [Directive]s. |
162 */ | 161 */ |
163 void _sortUnitDirectives() { | 162 void _sortUnitDirectives() { |
| 163 bool hasLibraryDirective = false; |
164 List<_DirectiveInfo> directives = []; | 164 List<_DirectiveInfo> directives = []; |
165 for (Directive directive in unit.directives) { | 165 for (Directive directive in unit.directives) { |
| 166 if (directive is LibraryDirective) { |
| 167 hasLibraryDirective = true; |
| 168 } |
166 if (directive is! UriBasedDirective) { | 169 if (directive is! UriBasedDirective) { |
167 continue; | 170 continue; |
168 } | 171 } |
169 UriBasedDirective uriDirective = directive as UriBasedDirective; | 172 UriBasedDirective uriDirective = directive as UriBasedDirective; |
170 String uriContent = uriDirective.uri.stringValue; | 173 String uriContent = uriDirective.uri.stringValue; |
171 _DirectivePriority kind = null; | 174 _DirectivePriority kind = null; |
172 if (directive is ImportDirective) { | 175 if (directive is ImportDirective) { |
173 if (uriContent.startsWith("dart:")) { | 176 if (uriContent.startsWith("dart:")) { |
174 kind = _DirectivePriority.IMPORT_SDK; | 177 kind = _DirectivePriority.IMPORT_SDK; |
175 } else if (uriContent.startsWith("package:")) { | 178 } else if (uriContent.startsWith("package:")) { |
(...skipping 12 matching lines...) Expand all Loading... |
188 } else if (uriContent.contains('://')) { | 191 } else if (uriContent.contains('://')) { |
189 kind = _DirectivePriority.EXPORT_OTHER; | 192 kind = _DirectivePriority.EXPORT_OTHER; |
190 } else { | 193 } else { |
191 kind = _DirectivePriority.EXPORT_REL; | 194 kind = _DirectivePriority.EXPORT_REL; |
192 } | 195 } |
193 } | 196 } |
194 if (directive is PartDirective) { | 197 if (directive is PartDirective) { |
195 kind = _DirectivePriority.PART; | 198 kind = _DirectivePriority.PART; |
196 } | 199 } |
197 if (kind != null) { | 200 if (kind != null) { |
198 int offset = directive.offset; | 201 String documentationText; |
199 int length = directive.length; | 202 if (directive.documentationComment != null) { |
| 203 documentationText = code.substring( |
| 204 directive.documentationComment.offset, |
| 205 directive.documentationComment.end); |
| 206 } |
| 207 int offset = directive.firstTokenAfterCommentAndMetadata.offset; |
| 208 int length = directive.end - offset; |
200 String text = code.substring(offset, offset + length); | 209 String text = code.substring(offset, offset + length); |
201 directives.add(new _DirectiveInfo(directive, kind, uriContent, text)); | 210 directives.add(new _DirectiveInfo( |
| 211 directive, kind, uriContent, documentationText, text)); |
202 } | 212 } |
203 } | 213 } |
204 // nothing to do | 214 // nothing to do |
205 if (directives.isEmpty) { | 215 if (directives.isEmpty) { |
206 return; | 216 return; |
207 } | 217 } |
208 int firstDirectiveOffset = directives[0].directive.offset; | 218 int firstDirectiveOffset = directives[0].directive.offset; |
209 int lastDirectiveEnd = directives[directives.length - 1].directive.end; | 219 int lastDirectiveEnd = directives[directives.length - 1].directive.end; |
| 220 // Without a library directive, the library comment is the comment of the |
| 221 // first directive. |
| 222 _DirectiveInfo libraryDocumentationDirective; |
| 223 if (!hasLibraryDirective && directives.isNotEmpty) { |
| 224 libraryDocumentationDirective = directives.first; |
| 225 } |
210 // do sort | 226 // do sort |
211 directives.sort(); | 227 directives.sort(); |
212 // append directives with grouping | 228 // append directives with grouping |
213 String directivesCode; | 229 String directivesCode; |
214 { | 230 { |
215 StringBuffer sb = new StringBuffer(); | 231 StringBuffer sb = new StringBuffer(); |
216 String endOfLine = this.endOfLine; | 232 String endOfLine = this.endOfLine; |
217 _DirectivePriority currentPriority = null; | 233 _DirectivePriority currentPriority = null; |
| 234 bool firstOutputDirective = true; |
218 for (_DirectiveInfo directive in directives) { | 235 for (_DirectiveInfo directive in directives) { |
219 if (currentPriority != directive.priority) { | 236 if (currentPriority != directive.priority) { |
220 if (sb.length != 0) { | 237 if (sb.length != 0) { |
221 sb.write(endOfLine); | 238 sb.write(endOfLine); |
222 } | 239 } |
223 currentPriority = directive.priority; | 240 currentPriority = directive.priority; |
224 } | 241 } |
| 242 if (directive != libraryDocumentationDirective && |
| 243 directive.documentationText != null) { |
| 244 sb.write(directive.documentationText); |
| 245 sb.write(endOfLine); |
| 246 } |
| 247 if (firstOutputDirective) { |
| 248 firstOutputDirective = false; |
| 249 if (libraryDocumentationDirective != null && |
| 250 libraryDocumentationDirective.documentationText != null) { |
| 251 sb.write(libraryDocumentationDirective.documentationText); |
| 252 sb.write(endOfLine); |
| 253 } |
| 254 } |
225 sb.write(directive.text); | 255 sb.write(directive.text); |
226 sb.write(endOfLine); | 256 sb.write(endOfLine); |
227 } | 257 } |
228 directivesCode = sb.toString(); | 258 directivesCode = sb.toString(); |
229 directivesCode = directivesCode.trimRight(); | 259 directivesCode = directivesCode.trimRight(); |
230 } | 260 } |
231 // append comment tokens which otherwise would be removed completely | |
232 { | |
233 bool firstCommentToken = true; | |
234 Token token = unit.beginToken; | |
235 while (token != null && | |
236 token.type != TokenType.EOF && | |
237 token.end < lastDirectiveEnd) { | |
238 Token commentToken = token.precedingComments; | |
239 while (commentToken != null) { | |
240 int offset = commentToken.offset; | |
241 int end = commentToken.end; | |
242 if (offset > firstDirectiveOffset && offset < lastDirectiveEnd) { | |
243 if (firstCommentToken) { | |
244 directivesCode += endOfLine; | |
245 firstCommentToken = false; | |
246 } | |
247 directivesCode += code.substring(offset, end) + endOfLine; | |
248 } | |
249 commentToken = commentToken.next; | |
250 } | |
251 token = token.next; | |
252 } | |
253 } | |
254 // prepare code | 261 // prepare code |
255 String beforeDirectives = code.substring(0, firstDirectiveOffset); | 262 String beforeDirectives = code.substring(0, firstDirectiveOffset); |
256 String afterDirectives = code.substring(lastDirectiveEnd); | 263 String afterDirectives = code.substring(lastDirectiveEnd); |
257 code = beforeDirectives + directivesCode + afterDirectives; | 264 code = beforeDirectives + directivesCode + afterDirectives; |
258 } | 265 } |
259 | 266 |
260 /** | 267 /** |
261 * Sorts all [CompilationUnitMember]s. | 268 * Sorts all [CompilationUnitMember]s. |
262 */ | 269 */ |
263 void _sortUnitMembers() { | 270 void _sortUnitMembers() { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 return priority1 - priority2; | 368 return priority1 - priority2; |
362 }); | 369 }); |
363 return membersSorted; | 370 return membersSorted; |
364 } | 371 } |
365 } | 372 } |
366 | 373 |
367 class _DirectiveInfo implements Comparable<_DirectiveInfo> { | 374 class _DirectiveInfo implements Comparable<_DirectiveInfo> { |
368 final Directive directive; | 375 final Directive directive; |
369 final _DirectivePriority priority; | 376 final _DirectivePriority priority; |
370 final String uri; | 377 final String uri; |
| 378 final String documentationText; |
371 final String text; | 379 final String text; |
372 | 380 |
373 _DirectiveInfo(this.directive, this.priority, this.uri, this.text); | 381 _DirectiveInfo(this.directive, this.priority, this.uri, |
| 382 this.documentationText, this.text); |
374 | 383 |
375 @override | 384 @override |
376 int compareTo(_DirectiveInfo other) { | 385 int compareTo(_DirectiveInfo other) { |
377 if (priority == other.priority) { | 386 if (priority == other.priority) { |
378 return _compareUri(uri, other.uri); | 387 return _compareUri(uri, other.uri); |
379 } | 388 } |
380 return priority.ordinal - other.priority.ordinal; | 389 return priority.ordinal - other.priority.ordinal; |
381 } | 390 } |
382 | 391 |
383 @override | 392 @override |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 return other.kind == kind && other.isStatic == isStatic; | 494 return other.kind == kind && other.isStatic == isStatic; |
486 } | 495 } |
487 return other.kind == kind && | 496 return other.kind == kind && |
488 other.isPrivate == isPrivate && | 497 other.isPrivate == isPrivate && |
489 other.isStatic == isStatic; | 498 other.isStatic == isStatic; |
490 } | 499 } |
491 | 500 |
492 @override | 501 @override |
493 String toString() => kind.toString(); | 502 String toString() => kind.toString(); |
494 } | 503 } |
OLD | NEW |