C-Family Tree-sitter Analyzers
August 6, 2026 · View on GitHub
Purpose
This module provides the static-analysis front end for the C-family of programming languages — C, C++, C#, Java, and Kotlin — inside CodeWiki's Dependency Analysis Service. Each analyzer parses a single source file with a tree-sitter grammar and produces two things that the rest of the pipeline consumes:
Noderecords — one per top-level declaration (class, struct, interface, function, method, global variable, type alias, …) representing a documentable "component".CallRelationshiprecords — directed edges describing how those components reference each other (calls, inheritance, field/property types, object creation, …).
These analyzers do not attempt full semantic resolution (that would
require a real compiler front end). Instead, each one performs the
best-effort, file-local resolution that is possible from syntax alone, and
emits unresolved relationships (is_resolved=False) whenever a target
cannot be pinned down within the file. The heavy lifting of matching those
unresolved edges to real components anywhere in the repository — and of
deciding which un-matched edges are truly external (standard library,
third-party) rather than real gaps — is centralized in
CallGraphAnalyzer, which every analyzer in
this module is designed to feed.
Where this module sits in the system
graph TD
RA["RepoAnalyzer<br/>(file discovery)"] --> AS["AnalysisService"]
AS --> CGA["CallGraphAnalyzer"]
CGA -->|"routes by file extension/language"| ThisModule["C-Family Tree-sitter Analyzers<br/>(this module)"]
CGA -->|"routes by file extension/language"| JSTS["JavaScript_TypeScript_Analyzers.md"]
CGA -->|"routes by file extension/language"| PHP["PHP_Analyzer.md"]
CGA -->|"routes by file extension/language"| PY["Python_Analyzer.md"]
ThisModule -->|"Node + CallRelationship lists"| CGA
CGA -->|"cross-file resolution + external filtering"| DP["DependencyParser"]
DP --> DGB["DependencyGraphBuilder"]
DGB --> Docs["Documentation Generator"]
click AS "Dependency_Analysis_Service.md"
click CGA "Dependency_Analysis_Service.md"
click DP "Dependency_Analyzer_Core.md"
click DGB "Dependency_Analyzer_Core.md"
click Docs "Backend_LLM_&_Documentation_Services_documentation_generator.md"
Dependency_Analysis_ServiceownsCallGraphAnalyzer, which discovers source files, dispatches each file to the language-appropriate analyzer (including the ones documented here), and then performs cross-file symbol resolution and external-symbol filtering over the combined output of all language analyzers.Dependency_Analyzer_Coredefines the shared data models (Node,CallRelationship) that every analyzer — in this module and its sibling language modules — must produce, plus theDependencyParserandDependencyGraphBuilderthat turn the resolved call graph into the dependency graph used for documentation generation.- Sibling language front ends live in
JavaScript_TypeScript_Analyzers,PHP_Analyzer, andPython_Analyzer— architecturally identical in role, just for different grammars.
Shared data contract
Every analyzer in this module builds instances of the same two Pydantic
models (defined in Dependency_Analyzer_Core):
classDiagram
class Node {
+str id
+str name
+str component_type
+str file_path
+str relative_path
+str source_code
+int start_line
+int end_line
+str docstring
+str node_type
+str class_name
+str display_name
+str component_id
+str language
+str qualified_name
+Set~str~ depends_on
}
class CallRelationship {
+str caller
+str callee
+int call_line
+bool is_resolved
}
Node "1" --> "*" CallRelationship : caller/callee reference Node.id
Node.id/Node.component_idare built as"{relative_path_from_repo_root}::{qualified_name}", e.g.src/Foo.cpp::Logger.write. This is the canonical identifier every other module in CodeWiki (documentation generator, HTML viewer, MCP tools) uses to refer to a piece of code.CallRelationship.is_resolvedis the key coordination flag withCallGraphAnalyzer:Truemeans the analyzer is confident thecalleeis an exactNode.id(usually a same-file resolution).Falsemeans the analyzer only knows a name — simple, qualified, or dotted — and is delegating final resolution toCallGraphAnalyzer's repository-wide indexes (_resolve_call_relationships,_build_resolution_indexes) and its external-symbol classifier (_is_external_callee).
Common analyzer architecture
Despite covering five different languages with very different grammars, all five analyzers in this module follow the same three-phase pipeline:
sequenceDiagram
participant CGA as CallGraphAnalyzer
participant AN as Tree-sitter Analyzer
participant TS as tree-sitter grammar
participant Model as Node / CallRelationship
CGA->>AN: analyze_<lang>_file(file_path, content, repo_path)
AN->>TS: Parser(Language).parse(content)
TS-->>AN: syntax tree (root node)
AN->>AN: _extract_nodes(root) — walk tree, build top_level_nodes map
AN->>Model: construct Node per declaration
AN->>AN: _extract_relationships(root, top_level_nodes)
AN->>Model: construct CallRelationship per reference
AN-->>CGA: (nodes, call_relationships)
- Parse — each analyzer instantiates its own
tree_sitter.Languagebinding (tree_sitter_c,tree_sitter_cpp,tree_sitter_c_sharp,tree_sitter_java,tree_sitter_kotlin) and parses the file content into a syntax tree. _extract_nodes— a recursive tree walk that recognizes language-specific declaration node types (function_definition,class_declaration,method_declaration, …), builds aNodefor each, and populates atop_level_nodeslookup dict (by simple name, qualified name, and/or component id) used later for local resolution._extract_relationships— a second recursive walk that recognizes reference sites (calls,new/object-creation, inheritance clauses, field / property type annotations) and emits aCallRelationshipfor each, resolving locally when possible and leavingis_resolved=Falseotherwise.
Every analyzer also implements the same pair of path helpers so that
Node.id is consistent across languages:
_get_relative_path()— path of the file relative torepo_path._get_component_id(name, parent_class=None)—"{relative_path}::{name}", or"{relative_path}::{parent_class}.{name}"for members.
Sub-modules
Because the five languages split naturally into families that share resolution strategy and complexity level, this module's detailed documentation is organized into three sub-modules:
| Sub-module | Languages | Focus |
|---|---|---|
| C-Family_Tree-sitter_Analyzers_C_Cpp | C, C++ | Positional/textual analysis, macro-tolerant parsing recovery for C++, no import/namespace system to resolve against |
| C-Family_Tree-sitter_Analyzers_JVM | Java, Kotlin | Package/import-aware resolution, JDK filtering, variable-type tracking for member-call resolution |
| C-Family_Tree-sitter_Analyzers_CSharp | C# | using/alias-aware resolution, namespace declarations (block and file-scoped), static-import fallback |
Each sub-module page documents its analyzer(s) in depth: which AST node types are recognized, how names are qualified, how member/variable types are tracked for call resolution, and language-specific edge cases (macros, partial classes, generics, primary constructors, etc.).
How output feeds the rest of the pipeline
flowchart LR
subgraph "This module"
A1["TreeSitterCAnalyzer"]
A2["TreeSitterCppAnalyzer"]
A3["TreeSitterCSharpAnalyzer"]
A4["TreeSitterJavaAnalyzer"]
A5["TreeSitterKotlinAnalyzer"]
end
A1 & A2 & A3 & A4 & A5 --> Funcs["functions: List[Node]"]
A1 & A2 & A3 & A4 & A5 --> Rels["relationships: List[CallRelationship]"]
Funcs --> Resolve["CallGraphAnalyzer._resolve_call_relationships"]
Rels --> Resolve
Resolve --> Filter["CallGraphAnalyzer._is_external_callee<br/>(drops stdlib / third-party edges)"]
Filter --> Graph["Complete call graph<br/>(functions + resolved relationships)"]
Graph --> DP["DependencyParser._build_components_from_analysis"]
DP --> DGB["DependencyGraphBuilder"]
DGB --> Gen["DocumentationGenerator"]
CallGraphAnalyzer dispatches to this module's analyzers based on file
language (_analyze_c_file, _analyze_cpp_file, _analyze_csharp_file,
_analyze_java_file, _analyze_kotlin_file), including a special routing
step (_route_contextual_headers) that decides whether an ambiguous .h
header should be parsed as C or C++ based on content signals and the
repository's overall file mix. See
Dependency_Analysis_Service for full detail
on cross-file resolution and external-symbol filtering, and
Dependency_Analyzer_Core for the Node /
CallRelationship schema and how the resolved graph becomes the final
dependency graph used by
documentation generation.