|
17 | 17 | CommentType.python: {"function_definition", "class_definition"},
|
18 | 18 | CommentType.cpp: {"function_definition", "class_definition"},
|
19 | 19 | CommentType.cs: {"method_declaration", "class_declaration", "property_declaration"},
|
| 20 | + CommentType.yaml: {"block_mapping_pair", "block_sequence_item", "document"}, |
20 | 21 | }
|
21 | 22 |
|
22 | 23 | # initialize logger
|
|
43 | 44 | """
|
44 | 45 | CPP_QUERY = """(comment) @comment"""
|
45 | 46 | C_SHARP_QUERY = """(comment) @comment"""
|
| 47 | +YAML_QUERY = """(comment) @comment""" |
46 | 48 |
|
47 | 49 |
|
48 | 50 | def is_text_file(filepath: Path, sample_size: int = 2048) -> bool:
|
@@ -76,6 +78,11 @@ def init_tree_sitter(comment_type: CommentType) -> tuple[Parser, Query]:
|
76 | 78 |
|
77 | 79 | parsed_language = Language(tree_sitter_c_sharp.language())
|
78 | 80 | query = Query(parsed_language, C_SHARP_QUERY)
|
| 81 | + elif comment_type == CommentType.yaml: |
| 82 | + import tree_sitter_yaml # noqa: PLC0415 |
| 83 | + |
| 84 | + parsed_language = Language(tree_sitter_yaml.language()) |
| 85 | + query = Query(parsed_language, YAML_QUERY) |
79 | 86 | else:
|
80 | 87 | raise ValueError(f"Unsupported comment style: {comment_type}")
|
81 | 88 | parser = Parser(parsed_language)
|
@@ -133,10 +140,96 @@ def find_next_scope(
|
133 | 140 | return None
|
134 | 141 |
|
135 | 142 |
|
| 143 | +def _find_yaml_structure_in_block_node( |
| 144 | + block_node: TreeSitterNode, |
| 145 | +) -> TreeSitterNode | None: |
| 146 | + """Find YAML structure elements within a block_node.""" |
| 147 | + for grandchild in block_node.named_children: |
| 148 | + if grandchild.type == "block_mapping": |
| 149 | + for ggchild in grandchild.named_children: |
| 150 | + if ggchild.type == "block_mapping_pair": |
| 151 | + return ggchild |
| 152 | + elif grandchild.type == "block_sequence": |
| 153 | + for ggchild in grandchild.named_children: |
| 154 | + if ggchild.type == "block_sequence_item": |
| 155 | + return ggchild |
| 156 | + return None |
| 157 | + |
| 158 | + |
| 159 | +def find_yaml_next_structure(node: TreeSitterNode) -> TreeSitterNode | None: |
| 160 | + """Find the next YAML structure element after the comment node.""" |
| 161 | + current = node.next_named_sibling |
| 162 | + while current: |
| 163 | + if current.type in { |
| 164 | + "block_mapping_pair", |
| 165 | + "block_sequence_item", |
| 166 | + "flow_mapping", |
| 167 | + "flow_sequence", |
| 168 | + }: |
| 169 | + return current |
| 170 | + if current.type == "document": |
| 171 | + for child in current.named_children: |
| 172 | + if child.type == "block_node": |
| 173 | + result = _find_yaml_structure_in_block_node(child) |
| 174 | + if result: |
| 175 | + return result |
| 176 | + if current.type == "block_node": |
| 177 | + result = _find_yaml_structure_in_block_node(current) |
| 178 | + if result: |
| 179 | + return result |
| 180 | + current = current.next_named_sibling |
| 181 | + return None |
| 182 | + |
| 183 | + |
| 184 | +def find_yaml_prev_sibling_on_same_row(node: TreeSitterNode) -> TreeSitterNode | None: |
| 185 | + """Find a previous named sibling that is on the same row as the comment.""" |
| 186 | + comment_row = node.start_point.row |
| 187 | + current = node.prev_named_sibling |
| 188 | + |
| 189 | + while current: |
| 190 | + # Check if this sibling ends on the same row as the comment starts |
| 191 | + # This indicates it's an inline comment |
| 192 | + if current.end_point.row == comment_row: |
| 193 | + return current |
| 194 | + # If we find a sibling that ends before the comment row, we can stop |
| 195 | + # as we won't find any siblings on the same row going backwards |
| 196 | + if current.end_point.row < comment_row: |
| 197 | + break |
| 198 | + current = current.prev_named_sibling |
| 199 | + |
| 200 | + return None |
| 201 | + |
| 202 | + |
| 203 | +def find_yaml_associated_structure(node: TreeSitterNode) -> TreeSitterNode | None: |
| 204 | + """Find the YAML structure (key-value pair, list item, etc.) associated with a comment.""" |
| 205 | + # First, check if this is an inline comment by looking for a previous sibling on the same row |
| 206 | + prev_sibling_same_row = find_yaml_prev_sibling_on_same_row(node) |
| 207 | + if prev_sibling_same_row: |
| 208 | + return prev_sibling_same_row |
| 209 | + |
| 210 | + # If no previous sibling on same row, try to find the next named sibling (structure after the comment) |
| 211 | + structure = find_yaml_next_structure(node) |
| 212 | + if structure: |
| 213 | + return structure |
| 214 | + |
| 215 | + # If no next sibling found, traverse up to find parent structure |
| 216 | + parent = node.parent |
| 217 | + while parent: |
| 218 | + if parent.type in {"block_mapping_pair", "block_sequence_item"}: |
| 219 | + return parent |
| 220 | + parent = parent.parent |
| 221 | + |
| 222 | + return None |
| 223 | + |
| 224 | + |
136 | 225 | def find_associated_scope(
|
137 | 226 | node: TreeSitterNode, comment_type: CommentType = CommentType.cpp
|
138 | 227 | ) -> TreeSitterNode | None:
|
139 | 228 | """Find the associated scope of a comment."""
|
| 229 | + if comment_type == CommentType.yaml: |
| 230 | + # YAML uses different structure association logic |
| 231 | + return find_yaml_associated_structure(node) |
| 232 | + |
140 | 233 | if node.type == CommentCategory.docstring:
|
141 | 234 | # Only for python's docstring
|
142 | 235 | return find_enclosing_scope(node, comment_type)
|
|
0 commit comments