1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages

Group source comments in logic views

This commit is contained in:
Andraxion 2026-07-25 22:51:56 -04:00
parent 6d659ba381
commit a30f021a52
4 changed files with 67 additions and 13 deletions

View file

@ -209,6 +209,9 @@ const contributionStyles = Object.freeze({
"logic-action": {
label: "Action", section: "Actions & calls", color: "#34d399", fill: "#15372e",
},
"logic-comment": {
label: "Comment", section: "Source commentary", color: "#7dd3fc", fill: "#173447",
},
"logic-control": {
label: "Control", section: "Loops & exception handling", color: "#c084fc", fill: "#302044",
},
@ -223,7 +226,7 @@ const contributionOrder = Object.freeze([
"focus", "composition", "behavior", "dependency", "execution",
"data", "evidence", "context", "related",
"logic-entry", "logic-condition", "logic-action", "logic-control",
"logic-convergence", "logic-terminal",
"logic-comment", "logic-convergence", "logic-terminal",
]);
const compositionRelations = new Set(["contains", "defines", "defined_in"]);
const behaviorRelations = new Set(["inherits", "implemented_by"]);
@ -939,6 +942,7 @@ function nodeContributionCategory(nodeId, data, topology) {
if (kind === "entry") return "logic-entry";
if (["condition", "case"].includes(kind)) return "logic-condition";
if (["action", "call"].includes(kind)) return "logic-action";
if (kind === "comment") return "logic-comment";
if (["loop", "try", "except", "finally", "break", "continue"].includes(kind)) {
return "logic-control";
}

View file

@ -20,7 +20,7 @@ from tree_sitter import Language, Node, Parser
from .errors import DocForgeError
from .models import LogicEdge, LogicNode, LogicProjection
_TRIVIA_NODE_TYPES = frozenset({"comment"})
_COMMENT_NODE_TYPES = frozenset({"comment"})
@dataclass(frozen=True)
@ -421,10 +421,29 @@ class _TreeSitterFunctionBuilder:
control: _Control | None,
) -> tuple[_Tail, ...]:
tails = incoming
for statement in statements:
items = tuple(statements)
index = 0
while index < len(items):
if not tails:
break
statement = items[index]
if statement.type in _COMMENT_NODE_TYPES:
comments = [statement]
index += 1
while index < len(items):
candidate = items[index]
previous = comments[-1]
if (
candidate.type not in _COMMENT_NODE_TYPES
or candidate.start_point.row > previous.end_point.row + 1
):
break
comments.append(candidate)
index += 1
tails = self._comment_block(tuple(comments), tails)
continue
tails = self._statement(statement, tails, control=control)
index += 1
return tails
def _statement(
@ -434,8 +453,8 @@ class _TreeSitterFunctionBuilder:
*,
control: _Control | None,
) -> tuple[_Tail, ...]:
if statement.type in _TRIVIA_NODE_TYPES:
return incoming
if statement.type in _COMMENT_NODE_TYPES:
return self._comment_block((statement,), incoming)
if statement.type in self.profile.block_types:
return self._statements(statement.named_children, incoming, control=control)
if statement.type == "if_statement":
@ -493,6 +512,19 @@ class _TreeSitterFunctionBuilder:
self._connect(incoming, node_id)
return (_Tail(node_id),)
def _comment_block(
self,
comments: tuple[Node, ...],
incoming: tuple[_Tail, ...],
) -> tuple[_Tail, ...]:
node_id = self._node(
"comment",
_compact(" ".join(_comment_text(comment, self.raw) for comment in comments), 480),
comments[0],
)
self._connect(incoming, node_id)
return (_Tail(node_id),)
def _if(
self,
statement: Node,
@ -830,6 +862,15 @@ def _text(node: Node, raw: bytes) -> str:
return raw[node.start_byte : node.end_byte].decode("utf-8", errors="replace")
def _comment_text(node: Node, raw: bytes) -> str:
value = _text(node, raw).strip()
if value.startswith("//"):
return value[2:].strip()
if value.startswith("/*") and value.endswith("*/"):
value = value[2:-2]
return " ".join(line.strip().removeprefix("*").strip() for line in value.splitlines()).strip()
def _compact(value: str, limit: int = 240) -> str:
compact = " ".join(value.strip().split())
return compact if len(compact) <= limit else f"{compact[: limit - 1]}"