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 theLanguageobject. Most parsers expose this aslanguage(), 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., JavaScriptonClick).
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 whenname_fieldis missing.body_field(str, default"body"): The field containing a declaration's executable body.body_fallback_child_types(tuple): Alternate child types whenbody_fieldis 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., forthisin 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, defaultTrue): WhenTrue, 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
LanguageConfigdataclass ingraphify/extractors/models.pydefines 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, andcall_accessor_field. - Language-specific customization is enabled through optional callbacks:
import_handler,resolve_function_name_fn, andextra_walk_fn. - The generic engine in
graphify/extractors/engine.pyconsumes 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →