refactor(type): 全面清理旧联合与 t/c 标记判断
审计并修复 23 个文件:类型注解中的 T1 | T2 一律 fail-fast;typedef/define/export/extern/static/const/volatile/attribute 优先读取 Markers/Attributes/ByteOrder/BitWidth;指针统一 CPtr/rawptr/CRef/CTempRef/CArrayPtr/CAutoPtr Subscript;stub 输出统一新语法。
This commit is contained in:
1 parent
a410de2cf7
commit
0bded58999
23 files changed
+887
-694
No files matched your search
@@ -97,11 +97,9 @@ class DeclarationGenerator:
|
||||
Markers: tuple[str, ...] = tuple(getattr(node, 'Markers', None) or ()) + tuple(
|
||||
getattr(node.annotation, 'Markers', None) or ())
|
||||
is_typedef: bool = 'typedef' in Markers
|
||||
if not is_typedef:
|
||||
if isinstance(node.annotation, ast.Attribute) and getattr(node.annotation, 'attr', '') == 'CTypedef':
|
||||
is_typedef = True
|
||||
elif isinstance(node.annotation, ast.Name) and node.annotation.id == 'CTypedef':
|
||||
is_typedef = True
|
||||
if not is_typedef and AnnotationContainsName(node.annotation, 'CTypedef'):
|
||||
# 兼容旧写法 `名字: CTypedef = 类型`(仅文本判据回落)。
|
||||
is_typedef = True
|
||||
if is_typedef and node.value:
|
||||
self.typedef_map[var_name] = node.value
|
||||
|
||||
@@ -230,22 +228,33 @@ class DeclarationGenerator:
|
||||
return f'declare {ret_type} @{func_name}({param_str})'
|
||||
|
||||
def _is_export_func(self, node: ast.FunctionDef) -> bool:
|
||||
"""检查函数是否标记为 CExport"""
|
||||
"""检查函数是否导出/外部可见(export / extern / state)。
|
||||
|
||||
新语法的 `export def` / `extern def` 由解析器写入 FunctionDef.Export /
|
||||
Extern;旧语法的 `-> CExport | T` / `-> State | T` 仍走注解兼容判据。
|
||||
"""
|
||||
if bool(getattr(node, 'Export', False)) or bool(getattr(node, 'Extern', False)):
|
||||
return True
|
||||
Markers: tuple[str, ...] = getattr(node, 'Markers', None) or ()
|
||||
if 'export' in Markers or 'state' in Markers:
|
||||
if 'export' in Markers or 'extern' in Markers or 'state' in Markers:
|
||||
return True
|
||||
if not node.returns:
|
||||
return False
|
||||
return self._check_annotation_for_export(node.returns)
|
||||
|
||||
def _check_annotation_for_export(self, annotation: ast.AST | None) -> bool:
|
||||
"""检查类型注解是否带 export / state 标记"""
|
||||
"""检查类型注解是否带 export / extern / state 标记。
|
||||
|
||||
优先读 AST 的 Markers 字段;旧的 CExport/State 文本判断仅作兼容。
|
||||
"""
|
||||
if annotation is None:
|
||||
return False
|
||||
Markers: tuple[str, ...] = getattr(annotation, 'Markers', None) or ()
|
||||
if 'export' in Markers or 'state' in Markers:
|
||||
if 'export' in Markers or 'extern' in Markers or 'state' in Markers:
|
||||
return True
|
||||
return AnnotationContainsName(annotation, 'CExport') or AnnotationContainsName(annotation, 'State')
|
||||
return (AnnotationContainsName(annotation, 'CExport')
|
||||
or AnnotationContainsName(annotation, 'CExtern')
|
||||
or AnnotationContainsName(annotation, 'State'))
|
||||
|
||||
def _generate_global_decl(self, node: ast.AnnAssign) -> str | None:
|
||||
"""生成全局变量声明"""
|
||||
@@ -258,11 +267,7 @@ class DeclarationGenerator:
|
||||
getattr(node.annotation, 'Markers', None) or ())
|
||||
if 'define' in Markers or AnnotationContainsName(node.annotation, 'CDefine'):
|
||||
return None
|
||||
if 'typedef' in Markers:
|
||||
return None
|
||||
if isinstance(node.annotation, ast.Attribute) and getattr(node.annotation, 'attr', '') == 'CTypedef':
|
||||
return None
|
||||
if isinstance(node.annotation, ast.Name) and node.annotation.id == 'CTypedef':
|
||||
if 'typedef' in Markers or AnnotationContainsName(node.annotation, 'CTypedef'):
|
||||
return None
|
||||
if isinstance(node.annotation, ast.List):
|
||||
for elt in node.annotation.elts:
|
||||
@@ -1145,7 +1150,8 @@ class DeclarationGenerator:
|
||||
Line: int = getattr(annotation, 'lineno', 0) or 0
|
||||
raise TypeError(
|
||||
f"[TPC] 不支持类型联合 'T1 | T2'(第 {Line} 行);"
|
||||
f"类型注解只能是单一类型:指针请写 CPtr[T],修饰符请用关键字")
|
||||
f"类型注解只能是单一类型:指针请写 `T*` 或 `rawptr[T]`,"
|
||||
f"修饰符请用关键字(const/volatile/static/export/extern)")
|
||||
|
||||
non_struct_types: set[str] = {'list', 'dict', 'tuple', 'set', 'array', 'CArray', 'rawarray'}
|
||||
|
||||
@@ -1154,6 +1160,10 @@ class DeclarationGenerator:
|
||||
return 'void'
|
||||
if annotation.id in ('str', 'bytes'):
|
||||
return 'i8*'
|
||||
# 裸指针标记(rawptr = void*,CPtr 亦为裸指针):一律 i8*。
|
||||
# 不得落入下方"未知类型 → %"{sha}.rawptr"*" 的伪结构体分支。
|
||||
if annotation.id in ('rawptr', 'CPtr'):
|
||||
return 'i8*'
|
||||
# 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`,非真实类):按
|
||||
# CPtr 同形的一层指针(i8*)参与联合合并(`T | CRef` → T*)。
|
||||
if annotation.id in ('CRef', 'CTempRef'):
|
||||
@@ -1215,6 +1225,9 @@ class DeclarationGenerator:
|
||||
return f'{sname}*'
|
||||
elif isinstance(annotation, ast.Attribute):
|
||||
attr_name: str = annotation.attr if hasattr(annotation, 'attr') else ''
|
||||
# 裸指针标记(t.rawptr / t.CPtr):i8*,不做结构体回落。
|
||||
if attr_name in ('rawptr', 'CPtr'):
|
||||
return 'i8*'
|
||||
# 值引用参数标记(CRef = `&T`、CTempRef = `&temp T`,非真实类):按 CPtr
|
||||
# 同形的「一层指针 = i8*」参与联合合并(`T | CRef` → T*),保证跨模块
|
||||
# .vpi 声明端类型与定义端 _ctype_to_llvm 一致。
|
||||
|
||||
@@ -9,7 +9,7 @@ import traceback
|
||||
from lib.Projectrans.Utils import compute_sha1, get_file_dependencies, find_reachable_files_from_entries, parse_python_file
|
||||
from lib.Projectrans.DeclarationGenerator import DeclarationGenerator
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.core.SymbolUtils import ExpandSoftKeywords
|
||||
from lib.core.SymbolUtils import ExpandSoftKeywords, AnnotationContainsName
|
||||
from lib.constants.config import mode as _ConfigMode
|
||||
from lib.core import TypeSystem
|
||||
from StubGen import PythonToStubConverter
|
||||
@@ -380,19 +380,14 @@ class Phase1Generator:
|
||||
for node in ast.iter_child_nodes(tree):
|
||||
if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
|
||||
var_name: str = node.target.id
|
||||
is_typedef: bool = False
|
||||
# 新语法 `typedef 名字 = 类型` 由解析器写入
|
||||
# node/annotation 的 Markers;旧 `名字: CTypedef = 类型`
|
||||
# 只作为兼容回落。
|
||||
_Markers: tuple[str, ...] = (tuple(getattr(node, 'Markers', None) or ())
|
||||
+ tuple(getattr(node.annotation, 'Markers', None) or ()))
|
||||
if 'typedef' in _Markers:
|
||||
is_typedef = True
|
||||
elif isinstance(node.annotation, ast.Attribute) and hasattr(node.annotation, 'attr') and node.annotation.attr == 'CTypedef':
|
||||
is_typedef = True
|
||||
elif isinstance(node.annotation, ast.Name) and node.annotation.id == 'CTypedef':
|
||||
is_typedef = True
|
||||
elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Attribute) and hasattr(node.annotation.left, 'attr') and node.annotation.left.attr == 'CTypedef':
|
||||
is_typedef = True
|
||||
elif isinstance(node.annotation, ast.BinOp) and isinstance(node.annotation.left, ast.Name) and node.annotation.left.id == 'CTypedef':
|
||||
is_typedef = True
|
||||
is_typedef: bool = (
|
||||
'typedef' in _Markers
|
||||
or AnnotationContainsName(node.annotation, 'CTypedef'))
|
||||
if is_typedef and node.value and var_name not in typedef_map:
|
||||
typedef_map[var_name] = node.value
|
||||
except Exception as _e:
|
||||
|
||||
@@ -640,7 +640,12 @@ def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object],
|
||||
|
||||
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:
|
||||
Markers: tuple[str, ...] = (tuple(getattr(node, 'Markers', None) or ())
|
||||
+ tuple(getattr(node.annotation, 'Markers', None) or ()))
|
||||
# 新语法 `define NAME = v` 由解析器写入 Markers;旧
|
||||
# `NAME: CDefine = v` 仅作兼容回落。
|
||||
if ('define' in Markers
|
||||
or AnnotationContainsName(node.annotation, 'CDefine')) and node.value:
|
||||
val: object = ConstEvaluator.eval_full(node.value, ctx)
|
||||
if val is None and isinstance(node.value, ast.Call) and len(node.value.args) == 1:
|
||||
# 类型构造的**裸别名**形态(如 `DWORD(-11)`,非 `CUnsignedLong(-11)`):
|
||||
@@ -664,6 +669,17 @@ def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object],
|
||||
_vlog().warning(f"Phase2Translator: 忽略异常 {e}", exc_info=e)
|
||||
|
||||
|
||||
def _IsExportExternFuncNode(node: ast.FunctionDef) -> bool:
|
||||
"""函数是否导出/外部可见:优先读 `export def` / `extern def` 的 AST 标记,
|
||||
再回落到 Markers,最后兼容旧的 `-> CExport/CExtern/State` 注解写法。"""
|
||||
if bool(getattr(node, 'Export', False)) or bool(getattr(node, 'Extern', False)):
|
||||
return True
|
||||
Markers: tuple[str, ...] = getattr(node, 'Markers', None) or ()
|
||||
if 'export' in Markers or 'extern' in Markers or 'state' in Markers:
|
||||
return True
|
||||
return _check_annotation_for_export(node.returns)
|
||||
|
||||
|
||||
def _CountUnresolvedTypedefs(module_symbols: object) -> int:
|
||||
"""该模块"有值注解却解析不出类型"的 typedef 个数(供声明阶段判断是否要下一轮)。
|
||||
|
||||
@@ -2388,7 +2404,7 @@ class Phase2Translator:
|
||||
sig_tree = ast.parse(sig_content, sig_path)
|
||||
for node in ast.iter_child_nodes(sig_tree):
|
||||
if isinstance(node, ast.FunctionDef):
|
||||
if _check_annotation_for_export(node.returns):
|
||||
if _IsExportExternFuncNode(node):
|
||||
export_extern_funcs[node.name] = sha1_key
|
||||
except Exception as _e:
|
||||
if _config_mode == "strict":
|
||||
@@ -4345,19 +4361,19 @@ class Phase2Translator:
|
||||
module_name = os.path.splitext(os.path.basename(src_path))[0]
|
||||
for node in ast.iter_child_nodes(tree):
|
||||
if isinstance(node, ast.FunctionDef) and node.returns:
|
||||
is_inline = False
|
||||
if isinstance(node.returns, ast.BinOp) and isinstance(node.returns.op, ast.BitOr):
|
||||
for part in [node.returns.left, node.returns.right]:
|
||||
if isinstance(part, ast.Attribute) and part.attr == 'CInline':
|
||||
is_inline = True
|
||||
break
|
||||
if isinstance(part, ast.Name) and part.id == 'CInline':
|
||||
is_inline = True
|
||||
break
|
||||
elif isinstance(node.returns, ast.Attribute) and node.returns.attr == 'CInline':
|
||||
# 新语法 `inline` 由解析器写入返回注解的 Markers;
|
||||
# 旧 `-> CInline | T` 的联合形态已废止(下方 fail-fast)。
|
||||
ReturnMarkers: tuple[str, ...] = getattr(node.returns, 'Markers', None) or ()
|
||||
is_inline: bool = 'inline' in ReturnMarkers
|
||||
if isinstance(node.returns, ast.Attribute) and node.returns.attr == 'CInline':
|
||||
is_inline = True
|
||||
elif isinstance(node.returns, ast.Name) and node.returns.id == 'CInline':
|
||||
is_inline = True
|
||||
elif isinstance(node.returns, ast.BinOp) and isinstance(node.returns.op, ast.BitOr):
|
||||
_Line: int = getattr(node.returns, 'lineno', 0) or 0
|
||||
raise TypeError(
|
||||
f"[TPC] 不支持类型联合 'T1 | T2'(第 {_Line} 行);"
|
||||
f"内联标记请写 `-> inline T`,类型注解只能是单一类型")
|
||||
if is_inline:
|
||||
func_name = node.name
|
||||
sym_key = f"{module_name}.{func_name}"
|
||||
@@ -4370,6 +4386,9 @@ class Phase2Translator:
|
||||
info.Storage = TypeSystem.CInline()
|
||||
self.inline_func_symbols[func_name] = info
|
||||
self.inline_func_symbols[sym_key] = info
|
||||
except TypeError:
|
||||
# 类型注解 fail-fast(BinOp(BitOr) 联合)不得被 strict 开关吞掉
|
||||
raise
|
||||
except Exception as _e:
|
||||
if _config_mode == "strict":
|
||||
raise
|
||||
@@ -4499,7 +4518,7 @@ class Phase2Translator:
|
||||
continue
|
||||
for node in ast.iter_child_nodes(sig_tree):
|
||||
if isinstance(node, ast.FunctionDef):
|
||||
if _check_annotation_for_export(node.returns):
|
||||
if _IsExportExternFuncNode(node):
|
||||
export_extern_funcs[node.name] = sha1_key
|
||||
except Exception as _e:
|
||||
if _config_mode == "strict":
|
||||
|
||||
@@ -41,9 +41,16 @@ _FILE_AST_CACHE: dict[str, tuple[float, str, ast.Module]] = {}
|
||||
|
||||
|
||||
def _check_annotation_for_export(annotation: ast.AST | None) -> bool:
|
||||
"""递归检查类型注解中是否包含 CExport/CExtern/State(State = CExtern | CExport)"""
|
||||
"""检查类型注解是否带 export / extern / state。
|
||||
|
||||
优先读解析器写入的 Markers 字段(export/extern/state);旧的
|
||||
CExport/CExtern/State 文本判断仅作兼容回落。
|
||||
"""
|
||||
if not annotation:
|
||||
return False
|
||||
Markers: tuple[str, ...] = getattr(annotation, 'Markers', None) or ()
|
||||
if 'export' in Markers or 'extern' in Markers or 'state' in Markers:
|
||||
return True
|
||||
return (AnnotationContainsName(annotation, 'CExport') or
|
||||
AnnotationContainsName(annotation, 'CExtern') or
|
||||
AnnotationContainsName(annotation, 'State'))
|
||||
|
||||
Reference in new issue
Block a user