Some simple information syncing
This commit is contained in:
@@ -23,7 +23,18 @@ from StubGen import PythonToStubConverter
|
||||
|
||||
|
||||
def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object]) -> None:
|
||||
"""从 .pyi 文件中提取 CDefine 常量到 all_dc。文件不存在时静默跳过。"""
|
||||
"""从 .pyi 文件中提取 CDefine 常量到 all_dc。文件不存在时静默跳过。
|
||||
|
||||
治本修复:原实现只支持 ast.Constant 和 float() 调用,
|
||||
无法处理 t.CUnsignedLong(-11)(ast.Call)和
|
||||
FOREGROUND_GREEN | FOREGROUND_INTENSITY(ast.BinOp)等复杂表达式。
|
||||
现使用 ConstEvaluator.eval_full 统一求值,支持:
|
||||
- ast.Constant: 简单常量 (0x0002)
|
||||
- ast.Call: 类型构造 (t.CUnsignedLong(-11))
|
||||
- ast.BinOp: 位运算 (FOREGROUND_RED | FOREGROUND_GREEN)
|
||||
- ast.UnaryOp: 一元运算 (-11)
|
||||
- ast.Name: 引用其他 CDefine 常量
|
||||
"""
|
||||
if not os.path.exists(pyi_path):
|
||||
return
|
||||
try:
|
||||
@@ -31,16 +42,25 @@ def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object]) ->
|
||||
_, tree = parse_python_file(pyi_path)
|
||||
if tree is None:
|
||||
return
|
||||
# 治本修复:使用 ConstEvaluator 处理复杂表达式
|
||||
# 创建 mock Gen 对象,其 _define_constants 指向 all_dc,
|
||||
# 使 ConstEvaluator 能查找同文件中已提取的常量(如 FOREGROUND_RED 引用 FOREGROUND_BLUE)
|
||||
from lib.core.ConstEvaluator import ConstEvaluator, EvalContext
|
||||
|
||||
class _MockGen:
|
||||
"""轻量 mock,仅提供 _define_constants 供 ConstEvaluator 查找"""
|
||||
def __init__(self) -> None:
|
||||
self._define_constants: dict[str, object] = all_dc
|
||||
|
||||
mock_gen: _MockGen = _MockGen()
|
||||
ctx: EvalContext = EvalContext(Gen=mock_gen)
|
||||
|
||||
for node in ast.iter_child_nodes(tree):
|
||||
if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
|
||||
if AnnotationContainsName(node.annotation, 'CDefine') and node.value:
|
||||
val = None
|
||||
if isinstance(node.value, ast.Constant):
|
||||
val = node.value.value
|
||||
elif isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Name) and node.value.func.id == 'float' and node.value.args and isinstance(node.value.args[0], ast.Constant):
|
||||
val = node.value.args[0].value
|
||||
if val is not None:
|
||||
all_dc[f"{node.target.id}"] = val
|
||||
val: object = ConstEvaluator.eval_full(node.value, ctx)
|
||||
if val is not None and isinstance(val, (int, float, str)):
|
||||
all_dc[node.target.id] = val
|
||||
except Exception as e:
|
||||
_vlog().warning(f"Phase2Translator: 忽略异常 {e}", exc_info=e)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user