|
8 | 8 |
|
9 | 9 | import python |
10 | 10 | import semmle.python.RegexTreeView |
| 11 | +import semmle.python.Yaml |
11 | 12 |
|
12 | 13 | private newtype TPrintAstConfiguration = MkPrintAstConfiguration() |
13 | 14 |
|
@@ -53,7 +54,9 @@ private newtype TPrintAstNode = |
53 | 54 | shouldPrint(list.getAnItem(), _) and |
54 | 55 | not list = any(Module mod).getBody() and |
55 | 56 | not forall(AstNode child | child = list.getAnItem() | isNotNeeded(child)) |
56 | | - } |
| 57 | + } or |
| 58 | + TYamlNode(YamlNode node) or |
| 59 | + TYamlMappingNode(YamlMapping mapping, int i) { exists(mapping.getKeyNode(i)) } |
57 | 60 |
|
58 | 61 | /** |
59 | 62 | * A node in the output tree. |
@@ -633,6 +636,80 @@ private module PrettyPrinting { |
633 | 636 | } |
634 | 637 | } |
635 | 638 |
|
| 639 | +/** |
| 640 | + * Classes for printing YAML AST. |
| 641 | + */ |
| 642 | +module PrintYaml { |
| 643 | + /** |
| 644 | + * A print node representing a YAML value in a .yml file. |
| 645 | + */ |
| 646 | + class YamlNodeNode extends PrintAstNode, TYamlNode { |
| 647 | + YamlNode node; |
| 648 | + |
| 649 | + YamlNodeNode() { this = TYamlNode(node) } |
| 650 | + |
| 651 | + override string toString() { |
| 652 | + result = "[" + concat(node.getAPrimaryQlClass(), ",") + "] " + node.toString() |
| 653 | + } |
| 654 | + |
| 655 | + override Location getLocation() { result = node.getLocation() } |
| 656 | + |
| 657 | + /** |
| 658 | + * Gets the `YAMLNode` represented by this node. |
| 659 | + */ |
| 660 | + final YamlNode getValue() { result = node } |
| 661 | + |
| 662 | + override PrintAstNode getChild(int childIndex) { |
| 663 | + exists(YamlNode child | result.(YamlNodeNode).getValue() = child | |
| 664 | + child = node.getChildNode(childIndex) |
| 665 | + ) |
| 666 | + } |
| 667 | + } |
| 668 | + |
| 669 | + /** |
| 670 | + * A print node representing a `YAMLMapping`. |
| 671 | + * |
| 672 | + * Each child of this node aggregates the key and value of a mapping. |
| 673 | + */ |
| 674 | + class YamlMappingNode extends YamlNodeNode { |
| 675 | + override YamlMapping node; |
| 676 | + |
| 677 | + override PrintAstNode getChild(int childIndex) { |
| 678 | + exists(YamlMappingMapNode map | map = result | map.maps(node, childIndex)) |
| 679 | + } |
| 680 | + } |
| 681 | + |
| 682 | + /** |
| 683 | + * A print node representing the `i`th mapping in `mapping`. |
| 684 | + */ |
| 685 | + class YamlMappingMapNode extends PrintAstNode, TYamlMappingNode { |
| 686 | + YamlMapping mapping; |
| 687 | + int i; |
| 688 | + |
| 689 | + YamlMappingMapNode() { this = TYamlMappingNode(mapping, i) } |
| 690 | + |
| 691 | + override string toString() { |
| 692 | + result = "(Mapping " + i + ")" and not exists(mapping.getKeyNode(i).(YamlScalar).getValue()) |
| 693 | + or |
| 694 | + result = "(Mapping " + i + ") " + mapping.getKeyNode(i).(YamlScalar).getValue() + ":" |
| 695 | + } |
| 696 | + |
| 697 | + /** |
| 698 | + * Holds if this print node represents the `index`th mapping of `m`. |
| 699 | + */ |
| 700 | + predicate maps(YamlMapping m, int index) { |
| 701 | + m = mapping and |
| 702 | + index = i |
| 703 | + } |
| 704 | + |
| 705 | + override PrintAstNode getChild(int childIndex) { |
| 706 | + childIndex = 0 and result.(YamlNodeNode).getValue() = mapping.getKeyNode(i) |
| 707 | + or |
| 708 | + childIndex = 1 and result.(YamlNodeNode).getValue() = mapping.getValueNode(i) |
| 709 | + } |
| 710 | + } |
| 711 | +} |
| 712 | + |
636 | 713 | /** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */ |
637 | 714 | query predicate nodes(PrintAstNode node, string key, string value) { value = node.getProperty(key) } |
638 | 715 |
|
|
0 commit comments