use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause in project ballerina by ballerina-lang.
the class CodeAnalyzer method visit.
@Override
public void visit(BLangMatch matchStmt) {
this.returnWithintransactionCheckStack.push(true);
boolean unmatchedExprTypesAvailable = false;
analyzeExpr(matchStmt.expr);
// TODO Handle **any** as a expr type.. special case it..
// TODO Complete the exhaustive tests with any, struct and connector types
// TODO Handle the case where there are incompatible types. e.g. input string : pattern int and pattern string
List<BType> unmatchedExprTypes = new ArrayList<>();
for (BType exprType : matchStmt.exprTypes) {
boolean assignable = false;
for (BLangMatchStmtPatternClause pattern : matchStmt.patternClauses) {
BType patternType = pattern.variable.type;
if (exprType.tag == TypeTags.ERROR || patternType.tag == TypeTags.ERROR) {
return;
}
assignable = this.types.isAssignable(exprType, patternType);
if (assignable) {
pattern.matchedTypesDirect.add(exprType);
break;
} else if (exprType.tag == TypeTags.ANY) {
pattern.matchedTypesIndirect.add(exprType);
} else if (exprType.tag == TypeTags.JSON && this.types.isAssignable(patternType, exprType)) {
pattern.matchedTypesIndirect.add(exprType);
} else if (exprType.tag == TypeTags.STRUCT && this.types.isAssignable(patternType, exprType)) {
pattern.matchedTypesIndirect.add(exprType);
} else {
// TODO Support other assignable types
}
}
if (!assignable) {
unmatchedExprTypes.add(exprType);
}
}
if (!unmatchedExprTypes.isEmpty()) {
unmatchedExprTypesAvailable = true;
dlog.error(matchStmt.pos, DiagnosticCode.MATCH_STMT_CANNOT_GUARANTEE_A_MATCHING_PATTERN, unmatchedExprTypes);
}
boolean matchedPatternsAvailable = false;
for (int i = matchStmt.patternClauses.size() - 1; i >= 0; i--) {
BLangMatchStmtPatternClause pattern = matchStmt.patternClauses.get(i);
if (pattern.matchedTypesDirect.isEmpty() && pattern.matchedTypesIndirect.isEmpty()) {
if (matchedPatternsAvailable) {
dlog.error(pattern.pos, DiagnosticCode.MATCH_STMT_UNMATCHED_PATTERN);
} else {
dlog.error(pattern.pos, DiagnosticCode.MATCH_STMT_UNREACHABLE_PATTERN);
}
} else {
matchedPatternsAvailable = true;
}
}
// Execute the following block if there are no unmatched expression types
if (!unmatchedExprTypesAvailable) {
this.checkStatementExecutionValidity(matchStmt);
boolean matchStmtReturns = true;
for (BLangMatchStmtPatternClause patternClause : matchStmt.patternClauses) {
patternClause.body.accept(this);
matchStmtReturns = matchStmtReturns && this.statementReturns;
this.resetStatementReturns();
}
this.statementReturns = matchStmtReturns;
}
this.returnWithintransactionCheckStack.pop();
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause in project ballerina by ballerina-lang.
the class ASTBuilderUtil method createMatchStatementPattern.
static BLangMatchStmtPatternClause createMatchStatementPattern(DiagnosticPos pos, BLangVariable variable, BLangBlockStmt body) {
BLangMatchStmtPatternClause patternClause = (BLangMatchStmtPatternClause) TreeBuilder.createMatchStatementPattern();
patternClause.pos = pos;
patternClause.variable = variable;
patternClause.body = body;
return patternClause;
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause in project ballerina by ballerina-lang.
the class ASTBuilderUtil method createMatchStatement.
static BLangMatch createMatchStatement(DiagnosticPos pos, BLangExpression expr, List<BLangMatchStmtPatternClause> patternClauses) {
BLangMatch matchStmt = (BLangMatch) TreeBuilder.createMatchStatement();
matchStmt.pos = pos;
matchStmt.expr = expr;
matchStmt.patternClauses = patternClauses;
return matchStmt;
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause in project ballerina by ballerina-lang.
the class Desugar method getMatchPatternBody.
private BLangBlockStmt getMatchPatternBody(BLangMatchStmtPatternClause patternClause, BLangVariable matchExprVar) {
// Add the variable definition to the body of the pattern clause
if (patternClause.variable.name.value.equals(Names.IGNORE.value)) {
return patternClause.body;
}
// create TypeName i = <TypeName> _$$_
// Create a variable reference for _$$_
BLangSimpleVarRef matchExprVarRef = ASTBuilderUtil.createVariableRef(patternClause.pos, matchExprVar.symbol);
BLangExpression patternVarExpr = addConversionExprIfRequired(matchExprVarRef, patternClause);
// Add the variable def statement
BLangVariable patternVar = ASTBuilderUtil.createVariable(patternClause.pos, "", patternClause.variable.type, patternVarExpr, patternClause.variable.symbol);
BLangVariableDef patternVarDef = ASTBuilderUtil.createVariableDef(patternVar.pos, patternVar);
patternClause.body.stmts.add(0, patternVarDef);
return patternClause.body;
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause 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);
}
Aggregations