implements PR-13.5

This commit is contained in:
bQUARKz 2026-03-10 10:35:08 +00:00
parent a1f92375a6
commit 079db44cd1
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8

View File

@ -31,70 +31,94 @@ final class PbsFlowBodyAnalyzer {
final var model = Model.from(ast, supplementalTopDecls); final var model = Model.from(ast, supplementalTopDecls);
for (final var topDecl : ast.topDecls()) { for (final var topDecl : ast.topDecls()) {
validateTopDecl(topDecl, model, diagnostics);
}
}
private void validateTopDecl(
final PbsAst.TopDecl topDecl,
final Model model,
final DiagnosticSink diagnostics) {
if (topDecl instanceof PbsAst.FunctionDecl functionDecl) { if (topDecl instanceof PbsAst.FunctionDecl functionDecl) {
validateFunction(functionDecl, model, diagnostics);
return;
}
if (topDecl instanceof PbsAst.StructDecl structDecl) {
validateStruct(structDecl, model, diagnostics);
return;
}
if (topDecl instanceof PbsAst.ServiceDecl serviceDecl) {
validateService(serviceDecl, model, diagnostics);
}
}
private void validateFunction(
final PbsAst.FunctionDecl functionDecl,
final Model model,
final DiagnosticSink diagnostics) {
validateCallableBody( validateCallableBody(
functionDecl.parameters(), functionDecl.parameters(),
functionDecl.body(), functionDecl.body(),
newCallableContext(
typeOps.callableReturnType( typeOps.callableReturnType(
functionDecl.returnKind(), functionDecl.returnKind(),
functionDecl.returnType(), functionDecl.returnType(),
functionDecl.resultErrorType(), functionDecl.resultErrorType(),
model), model),
functionDecl.resultErrorType() == null ? null : functionDecl.resultErrorType().name(), errorName(functionDecl.resultErrorType()),
null, null,
model, model,
diagnostics)); diagnostics);
continue;
} }
if (topDecl instanceof PbsAst.StructDecl structDecl) {
private void validateStruct(
final PbsAst.StructDecl structDecl,
final Model model,
final DiagnosticSink diagnostics) {
final var receiverType = TypeView.struct(structDecl.name()); final var receiverType = TypeView.struct(structDecl.name());
for (final var method : structDecl.methods()) { for (final var method : structDecl.methods()) {
validateCallableBody( validateCallableBody(
method.parameters(), method.parameters(),
method.body(), method.body(),
newCallableContext(
typeOps.callableReturnType( typeOps.callableReturnType(
method.returnKind(), method.returnKind(),
method.returnType(), method.returnType(),
method.resultErrorType(), method.resultErrorType(),
model), model),
method.resultErrorType() == null ? null : method.resultErrorType().name(), errorName(method.resultErrorType()),
receiverType, receiverType,
model, model,
diagnostics)); diagnostics);
} }
for (final var ctor : structDecl.ctors()) { for (final var ctor : structDecl.ctors()) {
validateCallableBody( validateCallableBody(
ctor.parameters(), ctor.parameters(),
ctor.body(), ctor.body(),
newCallableContext(
TypeView.unit(), TypeView.unit(),
null, null,
receiverType, receiverType,
model, model,
diagnostics)); diagnostics);
} }
continue;
} }
if (topDecl instanceof PbsAst.ServiceDecl serviceDecl) {
private void validateService(
final PbsAst.ServiceDecl serviceDecl,
final Model model,
final DiagnosticSink diagnostics) {
final var receiverType = TypeView.service(serviceDecl.name()); final var receiverType = TypeView.service(serviceDecl.name());
for (final var method : serviceDecl.methods()) { for (final var method : serviceDecl.methods()) {
validateCallableBody( validateCallableBody(
method.parameters(), method.parameters(),
method.body(), method.body(),
newCallableContext(
typeOps.callableReturnType( typeOps.callableReturnType(
method.returnKind(), method.returnKind(),
method.returnType(), method.returnType(),
method.resultErrorType(), method.resultErrorType(),
model), model),
method.resultErrorType() == null ? null : method.resultErrorType().name(), errorName(method.resultErrorType()),
receiverType, receiverType,
model, model,
diagnostics)); diagnostics);
}
}
} }
} }
@ -113,6 +137,29 @@ final class PbsFlowBodyAnalyzer {
diagnostics); diagnostics);
} }
private void validateCallableBody(
final ReadOnlyList<PbsAst.Parameter> parameters,
final PbsAst.Block body,
final TypeView returnType,
final String resultErrorName,
final TypeView receiverType,
final Model model,
final DiagnosticSink diagnostics) {
validateCallableBody(
parameters,
body,
newCallableContext(
returnType,
resultErrorName,
receiverType,
model,
diagnostics));
}
private String errorName(final PbsAst.TypeRef errorType) {
return errorType == null ? null : errorType.name();
}
private void validateCallableBody( private void validateCallableBody(
final ReadOnlyList<PbsAst.Parameter> parameters, final ReadOnlyList<PbsAst.Parameter> parameters,
final PbsAst.Block body, final PbsAst.Block body,