Tree-sitter Parsers in Graphify: Complete Configuration Guide

Tree-sitter parsers in Graphify are controlled through the LanguageConfig dataclass in graphify/extractors/models.py, which exposes over 20 configuration fields specifying node types, field names, and optional callbacks that customize how the generic extraction engine parses language-specific syntax trees.

Graphify relies on Tree-sitter grammars to extract abstract syntax trees (ASTs) from source code. Rather than hardcoding language logic, the framework uses a declarative configuration system that allows fine-grained control over parser behavior. The LanguageConfig dataclass serves as the central contract between language-specific extractors and the generic engine located in graphify/extractors/engine.py.

Core Configuration Structure

All Tree-sitter parser behavior in Graphify flows through the LanguageConfig dataclass. This single structure defines which compiled Tree-sitter module to load, which node types represent classes and functions, how to resolve identifier names, and how to traverse call expressions.

According to the Graphify source code, the engine imports this configuration and uses it to drive the AST walker without requiring language-specific hardcoding in the core logic.

Key Configuration Categories

Parser Loading Options

Two fields control how Graphify loads the compiled Tree-sitter library:

  • ts_module (str): The Python module name providing the compiled language (e.g., "tree_sitter_python"). This is required for every configuration.
  • ts_language_fn (str, default "language"): The attribute name on the module that returns the Language object. Most parsers expose this as language(), but custom builds may use different names.

Node Type Definitions

These frozenset fields map Graphify's internal concepts to specific Tree-sitter node type strings:

  • class_types: Node types representing class-like definitions (e.g., {"class_declaration", "struct"}).
  • function_types: Node types for function or method definitions (e.g., {"function_definition", "method_definition"}).
  • import_types: Node types representing import statements (e.g., {"import_statement", "using_directive"}).
  • call_types: Node types denoting call expressions (e.g., {"call_expression", "method_invocation"}).
  • static_prop_types: Node types for static property declarations.
  • function_boundary_types: Node types where the recursive call-walker should stop to prevent infinite recursion in nested constructs like lambdas.

Specialized Recognition Fields

Graphify supports complex language constructs through additional node type sets:

  • helper_fn_names: Function names treated as "inline" (e.g., getters) during call walking.
  • container_bind_methods: Method names that bind containers (e.g., C++ operator=), helping the engine stop recursion appropriately.
  • event_listener_properties: Property names representing event listeners (e.g., JavaScript onClick).

Field Resolution

These string fields specify which Tree-sitter node attributes contain key metadata:

  • name_field (str, default "name"): The field storing the identifier name. Some languages use "identifier" instead.
  • name_fallback_child_types (tuple): Alternate child node types to search when name_field is missing.
  • body_field (str, default "body"): The field containing a declaration's executable body.
  • body_fallback_child_types (tuple): Alternate child types when body_field is absent (e.g., compound_statement).

Call Graph Construction

