| 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 |