| 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 computers; | 5 library computer.highlights; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; | 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; | 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 import 'package:analyzer/src/generated/scanner.dart'; | 9 import 'package:analyzer/src/generated/scanner.dart'; |
| 10 import 'package:analyzer/src/generated/source.dart'; | |
| 11 | 10 |
| 12 | 11 |
| 13 /** | 12 /** |
| 14 * A computer for [HighlightRegion]s in a Dart [CompilationUnit]. | 13 * A computer for [HighlightRegion]s in a Dart [CompilationUnit]. |
| 15 */ | 14 */ |
| 16 class DartUnitHighlightsComputer { | 15 class DartUnitHighlightsComputer { |
| 17 final CompilationUnit _unit; | 16 final CompilationUnit _unit; |
| 18 | 17 |
| 19 final List<Map<String, Object>> _regions = <Map<String, Object>>[]; | 18 final List<Map<String, Object>> _regions = <Map<String, Object>>[]; |
| 20 | 19 |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 static const HighlightType TYPE_NAME_DYNAMIC = const HighlightType('TYPE_NAME_
DYNAMIC'); | 508 static const HighlightType TYPE_NAME_DYNAMIC = const HighlightType('TYPE_NAME_
DYNAMIC'); |
| 510 static const HighlightType TYPE_PARAMETER = const HighlightType('TYPE_PARAMETE
R'); | 509 static const HighlightType TYPE_PARAMETER = const HighlightType('TYPE_PARAMETE
R'); |
| 511 | 510 |
| 512 final String name; | 511 final String name; |
| 513 | 512 |
| 514 @override | 513 @override |
| 515 String toString() => name; | 514 String toString() => name; |
| 516 | 515 |
| 517 const HighlightType(this.name); | 516 const HighlightType(this.name); |
| 518 } | 517 } |
| 519 | |
| 520 | |
| 521 /** | |
| 522 * A computer for navigation regions in a Dart [CompilationUnit]. | |
| 523 */ | |
| 524 class DartUnitNavigationComputer { | |
| 525 final CompilationUnit _unit; | |
| 526 | |
| 527 List<Map<String, Object>> _regions = []; | |
| 528 | |
| 529 DartUnitNavigationComputer(this._unit); | |
| 530 | |
| 531 /** | |
| 532 * Returns the computed navigation regions, not `null`. | |
| 533 */ | |
| 534 List<Map<String, Object>> compute() { | |
| 535 _unit.accept(new _DartUnitNavigationComputerVisitor(this)); | |
| 536 return new List.from(_regions); | |
| 537 } | |
| 538 | |
| 539 void _addRegion(int offset, int length, Element element) { | |
| 540 Map<String, Object> target = _createTarget(element); | |
| 541 if (target == null) { | |
| 542 return; | |
| 543 } | |
| 544 _regions.add({ | |
| 545 'offset': offset, | |
| 546 'length': length, | |
| 547 'targets': [target] | |
| 548 }); | |
| 549 } | |
| 550 | |
| 551 void _addRegion_nodeStart_nodeEnd(AstNode a, AstNode b, Element element) { | |
| 552 int offset = a.offset; | |
| 553 int length = b.end - offset; | |
| 554 _addRegion(offset, length, element); | |
| 555 } | |
| 556 | |
| 557 void _addRegion_nodeStart_nodeStart(AstNode a, AstNode b, Element element) { | |
| 558 int offset = a.offset; | |
| 559 int length = b.offset - offset; | |
| 560 _addRegion(offset, length, element); | |
| 561 } | |
| 562 | |
| 563 void _addRegion_tokenStart_nodeEnd(Token a, AstNode b, Element element) { | |
| 564 int offset = a.offset; | |
| 565 int length = b.end - offset; | |
| 566 _addRegion(offset, length, element); | |
| 567 } | |
| 568 | |
| 569 void _addRegionForNode(AstNode node, Element element) { | |
| 570 int offset = node.offset; | |
| 571 int length = node.length; | |
| 572 _addRegion(offset, length, element); | |
| 573 } | |
| 574 | |
| 575 void _addRegionForToken(Token token, Element element) { | |
| 576 int offset = token.offset; | |
| 577 int length = token.length; | |
| 578 _addRegion(offset, length, element); | |
| 579 } | |
| 580 | |
| 581 /** | |
| 582 * Returns the JSON for the given [Element], maybe `null` if `null` was given. | |
| 583 */ | |
| 584 Map<String, Object> _createTarget(Element element) { | |
| 585 if (element == null) { | |
| 586 return null; | |
| 587 } | |
| 588 if (element is FieldFormalParameterElement) { | |
| 589 element = (element as FieldFormalParameterElement).field; | |
| 590 } | |
| 591 // prepare Source | |
| 592 Source source = element.source; | |
| 593 if (source == null) { | |
| 594 return null; | |
| 595 } | |
| 596 // prepare location | |
| 597 int offset = element.nameOffset; | |
| 598 int length = element.displayName.length; | |
| 599 if (element is CompilationUnitElement) { | |
| 600 offset = 0; | |
| 601 length = 0; | |
| 602 } | |
| 603 // return as JSON | |
| 604 return { | |
| 605 'file': source.fullName, | |
| 606 'offset': offset, | |
| 607 'length': length, | |
| 608 'elementId': element.location.encoding | |
| 609 }; | |
| 610 } | |
| 611 } | |
| 612 | |
| 613 | |
| 614 | |
| 615 class _DartUnitNavigationComputerVisitor extends RecursiveAstVisitor { | |
| 616 final DartUnitNavigationComputer computer; | |
| 617 | |
| 618 _DartUnitNavigationComputerVisitor(this.computer); | |
| 619 | |
| 620 @override | |
| 621 visitAssignmentExpression(AssignmentExpression node) { | |
| 622 computer._addRegionForToken(node.operator, node.bestElement); | |
| 623 return super.visitAssignmentExpression(node); | |
| 624 } | |
| 625 | |
| 626 @override | |
| 627 visitBinaryExpression(BinaryExpression node) { | |
| 628 computer._addRegionForToken(node.operator, node.bestElement); | |
| 629 return super.visitBinaryExpression(node); | |
| 630 } | |
| 631 | |
| 632 @override | |
| 633 visitConstructorDeclaration(ConstructorDeclaration node) { | |
| 634 // associate constructor with "T" or "T.name" | |
| 635 { | |
| 636 AstNode firstNode = node.returnType; | |
| 637 AstNode lastNode = node.name; | |
| 638 if (lastNode == null) { | |
| 639 lastNode = firstNode; | |
| 640 } | |
| 641 if (firstNode != null && lastNode != null) { | |
| 642 computer._addRegion_nodeStart_nodeEnd(firstNode, lastNode, node.element)
; | |
| 643 } | |
| 644 } | |
| 645 return super.visitConstructorDeclaration(node); | |
| 646 } | |
| 647 | |
| 648 @override | |
| 649 visitExportDirective(ExportDirective node) { | |
| 650 ExportElement exportElement = node.element; | |
| 651 if (exportElement != null) { | |
| 652 Element element = exportElement.exportedLibrary; | |
| 653 computer._addRegion_tokenStart_nodeEnd(node.keyword, node.uri, element); | |
| 654 } | |
| 655 return super.visitExportDirective(node); | |
| 656 } | |
| 657 | |
| 658 @override | |
| 659 visitImportDirective(ImportDirective node) { | |
| 660 ImportElement importElement = node.element; | |
| 661 if (importElement != null) { | |
| 662 Element element = importElement.importedLibrary; | |
| 663 computer._addRegion_tokenStart_nodeEnd(node.keyword, node.uri, element); | |
| 664 } | |
| 665 return super.visitImportDirective(node); | |
| 666 } | |
| 667 | |
| 668 @override | |
| 669 visitIndexExpression(IndexExpression node) { | |
| 670 computer._addRegionForToken(node.rightBracket, node.bestElement); | |
| 671 return super.visitIndexExpression(node); | |
| 672 } | |
| 673 | |
| 674 @override | |
| 675 visitInstanceCreationExpression(InstanceCreationExpression node) { | |
| 676 Element element = node.staticElement; | |
| 677 if (element != null && element.isSynthetic) { | |
| 678 element = element.enclosingElement; | |
| 679 } | |
| 680 computer._addRegion_nodeStart_nodeStart(node, node.argumentList, element); | |
| 681 return super.visitInstanceCreationExpression(node); | |
| 682 } | |
| 683 | |
| 684 @override | |
| 685 visitPartDirective(PartDirective node) { | |
| 686 computer._addRegion_tokenStart_nodeEnd(node.keyword, node.uri, node.element)
; | |
| 687 return super.visitPartDirective(node); | |
| 688 } | |
| 689 | |
| 690 @override | |
| 691 visitPartOfDirective(PartOfDirective node) { | |
| 692 computer._addRegion_tokenStart_nodeEnd(node.keyword, node.libraryName, node.
element); | |
| 693 return super.visitPartOfDirective(node); | |
| 694 } | |
| 695 | |
| 696 @override | |
| 697 visitPostfixExpression(PostfixExpression node) { | |
| 698 computer._addRegionForToken(node.operator, node.bestElement); | |
| 699 return super.visitPostfixExpression(node); | |
| 700 } | |
| 701 | |
| 702 @override | |
| 703 visitPrefixExpression(PrefixExpression node) { | |
| 704 computer._addRegionForToken(node.operator, node.bestElement); | |
| 705 return super.visitPrefixExpression(node); | |
| 706 } | |
| 707 | |
| 708 @override | |
| 709 visitSimpleIdentifier(SimpleIdentifier node) { | |
| 710 if (node.parent is ConstructorDeclaration) { | |
| 711 } else { | |
| 712 computer._addRegionForNode(node, node.bestElement); | |
| 713 } | |
| 714 return super.visitSimpleIdentifier(node); | |
| 715 } | |
| 716 } | |
| OLD | NEW |