use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch in project ballerina by ballerina-lang.
the class Desugar method visit.
@Override
public void visit(BLangAssignment assignNode) {
if (assignNode.expr.type.tag == TypeTags.STREAM && assignNode.varRefs.get(0) instanceof BLangSimpleVarRef) {
((BLangRecordLiteral) assignNode.expr).name = ((BLangSimpleVarRef) assignNode.varRefs.get(0)).variableName;
}
assignNode.varRefs = rewriteExprs(assignNode.varRefs);
assignNode.expr = rewriteExpr(assignNode.expr);
result = assignNode;
if (!assignNode.safeAssignment) {
return;
}
// Desugar the =? operator with the match statement
//
// e.g.
// File f;
// .....
// f =? openFile("/tmp/foo.txt"); // openFile: () -> (File | error)
//
// {
// match openFile("/tmp/foo.txt") {
// File _$_f1 => f = _$_f1;
// error e => throw e | return e
// }
// }
BLangBlockStmt safeAssignmentBlock = ASTBuilderUtil.createBlockStmt(assignNode.pos, new ArrayList<>());
BLangExpression lhsExpr = assignNode.varRefs.get(0);
BLangMatchStmtPatternClause patternSuccessCase;
if (assignNode.declaredWithVar) {
BVarSymbol varSymbol = ((BLangSimpleVarRef) lhsExpr).symbol;
BLangVariable variable = ASTBuilderUtil.createVariable(assignNode.pos, "", lhsExpr.type, null, varSymbol);
BLangVariableDef variableDef = ASTBuilderUtil.createVariableDef(assignNode.pos, variable);
safeAssignmentBlock.stmts.add(variableDef);
patternSuccessCase = getSafeAssignSuccessPattern(assignNode.pos, lhsExpr.type, true, varSymbol, null);
} else {
patternSuccessCase = getSafeAssignSuccessPattern(assignNode.pos, lhsExpr.type, false, null, lhsExpr);
}
// Create the pattern to match the success case
BLangMatchStmtPatternClause patternErrorCase = getSafeAssignErrorPattern(assignNode.pos, this.env.enclInvokable.symbol);
// Create the match statement
BLangMatch matchStmt = ASTBuilderUtil.createMatchStatement(assignNode.pos, assignNode.expr, new ArrayList<BLangMatchStmtPatternClause>() {
{
add(patternSuccessCase);
add(patternErrorCase);
}
});
// var f =? foo() -> var f;
assignNode.expr = null;
assignNode.safeAssignment = false;
safeAssignmentBlock.stmts.add(matchStmt);
result = rewrite(safeAssignmentBlock, this.env);
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangMatch matchNode) {
List<BType> exprTypes = typeChecker.checkExpr(matchNode.expr, env, Lists.of(symTable.noType));
if (exprTypes.size() > 1) {
dlog.error(matchNode.expr.pos, DiagnosticCode.MULTI_VAL_EXPR_IN_SINGLE_VAL_CONTEXT);
return;
} else if (exprTypes.size() == 0) {
dlog.error(matchNode.expr.pos, DiagnosticCode.INVALID_EXPR_IN_MATCH_STMT);
return;
} else if (exprTypes.get(0).tag == TypeTags.UNION) {
BUnionType unionType = (BUnionType) exprTypes.get(0);
exprTypes = new ArrayList<>(unionType.memberTypes);
}
// visit patterns
matchNode.patternClauses.forEach(patternClause -> patternClause.accept(this));
matchNode.exprTypes = exprTypes;
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch in project ballerina by ballerina-lang.
the class Desugar method visit.
@Override
public void visit(BLangVariableDef varDefNode) {
if (varDefNode.var.expr instanceof BLangRecordLiteral && ((BLangRecordLiteral) varDefNode.var.expr).type.tag == TypeTags.STREAM) {
((BLangRecordLiteral) varDefNode.var.expr).name = varDefNode.var.name;
}
varDefNode.var = rewrite(varDefNode.var, env);
BLangVariable varNode = varDefNode.var;
// Generate default init expression, if rhs expr is null
if (varNode.expr == null) {
varNode.expr = getInitExpr(varNode.type);
}
if (!varNode.safeAssignment) {
result = varDefNode;
return;
}
// Desugar the =? operator with the match statement
//
// e.g.
// var f =? openFile("/tmp/foo.txt"); // openFile: () -> (File | error)
//
// {
// File f;
// match openFile("/tmp/foo.txt") {
// File _$_f1 => f = _$_f1;
// error e => throw e | return e
// }
// }
// Create the pattern to match the success case
BLangMatchStmtPatternClause patternSuccessCase = getSafeAssignSuccessPattern(varNode.pos, varNode.symbol.type, true, varNode.symbol, null);
BLangMatchStmtPatternClause patternErrorCase = getSafeAssignErrorPattern(varNode.pos, varNode.symbol.owner);
// Create the match statement
BLangMatch matchStmt = ASTBuilderUtil.createMatchStatement(varNode.expr.pos, varNode.expr, new ArrayList<BLangMatchStmtPatternClause>() {
{
add(patternSuccessCase);
add(patternErrorCase);
}
});
// var f =? foo() -> var f;
varNode.expr = null;
varNode.safeAssignment = false;
BLangBlockStmt safeAssignmentBlock = ASTBuilderUtil.createBlockStmt(varDefNode.pos, new ArrayList<BLangStatement>() {
{
add(varDefNode);
add(matchStmt);
}
});
result = rewrite(safeAssignmentBlock, this.env);
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch in project ballerina by ballerina-lang.
the class Desugar method visit.
@Override
public void visit(BLangMatch matchStmt) {
// Here we generate an if-else statement for the match statement
// Here is an example match statement
//
// match expr {
// int k => io:println("int value: " + k);
// string s => io:println("string value: " + s);
// json j => io:println("json value: " + s);
//
// }
//
// Here is how we convert the match statement to an if-else statement. The last clause should always be the
// else clause
//
// string | int | json | any _$$_matchexpr = expr;
// if ( _$$_matchexpr isassignable int ){
// int k = (int) _$$_matchexpr; // unbox
// io:println("int value: " + k);
//
// } else if (_$$_matchexpr isassignable string ) {
// string s = (string) _$$_matchexpr; // unbox
// io:println("string value: " + s);
//
// } else if ( _$$_matchexpr isassignable float || // should we consider json[] as well
// _$$_matchexpr isassignable boolean ||
// _$$_matchexpr isassignable json) {
//
// } else {
// // handle the last pattern
// any case..
// }
//
// First create a block statement to hold generated statements
BLangBlockStmt matchBlockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode();
matchBlockStmt.pos = matchStmt.pos;
// Create a variable definition to store the value of the match expression
String matchExprVarName = GEN_VAR_PREFIX.value;
BLangVariable matchExprVar = ASTBuilderUtil.createVariable(matchStmt.expr.pos, matchExprVarName, matchStmt.expr.type, matchStmt.expr, new BVarSymbol(0, names.fromString(matchExprVarName), this.env.scope.owner.pkgID, matchStmt.expr.type, this.env.scope.owner));
// Now create a variable definition node
BLangVariableDef matchExprVarDef = ASTBuilderUtil.createVariableDef(matchBlockStmt.pos, matchExprVar);
// Add the var def statement to the block statement
// string | int _$$_matchexpr = expr;
matchBlockStmt.stmts.add(matchExprVarDef);
// Create if/else blocks with typeof binary expressions for each pattern
matchBlockStmt.stmts.add(generateIfElseStmt(matchStmt, matchExprVar));
rewrite(matchBlockStmt, this.env);
result = matchBlockStmt;
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch in project ballerina by ballerina-lang.
the class BLangPackageBuilder method completeMatchNode.
public void completeMatchNode(DiagnosticPos pos, Set<Whitespace> ws) {
BLangMatch matchStmt = this.matchStmtStack.removeFirst();
matchStmt.pos = pos;
matchStmt.addWS(ws);
matchStmt.expr = (BLangExpression) this.exprNodeStack.pop();
addStmtToCurrentBlock(matchStmt);
}
Aggregations