Search in sources :

Example 1 with BLangMatchStmtPatternClause

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();
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) ArrayList(java.util.ArrayList) BLangMatchStmtPatternClause(org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause) BLangEndpoint(org.wso2.ballerinalang.compiler.tree.BLangEndpoint)

Example 2 with BLangMatchStmtPatternClause

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;
}
Also used : BLangMatchStmtPatternClause(org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause)

Example 3 with BLangMatchStmtPatternClause

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;
}
Also used : BLangMatch(org.wso2.ballerinalang.compiler.tree.statements.BLangMatch)

Example 4 with BLangMatchStmtPatternClause

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;
}
Also used : BLangSimpleVarRef(org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef) BLangVariableDef(org.wso2.ballerinalang.compiler.tree.statements.BLangVariableDef) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable)

Example 5 with BLangMatchStmtPatternClause

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);
}
Also used : BLangBlockStmt(org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt) BLangSimpleVarRef(org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef) BLangMatch(org.wso2.ballerinalang.compiler.tree.statements.BLangMatch) BLangMatchStmtPatternClause(org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause) BLangVariableDef(org.wso2.ballerinalang.compiler.tree.statements.BLangVariableDef) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression) BVarSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable)

Aggregations

BLangMatchStmtPatternClause (org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStmtPatternClause)7 BLangVariable (org.wso2.ballerinalang.compiler.tree.BLangVariable)6 BLangExpression (org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)6 BLangBlockStmt (org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt)5 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)4 BLangEndpoint (org.wso2.ballerinalang.compiler.tree.BLangEndpoint)4 BLangMatch (org.wso2.ballerinalang.compiler.tree.statements.BLangMatch)4 BVarSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol)3 BLangStatement (org.wso2.ballerinalang.compiler.tree.statements.BLangStatement)3 ArrayList (java.util.ArrayList)2 SymbolEnv (org.wso2.ballerinalang.compiler.semantics.model.SymbolEnv)2 BConversionOperatorSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BConversionOperatorSymbol)2 BLangRecordLiteral (org.wso2.ballerinalang.compiler.tree.expressions.BLangRecordLiteral)2 BLangSimpleVarRef (org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef)2 BLangTypeConversionExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangTypeConversionExpr)2 BLangVariableReference (org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference)2 BLangXMLQuotedString (org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQuotedString)2 BLangAssignment (org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment)2 BLangIf (org.wso2.ballerinalang.compiler.tree.statements.BLangIf)2 BLangVariableDef (org.wso2.ballerinalang.compiler.tree.statements.BLangVariableDef)2