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);
}
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);
}
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;
});
}
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));
}
}
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);
}
Aggregations