diff --git a/lib/core/Handles/HandlesFunctions.py b/lib/core/Handles/HandlesFunctions.py index 558fe12..d7bfc96 100644 --- a/lib/core/Handles/HandlesFunctions.py +++ b/lib/core/Handles/HandlesFunctions.py @@ -19,6 +19,42 @@ from lib.includes.t import CTypeRegistry _T_STORAGE_DECORATORS = frozenset({'CExport', 'CExtern', 'CStatic', 'State', 'CInline', 'TLS'}) +def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool: + """判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。 + + void:None / t.CVoid,含 `|` 联合形式(注解中 `|` 表示 and), + 如 `-> t.CVoid | t.CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。 + 声明型辅助符号:t.State(extern)/ t.CExport(export)/ t.CExtern—— + 此类函数返回注解被改写为 `<原类型> | 辅助符号` 且 body 为空(extern 声明), + 掉出末尾是正常形态,必须豁免 fail-fast。 + """ + if isinstance(Annot, ast.Constant): + return Annot.value is None + if isinstance(Annot, ast.Attribute): + return getattr(Annot, 'attr', '') in ('CVoid', 'State', 'CExport', 'CExtern') + if isinstance(Annot, ast.BinOp) and isinstance(Annot.op, ast.BitOr): + return _IsVoidOrDeclAnnotation(Annot.left) or _IsVoidOrDeclAnnotation(Annot.right) + return False + + +def _IsVoidOrDeclAnnotation(Annot: ast.AST) -> bool: + """判断函数返回注解是否为 void 或 extern/export 声明型辅助符号。 + + void:None / t.CVoid,含 `|` 联合形式(注解中 `|` 表示 and), + 如 `-> t.CVoid | t.CExport`(sprintf 先例)→ 掉出末尾 ret void 合法。 + 声明型辅助符号:t.State(extern)/ t.CExport(export)/ t.CExtern—— + 此类函数返回注解被改写为 `<原类型> | 辅助符号` 且 body 为空(extern 声明), + 掉出末尾是正常形态,必须豁免 fail-fast。 + """ + if isinstance(Annot, ast.Constant): + return Annot.value is None + if isinstance(Annot, ast.Attribute): + return getattr(Annot, 'attr', '') in ('CVoid', 'State', 'CExport', 'CExtern') + if isinstance(Annot, ast.BinOp) and isinstance(Annot.op, ast.BitOr): + return _IsVoidOrDeclAnnotation(Annot.left) or _IsVoidOrDeclAnnotation(Annot.right) + return False + + class FunctionHandle(BaseHandle): @staticmethod def _ExtractFuncMeta(decorator_list: list[ast.AST]) -> FuncMeta: @@ -1852,10 +1888,9 @@ class FunctionHandle(BaseHandle): _is_ret_or_ctrl_tail: bool = isinstance(_last_stmt, ( ast.Return, ast.If, ast.Match, ast.While, ast.For, ast.Try, ast.With)) if Node.returns is not None and not _is_ret_or_ctrl_tail: - _ret_annot_void: bool = ( - isinstance(Node.returns, ast.Constant) and Node.returns.value is None) or ( - isinstance(Node.returns, ast.Attribute) and getattr(Node.returns, 'attr', '') == 'CVoid') - if not _ret_annot_void: + # void(None / t.CVoid,含 | 联合)/ extern|export 声明型辅助符号 + # (State / CExport / CExtern)→ 掉出合法,不 fail-fast + if not _IsVoidOrDeclAnnotation(Node.returns): raise Exception( f"函数 {Node.name} 声明了返回类型但函数体可能掉出末尾(缺少 return 语句);" f"普通语句掉出末尾 + 有返回注解属于定义缺陷,请补显式 return")