Four fields control how the engine resolves method calls and member access:

  • call_function_field (str, default "function"): The field on a call node pointing to the callee.
  • call_accessor_node_types (frozenset): Node types for member access (e.g., member_expression).
  • call_accessor_field (str, default "attribute"): The field on an accessor node holding the member name.
  • call_accessor_object_field (str, default ""): Optional field storing the receiver/object (e.g., for this in C#).

Language-Specific Hooks

Three optional callbacks enable custom logic:

  • import_handler (Callable | None): Custom handler for import nodes, enabling language-specific resolution such as Go's dot imports.
  • resolve_function_name_fn (Callable | None): Hook to post-process function names (e.g., unwrap C/C++ declarators).
  • extra_walk_fn (Callable | None): Hook executed after the generic walk for a node, useful for extensions like JavaScript arrow functions or C# namespaces.

Display Options

  • function_label_parens (bool, default True): When True, appends () to function node labels in the generated graph for improved readability.

Practical Configuration Examples

Basic Python Configuration

This example configures the Python parser using standard Tree-sitter node types:

from graphify.extractors.models import LanguageConfig

python_cfg = LanguageConfig(
    ts_module="tree_sitter_python",
    class_types=frozenset({"class_definition"}),
    function_types=frozenset({"function_definition", "lambda"}),
    import_types=frozenset({"import_statement", "import_from_statement"}),
    call_types=frozenset({"call"}),
    name_field="name",
    body_field="body",
    call_function_field="function",
    call_accessor_node_types=frozenset({"attribute", "subscript"}),
    call_accessor_field="attribute",
)

Source: graphify/extractors/models.py

JavaScript/TypeScript with Extra Walk Hook

This configuration demonstrates using extra_walk_fn to handle anonymous arrow functions:

def js_extra_walk(node, ctx):
    # Arrow functions have their body under the "body" field but lack a name.

    if node.type == "arrow_function":
        ctx.add_anonymous_function(node)

js_cfg = LanguageConfig(
    ts_module="tree_sitter_javascript",
    class_types=frozenset({"class_declaration"}),
    function_types=frozenset({"function_declaration", "method_definition", "arrow_function"}),
    import_types=frozenset({"import_statement", "export_statement"}),
    call_types=frozenset({"call_expression"}),
    call_accessor_node_types=frozenset({"member_expression"}),
    extra_walk_fn=js_extra_walk,
)

Source: graphify/extractors/engine.py

Custom Import Handler for Go

This example shows how to implement language-specific import resolution using import_handler:

def go_import_handler(node, ctx):
    # Go's import specs may contain a dot import; treat specially.

    if node.type == "dot_import":
        ctx.register_dot_import(node)

go_cfg = LanguageConfig(
    ts_module="tree_sitter_go",
    import_handler=go_import_handler,
    class_types=frozenset({"type_declaration"}),
    function_types=frozenset({"function_declaration"}),
    call_types=frozenset({"call_expression"}),
)

Source: graphify/extractors/engine.py

Using the Configuration

Once defined, pass the configuration to the generic extractor:

from graphify.extractors.engine import extract_generic

# source_bytes contains the file contents.

graph = extract_generic(source_bytes, config=python_cfg)

Source: graphify/extractors/engine.py

How the Engine Interprets These Settings

The generic extraction engine in graphify/extractors/engine.py reads the supplied LanguageConfig and applies it during the AST traversal. The engine uses class_types and function_types to locate definitions, name_field and body_field to extract identifiers and implementation blocks, and call_types combined with call_accessor_* fields to build call graphs.

Because the configuration is a plain dataclass, adding support for a new language requires only constructing a LanguageConfig instance with appropriate node-type strings and optional callbacks, then passing it to the engine via the language-specific extractor (e.g., graphify/extractors/python.py or graphify/extractors/javascript.py).

Summary

  • The LanguageConfig dataclass in graphify/extractors/models.py defines all Tree-sitter parser configuration options in Graphify.
  • Required fields include ts_module (specifying the parser library) and various node type sets (class_types, function_types, call_types).
  • Field resolution is controlled through name_field, body_field, and their fallback counterparts.
  • Call graph construction relies on call_function_field, call_accessor_node_types, and call_accessor_field.
  • Language-specific customization is enabled through optional callbacks: import_handler, resolve_function_name_fn, and extra_walk_fn.
  • The generic engine in graphify/extractors/engine.py consumes these configurations to perform language-agnostic AST extraction.

Frequently Asked Questions

What is the minimum required configuration for a new language in Graphify?

At minimum, you must specify ts_module (the Tree-sitter Python module name) and define the core node type sets: class_types, function_types, import_types, and call_types. Without these, the generic engine cannot identify definitions or calls in the AST. You may also need to adjust name_field if the language uses a non-standard identifier field.

How does Graphify handle languages with different naming conventions for AST nodes?

Use the name_field and name_fallback_child_types options. If a language stores identifiers in a field other than name, set name_field to the correct attribute name (e.g., "identifier"). If the name might be stored in different node types depending on context, populate name_fallback_child_types with a tuple of alternative node types to search.

Can I customize how Graphify resolves imports for a specific language?

Yes. Provide a callable to the import_handler field in LanguageConfig. This callback receives the import node and the extraction context, allowing you to implement language-specific logic such as handling Go's dot imports or Python's relative imports. The engine invokes this handler instead of the generic import processing logic when it is provided.

What is the purpose of the extra_walk_fn callback?

The extra_walk_fn callback allows you to extend the generic AST traversal with language-specific logic. It is executed after the generic walk for each node. For example, JavaScript extractors use this to handle arrow functions, which lack a name field but require special handling to register as anonymous functions in the call graph.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →