feat: 优化结构体构造函数选择逻辑

- 支持构造函数重载:根据实参个数选择合适的构造函数
- 改进错误提示:增加未找到对应形参个数构造函数的提示
- 保留零参数构造的旧行为:当结构体未声明任何 init 且调用为 0 实参时,允许隐式默认构造
- 优化代码结构:调整注释格式,提高代码可读性
This commit is contained in:
Luke 2025-09-01 16:42:59 +08:00
parent 4ac95dd5ef
commit 5367fc39f6

View File

@ -51,7 +51,7 @@ public class NewExpressionAnalyzer implements ExpressionAnalyzer<NewExpressionNo
final String typeName = expr.typeName(); final String typeName = expr.typeName();
// 1) 解析目标类型通过语义上下文统一入口支持别名跨模块等情况 // 1. 解析目标类型通过语义上下文统一入口支持别名跨模块等情况
Type parsed = ctx.parseType(typeName); Type parsed = ctx.parseType(typeName);
if (parsed == null) { if (parsed == null) {
// 类型不存在报错并降级 // 类型不存在报错并降级
@ -64,7 +64,7 @@ public class NewExpressionAnalyzer implements ExpressionAnalyzer<NewExpressionNo
return BuiltinType.INT; return BuiltinType.INT;
} }
// 2) 分析所有实参的类型 // 2. 分析所有实参的类型
List<Type> argTypes = new ArrayList<>(); List<Type> argTypes = new ArrayList<>();
for (ExpressionNode a : expr.arguments()) { for (ExpressionNode a : expr.arguments()) {
Type at = ctx.getRegistry() Type at = ctx.getRegistry()
@ -77,30 +77,25 @@ public class NewExpressionAnalyzer implements ExpressionAnalyzer<NewExpressionNo
argTypes.add(at); argTypes.add(at);
} }
// 3) 检查并获取结构体构造函数init签名 // 3. 选择并检查结构体构造函数init支持重载参数个数匹配
FunctionType ctor = st.getConstructor(); FunctionType ctor = st.getConstructor(argTypes.size());
if (ctor == null) { if (ctor == null) {
// 未定义构造函数仅允许零参数否则报错 // 若该结构体完全未声明任何 init且调用为 0 实参则允许隐式默认构造保留旧行为
if (!argTypes.isEmpty()) { if (st.getConstructors().isEmpty() && argTypes.isEmpty()) {
ctx.errors().add(new SemanticError(expr, return st;
"结构体 " + st.name() + " 未定义构造函数 init不能接收参数"));
} }
// 允许 new T() 零参数构造 // 否则报错未找到对应形参个数的构造函数
return st;
}
// 3.1) 构造函数参数数量检查
if (ctor.paramTypes().size() != argTypes.size()) {
ctx.errors().add(new SemanticError(expr, ctx.errors().add(new SemanticError(expr,
String.format("构造函数参数数量不匹配: 期望 %d 个, 实际 %d 个", "未找到参数个数为 " + argTypes.size() + " 的构造函数"));
ctor.paramTypes().size(), argTypes.size())));
return st; return st;
} }
// 3.2) 构造函数参数类型兼容性检查包括数值类型宽化 // 3.1. 构造函数参数类型兼容性检查包括数值类型宽化
for (int i = 0; i < argTypes.size(); i++) { List<Type> expectedParams = ctor.paramTypes();
Type expected = ctor.paramTypes().get(i); // 构造函数声明的参数类型 for (int i = 0; i < expectedParams.size(); i++) {
Type actual = argTypes.get(i); // 实际传入的实参类型 Type expected = expectedParams.get(i); // 构造函数声明的参数类型
Type actual = argTypes.get(i); // 实际传入的实参类型
boolean compatible = expected.isCompatible(actual); // 直接类型兼容 boolean compatible = expected.isCompatible(actual); // 直接类型兼容
boolean widenOK = expected.isNumeric() boolean widenOK = expected.isNumeric()
@ -115,7 +110,7 @@ public class NewExpressionAnalyzer implements ExpressionAnalyzer<NewExpressionNo
} }
} }
// 4) new 表达式的类型就是结构体类型 // 4. new 表达式的类型就是结构体类型
return st; return st;
} }
} }