feat(cli): update highlighter with new nodes

This commit is contained in:
2026-05-25 22:14:44 +02:00
parent 4d23e8840e
commit bbd0e3ae8d
2 changed files with 45 additions and 26 deletions

View File

@@ -104,7 +104,12 @@ class Highlighter(ABC):
self.openings.setdefault((l + 1, 0), []).append(opening) self.openings.setdefault((l + 1, 0), []).append(opening)
class PythonHighlighter(Highlighter, p.Expr.Visitor[None]): class PythonHighlighter(
Highlighter,
p.MidasType.Visitor[None],
p.Stmt.Visitor[None],
p.Expr.Visitor[None],
):
EXTRA_CSS_PATH: Optional[Path] = Path(__file__).parent / "hl_python.css" EXTRA_CSS_PATH: Optional[Path] = Path(__file__).parent / "hl_python.css"
def highlight(self, node: Highlightable[PythonHighlighter]): def highlight(self, node: Highlightable[PythonHighlighter]):
@@ -130,15 +135,39 @@ class PythonHighlighter(Highlighter, p.Expr.Visitor[None]):
for column in node.columns: for column in node.columns:
column.accept(self) column.accept(self)
def visit_function(self, node: p.Function) -> None: def visit_expression_stmt(self, stmt: p.ExpressionStmt) -> None:
self.wrap(node, "function") stmt.expr.accept(self)
for arg in node.posonlyargs + node.args + node.kwonlyargs:
arg.accept(self)
def visit_function_argument(self, node: p.FunctionArgument) -> None: def visit_function(self, stmt: p.Function) -> None:
self.wrap(node, "argument") self.wrap(stmt, "function")
if node.type is not None: for arg in stmt.posonlyargs + stmt.args + stmt.kwonlyargs:
node.type.accept(self) self._highlight_function_argument(arg)
def _highlight_function_argument(self, arg: p.Function.Argument) -> None:
self.wrap(arg, "argument")
if arg.type is not None:
arg.type.accept(self)
def visit_type_assign(self, stmt: p.TypeAssign) -> None:
stmt.type.accept(self)
def visit_assign_expr(self, expr: p.AssignExpr) -> None: ...
def visit_binary_expr(self, expr: p.BinaryExpr) -> None: ...
def visit_unary_expr(self, expr: p.UnaryExpr) -> None: ...
def visit_call_expr(self, expr: p.CallExpr) -> None: ...
def visit_get_expr(self, expr: p.GetExpr) -> None: ...
def visit_literal_expr(self, expr: p.LiteralExpr) -> None: ...
def visit_variable_expr(self, expr: p.VariableExpr) -> None: ...
def visit_logical_expr(self, expr: p.LogicalExpr) -> None: ...
def visit_set_expr(self, expr: p.SetExpr) -> None: ...
class MidasHighlighter(Highlighter, m.Stmt.Visitor[None], m.Expr.Visitor[None]): class MidasHighlighter(Highlighter, m.Stmt.Visitor[None], m.Expr.Visitor[None]):

View File

@@ -5,6 +5,7 @@ import click
from midas.ast.location import Location from midas.ast.location import Location
import midas.ast.midas as m import midas.ast.midas as m
import midas.ast.python as p
from midas.ast.printer import PythonAstPrinter from midas.ast.printer import PythonAstPrinter
from midas.cli.highlighter import Highlighter, MidasHighlighter, PythonHighlighter from midas.cli.highlighter import Highlighter, MidasHighlighter, PythonHighlighter
from midas.lexer.midas import MidasLexer from midas.lexer.midas import MidasLexer
@@ -40,21 +41,13 @@ def dump_ast(output: Optional[TextIO], parse: bool, file: TextIO):
if parse: if parse:
parser = PythonParser() parser = PythonParser()
parser.visit(tree) stmts: list[p.Stmt] = parser.parse_module(tree)
printer = PythonAstPrinter() printer = PythonAstPrinter()
dump = "" dump = ""
for name, annotation in parser.annotations: for stmt in stmts:
dump += f"{name} = " dump += printer.print(stmt)
if annotation is None:
dump += "None"
else:
dump += printer.print(annotation)
dump += "\n" dump += "\n"
dump += "\n# Functions\n\n"
for func in parser.functions:
dump += printer.print(func) + "\n"
else: else:
dump = ast.dump(tree, indent=4) dump = ast.dump(tree, indent=4)
@@ -67,13 +60,10 @@ def dump_ast(output: Optional[TextIO], parse: bool, file: TextIO):
def highlight_python(source: str, path: str) -> Highlighter: def highlight_python(source: str, path: str) -> Highlighter:
tree: ast.Module = ast.parse(source, filename=path) tree: ast.Module = ast.parse(source, filename=path)
parser = PythonParser() parser = PythonParser()
parser.visit(tree) stmts: list[p.Stmt] = parser.parse_module(tree)
highlighter = PythonHighlighter(source) highlighter = PythonHighlighter(source)
for _, annotation in parser.annotations: for stmt in stmts:
if annotation is not None: highlighter.highlight(stmt)
highlighter.highlight(annotation)
for func in parser.functions:
highlighter.highlight(func)
return highlighter return highlighter