Skip to content

Commit 9eda155

Browse files
committed
feat: Lua language support
1 parent 79b8d8d commit 9eda155

5 files changed

Lines changed: 49 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ Works with any mix of file types:
148148

149149
| Type | Extensions | Extraction |
150150
|------|-----------|------------|
151-
| Code | `.py .ts .js .go .rs .java .c .cpp .rb .cs .kt .scala .php` | AST via tree-sitter + call-graph + docstring/comment rationale |
151+
| Code | `.py .ts .js .go .rs .java .c .cpp .rb .cs .kt .scala .php .swift .lua` | AST via tree-sitter + call-graph + docstring/comment rationale |
152152
| Docs | `.md .txt .rst` | Concepts + relationships + design rationale via Claude |
153153
| Papers | `.pdf` | Citation mining + concept extraction |
154154
| Images | `.png .jpg .webp .gif` | Claude vision - screenshots, diagrams, any language |

graphify/detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class FileType(str, Enum):
1616

1717
_MANIFEST_PATH = "graphify-out/manifest.json"
1818

19-
CODE_EXTENSIONS = {'.py', '.ts', '.js', '.tsx', '.go', '.rs', '.java', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.rb', '.swift', '.kt', '.kts', '.cs', '.scala', '.php'}
19+
CODE_EXTENSIONS = {'.py', '.ts', '.js', '.tsx', '.go', '.rs', '.java', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.rb', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.toc'}
2020
DOC_EXTENSIONS = {'.md', '.txt', '.rst'}
2121
PAPER_EXTENSIONS = {'.pdf'}
2222
IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'}

graphify/extract.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,43 @@ def _swift_extra_walk(node, source: bytes, file_nid: str, stem: str, str_path: s
545545
)
546546

547547

548+
def _import_lua(node, source: bytes, file_nid: str, stem: str, edges: list, str_path: str) -> None:
549+
"""Extract require('module') from Lua variable_declaration nodes."""
550+
text = _read_text(node, source)
551+
import re
552+
m = re.search(r"""require\s*[\('"]\s*['"]?([^'")\s]+)""", text)
553+
if m:
554+
module_name = m.group(1).split(".")[-1]
555+
if module_name:
556+
edges.append({
557+
"source": file_nid,
558+
"target": module_name,
559+
"relation": "imports",
560+
"confidence": "EXTRACTED",
561+
"confidence_score": 1.0,
562+
"source_file": str_path,
563+
"source_location": str(node.start_point[0] + 1),
564+
"weight": 1.0,
565+
})
566+
567+
568+
_LUA_CONFIG = LanguageConfig(
569+
ts_module="tree_sitter_lua",
570+
ts_language_fn="language",
571+
class_types=frozenset(),
572+
function_types=frozenset({"function_declaration"}),
573+
import_types=frozenset({"variable_declaration"}),
574+
call_types=frozenset({"function_call"}),
575+
call_function_field="name",
576+
call_accessor_node_types=frozenset({"method_index_expression"}),
577+
call_accessor_field="name",
578+
name_fallback_child_types=("identifier", "method_index_expression"),
579+
body_fallback_child_types=("block",),
580+
function_boundary_types=frozenset({"function_declaration"}),
581+
import_handler=_import_lua,
582+
)
583+
584+
548585
def _import_swift(node, source: bytes, file_nid: str, stem: str, edges: list, str_path: str) -> None:
549586
for child in node.children:
550587
if child.type == "identifier":
@@ -1078,6 +1115,11 @@ def extract_php(path: Path) -> dict:
10781115
return _extract_generic(path, _PHP_CONFIG)
10791116

10801117

1118+
def extract_lua(path: Path) -> dict:
1119+
"""Extract functions, methods, require() imports, and calls from a .lua file."""
1120+
return _extract_generic(path, _LUA_CONFIG)
1121+
1122+
10811123
def extract_swift(path: Path) -> dict:
10821124
"""Extract classes, structs, protocols, functions, imports, and calls from a .swift file."""
10831125
return _extract_generic(path, _SWIFT_CONFIG)
@@ -1623,6 +1665,8 @@ def extract(paths: list[Path]) -> dict:
16231665
".scala": extract_scala,
16241666
".php": extract_php,
16251667
".swift": extract_swift,
1668+
".lua": extract_lua,
1669+
".toc": extract_lua,
16261670
}
16271671

16281672
for path in paths:
@@ -1665,6 +1709,7 @@ def collect_files(target: Path) -> list[Path]:
16651709
"*.py", "*.js", "*.ts", "*.tsx", "*.go", "*.rs",
16661710
"*.java", "*.c", "*.h", "*.cpp", "*.cc", "*.cxx", "*.hpp",
16671711
"*.rb", "*.cs", "*.kt", "*.kts", "*.scala", "*.php", "*.swift",
1712+
"*.lua", "*.toc",
16681713
)
16691714
results: list[Path] = []
16701715
for pattern in _EXTENSIONS:

graphify/skill.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ import json
702702
from pathlib import Path
703703
704704
result = json.loads(open('.graphify_incremental.json').read()) if Path('.graphify_incremental.json').exists() else {}
705-
code_exts = {'.py','.ts','.js','.go','.rs','.java','.cpp','.c','.rb','.swift','.kt','.cs','.scala','.php','.cc','.cxx','.hpp','.h','.kts'}
705+
code_exts = {'.py','.ts','.js','.go','.rs','.java','.cpp','.c','.rb','.swift','.kt','.cs','.scala','.php','.cc','.cxx','.hpp','.h','.kts','.lua','.toc'}
706706
new_files = result.get('new_files', {})
707707
all_changed = [f for files in new_files.values() for f in files]
708708
code_only = all(Path(f).suffix.lower() in code_exts for f in all_changed)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dependencies = [
2727
"tree-sitter-scala",
2828
"tree-sitter-php",
2929
"tree-sitter-swift",
30+
"tree-sitter-lua",
3031
]
3132

3233
[project.urls]

0 commit comments

Comments
 (0)