Search in sources :

Example 41 with BLangFunction

use of org.wso2.ballerinalang.compiler.tree.BLangFunction in project ballerina by ballerina-lang.

the class IterableCodeDesugar method defineFunction.

private void defineFunction(BLangFunction funcNode, BLangPackage targetPkg) {
    final BPackageSymbol packageSymbol = targetPkg.symbol;
    final SymbolEnv packageEnv = this.symTable.pkgEnvMap.get(packageSymbol);
    symbolEnter.defineNode(funcNode, packageEnv);
    packageEnv.enclPkg.functions.add(funcNode);
    packageEnv.enclPkg.topLevelNodes.add(funcNode);
}
Also used : BPackageSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol) SymbolEnv(org.wso2.ballerinalang.compiler.semantics.model.SymbolEnv)

Example 42 with BLangFunction

use of org.wso2.ballerinalang.compiler.tree.BLangFunction in project ballerina by ballerina-lang.

the class IterableCodeDesugar method generateIteratorFunction.

private void generateIteratorFunction(IterableContext ctx) {
    final Operation firstOperation = ctx.getFirstOperation();
    final DiagnosticPos pos = firstOperation.pos;
    // Create and define function signature.
    final BLangFunction funcNode = ASTBuilderUtil.createFunction(pos, getFunctionName(FUNC_CALLER));
    funcNode.requiredParams.add(ctx.collectionVar);
    if (isReturningIteratorFunction(ctx)) {
        funcNode.retParams.add(ctx.resultVar);
    }
    defineFunction(funcNode, ctx.env.enclPkg);
    ctx.iteratorFuncSymbol = funcNode.symbol;
    LinkedList<Operation> streamableOperations = new LinkedList<>();
    ctx.operations.stream().filter(op -> op.kind.isLambdaRequired()).forEach(streamableOperations::add);
    if (streamableOperations.isEmpty()) {
        // Generate simple iterator function body.
        generateSimpleIteratorBlock(ctx, funcNode);
        return;
    }
    // Generate Caller Function.
    generateStreamingIteratorBlock(ctx, funcNode, streamableOperations);
}
Also used : DiagnosticPos(org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos) BTupleType(org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType) BLangReturn(org.wso2.ballerinalang.compiler.tree.statements.BLangReturn) Lists(org.wso2.ballerinalang.util.Lists) BVarSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol) OperatorKind(org.ballerinalang.model.tree.OperatorKind) BLangTupleDestructure(org.wso2.ballerinalang.compiler.tree.statements.BLangTupleDestructure) SymbolResolver(org.wso2.ballerinalang.compiler.semantics.analyzer.SymbolResolver) BOperatorSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BOperatorSymbol) Names(org.wso2.ballerinalang.compiler.util.Names) BLangAssignment(org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment) BLangSimpleVarRef(org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef) BLangBinaryExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangBinaryExpr) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression) PackageID(org.ballerinalang.model.elements.PackageID) Set(java.util.Set) BPackageSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol) List(java.util.List) NodeKind(org.ballerinalang.model.tree.NodeKind) BLangLambdaFunction(org.wso2.ballerinalang.compiler.tree.expressions.BLangLambdaFunction) BLangIf(org.wso2.ballerinalang.compiler.tree.statements.BLangIf) SymbolEnter(org.wso2.ballerinalang.compiler.semantics.analyzer.SymbolEnter) BLangForeach(org.wso2.ballerinalang.compiler.tree.statements.BLangForeach) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable) BLangExpressionStmt(org.wso2.ballerinalang.compiler.tree.statements.BLangExpressionStmt) Operation(org.wso2.ballerinalang.compiler.semantics.model.iterable.Operation) Types(org.wso2.ballerinalang.compiler.semantics.analyzer.Types) BLangIndexBasedAccess(org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess) ArrayList(java.util.ArrayList) TypeTags(org.wso2.ballerinalang.compiler.util.TypeTags) HashSet(java.util.HashSet) IterableKind(org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableKind) BLangVariableDef(org.wso2.ballerinalang.compiler.tree.statements.BLangVariableDef) TreeBuilder(org.ballerinalang.model.TreeBuilder) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BLangArrayLiteral(org.wso2.ballerinalang.compiler.tree.expressions.BLangArrayLiteral) BLangUnaryExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangUnaryExpr) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol) BLangTernaryExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangTernaryExpr) DiagnosticPos(org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos) LinkedList(java.util.LinkedList) BLangPackage(org.wso2.ballerinalang.compiler.tree.BLangPackage) SymbolEnv(org.wso2.ballerinalang.compiler.semantics.model.SymbolEnv) IterableContext(org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext) BLangFunction(org.wso2.ballerinalang.compiler.tree.BLangFunction) BLangInvocation(org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation) BTableType(org.wso2.ballerinalang.compiler.semantics.model.types.BTableType) BLangBlockStmt(org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt) BLangBracedOrTupleExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangBracedOrTupleExpr) Collections(java.util.Collections) SymbolTable(org.wso2.ballerinalang.compiler.semantics.model.SymbolTable) CompilerContext(org.wso2.ballerinalang.compiler.util.CompilerContext) BLangFunction(org.wso2.ballerinalang.compiler.tree.BLangFunction) Operation(org.wso2.ballerinalang.compiler.semantics.model.iterable.Operation) LinkedList(java.util.LinkedList)

Example 43 with BLangFunction

use of org.wso2.ballerinalang.compiler.tree.BLangFunction in project ballerina by ballerina-lang.

the class IterableCodeDesugar method defineRequiredVariables.

private void defineRequiredVariables(IterableContext ctx, LinkedList<Operation> streamOperations, List<BLangVariable> foreachVariables, BLangFunction funcNode) {
    Set<BLangVariable> notDefinedVars = new HashSet<>();
    streamOperations.forEach(operation -> {
        notDefinedVars.add(operation.argVar);
        if (operation.kind != IterableKind.FILTER && operation.retVar != null) {
            notDefinedVars.add(operation.retVar);
        }
    });
    notDefinedVars.addAll(ctx.iteratorResultVariables);
    notDefinedVars.removeAll(foreachVariables);
    notDefinedVars.forEach(var -> defineVariable(var, ctx.env.enclPkg.symbol.pkgID, funcNode));
    notDefinedVars.forEach(var -> {
        BLangVariableDef variableDefStmt = ASTBuilderUtil.createVariableDefStmt(funcNode.pos, funcNode.body);
        variableDefStmt.var = var;
    });
}
Also used : BLangVariableDef(org.wso2.ballerinalang.compiler.tree.statements.BLangVariableDef) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable) HashSet(java.util.HashSet)

Example 44 with BLangFunction

use of org.wso2.ballerinalang.compiler.tree.BLangFunction in project ballerina by ballerina-lang.

the class IterableCodeDesugar method generateStreamingIteratorBlock.

private void generateStreamingIteratorBlock(IterableContext ctx, BLangFunction funcNode, LinkedList<Operation> streamOperations) {
    final Operation firstOperation = ctx.getFirstOperation();
    final DiagnosticPos pos = firstOperation.pos;
    // Generate streaming based function Body.
    if (isReturningIteratorFunction(ctx)) {
        if (ctx.resultType.tag != TypeTags.TABLE) {
            // This should be the select operation. No need of a count variable.
            createCounterVarDefStmt(funcNode, ctx);
        }
        createResultVarDefStmt(funcNode, ctx);
        ctx.iteratorResultVariables = createIteratorResultVariables(ctx, streamOperations.getLast().retVar, funcNode);
    } else {
        ctx.iteratorResultVariables = Collections.emptyList();
    }
    // Create variables required.
    final List<BLangVariable> foreachVariables = createForeachVariables(ctx, ctx.getFirstOperation().argVar, funcNode);
    // Define all undefined variables.
    defineRequiredVariables(ctx, streamOperations, foreachVariables, funcNode);
    // Generate foreach iteration.
    final BLangForeach foreachStmt = ASTBuilderUtil.createForeach(pos, funcNode.body, ASTBuilderUtil.createVariableRef(pos, ctx.collectionVar.symbol), ASTBuilderUtil.createVariableRefList(pos, foreachVariables), ctx.foreachTypes);
    if (foreachVariables.size() > 1) {
        // Create tuple, for lambda invocation.
        final BLangAssignment assignmentStmt = ASTBuilderUtil.createAssignmentStmt(pos, foreachStmt.body);
        assignmentStmt.declaredWithVar = true;
        assignmentStmt.varRefs.add(ASTBuilderUtil.createVariableRef(pos, ctx.getFirstOperation().argVar.symbol));
        final BLangBracedOrTupleExpr tupleExpr = (BLangBracedOrTupleExpr) TreeBuilder.createBracedOrTupleExpression();
        for (BLangVariable foreachVariable : foreachVariables) {
            tupleExpr.expressions.add(ASTBuilderUtil.createVariableRef(pos, foreachVariable.symbol));
        }
        tupleExpr.isBracedExpr = foreachVariables.size() == 1;
        tupleExpr.type = new BTupleType(getTupleTypeList(ctx.getFirstOperation().inputType));
        assignmentStmt.expr = tupleExpr;
    }
    // Generate Operations related
    ctx.operations.forEach(operation -> generateOperationCode(foreachStmt.body, operation));
    // Generate aggregator and result
    if (isReturningIteratorFunction(ctx)) {
        if (ctx.iteratorResultVariables.size() > 1) {
            // Destructure return Values.
            final BLangTupleDestructure tupleAssign = (BLangTupleDestructure) TreeBuilder.createTupleDestructureStatementNode();
            tupleAssign.pos = pos;
            tupleAssign.declaredWithVar = true;
            foreachStmt.body.addStatement(tupleAssign);
            tupleAssign.expr = ASTBuilderUtil.createVariableRef(pos, ctx.getLastOperation().retVar.symbol);
            tupleAssign.varRefs.addAll(ASTBuilderUtil.createVariableRefList(pos, ctx.iteratorResultVariables));
        }
        generateAggregator(foreachStmt.body, ctx);
        generateFinalResult(funcNode.body, ctx);
    }
    final BLangReturn returnStmt = ASTBuilderUtil.createReturnStmt(firstOperation.pos, funcNode.body);
    if (isReturningIteratorFunction(ctx)) {
        returnStmt.addExpression(ASTBuilderUtil.createVariableRef(pos, ctx.resultVar.symbol));
    }
}
Also used : DiagnosticPos(org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos) BLangForeach(org.wso2.ballerinalang.compiler.tree.statements.BLangForeach) BLangAssignment(org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment) BLangReturn(org.wso2.ballerinalang.compiler.tree.statements.BLangReturn) BTupleType(org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType) Operation(org.wso2.ballerinalang.compiler.semantics.model.iterable.Operation) BLangTupleDestructure(org.wso2.ballerinalang.compiler.tree.statements.BLangTupleDestructure) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable) BLangBracedOrTupleExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangBracedOrTupleExpr)

