Some simple information syncing
This commit is contained in:
@@ -12,6 +12,8 @@ from lib.constants.config import mode as _config_mode
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.core.DecoratorPass import run as _run_decorator_pass
|
||||
from lib.core.SymbolUtils import IsTModule, AnnotationContainsName
|
||||
# 治本修复:导入 ConstEvaluator 用于预扫描 CDefine 常量的复杂表达式求值
|
||||
from lib.core.ConstEvaluator import ConstEvaluator
|
||||
|
||||
|
||||
class LlvmGeneratorMixin:
|
||||
@@ -59,26 +61,31 @@ class LlvmGeneratorMixin:
|
||||
Gen.known_return_types[Node.name] = ir.PointerType(ir.IntType(8))
|
||||
|
||||
# 首先收集所有 CDefine 常量,确保类定义中可以引用
|
||||
def _extract_call_const_val(node: ast.AST) -> int | str | float | None:
|
||||
if isinstance(node, ast.Call):
|
||||
if isinstance(node.func, ast.Attribute):
|
||||
if getattr(node.func.value, 'id', None) == 't':
|
||||
if node.args and isinstance(node.args[0], ast.Constant):
|
||||
return node.args[0].value
|
||||
elif isinstance(node.func, ast.Name):
|
||||
if node.args and isinstance(node.args[0], ast.Constant):
|
||||
return node.args[0].value
|
||||
return None
|
||||
def _extract_const_value(node: ast.AST) -> int | str | float | None:
|
||||
"""求值 CDefine 常量表达式,支持 Constant、BinOp、UnaryOp、Name(引用其他 define)、Call(类型构造)。
|
||||
|
||||
治本修复:原 _extract_call_const_val 只支持 t.XxxType(Constant) 形式,
|
||||
无法处理 FOREGROUND_WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
等引用其他 CDefine 的 BinOp 表达式,导致依赖常量无法被预扫描。
|
||||
现使用 ConstEvaluator.eval_with_symtab 统一求值。
|
||||
"""
|
||||
if isinstance(node, ast.Constant):
|
||||
return node.value
|
||||
# 使用 ConstEvaluator 处理 BinOp/UnaryOp/Name/Attribute/Call
|
||||
return ConstEvaluator.eval_with_symtab(node, self.SymbolTable)
|
||||
|
||||
for Node in ast.iter_child_nodes(Tree):
|
||||
if isinstance(Node, ast.AnnAssign) and isinstance(Node.target, ast.Name) and Node.value:
|
||||
TypeInfo: CTypeInfo | None = self.TypeMergeHandler.GetCTypeInfo(Node.annotation)
|
||||
if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine)):
|
||||
val: int | str | float | None = None
|
||||
if isinstance(Node.value, ast.Constant):
|
||||
val = Node.value.value
|
||||
else:
|
||||
val = _extract_call_const_val(Node.value)
|
||||
# 治本修复:检查 BaseType 是否为 t.CDefine 实例/子类,或 IsDefine 标志
|
||||
# IsDefine 由 GetCTypeInfo 对 t.CDefine 注解自动设置
|
||||
if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine) or TypeInfo.IsDefine):
|
||||
val: int | str | float | None = _extract_const_value(Node.value)
|
||||
import sys as _sys
|
||||
_nm = Node.target.id
|
||||
# [CD] 仅输出关键常量(FOREGROUND_*, STD_OUTPUT_HANDLE, BACKGROUND_*)
|
||||
if isinstance(_nm, str) and (_nm.startswith('FOREGROUND_') or _nm.startswith('BACKGROUND_') or 'STD_' in _nm or 'HANDLE' in _nm):
|
||||
print(f"[CD] extract: '{_nm}' IsDefine={TypeInfo.IsDefine} val={val}", file=_sys.stderr, flush=True)
|
||||
if val is not None:
|
||||
if not hasattr(Gen, '_define_constants'):
|
||||
Gen._define_constants: dict[str, int | str | float | bool] = {}
|
||||
@@ -89,6 +96,8 @@ class LlvmGeneratorMixin:
|
||||
sym_info.IsDefine = True
|
||||
sym_info.DefineValue = val
|
||||
self.SymbolTable.insert(Node.target.id, sym_info)
|
||||
else:
|
||||
print(f"[CD] extract: WARN val is None for '{_nm}'", file=_sys.stderr, flush=True)
|
||||
elif isinstance(Node, ast.Assign):
|
||||
for target in Node.targets:
|
||||
if isinstance(target, ast.Name):
|
||||
@@ -102,11 +111,7 @@ class LlvmGeneratorMixin:
|
||||
raise
|
||||
_vlog().warning(f"解析类型注释失败: {_e}", "Exception")
|
||||
if TypeInfo and TypeInfo.BaseType and ((isinstance(TypeInfo.BaseType, type) and issubclass(TypeInfo.BaseType, t.CDefine)) or isinstance(TypeInfo.BaseType, t.CDefine)):
|
||||
val: int | str | float | None = None
|
||||
if isinstance(Node.value, ast.Constant):
|
||||
val = Node.value.value
|
||||
else:
|
||||
val = _extract_call_const_val(Node.value)
|
||||
val: int | str | float | None = _extract_const_value(Node.value)
|
||||
if val is not None:
|
||||
if not hasattr(Gen, '_define_constants'):
|
||||
Gen._define_constants: dict[str, int | str | float | bool] = {}
|
||||
|
||||
Reference in New Issue
Block a user