Repository navigation
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
- Update checks.yaml to run pylint and mypy on changed files only. - Import tree_sitter_base.py from PR google#21 to validate GHA Python checks.
|
Thank you for these contributions (PR#21 through PR#25) to integrate Tree-sitter! To help us test and import these changes successfully, could you please consolidate these 5 PRs into a single pull request? (Note: A single PR can still contain multiple commits). Alternatively, if they need to remain separate, please re-structure them so they can be merged independently. Why this is needed: Our continuous integration and import pipeline requires changes to be validated atomically. Because these five PRs depend on one another, testing them individually causes temporary compilation and test failures during import. Having them in a single PR allows us to run validation checks on the complete integration at once. Author Attribution: We want to ensure everyone who contributed gets proper credit. When the consolidated change is imported:
As outlined in the GitHub documentation, Thank you for your co-operation and assistance! |
|
Thanks for this info. Let me share a single PR with all the changes! |
@varungoyal-ittiam - single PR with all commits has been raised: #27 |
|
Thanks for the quick reply and for consolidating the PRs! I've verified the import configuration locally and confirmed that the author attribution is captured as per the individual commit information:
|
Summary
Adds
TreeSitterParserBase, a shared abstract base class that sits betweenAbstractLanguageParserand any future tree-sitter-backed language parser. This PR introduces the infrastructure layer only, no language-specific logic is included. The first concrete subclass (PythonParser) follows in a separate PR.Objective
Vanir's parser pipeline expects every language parser to produce a
ParseResultsobject containing:function_chunks- oneFunctionChunkBaseper function, carrying its name, parameters, return types, used data types, local variables, called functions, and raw tokensline_chunk- aLineChunkBasewith all file tokens grouped by line number, used for line-based signature matchingparse_errors- a list ofParseErrorfor any syntax errors encounteredExisting parsers (C/C++, Java) fulfill this contract via ANTLR4 grammars. This PR fulfills the same contract using tree-sitter, enabling faster parser development for new languages with no grammar compilation step.
Implementation
tree_sitter_base.pyTreeSitterParserBase(class)The core class. Subclasses set three class-level attributes:
LANGUAGE- atree_sitter.Languageinstance for the target language_FUNC_QUERY- a compiled tree-sitterQueryfor matching function definitionsSKIP_TOKEN_TYPES- afrozensetof node types to exclude from token collection (e.g. comments)STRING_NODE_TYPE- the node type to treat as an opaque string token (default:'string')__init__(filename)Parserwith the subclass'sLANGUAGEself._tree)Parser,tree_sitter.Languageget_chunks(affected_line_ranges_for_functions), main pipelineImplements the full
ParseResultsassembly in four steps:Step 1, Function discovery
_FUNC_QUERYagainst the root node usingQueryCursorfunc.defandfunc.namecapture groups from each matchQueryCursor,Query.matches(), named capturesStep 2, FunctionChunkBase construction
start_point/end_pointaffected_line_ranges_for_functionsusing_overlaps()func.namecapture nodeparameterschild field viachild_by_field_name('parameters')_flat_tokens_cursor()Step 3, LineChunkBase construction
_collect_tokens_cursor()over the entire root nodedict[int, list[str]]mapping line numbers to token listsLineChunkBaseStep 4, Parse error collection
_collect_errors_cursor()to find allERRORnodes in the treeParseErrorwith line, column, and token previewCursor utility functions
_collect_tokens_cursor(node, skip_types, string_type, out_dict)TreeCursor(avoids Python recursion limits)skip_types(e.g. comments, decorators)string_typeas a single opaque tokenout_dict[line_number] → [token, ...]node.walk(),TreeCursor.goto_first_child(),goto_next_sibling(),goto_parent(),node.text,node.start_point_flat_tokens_cursor(node, skip_types, string_type)_collect_tokens_cursor()_collect_errors_cursor(root)ERRORnodes and returns them asParseErrorobjectsnode.type == 'ERROR',node.start_point,node.text_overlaps(func_start, func_end, ranges)Trueif a function's line range overlaps any of the provided affected line rangesrangesmeans no filter (include all functions)Abstract methods (subclasses must implement)
_extract_param_names(params_node) → list[str]Extracts ordered parameter name strings from a tree-sitter
parametersnode. Subclasses traverse the parameter node's children according to the language's grammar (e.g.identifier,typed_parameter,default_parameter)._extract_annotations(func_node) → (return_types, used_data_types)Extracts type annotation information from a function definition node:
return_types- list of token lists from the return type annotation (empty if none)used_data_types- list of token lists, one per annotated parameter_collect_locals_calls(body_node, nested_ranges) → (local_vars, called_fns)Walks the function body node to collect:
local_vars- set of locally assigned variable namescalled_fns- set of called function namesnested_ranges- byte ranges of nested functions to exclude from collection, preventing inner-scope variables from leaking into the outer function's signatureDesign decisions
TreeCursorinstead of recursive calls.Dependencies
This PR is independent and can be merged alongside:
feat/python-parser-depsfeat/python-parser-buildbug/fix-subclass-discoveryIt must be merged before
feat/python-parser.