57 lines
2.3 KiB
Python
57 lines
2.3 KiB
Python
"""共享工具函数:符号表处理中使用的 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
|