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()) {
if (topDecl instanceof PbsAst.FunctionDecl functionDecl) { validateTopDecl(topDecl, model, diagnostics);
validateCallableBody( }
functionDecl.parameters(), }
functionDecl.body(),
newCallableContext( private void validateTopDecl(
typeOps.callableReturnType( final PbsAst.TopDecl topDecl,
functionDecl.returnKind(), final Model model,
functionDecl.returnType(), final DiagnosticSink diagnostics) {
functionDecl.resultErrorType(), if (topDecl instanceof PbsAst.FunctionDecl functionDecl) {
model), validateFunction(functionDecl, model, diagnostics);
functionDecl.resultErrorType() == null ? null : functionDecl.resultErrorType().name(), return;
null, }
model, if (topDecl instanceof PbsAst.StructDecl structDecl) {
diagnostics)); validateStruct(structDecl, model, diagnostics);
continue; return;
} }
if (topDecl instanceof PbsAst.StructDecl structDecl) { if (topDecl instanceof PbsAst.ServiceDecl serviceDecl) {
final var receiverType = TypeView.struct(structDecl.name()); validateService(serviceDecl, model, diagnostics);
for (final var method : structDecl.methods()) { }
validateCallableBody( }
method.parameters(),
method.body(), private void validateFunction(
newCallableContext( final PbsAst.FunctionDecl functionDecl,
typeOps.callableReturnType( final Model model,
method.returnKind(), final DiagnosticSink diagnostics) {
method.returnType(), validateCallableBody(
method.resultErrorType(), functionDecl.parameters(),
model), functionDecl.body(),
method.resultErrorType() == null ? null : method.resultErrorType().name(), typeOps.callableReturnType(
receiverType, functionDecl.returnKind(),
model, functionDecl.returnType(),
diagnostics)); functionDecl.resultErrorType(),
} model),
for (final var ctor : structDecl.ctors()) { errorName(functionDecl.resultErrorType()),
validateCallableBody( null,
ctor.parameters(), model,
ctor.body(), diagnostics);
newCallableContext( }
TypeView.unit(),
null, private void validateStruct(
receiverType, final PbsAst.StructDecl structDecl,
model, final Model model,
diagnostics)); final DiagnosticSink diagnostics) {
} final var receiverType = TypeView.struct(structDecl.name());
continue; for (final var method : structDecl.methods()) {
} validateCallableBody(
if (topDecl instanceof PbsAst.ServiceDecl serviceDecl) { method.parameters(),
final var receiverType = TypeView.service(serviceDecl.name()); method.body(),
for (final var method : serviceDecl.methods()) { typeOps.callableReturnType(
validateCallableBody( method.returnKind(),
method.parameters(), method.returnType(),
method.body(), method.resultErrorType(),
newCallableContext( model),
typeOps.callableReturnType( errorName(method.resultErrorType()),
method.returnKind(), receiverType,
method.returnType(), model,
method.resultErrorType(), diagnostics);
model), }
method.resultErrorType() == null ? null : method.resultErrorType().name(), for (final var ctor : structDecl.ctors()) {
receiverType, validateCallableBody(
model, ctor.parameters(),
diagnostics)); ctor.body(),
} TypeView.unit(),
} null,
receiverType,
model,
diagnostics);
}
}
private void validateService(
final PbsAst.ServiceDecl serviceDecl,
final Model model,
final DiagnosticSink diagnostics) {
final var receiverType = TypeView.service(serviceDecl.name());
for (final var method : serviceDecl.methods()) {
validateCallableBody(
method.parameters(),
method.body(),
typeOps.callableReturnType(
method.returnKind(),
method.returnType(),
method.resultErrorType(),
model),
errorName(method.resultErrorType()),
receiverType,
model,
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,