本次更新改动了非常多的文件。 本次更新升级了异常处理系统。
本次更新发行2.4.49版本。
再三审查后,我认为他是不必要的。
升级异常处理系统的想法诞生于以下背景: 1. 以往的异常处理系统,使用一个字符串来存储异常信息,这种简单做法带来的缺点就是,无法准确快速的获取更详细的信息(例如异常抛出者、异常类型、异常位置)。 2. 以往的异常处理系统,并没有封装文件编解码的异常生成函数,而只封装了编译端和虚拟端的异常生成函数(且两者并不完全统一)。 3. 随着项目的发展,日志系统的开发被认为是需要的。
对异常处理系统的升级,主要分为以下阶段:
在Exception.hpp中设立STMInfo。以此代替存储异常信息的字符串。事实上,STMInfo也可以存储程序运行信息和调试信息,这是将异常处理统一到日志系统的第一步。
STMInfo更详细的分别存储了异常的各类信息(例如信息发出者,信息发出位置)。STMInfo也提供了toString()方法来将异常格式化为字符串。从而让各种异常信息规范化。
以下是STMInfo的节选代码片段,通过这个片段,我们可以了解STMInfo存储了哪些信息:
String sender; // 信息发送者
String type; // 信息类型
String message; // 信息内容
String position; // 信息位置推荐调用下面这个构造函数来新建STMInfo:
STMInfo(
const String &Sender,
const String &Type,
const String &Message,
const String &Position
);在设计完STMInfo之后,用于异常抛出的STMException类也进行了改造,将抛出信息的数据类型从原本的字符串改造为STMInfo。对应的简便宏也做出了调整,具体宏定义如下:
#define THROW(info) ex->Throw(info);
#define CATCH if (ex->isError)
#define WARN(info) ex->Warn(info);
#define ISWARNING (ex->isWarning)将异常信息的生成函数迁移到stamon::exception命名空间中。stamon::exception的子命名空间存储着不同功能的异常信息生成函数。例如stamon::exception::compiler中存储着编译端的异常信息生成函数。
一个异常信息生成函数的原型通常符合下面的描述:
inline STMInfo 函数名(String position, String 相关参数,...);函数的返回值一般为STMInfo类型,函数的第一个参数一般为异常发生的位置,相关参数取决于具体需求,有些函数只有position参数。
例如AstFileReader.cpp中出现的代码为例,使用异常生成函数生成一个STMInfo,然后使用THROW宏抛出:
THROW(exception::astfilereader::RedundantRootNode("read()"));而RedundantRootNode的函数原型如下:
inline STMInfo RedundantEndNodeError(String position);将异常生成函数和对应的解释转写到JSON,并用Python编写代码生成脚本。使用
配置+生成脚本
的方式,开发者可以快速的创建异常处理生成函数,并且生成脚本也可以自动生成异常信息处理文档。
在JSON中声明一个异常信息生成函数,需要按照以下格式填写参数:
{
"type": "异常信息名", // 异常类型
"arg": ["参数1","参数2","..."],
// 参数列表可以为空,生成的参数皆为String类型
"msg": ["一段信息","$参数1","..."],
// 信息列表
// 如果一段信息的开头有“$”符号,则代表这是一个参数
// 否则脚本会把它当作一个字符串字面量
// 脚本会把这些信息和参数拼接在一起
"doc": "该文件存在未知的常量,请检查编码文件或重新编译。"
// 对这个异常的解释和解决措施,脚本会把他整理到文档中
}一个JSON配置文件的文件名就是异常信息生成函数要存储的命名空间,例如astrunner.json中的异常信息生成函数都存在于stamon::exception::astrunner中。
一个JSON文件的总体格式如下:
{
"name": "生成的文件名",
"error": [ "一系列异常信息生成函数..." ],
// 函数的格式已在上面说明
"warning": [ "一系列异常信息生成函数..." ]
// warning的函数格式同error
}我们挑选了较为简短的sfn.json为例,其代码如下:
{
"name": "SFNException.cpp",
"error": [
{
"type": "SFNError",
"arg": ["msg"],
"msg": ["$msg"],
"doc": "SFN产生的综合性错误。"
}
],
"warning": [
{
"type": "SFNWarning",
"arg": ["msg"],
"msg": ["$msg"],
"doc": "SFN产生的综合性警告。"
}
]
}交给脚本后,生成SFNException.cpp,其代码如下:
/*
Name: SFNException.cpp
License: Apache 2.0
Author: CLimber-Rong
Date: 13/07/2025 17:43
Description: 报错信息函数,由codegen.py自动生成
*/
#pragma once
#include "String.hpp"
#include "Exception.hpp"
namespace stamon::exception::sfn {
inline STMInfo SFNError(String position, String msg) {
return STMInfo(String("sfn"), String("SFNError"), msg, position);
}
inline STMInfo SFNWarning(String position, String msg) {
return STMInfo(String("sfn"), String("SFNWarning"), msg, position);
}
}自动化脚本和配置文件位于src/exception/codegen/目录,其中,codegen.py是生成脚本。
生成的文档会被命名为Stamon异常信息修复指南.md,并存入doc目录下。
codegen.py中的setting_list变量进行对应的修改。setting_list是一个列表,其成员由一系列元组组成。元组由两个元素构成,第一个元素是配置文件名(不包括.json后缀),第二个元素是该文件的作者(用于生成文件头注释)。doc_path变量。src/exception/codegen目录下运行codegen.py(该文件依赖time和json库)