| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import warnings
- from grep_ast import TreeContext, filename_to_lang
- from grep_ast.parsers import PARSERS
- from tree_sitter_languages import get_parser
- from openhands.linter.base import BaseLinter, LintResult
- # tree_sitter is throwing a FutureWarning
- warnings.simplefilter('ignore', category=FutureWarning)
- def tree_context(fname, code, line_nums):
- context = TreeContext(
- fname,
- code,
- color=False,
- line_number=True,
- child_context=False,
- last_line=False,
- margin=0,
- mark_lois=True,
- loi_pad=3,
- # header_max=30,
- show_top_of_file_parent_scope=False,
- )
- line_nums = set(line_nums)
- context.add_lines_of_interest(line_nums)
- context.add_context()
- output = context.format()
- return output
- def traverse_tree(node):
- """Traverses the tree to find errors."""
- errors = []
- if node.type == 'ERROR' or node.is_missing:
- line_no = node.start_point[0] + 1
- col_no = node.start_point[1] + 1
- error_type = 'Missing node' if node.is_missing else 'Syntax error'
- errors.append((line_no, col_no, error_type))
- for child in node.children:
- errors += traverse_tree(child)
- return errors
- class TreesitterBasicLinter(BaseLinter):
- @property
- def supported_extensions(self) -> list[str]:
- return list(PARSERS.keys())
- def lint(self, file_path: str) -> list[LintResult]:
- """Use tree-sitter to look for syntax errors, display them with tree context."""
- lang = filename_to_lang(file_path)
- if not lang:
- return []
- parser = get_parser(lang)
- with open(file_path, 'r') as f:
- code = f.read()
- tree = parser.parse(bytes(code, 'utf-8'))
- errors = traverse_tree(tree.root_node)
- if not errors:
- return []
- return [
- LintResult(
- file=file_path,
- line=int(line),
- column=int(col),
- message=error_details,
- )
- for line, col, error_details in errors
- ]
|