Skip to content

feat(graph): Lua symbol/call extraction + fix file discovery for whitelist .gitignore#67

Open
SIRTHEO wants to merge 2 commits into
giancarloerra:mainfrom
SIRTHEO:feat/lua-symbol-graph
Open

feat(graph): Lua symbol/call extraction + fix file discovery for whitelist .gitignore#67
SIRTHEO wants to merge 2 commits into
giancarloerra:mainfrom
SIRTHEO:feat/lua-symbol-graph

Conversation

@SIRTHEO

@SIRTHEO SIRTHEO commented Jun 2, 2026

Copy link
Copy Markdown

Summary

Two small graph-engine fixes that together make the code graph work for Lua
projects (and unblock any repo using a whitelist-style .gitignore).

1. Fix: getGraphableFiles skips whitelisted directories

getGraphableFiles calls shouldIgnore(ig, relPath) with the bare relative
path for every entry, directories included. For a repo that ignores everything
and re-includes a folder by its trailing-slash form — e.g. /* then !/src/
ignores("src") is true while ignores("src/") is false. The walk skips the
src directory and never descends, so the graph is empty for EVERY language on
such repos. Fix: pass the directory form (trailing slash) for directory entries,
matching gitignore directory semantics. Safe for normal ignores.

2. Feature: dedicated Lua symbol extractor

Lua had no node-kind-specific extractor and fell through to the regex fallback,
which records Mod for function Mod.parse(). Adds extractFromLua, walking
the ast-grep Lua tree: function T.f()/T:m()/local function f() (name = the
direct child before parameters), T.f = function() ... end assignments (RHS
must be directly a function), and call sites. Registers @ast-grep/lang-lua.
Namespace-table style now resolves to precise qualified symbols (Table.method).

Testing

  • npm run build (tsc strict) passes.
  • On a ~40-file Lua project: 0 -> 42 file nodes, 0 -> 683 symbols with qualified
    names + call edges. Same-file callees resolve; cross-file caller resolution is
    still bounded by the import-based resolver (Lua has no imports) — out of scope.

Notes

No breaking changes; other languages unaffected. The two changes are independent
but bundled since the Lua graph is only observable once discovery works.

Summary by CodeRabbit

  • New Features

    • Added Lua language support for code analysis, symbol extraction, and call tracing.
  • Bug Fixes

    • Improved directory path handling in file discovery to ensure accurate traversal and ignores.
  • Tests

    • Added regression and unit tests covering Lua symbol extraction and file-discovery behavior.
  • Chores

    • Added a runtime dependency required for Lua parsing.

… .gitignore

Two related graph-engine fixes that together make the code graph work on Lua
projects (and unblock any repo using a whitelist-style .gitignore):

- getGraphableFiles skipped every directory whose bare name matched .gitignore
  but was re-included only in trailing-slash form (e.g. `/*` then `!/src/`).
  The walk never descended, producing an empty graph for ALL languages on such
  repos. Check the directory form (trailing slash), per gitignore dir semantics.

- Lua had no dedicated ast-grep extractor and fell through to the regex
  fallback, which records `Mod` for `function Mod.parse()`. Add extractFromLua
  (function_declaration dotted/method/local names, `T.f = function()` assigns,
  and call sites) and register the @ast-grep/lang-lua grammar, so namespace-table
  style resolves to precise qualified symbols.
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3df96d19-6ed0-431b-a344-c202f09224a0

📥 Commits

Reviewing files that changed from the base of the PR and between 6c06bd9 and 8be929a.

📒 Files selected for processing (4)
  • src/services/code-graph.ts
  • src/services/graph-symbols.ts
  • tests/unit/graph-discovery.test.ts
  • tests/unit/graph-symbols.test.ts
✅ Files skipped from review due to trivial changes (1)
  • tests/unit/graph-symbols.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unit/graph-discovery.test.ts
  • src/services/code-graph.ts
  • src/services/graph-symbols.ts

📝 Walkthrough

Walkthrough

Adds Lua runtime grammar and dynamic registration, exports and tweaks code-graph discovery behavior, implements Lua AST-based symbol and call extraction with scope attribution, and adds unit tests for discovery and Lua extraction.

Changes

Lua Language Support and Symbol Extraction

Layer / File(s) Summary
Lua language dependency and dynamic registration
package.json, src/services/code-graph.ts
@ast-grep/lang-lua is added as a runtime dependency and registered in ensureDynamicLanguages.
Export getGraphableFiles & ignore check
src/services/code-graph.ts
getGraphableFiles is exported and directory traversal now passes directory paths with a trailing slash (${relPath}/) to shouldIgnore.
Lua symbol and call-site extraction from AST
src/services/graph-symbols.ts
extractSymbolsAndCalls dispatches Lua files to extractFromLua, which parses the Lua AST and extracts function symbols (namespace-table, local, assignment forms), builds scope frames, and collects/attributes calls from function_call nodes.
Unit tests: discovery and Lua extraction
tests/unit/graph-discovery.test.ts, tests/unit/graph-symbols.test.ts
Adds a .gitignore re-inclusion regression test for getGraphableFiles and a dedicated Lua test suite validating symbol extraction and call attribution.

Sequence Diagram(s)

sequenceDiagram
  participant Client as extractSymbolsAndCalls
  participant LuaExtractor as extractFromLua
  participant AstGrep as ast-grep
  participant ScopeTracker as ScopeFrameTracker
  Client->>LuaExtractor: route Lua file for extraction
  LuaExtractor->>AstGrep: parse source -> AST
  AstGrep-->>LuaExtractor: return AST nodes
  LuaExtractor->>ScopeTracker: emit symbols and record scope frames
  LuaExtractor->>LuaExtractor: find function_call nodes and derive callees
  LuaExtractor->>ScopeTracker: attribute calls to innermost scope or <module>
  LuaExtractor-->>Client: return symbols, calls, and scopes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through trees of Lua code tonight,
With ast-grep whiskers, sharp and bright.
I found each function, table, and call,
Scoped them snugly, one and all.
Hooray — the graph grows in moonlit light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes both main changes: Lua symbol/call extraction and the whitelist .gitignore file discovery fix.
Description check ✅ Passed The description includes all key sections: a comprehensive summary explaining both changes, detailed technical context, testing verification, and notes on impact. All required template sections are present and well-populated.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@giancarloerra giancarloerra self-assigned this Jun 2, 2026
@giancarloerra

Copy link
Copy Markdown
Owner

Thanks for this, it is a clean and well-scoped contribution, and CI is green across Node 18/20/22.

I verified both halves against the engine:

Discovery fix: correct and, importantly, complete. I tested our ignore@7.0.5 with the exact /* then !/src/ pattern: ignores("src") is true (the old walk bailed here, hence the empty graph), ignores("src/") is false (your fix descends), and ignores("src/foo.lua") is false, so the files under the re-included directory are actually picked up, not just the directory entered. I also confirmed the search/embedding discovery path (getIndexableFiles, which uses glob(nodir:true) plus a per-file check) is unaffected, so scoping this to the graph walk is right.

Lua extractor: faithful to the existing extractors. Good calls on taking the direct child before parameters as the name, requiring the assignment RHS to be directly a function_definition, and filtering keywords on call sites.

A few things before merge:

Add real Lua tests. tests/unit/graph-symbols.test.ts has a per-language block with concrete assertions for every other extractor. Please add a describe("Lua") that locks in the new behavior: qualified Table.method / T:m() names, local function, the T.f = function() ... end form, and call attribution to the enclosing function.

Fix the now-misleading existing test. it("handles Lua via regex fallback", ...) (currently in the "Regex fallback" block) no longer exercises the fallback, since Lua now routes to extractFromLua. It still passes because it only asserts exists, but the name and placement are now wrong. Please move it into the new Lua block and give it real assertions.
Add a regression test for the discovery fix. A whitelist .gitignore fixture (/* then !/src/) that asserts files under src are discovered. Note getGraphableFiles is not currently exported, so this likely means either exporting it for the test or asserting through the graph build.

Minor style: every other dynamically-registered grammar calls parse("x" as unknown as Lang, source). Please match that for parse("lua", ...) for consistency. Not blocking since it compiles.

The discovery fix is valuable also on its own. Thanks again.

@giancarloerra

Copy link
Copy Markdown
Owner

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

SIRTHEO added a commit to SIRTHEO/SocratiCode that referenced this pull request Jun 9, 2026
Address maintainer review on PR giancarloerra#67.

- Add a dedicated `describe("Lua")` block locking in qualified
  `Table.method` / `T:m()` names, `local function`, both
  `T.f = function() … end` and `local f = function() … end` assignment
  forms, call attribution to the enclosing function, top-level calls
  falling back to `<module>`, and dotted-callee resolution.
- Move the former "handles Lua via regex fallback" test out of the
  regex-fallback block (Lua now routes to extractFromLua) and give it
  real assertions; drop "Lua" from that block's title.
- Add a whitelist `.gitignore` regression test (`/*` then `!/src/`)
  asserting files under the re-included dir are discovered; export
  getGraphableFiles so the test can exercise discovery directly.
- Match the dynamic-grammar style for the Lua parse call
  (`parse("lua" as unknown as Lang, source)`).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address maintainer review on PR giancarloerra#67.

- Add a dedicated `describe("Lua")` block locking in qualified
  `Table.method` / `T:m()` names, `local function`, both
  `T.f = function() … end` and `local f = function() … end` assignment
  forms, call attribution to the enclosing function, top-level calls
  falling back to `<module>`, and dotted-callee resolution.
- Move the former "handles Lua via regex fallback" test out of the
  regex-fallback block (Lua now routes to extractFromLua) and give it
  real assertions; drop "Lua" from that block's title.
- Add a whitelist `.gitignore` regression test (`/*` then `!/src/`)
  asserting files under the re-included dir are discovered; export
  getGraphableFiles so the test can exercise discovery directly.
- Match the dynamic-grammar style for the Lua parse call
  (`parse("lua" as unknown as Lang, source)`).
@SIRTHEO SIRTHEO force-pushed the feat/lua-symbol-graph branch from 6c06bd9 to 8be929a Compare June 9, 2026 17:59
@SIRTHEO

SIRTHEO commented Jun 9, 2026

Copy link
Copy Markdown
Author

Thanks for the thorough review — all addressed in 8be929a:

  1. Lua tests — new describe("Lua") block locking in qualified Table.method / T:m() names, local function, both the T.f = function() … end and local f = function() … end forms, plus call attribution to the enclosing function (and top-level calls falling back to <module>).
  2. Misleading test — moved the former "handles Lua via regex fallback" into the Lua block with real assertions, and dropped "Lua" from the regex-fallback block title.
  3. Discovery regression — added a whitelist .gitignore fixture (/* then !/src/) asserting files under the re-included dir are discovered; exported getGraphableFiles for the test.
  4. Styleparse("lua" as unknown as Lang, source) to match the other dynamic grammars.

Local suite green for the touched areas; lint clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants