Search in sources :

Example 1 with IterableContext

use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.

the class IterableAnalyzer method handlerIterableOperation.

public void handlerIterableOperation(BLangInvocation iExpr, BType expectedType, SymbolEnv env) {
    final IterableContext context;
    if (iExpr.expr.type.tag != TypeTags.INTERMEDIATE_COLLECTION) {
        // This is a new iteration chain.
        context = new IterableContext(iExpr.expr, env);
    } else {
        // Get context from previous invocation.
        context = ((BLangInvocation) iExpr.expr).iContext;
    }
    iExpr.iContext = context;
    final IterableKind iterableKind = IterableKind.getFromString(iExpr.name.value);
    final Operation iOperation = new Operation(iterableKind, iExpr, expectedType);
    iExpr.iContext.addOperation(iOperation);
    if (iterableKind.isLambdaRequired()) {
        handleLambdaBasedIterableOperation(context, iOperation);
    } else {
        handleSimpleTerminalOperations(iOperation);
    }
    validateIterableContext(context);
    if (iOperation.resultType != symTable.errType && context.foreachTypes.isEmpty()) {
        calculateForeachTypes(context);
    }
}
Also used : IterableContext(org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext) IterableKind(org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableKind) Operation(org.wso2.ballerinalang.compiler.semantics.model.iterable.Operation)

Example 2 with IterableContext

use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.

the class IterableAnalyzer method validateIterableContext.

public void validateIterableContext(IterableContext context) {
    final Operation lastOperation = context.operations.getLast();
    final BType expectedType = lastOperation.expectedType;
    final BType outputType = lastOperation.resultType;
    if (expectedType.tag == TypeTags.VOID && outputType.tag == TypeTags.VOID) {
        context.resultType = symTable.noType;
        return;
    }
    if (expectedType.tag == TypeTags.VOID) {
        // This error already logged.
        return;
    }
    if (expectedType == symTable.errType) {
        context.resultType = symTable.errType;
        return;
    }
    if (outputType.tag == TypeTags.VOID) {
        dlog.error(lastOperation.pos, DiagnosticCode.DOES_NOT_RETURN_VALUE, lastOperation.kind);
        context.resultType = symTable.errType;
        return;
    }
    // Calculate expected type, if this is an chained iterable operation.
    if (outputType.tag == TypeTags.INTERMEDIATE_COLLECTION) {
        BIntermediateCollectionType collectionType = (BIntermediateCollectionType) outputType;
        final BTupleType tupleType = collectionType.tupleType;
        if (expectedType.tag == TypeTags.ARRAY && tupleType.tupleTypes.size() == 1) {
            // Convert result into an array.
            context.resultType = new BArrayType(tupleType.tupleTypes.get(0));
            return;
        } else if (expectedType.tag == TypeTags.MAP && tupleType.tupleTypes.size() == 2 && tupleType.tupleTypes.get(0).tag == TypeTags.STRING) {
            // Convert result into a map.
            context.resultType = new BMapType(TypeTags.MAP, tupleType.tupleTypes.get(1), null);
            return;
        } else if (expectedType.tag == TypeTags.TABLE) {
            // 3. Whether the returned struct is compatible with the constraint struct of the expected type(table)
            if (tupleType.getTupleTypes().size() == 1 && tupleType.getTupleTypes().get(0).tag == TypeTags.STRUCT && types.isAssignable(tupleType.getTupleTypes().get(0), ((BTableType) expectedType).constraint)) {
                context.resultType = symTable.tableType;
            } else {
                context.resultType = types.checkType(lastOperation.pos, outputType, ((BTableType) expectedType).constraint, DiagnosticCode.INCOMPATIBLE_TYPES);
            }
            return;
        } else if (expectedType.tag == TypeTags.ANY) {
            context.resultType = symTable.errType;
            dlog.error(lastOperation.pos, DiagnosticCode.ITERABLE_RETURN_TYPE_MISMATCH, lastOperation.kind);
            return;
        } else if (expectedType.tag == TypeTags.NONE) {
            context.resultType = symTable.noType;
            return;
        }
    }
    // Validate compatibility with calculated and expected type.
    context.resultType = types.checkType(lastOperation.pos, outputType, expectedType, DiagnosticCode.INCOMPATIBLE_TYPES);
}
Also used : BMapType(org.wso2.ballerinalang.compiler.semantics.model.types.BMapType) BArrayType(org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BTupleType(org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType) Operation(org.wso2.ballerinalang.compiler.semantics.model.iterable.Operation) BIntermediateCollectionType(org.wso2.ballerinalang.compiler.semantics.model.types.BIntermediateCollectionType) BTableType(org.wso2.ballerinalang.compiler.semantics.model.types.BTableType)

Example 3 with IterableContext

use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.

the class IterableCodeDesugar method desugar.

public void desugar(IterableContext ctx) {
    // Gather required data for code generation.
    processIterableContext(ctx);
    // Generate Iterable Iteration.
    generateIteratorFunction(ctx);
    // Create invocation expression to invoke iterable operation.
    final BLangInvocation iExpr = ASTBuilderUtil.createInvocationExpr(ctx.collectionExpr.pos, ctx.iteratorFuncSymbol, Collections.emptyList(), symResolver);
    iExpr.requiredArgs.add(ctx.collectionExpr);
    if (ctx.getLastOperation().expectedType == symTable.noType || ctx.getLastOperation().expectedType == symTable.voidType) {
        ctx.iteratorCaller = iExpr;
    } else {
        ctx.iteratorCaller = ASTBuilderUtil.wrapToConversionExpr(ctx.getLastOperation().expectedType, iExpr, symTable, types);
    }
}
Also used : BLangInvocation(org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation)

Example 4 with IterableContext

use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.

the class IterableCodeDesugar method generateTableAggregator.

private void generateTableAggregator(BLangBlockStmt blockStmt, IterableContext ctx) {
    final DiagnosticPos pos = blockStmt.pos;
    List<BLangVariable> variables = new ArrayList<>(1);
    variables.add(ctx.resultVar);
    variables.add(ctx.iteratorResultVariables.get(0));
    BInvokableSymbol addSymbol = (BInvokableSymbol) symTable.rootScope.lookup(names.fromString(TABLE_ADD_FUNCTION)).symbol;
    BLangInvocation addFunctionInvocation = ASTBuilderUtil.createInvocationExpr(pos, addSymbol, variables, symResolver);
    BLangExpressionStmt expressionStmt = ASTBuilderUtil.createExpressionStmt(pos, blockStmt);
    expressionStmt.expr = addFunctionInvocation;
}
Also used : DiagnosticPos(org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos) ArrayList(java.util.ArrayList) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol) BLangInvocation(org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation) BLangExpressionStmt(org.wso2.ballerinalang.compiler.tree.statements.BLangExpressionStmt) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable)

Example 5 with IterableContext

use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.

the class IterableCodeDesugar method createIteratorResultVariables.

private List<BLangVariable> createIteratorResultVariables(IterableContext ctx, BLangVariable lastOperationArg, BLangFunction funcNode) {
    List<BLangVariable> resultVariables = new ArrayList<>();
    if (lastOperationArg.type.tag != TypeTags.TUPLE) {
        resultVariables.add(lastOperationArg);
        defineVariable(lastOperationArg, ctx.env.enclPkg.symbol.pkgID, funcNode);
        return resultVariables;
    }
    final List<BType> tupleTypes = ((BTupleType) lastOperationArg.type).tupleTypes;
    int index = 0;
    for (BType type : tupleTypes) {
        String varName = VAR_RESULT_VAL + index++;
        final BLangVariable variable = ASTBuilderUtil.createVariable(funcNode.pos, varName, type);
        resultVariables.add(variable);
        defineVariable(variable, ctx.env.enclPkg.symbol.pkgID, funcNode);
    }
    return resultVariables;
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) ArrayList(java.util.ArrayList) BTupleType(org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable)

Aggregations

DiagnosticPos (org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos)12 BLangVariable (org.wso2.ballerinalang.compiler.tree.BLangVariable)8 BLangAssignment (org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment)8 Operation (org.wso2.ballerinalang.compiler.semantics.model.iterable.Operation)5 BTupleType (org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType)5 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)5 BLangBinaryExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangBinaryExpr)5 ArrayList (java.util.ArrayList)4 BLangReturn (org.wso2.ballerinalang.compiler.tree.statements.BLangReturn)4 BLangVariableDef (org.wso2.ballerinalang.compiler.tree.statements.BLangVariableDef)4 IterableKind (org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableKind)3 BTableType (org.wso2.ballerinalang.compiler.semantics.model.types.BTableType)3 BLangIndexBasedAccess (org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess)3 BLangForeach (org.wso2.ballerinalang.compiler.tree.statements.BLangForeach)3 HashSet (java.util.HashSet)2 IterableContext (org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext)2 BInvokableSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)2 BLangArrayLiteral (org.wso2.ballerinalang.compiler.tree.expressions.BLangArrayLiteral)2 BLangBracedOrTupleExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangBracedOrTupleExpr)2 BLangInvocation (org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation)2