Skip to content

feat: add GDScript (Godot) as a supported language#316

Merged
tirth8205 merged 1 commit intotirth8205:mainfrom
woolfi182:feature/gdscript-support
Apr 18, 2026
Merged

feat: add GDScript (Godot) as a supported language#316
tirth8205 merged 1 commit intotirth8205:mainfrom
woolfi182:feature/gdscript-support

Conversation

@woolfi182
Copy link
Copy Markdown
Contributor

Summary

Adds GDScript — the scripting language for the Godot Engine — as a fully supported language in code-review-graph. GDScript uses the tree-sitter-gdscript grammar, already shipped in tree-sitter-language-pack as gdscript.abi3.so, so no new dependencies are required. .gd files are now parsed end-to-end: classes, functions, extends parent-class imports, and method calls all land in the graph.

What changed

code_review_graph/parser.py

  • Added ".gd": "gdscript" to EXTENSION_TO_LANGUAGE
  • Added "gdscript": ["class_definition", "class_name_statement"] to _CLASS_TYPES — covers inner classes (class Name:) and the file-level class_name Name identity declaration
  • Added "gdscript": ["function_definition"] to _FUNCTION_TYPES — covers func, static func, and annotated @onready func
  • Added "gdscript": ["extends_statement"] to _IMPORT_TYPES — treats the parent class / script path as a hard import dependency
  • Added "gdscript": ["call", "attribute_call"] to _CALL_TYPES — bare calls produce call; obj.method() is an attribute node whose right-hand side is an attribute_call
  • Added a gdscript branch to _extract_import() that resolves extends Node (type → identifier), extends "res://path.gd" (string literal), and extends SomeClass.Nested (type node)

tests/test_multilang.py

  • Added TestGDScriptParsing class with 10 unit tests covering: language detection, class_name extraction, inner-class extraction, top-level & inner-class function extraction, extends → IMPORTS_FROM edge, direct and attribute method calls, qualified-name resolution for same-file calls, and CONTAINS edge wiring for both the file and the inner class

tests/fixtures/sample.gd

  • New fixture exercising extends Node, class_name, const preload(...), signal, @export / @onready annotations, inner class with its own method, bare calls, attribute calls, and static func

CHANGELOG.md

  • Added GDScript entry under [Unreleased]

Node-type mapping

Semantic role GDScript tree-sitter node types Notes
_CLASS_TYPES class_definition, class_name_statement Inner class X: + file-level class_name X
_FUNCTION_TYPES function_definition Includes static func and annotated funcs
_IMPORT_TYPES extends_statement Parent class / script path as IMPORTS_FROM edge
_CALL_TYPES call, attribute_call attribute_call lives inside an attribute node for obj.method()

The generic _get_name() handler already covers GDScript — class_definition, class_name_statement, and function_definition all expose a child of type name — so no changes were needed to name extraction.

How to test

# Run the GDScript-specific tests
pytest tests/test_multilang.py::TestGDScriptParsing -v

# Run the full multilang + parser suite
pytest tests/test_multilang.py tests/test_parser.py -q

# Lint
ruff check code_review_graph/

Local run: 10 new tests pass, 234 parser/multilang tests pass in total, ruff clean.

Usage

# Any Godot project
code-review-graph build --full
code-review-graph status        # .gd files now appear in language breakdown

Example queries that now work on a Godot codebase:

  • get_impact_radius_tool({target: "ItemsManager.add_main_grid_item"}) — blast radius before editing a manager method
  • query_graph_tool({pattern: "callers_of", name: "_ready"}) — find every scene that overrides _ready
  • semantic_search_nodes_tool({query: "merge two items"}) — locate the merge logic by concept

Known gaps / future work

  • preload("res://x.gd") and load("res://x.gd") currently show up as CALLS edges with target preload / load. Promoting them to IMPORTS_FROM would require a bespoke _extract_gdscript_constructs hook (mirroring _extract_lua_constructs). Left out to keep this PR minimal.
  • .tscn (scene) and .tres (resource) files carry real cross-file dependencies via [ext_resource path="..."], but they have no tree-sitter grammar. A follow-up PR can add a regex-based handler — same pattern as _parse_notebook / _parse_databricks_py_notebook.
  • signal declarations are not modeled (no semantic role fits). They could be added as Type nodes later if signal-aware review becomes useful.

@woolfi182
Copy link
Copy Markdown
Contributor Author

@tirth8205 Can you please review? This is a base PR that support the language and I will create a few more to cover sources and scenes files soon

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