Chromium Code Reviews| 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.correction.util; | 8 library services.src.correction.util; |
| 9 | 9 |
| 10 import 'package:analysis_services/src/correction/source_range.dart'; | 10 import 'package:analysis_services/src/correction/source_range.dart'; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 if (node is MethodDeclaration) { | 51 if (node is MethodDeclaration) { |
| 52 return node.element; | 52 return node.element; |
| 53 } | 53 } |
| 54 node = node.parent; | 54 node = node.parent; |
| 55 } | 55 } |
| 56 return null; | 56 return null; |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 /** | 60 /** |
| 61 * Returns a namespace of the given [ExportElement]. | |
| 62 */ | |
| 63 Map<String, Element> getExportNamespace(ExportElement exp) { | |
| 64 Namespace namespace = | |
| 65 new NamespaceBuilder().createExportNamespaceForDirective(exp); | |
| 66 return namespace.definedNames; | |
| 67 } | |
| 68 | |
| 69 | |
| 70 /** | |
| 71 * Returns a export namespace of the given [LibraryElement]. | |
| 72 */ | |
| 73 Map<String, Element> getExportNamespace2(LibraryElement library) { | |
|
Brian Wilkerson
2014/07/28 18:06:56
How about getExportNamespaceForDirective and getEx
scheglov
2014/07/28 18:27:28
Done.
| |
| 74 Namespace namespace = | |
| 75 new NamespaceBuilder().createExportNamespaceForLibrary(library); | |
| 76 return namespace.definedNames; | |
| 77 } | |
| 78 | |
| 79 | |
| 80 /** | |
| 81 * Returns an [Element] exported from the given [LibraryElement]. | |
| 82 */ | |
| 83 Element getExportedElement(LibraryElement library, String name) { | |
| 84 if (library == null) { | |
| 85 return null; | |
| 86 } | |
| 87 return getExportNamespace2(library)[name]; | |
| 88 } | |
| 89 | |
| 90 /** | |
| 61 * Returns [getExpressionPrecedence] for the parent of [node], | 91 * Returns [getExpressionPrecedence] for the parent of [node], |
| 62 * or `0` if the parent node is [ParenthesizedExpression]. | 92 * or `0` if the parent node is [ParenthesizedExpression]. |
| 63 * | 93 * |
| 64 * The reason is that `(expr)` is always executed after `expr`. | 94 * The reason is that `(expr)` is always executed after `expr`. |
| 65 */ | 95 */ |
| 66 int getExpressionParentPrecedence(AstNode node) { | 96 int getExpressionParentPrecedence(AstNode node) { |
| 67 AstNode parent = node.parent; | 97 AstNode parent = node.parent; |
| 68 if (parent is ParenthesizedExpression) { | 98 if (parent is ParenthesizedExpression) { |
| 69 return 0; | 99 return 0; |
| 70 } | 100 } |
| 71 return getExpressionPrecedence(parent); | 101 return getExpressionPrecedence(parent); |
| 72 } | 102 } |
| 73 | 103 |
| 74 | 104 |
| 75 /** | 105 /** |
| 76 * Returns the precedence of [node] it is an [Expression], negative otherwise. | 106 * Returns the precedence of [node] it is an [Expression], negative otherwise. |
| 77 */ | 107 */ |
| 78 int getExpressionPrecedence(AstNode node) { | 108 int getExpressionPrecedence(AstNode node) { |
| 79 if (node is Expression) { | 109 if (node is Expression) { |
| 80 return node.precedence; | 110 return node.precedence; |
| 81 } | 111 } |
| 82 return -1000; | 112 return -1000; |
| 83 } | 113 } |
| 84 | 114 |
| 85 | |
| 86 /** | 115 /** |
| 87 * Returns the namespace of the given [ImportElement]. | 116 * Returns the namespace of the given [ImportElement]. |
| 88 */ | 117 */ |
| 89 Map<String, Element> getImportNamespace(ImportElement imp) { | 118 Map<String, Element> getImportNamespace(ImportElement imp) { |
| 90 NamespaceBuilder builder = new NamespaceBuilder(); | 119 NamespaceBuilder builder = new NamespaceBuilder(); |
| 91 Namespace namespace = builder.createImportNamespaceForDirective(imp); | 120 Namespace namespace = builder.createImportNamespaceForDirective(imp); |
| 92 return namespace.definedNames; | 121 return namespace.definedNames; |
| 93 } | 122 } |
| 94 | 123 |
| 95 /** | 124 /** |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 106 } | 135 } |
| 107 if (parent is PropertyAccess) { | 136 if (parent is PropertyAccess) { |
| 108 PropertyAccess access = parent; | 137 PropertyAccess access = parent; |
| 109 if (identical(access.propertyName, node)) { | 138 if (identical(access.propertyName, node)) { |
| 110 return access.realTarget; | 139 return access.realTarget; |
| 111 } | 140 } |
| 112 } | 141 } |
| 113 return null; | 142 return null; |
| 114 } | 143 } |
| 115 | 144 |
| 116 | |
| 117 /** | 145 /** |
| 118 * Returns the [String] content of the given [Source]. | 146 * Returns the [String] content of the given [Source]. |
| 119 */ | 147 */ |
| 120 String getSourceContent(AnalysisContext context, Source source) { | 148 String getSourceContent(AnalysisContext context, Source source) { |
| 121 return context.getContents(source).data; | 149 return context.getContents(source).data; |
| 122 } | 150 } |
| 123 | 151 |
| 124 class CorrectionUtils { | 152 class CorrectionUtils { |
| 125 final CompilationUnit unit; | 153 final CompilationUnit unit; |
| 126 | 154 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 /** | 345 /** |
| 318 * Returns the line prefix consisting of spaces and tabs on the left from the | 346 * Returns the line prefix consisting of spaces and tabs on the left from the |
| 319 * given offset. | 347 * given offset. |
| 320 */ | 348 */ |
| 321 String getPrefix(int endIndex) { | 349 String getPrefix(int endIndex) { |
| 322 int startIndex = getLineContentStart(endIndex); | 350 int startIndex = getLineContentStart(endIndex); |
| 323 return _buffer.substring(startIndex, endIndex); | 351 return _buffer.substring(startIndex, endIndex); |
| 324 } | 352 } |
| 325 | 353 |
| 326 /** | 354 /** |
| 355 * Returns a [InsertDesc] describing where to insert a new library-related | |
| 356 * directive. | |
| 357 */ | |
| 358 CorrectionUtils_InsertDesc get insertDescImport { | |
|
Brian Wilkerson
2014/07/28 18:06:56
These getters look like they could take a while. I
scheglov
2014/07/28 18:27:28
Thank you, fixed.
| |
| 359 // analyze directives | |
| 360 Directive prevDirective = null; | |
| 361 for (Directive directive in unit.directives) { | |
| 362 if (directive is LibraryDirective || directive is ImportDirective || direc tive is ExportDirective) { | |
| 363 prevDirective = directive; | |
| 364 } | |
| 365 } | |
| 366 // insert after last library-related directive | |
| 367 if (prevDirective != null) { | |
| 368 CorrectionUtils_InsertDesc result = new CorrectionUtils_InsertDesc(); | |
| 369 result.offset = prevDirective.end; | |
| 370 String eol = endOfLine; | |
| 371 if (prevDirective is LibraryDirective) { | |
| 372 result.prefix = "${eol}${eol}"; | |
| 373 } else { | |
| 374 result.prefix = eol; | |
| 375 } | |
| 376 return result; | |
| 377 } | |
| 378 // no directives, use "top" location | |
| 379 return insertDescTop; | |
| 380 } | |
| 381 | |
| 382 /** | |
| 383 * Returns a [InsertDesc] describing where to insert a new 'part' directive. | |
| 384 */ | |
| 385 CorrectionUtils_InsertDesc get insertDescPart { | |
| 386 // analyze directives | |
| 387 Directive prevDirective = null; | |
| 388 for (Directive directive in unit.directives) { | |
| 389 prevDirective = directive; | |
| 390 } | |
| 391 // insert after last directive | |
| 392 if (prevDirective != null) { | |
| 393 CorrectionUtils_InsertDesc result = new CorrectionUtils_InsertDesc(); | |
| 394 result.offset = prevDirective.end; | |
| 395 String eol = endOfLine; | |
| 396 if (prevDirective is PartDirective) { | |
| 397 result.prefix = eol; | |
| 398 } else { | |
| 399 result.prefix = "${eol}${eol}"; | |
| 400 } | |
| 401 return result; | |
| 402 } | |
| 403 // no directives, use "top" location | |
| 404 return insertDescTop; | |
| 405 } | |
| 406 | |
| 407 /** | |
| 408 * Returns a [InsertDesc] describing where to insert a new directive or a | |
| 409 * top-level declaration at the top of the file. | |
| 410 */ | |
| 411 CorrectionUtils_InsertDesc get insertDescTop { | |
| 412 // skip leading line comments | |
| 413 int offset = 0; | |
| 414 bool insertEmptyLineBefore = false; | |
| 415 bool insertEmptyLineAfter = false; | |
| 416 String source = _buffer; | |
| 417 // skip hash-bang | |
| 418 if (offset < source.length - 2) { | |
| 419 String linePrefix = getText2(offset, 2); | |
| 420 if (linePrefix == "#!") { | |
| 421 insertEmptyLineBefore = true; | |
| 422 offset = getLineNext(offset); | |
| 423 // skip empty lines to first line comment | |
| 424 int emptyOffset = offset; | |
| 425 while (emptyOffset < source.length - 2) { | |
| 426 int nextLineOffset = getLineNext(emptyOffset); | |
| 427 String line = source.substring(emptyOffset, nextLineOffset); | |
| 428 if (line.trim().isEmpty) { | |
| 429 emptyOffset = nextLineOffset; | |
| 430 continue; | |
| 431 } else if (line.startsWith("//")) { | |
| 432 offset = emptyOffset; | |
| 433 break; | |
| 434 } else { | |
| 435 break; | |
| 436 } | |
| 437 } | |
| 438 } | |
| 439 } | |
| 440 // skip line comments | |
| 441 while (offset < source.length - 2) { | |
| 442 String linePrefix = getText2(offset, 2); | |
| 443 if (linePrefix == "//") { | |
| 444 insertEmptyLineBefore = true; | |
| 445 offset = getLineNext(offset); | |
| 446 } else { | |
| 447 break; | |
| 448 } | |
| 449 } | |
| 450 // determine if empty line is required after | |
| 451 int nextLineOffset = getLineNext(offset); | |
| 452 String insertLine = source.substring(offset, nextLineOffset); | |
| 453 if (!insertLine.trim().isEmpty) { | |
| 454 insertEmptyLineAfter = true; | |
| 455 } | |
| 456 // fill InsertDesc | |
| 457 CorrectionUtils_InsertDesc desc = new CorrectionUtils_InsertDesc(); | |
| 458 desc.offset = offset; | |
| 459 if (insertEmptyLineBefore) { | |
| 460 desc.prefix = endOfLine; | |
| 461 } | |
| 462 if (insertEmptyLineAfter) { | |
| 463 desc.suffix = endOfLine; | |
| 464 } | |
| 465 return desc; | |
| 466 } | |
| 467 | |
| 468 /** | |
| 469 * Returns a start index of the next line after the line which contains the | |
| 470 * given index. | |
| 471 */ | |
| 472 int getLineNext(int index) { | |
| 473 int length = _buffer.length; | |
| 474 // skip to the end of the line | |
| 475 while (index < length) { | |
| 476 int c = _buffer.codeUnitAt(index); | |
| 477 if (c == 0xD || c == 0xA) { | |
| 478 break; | |
| 479 } | |
| 480 index++; | |
| 481 } | |
| 482 // skip single \r | |
| 483 if (index < length && _buffer.codeUnitAt(index) == 0xD) { | |
| 484 index++; | |
| 485 } | |
| 486 // skip single \n | |
| 487 if (index < length && _buffer.codeUnitAt(index) == 0xA) { | |
| 488 index++; | |
| 489 } | |
| 490 // done | |
| 491 return index; | |
| 492 } | |
| 493 | |
| 494 /** | |
| 327 * Returns the text of the given [AstNode] in the unit. | 495 * Returns the text of the given [AstNode] in the unit. |
| 328 */ | 496 */ |
| 329 String getText(AstNode node) => getText2(node.offset, node.length); | 497 String getText(AstNode node) => getText2(node.offset, node.length); |
| 330 | 498 |
| 331 /** | 499 /** |
| 332 * Returns the text of the given range in the unit. | 500 * Returns the text of the given range in the unit. |
| 333 */ | 501 */ |
| 334 String getText2(int offset, int length) => | 502 String getText2(int offset, int length) => |
| 335 _buffer.substring(offset, offset + length); | 503 _buffer.substring(offset, offset + length); |
| 336 | 504 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 ImportElement _getImportElement(Element element) { | 562 ImportElement _getImportElement(Element element) { |
| 395 for (ImportElement imp in _library.imports) { | 563 for (ImportElement imp in _library.imports) { |
| 396 Map<String, Element> definedNames = getImportNamespace(imp); | 564 Map<String, Element> definedNames = getImportNamespace(imp); |
| 397 if (definedNames.containsValue(element)) { | 565 if (definedNames.containsValue(element)) { |
| 398 return imp; | 566 return imp; |
| 399 } | 567 } |
| 400 } | 568 } |
| 401 return null; | 569 return null; |
| 402 } | 570 } |
| 403 } | 571 } |
| 572 | |
| 573 | |
| 574 /** | |
| 575 * Describes where to insert new directive or top-level declaration. | |
| 576 */ | |
| 577 class CorrectionUtils_InsertDesc { | |
| 578 int offset = 0; | |
| 579 String prefix = ""; | |
| 580 String suffix = ""; | |
| 581 } | |
| OLD | NEW |