From 6d659ba381d804b1cdf952f10b994d4ca512fca3 Mon Sep 17 00:00:00 2001 From: Andraxion Date: Sat, 25 Jul 2026 22:46:01 -0400 Subject: [PATCH] Ignore comments in Tree-sitter logic graphs --- src/docforge/treesitter_logic.py | 4 +++ tests/test_treesitter_logic.py | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/docforge/treesitter_logic.py b/src/docforge/treesitter_logic.py index 7f2d556..fec8443 100644 --- a/src/docforge/treesitter_logic.py +++ b/src/docforge/treesitter_logic.py @@ -20,6 +20,8 @@ from tree_sitter import Language, Node, Parser from .errors import DocForgeError from .models import LogicEdge, LogicNode, LogicProjection +_TRIVIA_NODE_TYPES = frozenset({"comment"}) + @dataclass(frozen=True) class TreeSitterLogicOwner: @@ -432,6 +434,8 @@ class _TreeSitterFunctionBuilder: *, control: _Control | None, ) -> tuple[_Tail, ...]: + if statement.type in _TRIVIA_NODE_TYPES: + return incoming if statement.type in self.profile.block_types: return self._statements(statement.named_children, incoming, control=control) if statement.type == "if_statement": diff --git a/tests/test_treesitter_logic.py b/tests/test_treesitter_logic.py index 6a7014f..ad8c84f 100644 --- a/tests/test_treesitter_logic.py +++ b/tests/test_treesitter_logic.py @@ -11,6 +11,27 @@ from docforge.treesitter_logic import ( class JavaScriptLogicTests(unittest.TestCase): + def test_comments_do_not_become_logic_actions(self) -> None: + source = """ +function choose(enabled) { + // Explain the condition. + // Continue the explanation. + /* A block comment is trivia too. */ + if (enabled) { + accept(); + } +} +""".strip() + projection = analyze_javascript_source( + source, + source_id="source.javascript", + owners=(TreeSitterLogicOwner("js.symbol.choose", "choose", 1),), + )[0] + + labels = {node.label for node in projection.nodes} + self.assertFalse(any(label.startswith(("//", "/*")) for label in labels)) + self.assertIn("accept();", labels) + def test_branches_short_circuit_and_converge(self) -> None: source = """ function choose(enabled, ready) { @@ -90,6 +111,27 @@ function process(items, mode) { class CppLogicTests(unittest.TestCase): + def test_comments_do_not_become_logic_actions(self) -> None: + source = """ +int choose(bool enabled) { + // Explain the condition. + /* A block comment is trivia too. */ + if (enabled) { + return 1; + } + return 0; +} +""".strip() + projection = analyze_cpp_source( + source, + source_id="source.cpp", + owners=(TreeSitterLogicOwner("cpp.symbol.choose", "choose", 1),), + )[0] + + labels = {node.label for node in projection.nodes} + self.assertFalse(any(label.startswith(("//", "/*")) for label in labels)) + self.assertIn("return 1", labels) + def test_cpp_function_branches_and_throws(self) -> None: source = """ int choose(bool enabled) {