MCPcopy Create free account
hub / github.com/Graphify-Labs/graphify / _extract_spock_fallback

Function _extract_spock_fallback

graphify/extract.py:6358–6448  ·  view source on GitHub ↗

Regex-based fallback for Spock spec files where tree-sitter-groovy cannot parse ``def "feature name"()`` methods. Merges import edges from the tree-sitter pass (which survive reliably) with class and feature-method nodes extracted via regex.

(path: Path, ts_result: dict)

Source from the content-addressed store, hash-verified

6356
6357
6358def _extract_spock_fallback(path: Path, ts_result: dict) -> dict:
6359 """Regex-based fallback for Spock spec files where tree-sitter-groovy cannot parse
6360 ``def "feature name"()`` methods. Merges import edges from the tree-sitter pass
6361 (which survive reliably) with class and feature-method nodes extracted via regex.
6362 """
6363 import re as _re
6364 source = path.read_text(errors="replace")
6365 str_path = str(path)
6366 stem = _file_stem(path)
6367
6368 # Only keep the file node from the tree-sitter pass (guaranteed present and
6369 # correctly IDed) plus all import edges. All other ts nodes are discarded to
6370 # avoid orphaned method/constructor nodes whose parent edges were dropped.
6371 file_node = next((n for n in ts_result.get("nodes", []) if n.get("label") == path.name), None)
6372 nodes: list[dict] = [file_node] if file_node else []
6373 edges: list[dict] = [e for e in ts_result.get("edges", []) if e.get("context") == "import"]
6374 seen_ids: set[str] = {n["id"] for n in nodes}
6375
6376 def _add_node(nid: str, label: str, line: int) -> None:
6377 if nid not in seen_ids:
6378 seen_ids.add(nid)
6379 nodes.append({
6380 "id": nid,
6381 "label": label,
6382 "file_type": "code",
6383 "source_file": str_path,
6384 "source_location": f"L{line}",
6385 })
6386
6387 def _add_edge(src: str, tgt: str, relation: str, line: int,
6388 confidence: str = "EXTRACTED") -> None:
6389 edges.append({
6390 "source": src,
6391 "target": tgt,
6392 "relation": relation,
6393 "confidence": confidence,
6394 "source_file": str_path,
6395 "source_location": f"L{line}",
6396 "weight": 1.0,
6397 })
6398
6399 lines_text = source.splitlines()
6400
6401 # Extract class declarations
6402 class_re = _re.compile(r"^\s*(?:[\w@]+\s+)*class\s+(\w+)")
6403 # Extract Spock feature methods: def "..." () or def '...' ()
6404 # Two separate capture groups per quote style so apostrophes inside
6405 # double-quoted names (e.g. "shouldn't") are captured correctly.
6406 feature_re = _re.compile(r"""^\s*def\s+(?:\"([^\"]+)\"|'([^']+)')\s*\(""")
6407 # Extract plain def methods (non-string names) as well
6408 plain_method_re = _re.compile(r"""^\s*def\s+(\w+)\s*\(""")
6409
6410 current_class_nid: str | None = None
6411 file_nid = _make_id(str_path)
6412
6413 # Ensure the file node exists (tree-sitter pass may have emitted it)
6414 if file_nid not in seen_ids:
6415 _add_node(file_nid, path.name, 1)

Callers 1

extract_groovyFunction · 0.85

Calls 5

_file_stemFunction · 0.90
_make_idFunction · 0.90
_add_nodeFunction · 0.70
_add_edgeFunction · 0.70
getMethod · 0.45

Tested by

no test coverage detected