Skip to content

Add Common Lisp support - #1187

Closed
fade wants to merge 8 commits into
Graphify-Labs:v8from
fade:commonlisp-v8
Closed

Add Common Lisp support#1187
fade wants to merge 8 commits into
Graphify-Labs:v8from
fade:commonlisp-v8

Conversation

@fade

@fade fade commented Jun 7, 2026

Copy link
Copy Markdown

What

Adds Common Lisp as a supported language. graphify now extracts a structural
knowledge graph from .lisp, .cl, .lsp, and .asd sources — packages, classes,
functions, methods, macros, generic-function dispatch, struct/type/condition
definitions, custom definer forms, reader-conditional and wrapper-macro bodies, and
call edges.

The grammar (tree-sitter-commonlisp) is wired as an optional extra
(graphifyy[commonlisp]), matching the policy for other niche grammars (sql, dm).

Why

Common Lisp is a conspicuous gap for a class of users — Lisp/AllegroGraph shops,
scientific and systems CL projects — who otherwise can't graph their codebases.
Common Lisp is homoiconic: every defun/defclass/defpackage parses to the same
list_lit node, so it can't be expressed through the declarative LanguageConfig
(which keys on tree-sitter node types). It needs a dedicated walker that classifies
forms by their definer symbol — provided here as a standalone extract_commonlisp,
registered in _DISPATCH alongside the other custom extractors (extract_sql,
extract_markdown).

Credit

The extractor and its test suite originate from @jansaasman's earlier
#172, which was opened against the pre-rewrite line and never merged.
This PR rebases that work onto v8, brings it into conformity with the
current extraction schema and contribution conventions, and adds the
integration. Every commit carries their co-authorship.

What's included

  • extract_commonlisp walker + detect.py/_DISPATCH registration for .lisp/.cl/.lsp/.asd
  • tree-sitter-commonlisp as an optional extra (kept out of core dependencies)
  • 23 extraction tests in tests/test_languages.py + tests/fixtures/sample.lisp
  • README supported-extensions table (28 → 29 grammars) and the commonlisp extras row

Reviewer notes

  • Rationale nodes: docstring-derived nodes are emitted with file_type="rationale"
    so the cross-file resolution filter excludes them, consistent with the Python extractor.
  • Grammar deprecation: tree-sitter-commonlisp 0.4.1 (latest) returns an int pointer
    that tree_sitter.Language only accepts via a deprecated path; that single warning is
    suppressed at the construction site with an explanatory comment. Glad to switch to a
    capsule-based construction if/when the grammar ships one.
  • Suite: language, cache, and detect suites pass (411 passed, 22 skipped locally).

🄯 Brian O'Reilly fade@deepsky.com, 2026

fade and others added 8 commits June 7, 2026 15:44
Add an imperative tree-sitter-commonlisp walker that extracts packages,
classes, functions, methods, macros, generic-function dispatch, and calls
from Common Lisp source. Registered alongside the other custom extractors
so homoiconic CL — where every defXXX form is the same list_lit node — is
classified by reading definer symbols rather than tree-sitter node types.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
Emit docstring-derived rationale nodes with file_type "rationale" instead
of "code" so the cross-file resolution filter excludes them, keeping
docstrings out of import and symbol-resolution edges.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
Classify .lisp/.cl/.lsp/.asd as code and route them to the Common Lisp
extractor so ASDF systems and source files build into the graph.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
Declare the Common Lisp grammar under optional-dependencies, matching the
policy for other niche grammars, so the core install stays lean and Lisp
users opt in with the commonlisp extra.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
Add the sample.lisp fixture and the Common Lisp extraction tests covering
packages, classes, defuns, generics, macros, method specializers,
inheritance, imports, custom definers, reader conditionals, and docstring
rationale typing.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
The latest tree-sitter-commonlisp release returns an int pointer that the
tree-sitter runtime only accepts via a deprecated path, so extracting Lisp
spewed a DeprecationWarning per file. Suppress that one warning at the
construction site so Lisp extraction runs clean.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
Move the Common Lisp extraction tests into the language-extractor suite
where the project keeps per-language coverage, so they sit with their peers
rather than in the general multi-language file.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
Surface Common Lisp in the supported-extensions table and add the
commonlisp optional-extra row so users know the grammar exists and how to
install it.

🄯 Brian O'Reilly <fade@deepsky.com>, 2026

Co-authored-by: jansaasman <ja@franz.com>
@fade

fade commented Jul 28, 2026

Copy link
Copy Markdown
Author

Closing this in favour of #2274, which supersedes it.

This branch had gone stale and conflicting against v8. The replacement is rebased onto
current v8, and the extractor now lives in graphify/extractors/commonlisp.py following
extractors/MIGRATION.md and #1212, rather than adding to extract.py. It also keeps the
lineage from #172 by @jansaasman explicit.

Nothing is lost by closing this one; #2274 is the same feature, brought up to date.

@fade fade closed this Jul 28, 2026
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.

1 participant