fix(cli): ignore repeated visit of types

This commit is contained in:
2026-06-01 14:10:07 +02:00
parent 86ad348b99
commit 5d4df7978b
2 changed files with 33 additions and 11 deletions

View File

@@ -3,7 +3,7 @@ import json
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import Optional, TextIO from typing import Optional, TextIO, get_args
import click import click
@@ -13,7 +13,13 @@ from midas.ast.location import Location
from midas.ast.printer import MidasAstPrinter, PythonAstPrinter from midas.ast.printer import MidasAstPrinter, PythonAstPrinter
from midas.checker.checker import Checker from midas.checker.checker import Checker
from midas.checker.diagnostic import Diagnostic from midas.checker.diagnostic import Diagnostic
from midas.cli.highlighter import DiagnosticsHighlighter, Highlighter, MidasHighlighter, PythonHighlighter from midas.checker.types import Type
from midas.cli.highlighter import (
DiagnosticsHighlighter,
Highlighter,
MidasHighlighter,
PythonHighlighter,
)
from midas.lexer.midas import MidasLexer from midas.lexer.midas import MidasLexer
from midas.lexer.token import Token, TokenType from midas.lexer.token import Token, TokenType
from midas.parser.midas import MidasParser from midas.parser.midas import MidasParser
@@ -46,7 +52,9 @@ def compile(highlight: Optional[TextIO], file: TextIO):
print( print(
json.dumps( json.dumps(
UniversalJSONDumper.dump( UniversalJSONDumper.dump(
checker.global_env, [("Environment", "_children")] checker.global_env,
[("Environment", "_children")],
lambda obj: isinstance(obj, get_args(Type)),
), ),
indent=4, indent=4,
) )

View File

@@ -1,18 +1,27 @@
from typing import Any, Optional from typing import Any, Callable, Optional
AllowRepeat = Callable[[object], bool]
class UniversalJSONDumper: class UniversalJSONDumper:
@classmethod @classmethod
def dump( def dump(
cls, obj: Any, include_keys: Optional[list[str | tuple[str, str]]] = None cls,
obj: Any,
include_keys: Optional[list[str | tuple[str, str]]] = None,
allow_repeat: Optional[AllowRepeat] = None,
) -> Any: ) -> Any:
if include_keys is None: if include_keys is None:
include_keys = [] include_keys = []
return cls._dump(obj, include_keys, []) return cls._dump(obj, include_keys, allow_repeat, [])
@classmethod @classmethod
def _dump( def _dump(
cls, obj: Any, include_keys: list[str | tuple[str, str]], visited: list[Any] cls,
obj: Any,
include_keys: list[str | tuple[str, str]],
allow_repeat: Optional[AllowRepeat],
visited: list[Any],
) -> Any: ) -> Any:
if obj in visited: if obj in visited:
return None return None
@@ -20,17 +29,22 @@ class UniversalJSONDumper:
case str() | int() | float() | None: case str() | int() | float() | None:
return obj return obj
case list() | set() | tuple(): case list() | set() | tuple():
return [cls._dump(child, include_keys, visited) for child in obj] return [
cls._dump(child, include_keys, allow_repeat, visited)
for child in obj
]
case dict(): case dict():
return { return {
str(k): cls._dump(v, include_keys, visited) for k, v in obj.items() str(k): cls._dump(v, include_keys, allow_repeat, visited)
for k, v in obj.items()
} }
case object(): case object():
if allow_repeat is None or not allow_repeat(obj):
visited.append(obj) visited.append(obj)
return { return {
"_type": obj.__class__.__name__, "_type": obj.__class__.__name__,
} | { } | {
k: cls._dump(v, include_keys, visited) k: cls._dump(v, include_keys, allow_repeat, visited)
for k, v in obj.__dict__.items() for k, v in obj.__dict__.items()
if not k.startswith("_") if not k.startswith("_")
or k in include_keys or k in include_keys