Skip to content

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

Open
SIRTHEO wants to merge 1 commit 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 1 commit into
giancarloerra:mainfrom
SIRTHEO:feat/lua-symbol-graph

Conversation

@SIRTHEO
Copy link
Copy Markdown

@SIRTHEO SIRTHEO commented Jun 2, 2026

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 filtering to ensure accurate file traversal during analysis

… .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
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

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: 993267fa-dbed-4d29-aad2-17d3479c5663

📥 Commits

Reviewing files that changed from the base of the PR and between 62fcf49 and d4bbb6c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • package.json
  • src/services/code-graph.ts
  • src/services/graph-symbols.ts

📝 Walkthrough

Walkthrough

This PR adds Lua language support to the code graph and symbol extraction system. The changes add a runtime dependency for the Lua AST grammar, register Lua as a dynamically-loaded language, implement Lua-specific symbol extraction from namespace-table and local function patterns, and refine directory traversal to use trailing slashes in ignore-filter matching.

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 alongside other dynamically-loaded ast-grep language grammars in ensureDynamicLanguages.
Directory traversal with trailing slash in ignore filter
src/services/code-graph.ts
Directory paths passed to shouldIgnore during file discovery now include a trailing slash suffix, changing which directories are matched and traversed.
Lua symbol and call-site extraction from AST
src/services/graph-symbols.ts
extractSymbolsAndCalls routes Lua files to extractFromLua, which extracts function symbols (namespace-table forms, local functions, and assignments), builds scope frames for each symbol, and collects call sites from Lua function_call nodes with scope attribution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit hops through Lua's graceful trees,
With ast-grep as our trusty guide—
Functions found in tables, scopes run free,
Call sites tracked with rabbit pride! 🌙

🚥 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 the two main changes: Lua symbol/call extraction and fixing file discovery for whitelist .gitignore.
Description check ✅ Passed The description includes a clear summary, detailed changes, testing verification, and notes. However, required template sections like Type of change and Checklist items are not filled out.
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
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

✅ 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.

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