尝试进行 Qt 测试,增加了 AI 人机调试工具 _console,以及 TransPyV 进行修正
This commit is contained in:
@@ -253,6 +253,10 @@ class ClassHandle(BaseHandle):
|
||||
return 'union'
|
||||
if issubclass(cls, t.CStruct):
|
||||
return 'struct'
|
||||
# CType 及其子类(CChar/CInt/CVoid/CPtr 等)是"类型强转"标记,
|
||||
# 不应被编译为真实结构体。
|
||||
if issubclass(cls, t.CType):
|
||||
return 'ctype_marker'
|
||||
|
||||
# 2) 查 t 模块属性(直接引用 t.CEnum 等)
|
||||
t_cls: type | None = getattr(t, base_name, None)
|
||||
@@ -263,9 +267,47 @@ class ClassHandle(BaseHandle):
|
||||
return 'union'
|
||||
if issubclass(t_cls, t.CStruct):
|
||||
return 'struct'
|
||||
# CType 及其子类是"类型强转"标记,不编译为结构体。
|
||||
return 'ctype_marker'
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _is_classname_ctype_marker(class_name: str) -> bool:
|
||||
"""检查类名是否是 t.CType 的"类型强转"标记子类。
|
||||
|
||||
只有 position 不含 BASE 的纯修饰符/标记类型(CPtr/CVolatile/CConst/
|
||||
CInline/CStatic/CExtern/CExport/CRegister/CAuto/_CTypedef/CTypeDefault 等)
|
||||
才应跳过编译。有 BASE position 的基本类型(CInt/CChar/CSizeT/CLong 等)
|
||||
有具体大小,应被正常编译。CType 基类本身无 bases,base 检测无法触发,
|
||||
需要直接按类名检查。
|
||||
|
||||
注意:CTypeRegistry.GetClassByName 会跳过 CType 本身和 CTypeDefault,
|
||||
所以这里直接用 getattr(t, name) 检查 t 模块属性。
|
||||
|
||||
Returns:
|
||||
True 如果 class_name 是 CType 标记子类名(应跳过编译)
|
||||
"""
|
||||
if not class_name:
|
||||
return False
|
||||
# 直接查 t 模块属性(CTypeRegistry._build 会跳过 CType/CTypeDefault/BigEndian/LittleEndian)
|
||||
t_cls: type | None = getattr(t, class_name, None)
|
||||
if not isinstance(t_cls, type) or not issubclass(t_cls, t.CType):
|
||||
return False
|
||||
if issubclass(t_cls, (t.CStruct, t.CEnum, t.REnum, t.CUnion)):
|
||||
return False
|
||||
# 基本类型(position 含 BASE 且 Size > 0)有具体大小,不应跳过
|
||||
# CVoid 虽含 BASE 但 Size=0,CType Size=None,仍需跳过
|
||||
if t.CType.BASE in t_cls.position:
|
||||
try:
|
||||
inst = t_cls()
|
||||
size_val = getattr(inst, 'Size', None)
|
||||
if size_val is not None and size_val > 0:
|
||||
return False
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
def _resolve_decorator_kind(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin) -> str | None:
|
||||
"""从装饰器列表中解析结构体类型种类
|
||||
|
||||
@@ -409,6 +451,11 @@ class ClassHandle(BaseHandle):
|
||||
|
||||
def _EmitClassLlvm(self, Node: ast.ClassDef, Gen: LlvmGeneratorMixin, declare_only: bool = False) -> None:
|
||||
ClassName: str = Node.name
|
||||
# t.CType 及其子类(CChar/CInt/CVoid/CPtr/CTypeDefault 等)是"类型强转"标记,
|
||||
# 不应被编译为真实结构体。CType 基类本身无 bases,base 检测无法触发,
|
||||
# 此处在方法入口直接按类名跳过。
|
||||
if self._is_classname_ctype_marker(ClassName):
|
||||
return
|
||||
if self._is_generic_class(Node):
|
||||
if not hasattr(self, '_generic_class_templates'):
|
||||
self._generic_class_templates = {}
|
||||
@@ -449,6 +496,10 @@ class ClassHandle(BaseHandle):
|
||||
IsCunion = True
|
||||
elif kind == 'renum':
|
||||
IsRenum = True
|
||||
elif kind == 'ctype_marker':
|
||||
# CType 及其子类(CChar/CInt/CVoid/CPtr/CTypeDefault 等)是
|
||||
# "类型强转"标记,不应被编译为真实结构体。直接 return 跳过编译。
|
||||
return
|
||||
if IsCenum:
|
||||
self._RegisterEnumMembers(Node)
|
||||
return
|
||||
@@ -540,50 +591,33 @@ class ClassHandle(BaseHandle):
|
||||
if pm_name in parent_defaults:
|
||||
Gen.class_member_defaults[ClassName][pm_name] = parent_defaults[pm_name]
|
||||
Gen.class_members[ClassName] = inherited + Gen.class_members[ClassName]
|
||||
if ParentClass in Gen.class_methods:
|
||||
parent_methods: list = list(Gen.class_methods[ParentClass])
|
||||
# 从 Node.body 收集子类自有方法(此时 Gen.class_methods[ClassName] 可能为空,
|
||||
# 因为自有方法在 L660-676 才注册。若直接用 Gen.class_methods[ClassName],
|
||||
# child_method_map 会为空,所有父类方法被当作"未覆盖"添加为包装器,
|
||||
# 然后 register_method 又把它们追加到 Gen.class_methods[ClassName],
|
||||
# L566 循环再次添加 → 产生重复条目,vtable 布局与导入模块不一致)
|
||||
child_method_map: dict[str, str] = {}
|
||||
child_self_methods_snapshot: list[str] = []
|
||||
for _item in Node.body:
|
||||
if isinstance(_item, ast.FunctionDef):
|
||||
_mname: str = _item.name
|
||||
if _mname in ('__new__', '__init__', '__before_init__'):
|
||||
continue
|
||||
_item_meta: FuncMeta = self.Trans.FunctionHandler._ExtractFuncMeta(_item.decorator_list)
|
||||
if FuncMeta.PROPERTY_SETTER in _item_meta:
|
||||
_full: str = f"{ClassName}.{_mname}$set"
|
||||
elif FuncMeta.PROPERTY_DELETER in _item_meta:
|
||||
_full = f"{ClassName}.{_mname}$del"
|
||||
else:
|
||||
_full = f"{ClassName}.{_mname}"
|
||||
_short: str = _mname
|
||||
child_method_map[_short] = _full
|
||||
child_self_methods_snapshot.append(_full)
|
||||
# 父类方法在前(保证 vtable 布局一致性,子类多态分派索引正确),
|
||||
# 子类新增方法在后。子类覆盖的方法放在父类方法的位置(用子类实现)。
|
||||
new_methods: list = []
|
||||
covered_names: set[str] = set()
|
||||
for pm in parent_methods:
|
||||
method_name: str = pm.split('.')[-1] if '.' in pm else pm
|
||||
if method_name in child_method_map:
|
||||
# 子类覆盖了父类方法 — 用子类的实现,放在父类的位置
|
||||
new_methods.append(child_method_map[method_name])
|
||||
covered_names.add(method_name)
|
||||
else:
|
||||
# 父类独有方法 — 子类未覆盖,注册子类包装器
|
||||
child_method: str = f"{ClassName}.{method_name}"
|
||||
new_methods.append(child_method)
|
||||
Gen.register_method(ClassName, child_method)
|
||||
# 添加子类新增方法(不在父类中的)— 使用快照避免 register_method 污染
|
||||
for m in child_self_methods_snapshot:
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
if method_name not in covered_names:
|
||||
new_methods.append(m)
|
||||
if ParentClass in Gen.class_methods:
|
||||
parent_methods: list = list(Gen.class_methods[ParentClass])
|
||||
# 构建子类已有方法映射(方法短名 -> 方法全名)
|
||||
child_method_map: dict[str, str] = {}
|
||||
for m in Gen.class_methods[ClassName]:
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
child_method_map[method_name] = m
|
||||
# 父类方法在前(保证 vtable 布局一致性,子类多态分派索引正确),
|
||||
# 子类新增方法在后。子类覆盖的方法放在父类方法的位置(用子类实现)。
|
||||
new_methods: list = []
|
||||
covered_names: set[str] = set()
|
||||
for pm in parent_methods:
|
||||
method_name: str = pm.split('.')[-1] if '.' in pm else pm
|
||||
if method_name in child_method_map:
|
||||
# 子类覆盖了父类方法 — 用子类的实现,放在父类的位置
|
||||
new_methods.append(child_method_map[method_name])
|
||||
covered_names.add(method_name)
|
||||
else:
|
||||
# 父类独有方法 — 子类未覆盖,注册子类包装器
|
||||
child_method: str = f"{ClassName}.{method_name}"
|
||||
new_methods.append(child_method)
|
||||
Gen.register_method(ClassName, child_method)
|
||||
# 添加子类新增方法(不在父类中的)
|
||||
for m in Gen.class_methods[ClassName]:
|
||||
method_name: str = m.split('.')[-1] if '.' in m else m
|
||||
if method_name not in covered_names:
|
||||
new_methods.append(m)
|
||||
Gen.class_methods[ClassName] = new_methods
|
||||
# 提取首个裸字符串字面量作为结构体 __doc__ docstring
|
||||
if (Node.body and isinstance(Node.body[0], ast.Expr)
|
||||
|
||||
Reference in New Issue
Block a user