Example 45 with BLangFunction

use of org.wso2.ballerinalang.compiler.tree.BLangFunction in project ballerina by ballerina-lang.

the class BLangPackageBuilder method endFunctionDef.

public void endFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, boolean publicFunc, boolean nativeFunc, boolean bodyExists, boolean isReceiverAttached) {
    BLangFunction function = (BLangFunction) this.invokableNodeStack.pop();
    endEndpointDeclarationScope();
    function.pos = pos;
    function.addWS(ws);
    if (publicFunc) {
        function.flagSet.add(Flag.PUBLIC);
    }
    if (nativeFunc) {
        function.flagSet.add(Flag.NATIVE);
    }
    if (!bodyExists) {
        function.body = null;
    }
    if (isReceiverAttached) {
        BLangVariable receiver = (BLangVariable) this.varStack.pop();
        receiver.docTag = DocTag.RECEIVER;
        function.receiver = receiver;
        function.flagSet.add(Flag.ATTACHED);
    }
    if (!function.deprecatedAttachments.isEmpty()) {
        function.flagSet.add(Flag.DEPRECATED);
    }
    this.compUnit.addTopLevelNode(function);
}
Also used : BLangFunction(org.wso2.ballerinalang.compiler.tree.BLangFunction) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable)

Aggregations

BLangFunction (org.wso2.ballerinalang.compiler.tree.BLangFunction)37 BLangVariable (org.wso2.ballerinalang.compiler.tree.BLangVariable)24 BLangPackage (org.wso2.ballerinalang.compiler.tree.BLangPackage)16 DiagnosticPos (org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos)16 SymbolEnv (org.wso2.ballerinalang.compiler.semantics.model.SymbolEnv)15 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)15 ArrayList (java.util.ArrayList)14 BLangEndpoint (org.wso2.ballerinalang.compiler.tree.BLangEndpoint)14 BLangStruct (org.wso2.ballerinalang.compiler.tree.BLangStruct)13 List (java.util.List)11 BSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol)10 BLangConnector (org.wso2.ballerinalang.compiler.tree.BLangConnector)10 BLangBlockStmt (org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt)10 BInvokableSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)9 BLangEnum (org.wso2.ballerinalang.compiler.tree.BLangEnum)9 BLangObject (org.wso2.ballerinalang.compiler.tree.BLangObject)9 BLangReturn (org.wso2.ballerinalang.compiler.tree.statements.BLangReturn)9 CompilerContext (org.wso2.ballerinalang.compiler.util.CompilerContext)9 Collectors (java.util.stream.Collectors)8 NodeKind (org.ballerinalang.model.tree.NodeKind)8