Files
TransPyC/lib/core/SymbolUtils.py

57 lines
2.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""共享工具函数:符号表处理中使用的 AST 分析工具"""
from __future__ import annotations
import ast
from lib.includes import t
def IsTModuleType(TypeName: str) -> bool:
"""检测类型名称是否是 t 模块中的类型CType 或其他特殊类型)"""
if TypeName in ('t', 'State', 'Bit', 'Anonymous', 'Postdefinition'):
return True
TypeClass = getattr(t, TypeName, None)
if TypeClass and isinstance(TypeClass, type):
if issubclass(TypeClass, t.CType):
return True
FallbackClass = getattr(t, f'_{TypeName}', None)
if FallbackClass and isinstance(FallbackClass, type):
if issubclass(FallbackClass, t.CType):
return True
return False
def AnnotationContainsTType(node, TypeName: str) -> bool:
"""检测 AST 节点中是否包含指定名称的 t 模块类型"""
if isinstance(node, ast.Attribute):
if (hasattr(node.value, 'id') and node.value.id == 't' and
node.attr == TypeName):
return True
elif isinstance(node, ast.BinOp):
return AnnotationContainsTType(node.left, TypeName) or AnnotationContainsTType(node.right, TypeName)
elif isinstance(node, ast.Call):
if AnnotationContainsTType(node.func, TypeName):
return True
for arg in node.args:
if AnnotationContainsTType(arg, TypeName):
return True
elif isinstance(node, ast.Subscript):
if AnnotationContainsTType(node.value, TypeName):
return True
if AnnotationContainsTType(node.slice, TypeName):
return True
return False
def CheckAnnotationHasCInline(annotation_node) -> bool:
"""检测注解节点中是否包含 CInline"""
if annotation_node is None:
return False
if isinstance(annotation_node, ast.Attribute):
if hasattr(annotation_node.value, 'id') and annotation_node.value.id == 't' and annotation_node.attr == 'CInline':
return True
if isinstance(annotation_node, ast.Name):
if annotation_node.id == 'CInline':
return True
if isinstance(annotation_node, ast.BinOp) and isinstance(annotation_node.op, ast.BitOr):
return CheckAnnotationHasCInline(annotation_node.left) or CheckAnnotationHasCInline(annotation_node.right)
return False