Skip to content

Commit

Permalink
Merge pull request #41049 from ballerina-platform/on-fail-error-bp
Browse files Browse the repository at this point in the history
Add support for error binding patterns in the on fail clause
  • Loading branch information
MaryamZi authored Nov 23, 2023
2 parents 003242d + a99b983 commit a33bee3
Show file tree
Hide file tree
Showing 339 changed files with 99,260 additions and 1,164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,6 @@ public enum DiagnosticErrorCode implements DiagnosticCode {

FAIL_EXPR_NO_MATCHING_ERROR_RETURN_IN_ENCL_INVOKABLE(
"BCE3035", "fail.expr.no.matching.error.return.in.encl.invokable"),
INCOMPATIBLE_ON_FAIL_ERROR_DEFINITION("BCE3036", "on.fail.no.matching.error"),

START_REQUIRE_INVOCATION("BCE3037", "start.require.invocation"),
INVALID_EXPR_STATEMENT("BCE3038", "invalid.expr.statement"),
Expand Down Expand Up @@ -815,7 +814,8 @@ public enum DiagnosticErrorCode implements DiagnosticCode {
CANNOT_USE_ALTERNATE_WAIT_ACTION_WITHIN_MULTIPLE_WAIT_ACTION("BCE4056",
"cannot.use.alternate.wait.action.within.multiple.wait.action"),
EXPRESSION_OF_FUTURE_TYPE_EXPECTED("BCE4057", "future.expression.expected"),
INSTANTIATION_ERROR("BCE4058", "instantiation.error")
INSTANTIATION_ERROR("BCE4058", "instantiation.error"),
INVALID_BINDING_PATTERN_IN_ON_FAIL("BCE4059", "invalid.binding.pattern.in.on.fail")
;

private String diagnosticId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.wso2.ballerinalang.compiler.tree.BLangService;
import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable;
import org.wso2.ballerinalang.compiler.tree.BLangTupleVariable;
import org.wso2.ballerinalang.compiler.tree.BLangVariable;
import org.wso2.ballerinalang.compiler.tree.bindingpatterns.BLangBindingPattern;
import org.wso2.ballerinalang.compiler.tree.bindingpatterns.BLangCaptureBindingPattern;
import org.wso2.ballerinalang.compiler.tree.clauses.BLangMatchClause;
Expand Down Expand Up @@ -552,6 +553,21 @@ static BLangRecordVariableDef createRecordVariableDef(Location pos, BLangRecordV
return variableDef;
}

static BLangErrorVariable createErrorVariable(Location pos, BType type, BLangExpression expr,
BLangSimpleVariable message, BLangVariable cause,
BLangSimpleVariable restDetail,
List<BLangErrorVariable.BLangErrorDetailEntry> detail) {
final BLangErrorVariable errVariable = (BLangErrorVariable) TreeBuilder.createErrorVariableNode();
errVariable.pos = pos;
errVariable.setBType(type);
errVariable.expr = expr;
errVariable.message = message;
errVariable.cause = cause;
errVariable.restDetail = restDetail;
errVariable.detail = detail;
return errVariable;
}

static BLangErrorVariableDef createErrorVariableDef(Location pos, BLangErrorVariable variable) {
final BLangErrorVariableDef variableDef =
(BLangErrorVariableDef) TreeBuilder.createErrorVariableDefinitionNode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5168,18 +5168,8 @@ private BLangFail createOnFailInvocation(BLangOnFailClause onFailClause, BLangFa
onFailBody.stmts.addAll(onFailClause.body.stmts);
env.scope.entries.putAll(onFailClause.body.scope.entries);
onFailBody.failureBreakMode = onFailClause.body.failureBreakMode;
VariableDefinitionNode onFailVarDefNode = onFailClause.variableDefinitionNode;

if (onFailVarDefNode != null) {
BVarSymbol onFailErrorVariableSymbol =
((BLangSimpleVariableDef) onFailVarDefNode).var.symbol;
BLangSimpleVariable errorVar = ASTBuilderUtil.createVariable(onFailErrorVariableSymbol.pos,
onFailErrorVariableSymbol.name.value, onFailErrorVariableSymbol.type, rewrite(fail.expr, env),
onFailErrorVariableSymbol);
BLangSimpleVariableDef errorVarDef = ASTBuilderUtil.createVariableDef(onFailClause.pos, errorVar);
env.scope.define(onFailErrorVariableSymbol.name, onFailErrorVariableSymbol);
onFailBody.stmts.add(0, errorVarDef);
}
handleOnFailErrorVarDefNode(onFailClause.variableDefinitionNode, onFailBody, fail);

if (onFailClause.isInternal && fail.exprStmt != null) {
if (fail.exprStmt instanceof BLangPanic) {
Expand All @@ -5198,6 +5188,37 @@ onFailErrorVariableSymbol.name.value, onFailErrorVariableSymbol.type, rewrite(fa
return fail;
}

private void handleOnFailErrorVarDefNode(VariableDefinitionNode onFailVarDefNode, BLangBlockStmt onFailBody,
BLangFail fail) {
if (onFailVarDefNode == null) {
return;
}

BLangVariable variableNode = (BLangVariable) onFailVarDefNode.getVariable();
onFailBody.stmts.add(0,
variableNode.getKind() == NodeKind.ERROR_VARIABLE ?
handleErrorBPInOnFail((BLangErrorVariable) variableNode, fail) :
handleCaptureBPInOnFail((BLangSimpleVariable) variableNode, fail));
}

private BLangStatement handleErrorBPInOnFail(BLangErrorVariable varNode, BLangFail fail) {
BLangErrorVariable errorVar = ASTBuilderUtil.createErrorVariable(varNode.pos,
varNode.getBType(), rewrite(fail.expr, env), varNode.message, varNode.cause, varNode.restDetail,
varNode.detail);
BLangErrorVariableDef errorVarDef = ASTBuilderUtil.createErrorVariableDef(varNode.pos, errorVar);
return rewrite(errorVarDef, env);
}

private BLangStatement handleCaptureBPInOnFail(BLangSimpleVariable varNode, BLangFail fail) {
BVarSymbol onFailErrorVariableSymbol = varNode.symbol;
BLangSimpleVariable errorVar = ASTBuilderUtil.createVariable(onFailErrorVariableSymbol.pos,
onFailErrorVariableSymbol.name.value, onFailErrorVariableSymbol.type, rewrite(fail.expr, env),
onFailErrorVariableSymbol);
BLangSimpleVariableDef errorVarDef = ASTBuilderUtil.createVariableDef(onFailClause.pos, errorVar);
env.scope.define(onFailErrorVariableSymbol.name, onFailErrorVariableSymbol);
return errorVarDef;
}

private BLangBlockStmt rewriteNestedOnFail(BLangOnFailClause onFailClause, BLangFail fail) {
BLangOnFailClause currentOnFail = this.onFailClause;

Expand All @@ -5206,18 +5227,8 @@ private BLangBlockStmt rewriteNestedOnFail(BLangOnFailClause onFailClause, BLang
onFailBody.scope = onFailClause.body.scope;
onFailBody.mapSymbol = onFailClause.body.mapSymbol;
onFailBody.failureBreakMode = onFailClause.body.failureBreakMode;
VariableDefinitionNode onFailVarDefNode = onFailClause.variableDefinitionNode;

if (onFailVarDefNode != null) {
BVarSymbol onFailErrorVariableSymbol =
((BLangSimpleVariableDef) onFailVarDefNode).var.symbol;
BLangSimpleVariable errorVar = ASTBuilderUtil.createVariable(onFailErrorVariableSymbol.pos,
onFailErrorVariableSymbol.name.value, onFailErrorVariableSymbol.type, rewrite(fail.expr, env),
onFailErrorVariableSymbol);
BLangSimpleVariableDef errorVarDef = ASTBuilderUtil.createVariableDef(onFailClause.pos, errorVar);
onFailBody.scope.define(onFailErrorVariableSymbol.name, onFailErrorVariableSymbol);
onFailBody.stmts.add(0, errorVarDef);
}

handleOnFailErrorVarDefNode(onFailClause.variableDefinitionNode, onFailBody, fail);

int currentOnFailIndex = this.enclosingOnFailClause.indexOf(this.onFailClause);
int enclosingOnFailIndex = currentOnFailIndex <= 0 ? this.enclosingOnFailClause.size() - 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3936,25 +3936,13 @@ public BLangNode transform(OnFailClauseNode onFailClauseNode) {
Location pos = getPosition(onFailClauseNode);
BLangOnFailClause onFailClause = (BLangOnFailClause) TreeBuilder.createOnFailClauseNode();
onFailClause.pos = pos;
onFailClauseNode.typeDescriptor().ifPresent(typeDescriptorNode -> {
BLangSimpleVariableDef variableDefinitionNode =
(BLangSimpleVariableDef) TreeBuilder.createSimpleVariableDefinitionNode();
BLangSimpleVariable var = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode();
boolean isDeclaredWithVar = typeDescriptorNode.kind() == SyntaxKind.VAR_TYPE_DESC;
var.isDeclaredWithVar = isDeclaredWithVar;
if (!isDeclaredWithVar) {
var.setTypeNode(createTypeNode(typeDescriptorNode));
}
var.pos = pos;
onFailClauseNode.failErrorName().ifPresent(identifierToken -> {
var.setName(this.createIdentifier(identifierToken));
var.name.pos = getPosition(identifierToken);
variableDefinitionNode.setVariable(var);
variableDefinitionNode.pos = getPosition(typeDescriptorNode,
identifierToken);
});
onFailClause.isDeclaredWithVar = isDeclaredWithVar;
markVariableWithFlag(variableDefinitionNode.getVariable(), Flag.FINAL);
onFailClauseNode.typedBindingPattern().ifPresent(typedBindingPatternNode -> {
VariableDefinitionNode variableDefinitionNode =
createBLangVarDef(getPosition(typedBindingPatternNode), typedBindingPatternNode,
Optional.empty(), Optional.empty());
onFailClause.isDeclaredWithVar =
typedBindingPatternNode.typeDescriptor().kind() == SyntaxKind.VAR_TYPE_DESC;
markVariableWithFlag((BLangVariable) variableDefinitionNode.getVariable(), Flag.FINAL);
onFailClause.variableDefinitionNode = variableDefinitionNode;
});
BLangBlockStmt blockNode = (BLangBlockStmt) transform(onFailClauseNode.blockStatement());
Expand Down
Loading

0 comments on commit a33bee3

Please sign in to comment.