Some simple information syncing

This commit is contained in:
2026-07-28 21:08:58 +08:00
parent 1837339f69
commit 3633be1995
65 changed files with 1132 additions and 368581 deletions

View File

@@ -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_INTENSITYast.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)