Java tutorial
/* * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.ballerinalang.compiler.parser; import org.apache.commons.lang3.StringEscapeUtils; import org.ballerinalang.compiler.CompilerOptionName; import org.ballerinalang.model.TreeBuilder; import org.ballerinalang.model.TreeUtils; import org.ballerinalang.model.Whitespace; import org.ballerinalang.model.elements.AttachPoint; import org.ballerinalang.model.elements.Flag; import org.ballerinalang.model.elements.PackageID; import org.ballerinalang.model.elements.TableColumnFlag; import org.ballerinalang.model.tree.AnnotatableNode; import org.ballerinalang.model.tree.AnnotationAttachmentNode; import org.ballerinalang.model.tree.AnnotationNode; import org.ballerinalang.model.tree.CompilationUnitNode; import org.ballerinalang.model.tree.DeprecatedNode; import org.ballerinalang.model.tree.DocumentableNode; import org.ballerinalang.model.tree.FunctionNode; import org.ballerinalang.model.tree.IdentifierNode; import org.ballerinalang.model.tree.InvokableNode; import org.ballerinalang.model.tree.MarkdownDocumentationNode; import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.ServiceNode; import org.ballerinalang.model.tree.SimpleVariableNode; import org.ballerinalang.model.tree.VariableNode; import org.ballerinalang.model.tree.clauses.GroupByNode; import org.ballerinalang.model.tree.clauses.HavingNode; import org.ballerinalang.model.tree.clauses.JoinStreamingInput; import org.ballerinalang.model.tree.clauses.LimitNode; import org.ballerinalang.model.tree.clauses.OrderByNode; import org.ballerinalang.model.tree.clauses.OrderByVariableNode; import org.ballerinalang.model.tree.clauses.OutputRateLimitNode; import org.ballerinalang.model.tree.clauses.PatternClause; import org.ballerinalang.model.tree.clauses.PatternStreamingEdgeInputNode; import org.ballerinalang.model.tree.clauses.PatternStreamingInputNode; import org.ballerinalang.model.tree.clauses.SelectClauseNode; import org.ballerinalang.model.tree.clauses.SelectExpressionNode; import org.ballerinalang.model.tree.clauses.SetAssignmentNode; import org.ballerinalang.model.tree.clauses.StreamActionNode; import org.ballerinalang.model.tree.clauses.StreamingInput; import org.ballerinalang.model.tree.clauses.TableQuery; import org.ballerinalang.model.tree.clauses.WhereNode; import org.ballerinalang.model.tree.clauses.WindowClauseNode; import org.ballerinalang.model.tree.clauses.WithinClause; import org.ballerinalang.model.tree.expressions.ExpressionNode; import org.ballerinalang.model.tree.expressions.LiteralNode; import org.ballerinalang.model.tree.expressions.TableQueryExpression; import org.ballerinalang.model.tree.expressions.XMLAttributeNode; import org.ballerinalang.model.tree.expressions.XMLLiteralNode; import org.ballerinalang.model.tree.statements.BlockNode; import org.ballerinalang.model.tree.statements.ForeverNode; import org.ballerinalang.model.tree.statements.ForkJoinNode; import org.ballerinalang.model.tree.statements.IfNode; import org.ballerinalang.model.tree.statements.StatementNode; import org.ballerinalang.model.tree.statements.StreamingQueryStatementNode; import org.ballerinalang.model.tree.statements.TransactionNode; import org.ballerinalang.model.tree.statements.VariableDefinitionNode; import org.ballerinalang.model.tree.types.TypeNode; import org.ballerinalang.model.types.TypeKind; import org.ballerinalang.util.diagnostic.DiagnosticCode; import org.wso2.ballerinalang.compiler.semantics.model.BLangBuiltInMethod; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; import org.wso2.ballerinalang.compiler.tree.BLangAnnotation; import org.wso2.ballerinalang.compiler.tree.BLangAnnotationAttachment; import org.wso2.ballerinalang.compiler.tree.BLangDeprecatedNode; import org.wso2.ballerinalang.compiler.tree.BLangErrorVariable; import org.wso2.ballerinalang.compiler.tree.BLangFunction; import org.wso2.ballerinalang.compiler.tree.BLangIdentifier; import org.wso2.ballerinalang.compiler.tree.BLangImportPackage; import org.wso2.ballerinalang.compiler.tree.BLangMarkdownDocumentation; import org.wso2.ballerinalang.compiler.tree.BLangNameReference; import org.wso2.ballerinalang.compiler.tree.BLangRecordVariable; import org.wso2.ballerinalang.compiler.tree.BLangRecordVariable.BLangRecordVariableKeyValue; import org.wso2.ballerinalang.compiler.tree.BLangService; import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable; import org.wso2.ballerinalang.compiler.tree.BLangTupleVariable; import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.BLangVariable; import org.wso2.ballerinalang.compiler.tree.BLangXMLNS; import org.wso2.ballerinalang.compiler.tree.clauses.BLangGroupBy; import org.wso2.ballerinalang.compiler.tree.clauses.BLangHaving; import org.wso2.ballerinalang.compiler.tree.clauses.BLangJoinStreamingInput; import org.wso2.ballerinalang.compiler.tree.clauses.BLangLimit; import org.wso2.ballerinalang.compiler.tree.clauses.BLangOrderBy; import org.wso2.ballerinalang.compiler.tree.clauses.BLangOrderByVariable; import org.wso2.ballerinalang.compiler.tree.clauses.BLangOutputRateLimit; import org.wso2.ballerinalang.compiler.tree.clauses.BLangPatternClause; import org.wso2.ballerinalang.compiler.tree.clauses.BLangPatternStreamingEdgeInput; import org.wso2.ballerinalang.compiler.tree.clauses.BLangPatternStreamingInput; import org.wso2.ballerinalang.compiler.tree.clauses.BLangSelectClause; import org.wso2.ballerinalang.compiler.tree.clauses.BLangSelectExpression; import org.wso2.ballerinalang.compiler.tree.clauses.BLangSetAssignment; import org.wso2.ballerinalang.compiler.tree.clauses.BLangStreamAction; import org.wso2.ballerinalang.compiler.tree.clauses.BLangStreamingInput; import org.wso2.ballerinalang.compiler.tree.clauses.BLangTableQuery; import org.wso2.ballerinalang.compiler.tree.clauses.BLangWhere; import org.wso2.ballerinalang.compiler.tree.clauses.BLangWindow; import org.wso2.ballerinalang.compiler.tree.clauses.BLangWithinClause; import org.wso2.ballerinalang.compiler.tree.expressions.BLangArrayLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangArrowFunction; import org.wso2.ballerinalang.compiler.tree.expressions.BLangBinaryExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangBracedOrTupleExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangCheckedExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangConstant; import org.wso2.ballerinalang.compiler.tree.expressions.BLangElvisExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangErrorConstructorExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangErrorVarRef; import org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression; import org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess; import org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess; import org.wso2.ballerinalang.compiler.tree.expressions.BLangIntRangeExpression; import org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation; import org.wso2.ballerinalang.compiler.tree.expressions.BLangLambdaFunction; import org.wso2.ballerinalang.compiler.tree.expressions.BLangLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangMarkdownDocumentationLine; import org.wso2.ballerinalang.compiler.tree.expressions.BLangMarkdownParameterDocumentation; import org.wso2.ballerinalang.compiler.tree.expressions.BLangMarkdownReturnParameterDocumentation; import org.wso2.ballerinalang.compiler.tree.expressions.BLangNamedArgsExpression; import org.wso2.ballerinalang.compiler.tree.expressions.BLangNumericLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangRecordLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangRecordLiteral.BLangRecordKey; import org.wso2.ballerinalang.compiler.tree.expressions.BLangRecordLiteral.BLangRecordKeyValue; import org.wso2.ballerinalang.compiler.tree.expressions.BLangRecordVarRef; import org.wso2.ballerinalang.compiler.tree.expressions.BLangRecordVarRef.BLangRecordVarRefKeyValue; import org.wso2.ballerinalang.compiler.tree.expressions.BLangRestArgsExpression; import org.wso2.ballerinalang.compiler.tree.expressions.BLangServiceConstructorExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef; import org.wso2.ballerinalang.compiler.tree.expressions.BLangStringTemplateLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTableLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTableQueryExpression; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTernaryExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTrapExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTupleVarRef; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTypeConversionExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTypeInit; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTypeTestExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangTypedescExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangUnaryExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference; import org.wso2.ballerinalang.compiler.tree.expressions.BLangWaitExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangWaitForAllExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangWorkerFlushExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangWorkerReceive; import org.wso2.ballerinalang.compiler.tree.expressions.BLangWorkerSyncSendExpr; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLAttribute; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLAttributeAccess; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLCommentLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLElementLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLProcInsLiteral; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQName; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQuotedString; import org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLTextLiteral; import org.wso2.ballerinalang.compiler.tree.statements.BLangAbort; import org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment; import org.wso2.ballerinalang.compiler.tree.statements.BLangBlockStmt; import org.wso2.ballerinalang.compiler.tree.statements.BLangBreak; import org.wso2.ballerinalang.compiler.tree.statements.BLangCatch; import org.wso2.ballerinalang.compiler.tree.statements.BLangCompoundAssignment; import org.wso2.ballerinalang.compiler.tree.statements.BLangContinue; import org.wso2.ballerinalang.compiler.tree.statements.BLangErrorDestructure; import org.wso2.ballerinalang.compiler.tree.statements.BLangErrorVariableDef; import org.wso2.ballerinalang.compiler.tree.statements.BLangExpressionStmt; import org.wso2.ballerinalang.compiler.tree.statements.BLangForeach; import org.wso2.ballerinalang.compiler.tree.statements.BLangForever; import org.wso2.ballerinalang.compiler.tree.statements.BLangForkJoin; import org.wso2.ballerinalang.compiler.tree.statements.BLangIf; import org.wso2.ballerinalang.compiler.tree.statements.BLangLock; import org.wso2.ballerinalang.compiler.tree.statements.BLangMatch; import org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStaticBindingPatternClause; import org.wso2.ballerinalang.compiler.tree.statements.BLangMatch.BLangMatchStructuredBindingPatternClause; import org.wso2.ballerinalang.compiler.tree.statements.BLangPanic; import org.wso2.ballerinalang.compiler.tree.statements.BLangRecordDestructure; import org.wso2.ballerinalang.compiler.tree.statements.BLangRecordVariableDef; import org.wso2.ballerinalang.compiler.tree.statements.BLangRetry; import org.wso2.ballerinalang.compiler.tree.statements.BLangReturn; import org.wso2.ballerinalang.compiler.tree.statements.BLangSimpleVariableDef; import org.wso2.ballerinalang.compiler.tree.statements.BLangStreamingQueryStatement; import org.wso2.ballerinalang.compiler.tree.statements.BLangThrow; import org.wso2.ballerinalang.compiler.tree.statements.BLangTransaction; import org.wso2.ballerinalang.compiler.tree.statements.BLangTryCatchFinally; import org.wso2.ballerinalang.compiler.tree.statements.BLangTupleDestructure; import org.wso2.ballerinalang.compiler.tree.statements.BLangTupleVariableDef; import org.wso2.ballerinalang.compiler.tree.statements.BLangWhile; import org.wso2.ballerinalang.compiler.tree.statements.BLangWorkerSend; import org.wso2.ballerinalang.compiler.tree.statements.BLangXMLNSStatement; import org.wso2.ballerinalang.compiler.tree.types.BLangArrayType; import org.wso2.ballerinalang.compiler.tree.types.BLangBuiltInRefTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangConstrainedType; import org.wso2.ballerinalang.compiler.tree.types.BLangErrorType; import org.wso2.ballerinalang.compiler.tree.types.BLangFiniteTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangFunctionTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangObjectTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangRecordTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangStructureTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangTupleTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangType; import org.wso2.ballerinalang.compiler.tree.types.BLangUnionTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangUserDefinedType; import org.wso2.ballerinalang.compiler.tree.types.BLangValueType; import org.wso2.ballerinalang.compiler.util.CompilerContext; import org.wso2.ballerinalang.compiler.util.CompilerOptions; import org.wso2.ballerinalang.compiler.util.FieldKind; import org.wso2.ballerinalang.compiler.util.Names; import org.wso2.ballerinalang.compiler.util.QuoteType; import org.wso2.ballerinalang.compiler.util.RestBindingPatternState; import org.wso2.ballerinalang.compiler.util.TypeTags; import org.wso2.ballerinalang.compiler.util.diagnotic.BLangDiagnosticLog; import org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Stack; import java.util.TreeSet; import java.util.stream.Collectors; import static org.wso2.ballerinalang.compiler.util.Constants.WORKER_LAMBDA_VAR_PREFIX; /** * This class builds the package AST of a Ballerina source file. * * @since 0.94 */ public class BLangPackageBuilder { private CompilationUnitNode compUnit; private Stack<BLangNameReference> nameReferenceStack = new Stack<>(); private Stack<TypeNode> typeNodeStack = new Stack<>(); private Stack<BlockNode> blockNodeStack = new Stack<>(); private Stack<BLangVariable> varStack = new Stack<>(); private Stack<List<BLangVariable>> varListStack = new Stack<>(); private Stack<List<BLangRecordVariableKeyValue>> recordVarListStack = new Stack<>(); private Stack<List<BLangRecordVarRefKeyValue>> recordVarRefListStack = new Stack<>(); private Stack<InvokableNode> invokableNodeStack = new Stack<>(); private Stack<ExpressionNode> exprNodeStack = new Stack<>(); private Stack<List<ExpressionNode>> exprNodeListStack = new Stack<>(); private Stack<Set<Whitespace>> commaWsStack = new Stack<>(); private Stack<Set<Whitespace>> invocationWsStack = new Stack<>(); private Stack<BLangRecordLiteral> recordLiteralNodes = new Stack<>(); private Stack<BLangTableLiteral> tableLiteralNodes = new Stack<>(); private Stack<BLangWaitForAllExpr> waitCollectionStack = new Stack<>(); private Stack<BLangTryCatchFinally> tryCatchFinallyNodesStack = new Stack<>(); private Stack<AnnotationNode> annotationStack = new Stack<>(); private Stack<MarkdownDocumentationNode> markdownDocumentationStack = new Stack<>(); private Stack<DeprecatedNode> deprecatedAttachmentStack = new Stack<>(); private Stack<AnnotationAttachmentNode> annotAttachmentStack = new Stack<>(); private Stack<IfNode> ifElseStatementStack = new Stack<>(); private Stack<TransactionNode> transactionNodeStack = new Stack<>(); private Stack<ForkJoinNode> forkJoinNodesStack = new Stack<>(); private Stack<ServiceNode> serviceNodeStack = new Stack<>(); private Stack<XMLAttributeNode> xmlAttributeNodeStack = new Stack<>(); private Stack<AttachPoint> attachPointStack = new Stack<>(); private Stack<OrderByNode> orderByClauseStack = new Stack<>(); private Stack<OrderByVariableNode> orderByVariableStack = new Stack<>(); private Stack<LimitNode> limitClauseStack = new Stack<>(); private Stack<GroupByNode> groupByClauseStack = new Stack<>(); private Stack<HavingNode> havingClauseStack = new Stack<>(); private Stack<WhereNode> whereClauseStack = new Stack<>(); private Stack<SelectExpressionNode> selectExpressionsStack = new Stack<>(); private Stack<List<SelectExpressionNode>> selectExpressionsListStack = new Stack<>(); private Stack<SelectClauseNode> selectClausesStack = new Stack<>(); private Stack<WindowClauseNode> windowClausesStack = new Stack<>(); private Stack<StreamingInput> streamingInputStack = new Stack<>(); private Stack<JoinStreamingInput> joinStreamingInputsStack = new Stack<>(); private Stack<TableQuery> tableQueriesStack = new Stack<>(); private Stack<SetAssignmentNode> setAssignmentStack = new Stack<>(); private Stack<List<SetAssignmentNode>> setAssignmentListStack = new Stack<>(); private Stack<StreamActionNode> streamActionNodeStack = new Stack<>(); private Stack<PatternStreamingEdgeInputNode> patternStreamingEdgeInputStack = new Stack<>(); private Stack<PatternStreamingInputNode> patternStreamingInputStack = new Stack<>(); private Stack<StreamingQueryStatementNode> streamingQueryStatementStack = new Stack<>(); private Stack<ForeverNode> foreverNodeStack = new Stack<>(); private Stack<OutputRateLimitNode> outputRateLimitStack = new Stack<>(); private Stack<WithinClause> withinClauseStack = new Stack<>(); private Stack<PatternClause> patternClauseStack = new Stack<>(); private Set<BLangImportPackage> imports = new HashSet<>(); private List<VariableDefinitionNode> defaultableParamsList = new ArrayList<>(); private Stack<SimpleVariableNode> restParamStack = new Stack<>(); private Deque<BLangMatch> matchStmtStack; private PatternStreamingInputNode recentStreamingPatternInputNode; private Stack<Set<Whitespace>> operatorWs = new Stack<>(); private Stack<Set<Whitespace>> objectFieldBlockWs = new Stack<>(); private Stack<Set<Whitespace>> finiteTypeWsStack = new Stack<>(); private Stack<Set<Whitespace>> workerDefinitionWSStack = new Stack<>(); private Stack<Set<Whitespace>> bindingPatternIdentifierWS = new Stack<>(); private BLangAnonymousModelHelper anonymousModelHelper; private CompilerOptions compilerOptions; private SymbolTable symTable; private BLangDiagnosticLog dlog; private static final String IDENTIFIER_LITERAL_PREFIX = "^\""; private static final String IDENTIFIER_LITERAL_SUFFIX = "\""; public BLangPackageBuilder(CompilerContext context, CompilationUnitNode compUnit) { this.dlog = BLangDiagnosticLog.getInstance(context); this.anonymousModelHelper = BLangAnonymousModelHelper.getInstance(context); this.compilerOptions = CompilerOptions.getInstance(context); this.symTable = SymbolTable.getInstance(context); this.compUnit = compUnit; } void addAttachPoint(AttachPoint attachPoint, Set<Whitespace> ws) { attachPointStack.push(attachPoint); this.annotationStack.peek().addWS(ws); } void addValueType(DiagnosticPos pos, Set<Whitespace> ws, String typeName) { BLangValueType typeNode = (BLangValueType) TreeBuilder.createValueTypeNode(); typeNode.addWS(ws); typeNode.pos = pos; typeNode.typeKind = (TreeUtils.stringToTypeKind(typeName.replaceAll("\\s+", ""))); addType(typeNode); } void addUnionType(DiagnosticPos pos, Set<Whitespace> ws) { BLangType rhsTypeNode = (BLangType) this.typeNodeStack.pop(); BLangType lhsTypeNode = (BLangType) this.typeNodeStack.pop(); BLangUnionTypeNode unionTypeNode; if (rhsTypeNode.getKind() == NodeKind.UNION_TYPE_NODE) { unionTypeNode = (BLangUnionTypeNode) rhsTypeNode; unionTypeNode.memberTypeNodes.add(0, lhsTypeNode); unionTypeNode.addWS(ws); this.typeNodeStack.push(unionTypeNode); return; } else { unionTypeNode = (BLangUnionTypeNode) TreeBuilder.createUnionTypeNode(); unionTypeNode.memberTypeNodes.add(lhsTypeNode); unionTypeNode.memberTypeNodes.add(rhsTypeNode); } unionTypeNode.pos = pos; unionTypeNode.addWS(ws); this.typeNodeStack.push(unionTypeNode); } void addTupleType(DiagnosticPos pos, Set<Whitespace> ws, int members) { BLangTupleTypeNode tupleTypeNode = (BLangTupleTypeNode) TreeBuilder.createTupleTypeNode(); for (int i = 0; i < members; i++) { final BLangType member = (BLangType) this.typeNodeStack.pop(); tupleTypeNode.memberTypeNodes.add(0, member); } tupleTypeNode.pos = pos; tupleTypeNode.addWS(ws); this.typeNodeStack.push(tupleTypeNode); } void addRecordType(DiagnosticPos pos, Set<Whitespace> ws, boolean isFieldAnalyseRequired, boolean isAnonymous, boolean sealed, boolean hasRestField) { // If there is an explicitly defined rest field, take it. BLangType restFieldType = null; if (hasRestField && !sealed) { restFieldType = (BLangType) this.typeNodeStack.pop(); } // Create an anonymous record and add it to the list of records in the current package. BLangRecordTypeNode recordTypeNode = populateRecordTypeNode(pos, ws, isAnonymous); recordTypeNode.isFieldAnalyseRequired = isFieldAnalyseRequired; recordTypeNode.sealed = sealed; recordTypeNode.restFieldType = restFieldType; if (!isAnonymous) { addType(recordTypeNode); return; } BLangTypeDefinition typeDef = (BLangTypeDefinition) TreeBuilder.createTypeDefinition(); // Generate a name for the anonymous object String genName = anonymousModelHelper.getNextAnonymousTypeKey(pos.src.pkgID); IdentifierNode anonTypeGenName = createIdentifier(genName); typeDef.setName(anonTypeGenName); typeDef.flagSet.add(Flag.PUBLIC); typeDef.typeNode = recordTypeNode; typeDef.pos = pos; this.compUnit.addTopLevelNode(typeDef); addType(createUserDefinedType(pos, ws, (BLangIdentifier) TreeBuilder.createIdentifierNode(), typeDef.name)); } private BLangRecordTypeNode populateRecordTypeNode(DiagnosticPos pos, Set<Whitespace> ws, boolean isAnonymous) { BLangRecordTypeNode recordTypeNode = (BLangRecordTypeNode) typeNodeStack.pop(); recordTypeNode.pos = pos; recordTypeNode.addWS(ws); recordTypeNode.isAnonymous = isAnonymous; this.varListStack.pop().forEach(variableNode -> { recordTypeNode.addField((SimpleVariableNode) variableNode); }); return recordTypeNode; } void addFieldVariable(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean exprAvailable, int annotCount, boolean isPrivate, boolean isOptional) { BLangSimpleVariable field = addSimpleVar(pos, ws, identifier, exprAvailable, annotCount); if (!isPrivate) { field.flagSet.add(Flag.PUBLIC); } if (isOptional) { field.flagSet.add(Flag.OPTIONAL); } else if (!exprAvailable) { field.flagSet.add(Flag.REQUIRED); } } void addFieldVariable(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean exprAvailable, boolean deprecatedDocExit, int annotCount, boolean isPrivate, boolean isPublic) { BLangSimpleVariable field = addSimpleVar(pos, ws, identifier, exprAvailable, annotCount); attachAnnotations(field, annotCount); if (deprecatedDocExit) { attachDeprecatedNode(field); } if (isPublic) { field.flagSet.add(Flag.PUBLIC); } else if (isPrivate) { field.flagSet.add(Flag.PRIVATE); } } void addArrayType(DiagnosticPos pos, Set<Whitespace> ws, int dimensions, int[] sizes) { BLangType eType = (BLangType) this.typeNodeStack.pop(); BLangArrayType arrayTypeNode = (BLangArrayType) TreeBuilder.createArrayTypeNode(); arrayTypeNode.addWS(ws); arrayTypeNode.pos = pos; arrayTypeNode.elemtype = eType; arrayTypeNode.dimensions = dimensions; arrayTypeNode.sizes = sizes; addType(arrayTypeNode); } void markTypeNodeAsNullable(Set<Whitespace> ws) { BLangType typeNode = (BLangType) this.typeNodeStack.peek(); typeNode.addWS(ws); typeNode.nullable = true; } void markTypeNodeAsGrouped(Set<Whitespace> ws) { BLangType typeNode = (BLangType) this.typeNodeStack.peek(); typeNode.addWS(ws); typeNode.grouped = true; } void addUserDefineType(Set<Whitespace> ws) { BLangNameReference nameReference = nameReferenceStack.pop(); BLangUserDefinedType userDefinedType = createUserDefinedType(nameReference.pos, ws, (BLangIdentifier) nameReference.pkgAlias, (BLangIdentifier) nameReference.name); userDefinedType.addWS(nameReference.ws); addType(userDefinedType); } void addBuiltInReferenceType(DiagnosticPos pos, Set<Whitespace> ws, String typeName) { BLangBuiltInRefTypeNode refType = (BLangBuiltInRefTypeNode) TreeBuilder.createBuiltInReferenceTypeNode(); refType.typeKind = TreeUtils.stringToTypeKind(typeName); refType.pos = pos; refType.addWS(ws); addType(refType); } void addErrorType(DiagnosticPos pos, Set<Whitespace> ws, boolean isReasonTypeExists, boolean isDetailsTypeExists) { BLangErrorType errorType = (BLangErrorType) TreeBuilder.createErrorTypeNode(); errorType.pos = pos; errorType.addWS(ws); if (isDetailsTypeExists) { errorType.detailType = (BLangType) this.typeNodeStack.pop(); } if (isReasonTypeExists) { errorType.reasonType = (BLangType) this.typeNodeStack.pop(); } addType(errorType); } void addConstraintTypeWithTypeName(DiagnosticPos pos, Set<Whitespace> ws, String typeName) { Set<Whitespace> refTypeWS = removeNthFromLast(ws, 2); BLangBuiltInRefTypeNode refType = (BLangBuiltInRefTypeNode) TreeBuilder.createBuiltInReferenceTypeNode(); refType.typeKind = TreeUtils.stringToTypeKind(typeName); refType.pos = pos; refType.addWS(refTypeWS); BLangConstrainedType constrainedType = (BLangConstrainedType) TreeBuilder.createConstrainedTypeNode(); constrainedType.type = refType; constrainedType.constraint = (BLangType) this.typeNodeStack.pop(); constrainedType.pos = pos; constrainedType.addWS(ws); addType(constrainedType); } void addEndpointType(DiagnosticPos pos, Set<Whitespace> ws) { BLangNameReference nameReference = nameReferenceStack.pop(); BLangUserDefinedType constraintType = (BLangUserDefinedType) TreeBuilder.createUserDefinedTypeNode(); constraintType.pos = pos; constraintType.pkgAlias = (BLangIdentifier) nameReference.pkgAlias; constraintType.typeName = (BLangIdentifier) nameReference.name; constraintType.addWS(nameReference.ws); addType(constraintType); } void addFunctionType(DiagnosticPos pos, Set<Whitespace> ws, boolean paramsAvail, boolean retParamsAvail) { // TODO : Fix function main ()(boolean , function(string x)(float, int)){} issue BLangFunctionTypeNode functionTypeNode = (BLangFunctionTypeNode) TreeBuilder.createFunctionTypeNode(); functionTypeNode.pos = pos; functionTypeNode.returnsKeywordExists = true; if (retParamsAvail) { functionTypeNode.addWS(this.varStack.peek().getWS()); functionTypeNode.returnTypeNode = this.varStack.pop().getTypeNode(); } else { BLangValueType nilTypeNode = (BLangValueType) TreeBuilder.createValueTypeNode(); nilTypeNode.pos = pos; nilTypeNode.typeKind = TypeKind.NIL; functionTypeNode.returnTypeNode = nilTypeNode; } if (paramsAvail) { functionTypeNode.addWS(commaWsStack.pop()); this.varListStack.pop().forEach(v -> functionTypeNode.params.add(v)); } functionTypeNode.addWS(ws); addType(functionTypeNode); } private void addType(TypeNode typeNode) { this.typeNodeStack.push(typeNode); } void addNameReference(DiagnosticPos currentPos, Set<Whitespace> ws, String pkgName, String name) { IdentifierNode pkgNameNode = createIdentifier(pkgName); IdentifierNode nameNode = createIdentifier(name); nameReferenceStack.push(new BLangNameReference(currentPos, ws, pkgNameNode, nameNode)); } void startVarList() { this.varListStack.push(new ArrayList<>()); } void startFunctionDef(int annotCount) { FunctionNode functionNode = TreeBuilder.createFunctionNode(); attachAnnotations(functionNode, annotCount); attachMarkdownDocumentations(functionNode); attachDeprecatedNode(functionNode); this.invokableNodeStack.push(functionNode); } void startObjectFunctionDef() { FunctionNode functionNode = TreeBuilder.createFunctionNode(); this.invokableNodeStack.push(functionNode); } void startBlock() { this.blockNodeStack.push(TreeBuilder.createBlockNode()); } private IdentifierNode createIdentifier(String value) { IdentifierNode node = TreeBuilder.createIdentifierNode(); if (value == null) { return node; } if (value.startsWith(IDENTIFIER_LITERAL_PREFIX) && value.endsWith(IDENTIFIER_LITERAL_SUFFIX)) { value = StringEscapeUtils.unescapeJava(value); node.setValue(value.substring(2, value.length() - 1)); node.setLiteral(true); } else { node.setValue(value); node.setLiteral(false); } return node; } BLangSimpleVariable addSimpleVar(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean exprAvailable, int annotCount) { BLangSimpleVariable var = (BLangSimpleVariable) this.generateBasicVarNode(pos, ws, identifier, exprAvailable); attachAnnotations(var, annotCount); var.pos = pos; if (this.varListStack.empty()) { this.varStack.push(var); } else { this.varListStack.peek().add(var); } return var; } BLangVariable addBindingPatternMemberVariable(DiagnosticPos pos, Set<Whitespace> ws, String identifier) { BLangSimpleVariable memberVar = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); memberVar.pos = pos; IdentifierNode name = this.createIdentifier(identifier); memberVar.setName(name); memberVar.addWS(ws); this.varStack.push(memberVar); return memberVar; } void addErrorVariable(DiagnosticPos pos, Set<Whitespace> ws, String reasonIdentifier, String detailIdentifier, boolean hasRecordVariable) { BLangErrorVariable errorVariable = (BLangErrorVariable) TreeBuilder.createErrorVariableNode(); errorVariable.pos = pos; errorVariable.addWS(ws); errorVariable.reason = (BLangSimpleVariable) generateBasicVarNodeWithoutType(pos, null, reasonIdentifier, false); if (hasRecordVariable) { errorVariable.detail = this.varStack.pop(); } else if (detailIdentifier != null) { errorVariable.detail = (BLangVariable) generateBasicVarNodeWithoutType(pos, null, detailIdentifier, false); } this.varStack.push(errorVariable); } void addErrorVariableReference(DiagnosticPos pos, Set<Whitespace> ws, boolean hasDetailExpr) { BLangErrorVarRef errorVarRef = (BLangErrorVarRef) TreeBuilder.createErrorVariableReferenceNode(); errorVarRef.pos = pos; errorVarRef.addWS(ws); if (hasDetailExpr) { errorVarRef.detail = (BLangVariableReference) this.exprNodeStack.pop(); } errorVarRef.reason = (BLangVariableReference) this.exprNodeStack.pop(); this.exprNodeStack.push(errorVarRef); } void addTupleVariable(DiagnosticPos pos, Set<Whitespace> ws, int members) { BLangTupleVariable tupleVariable = (BLangTupleVariable) TreeBuilder.createTupleVariableNode(); tupleVariable.pos = pos; tupleVariable.addWS(ws); if (this.bindingPatternIdentifierWS.size() > 0) { tupleVariable.addWS(this.bindingPatternIdentifierWS.pop()); } for (int i = 0; i < members; i++) { final BLangVariable member = this.varStack.pop(); tupleVariable.memberVariables.add(0, member); } this.varStack.push(tupleVariable); } void addTupleVariableReference(DiagnosticPos pos, Set<Whitespace> ws, int members) { BLangTupleVarRef tupleVarRef = (BLangTupleVarRef) TreeBuilder.createTupleVariableReferenceNode(); tupleVarRef.pos = pos; tupleVarRef.addWS(ws); for (int i = 0; i < members; i++) { final BLangExpression expr = (BLangExpression) this.exprNodeStack.pop(); tupleVarRef.expressions.add(0, expr); } this.exprNodeStack.push(tupleVarRef); } void startRecordVariableList() { recordVarListStack.push(new ArrayList<>()); } void startRecordVariableReferenceList() { recordVarRefListStack.push(new ArrayList<>()); } void addRecordVariable(DiagnosticPos pos, Set<Whitespace> ws, RestBindingPatternState restBindingPattern) { BLangRecordVariable recordVariable = (BLangRecordVariable) TreeBuilder.createRecordVariableNode(); recordVariable.pos = pos; recordVariable.addWS(ws); recordVariable.variableList = this.recordVarListStack.pop(); switch (restBindingPattern) { case OPEN_REST_BINDING_PATTERN: recordVariable.restParam = this.varStack.pop(); break; case CLOSED_REST_BINDING_PATTERN: recordVariable.isClosed = true; break; case NO_BINDING_PATTERN: break; } this.varStack.push(recordVariable); } void addRecordBindingWS(Set<Whitespace> ws) { if (this.varStack.size() > 0) { BLangVariable var = this.varStack.peek(); var.addWS(ws); } } void addRecordVariableReference(DiagnosticPos pos, Set<Whitespace> ws, RestBindingPatternState restBindingPattern) { BLangRecordVarRef recordVarRef = (BLangRecordVarRef) TreeBuilder.createRecordVariableReferenceNode(); recordVarRef.pos = pos; recordVarRef.addWS(ws); switch (restBindingPattern) { case OPEN_REST_BINDING_PATTERN: recordVarRef.restParam = this.exprNodeStack.pop(); break; case CLOSED_REST_BINDING_PATTERN: recordVarRef.isClosed = true; break; case NO_BINDING_PATTERN: break; } recordVarRef.recordRefFields = this.recordVarRefListStack.pop(); this.exprNodeStack.push(recordVarRef); } void addFieldBindingMemberVar(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean bindingPattern) { BLangRecordVariableKeyValue recordKeyValue = new BLangRecordVariableKeyValue(); recordKeyValue.key = (BLangIdentifier) this.createIdentifier(identifier); if (!bindingPattern) { addBindingPatternMemberVariable(pos, ws, identifier); } recordKeyValue.valueBindingPattern = this.varStack.pop(); recordKeyValue.valueBindingPattern.addWS(ws); if (this.bindingPatternIdentifierWS.size() > 0) { recordKeyValue.valueBindingPattern.addWS(this.bindingPatternIdentifierWS.pop()); } this.recordVarListStack.peek().add(recordKeyValue); } void addFieldRefBindingMemberVar(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean bindingPattern) { BLangExpression expression; if (!bindingPattern) { addNameReference(pos, ws, null, identifier); createSimpleVariableReference(pos, ws); } expression = (BLangExpression) this.exprNodeStack.pop(); BLangRecordVarRefKeyValue keyValue = new BLangRecordVarRefKeyValue(); keyValue.variableName = (BLangIdentifier) createIdentifier(identifier); keyValue.variableReference = expression; keyValue.variableReference.addWS(ws); this.recordVarRefListStack.peek().add(keyValue); } public BLangVariable addVarWithoutType(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean exprAvailable, int annotCount) { BLangVariable var = (BLangVariable) this.generateBasicVarNodeWithoutType(pos, ws, identifier, exprAvailable); attachAnnotations(var, annotCount); var.pos = pos; if (this.varListStack.empty()) { this.varStack.push(var); } else { this.varListStack.peek().add(var); } return var; } public void endFormalParameterList(Set<Whitespace> ws) { this.commaWsStack.push(ws); } void addReturnParam(DiagnosticPos pos, Set<Whitespace> ws, int annotCount) { BLangSimpleVariable var = (BLangSimpleVariable) this.generateBasicVarNode(pos, ws, null, false); attachAnnotations(var, annotCount); var.pos = pos; this.varStack.push(var); } void endCallableUnitSignature(DiagnosticPos pos, Set<Whitespace> ws, String identifier, DiagnosticPos identifierPos, boolean paramsAvail, boolean retParamsAvail, boolean restParamAvail) { InvokableNode invNode = this.invokableNodeStack.peek(); BLangIdentifier identifierNode = (BLangIdentifier) this.createIdentifier(identifier); identifierNode.pos = identifierPos; invNode.setName(identifierNode); invNode.addWS(ws); BLangType returnTypeNode; if (retParamsAvail) { BLangSimpleVariable varNode = (BLangSimpleVariable) this.varStack.pop(); returnTypeNode = varNode.getTypeNode(); // set returns keyword to invocation node. invNode.addWS(varNode.getWS()); varNode.getAnnotationAttachments().forEach(invNode::addReturnTypeAnnotationAttachment); } else { BLangValueType nillTypeNode = (BLangValueType) TreeBuilder.createValueTypeNode(); nillTypeNode.pos = pos; nillTypeNode.typeKind = TypeKind.NIL; returnTypeNode = nillTypeNode; } invNode.setReturnTypeNode(returnTypeNode); if (paramsAvail) { this.varListStack.pop().forEach(variableNode -> { invNode.addParameter((SimpleVariableNode) variableNode); }); this.defaultableParamsList.forEach(variableDef -> { BLangSimpleVariableDef varDef = (BLangSimpleVariableDef) variableDef; invNode.addDefaultableParameter(varDef); }); this.defaultableParamsList = new ArrayList<>(); if (restParamAvail) { invNode.setRestParameter(this.restParamStack.pop()); } invNode.addWS(this.commaWsStack.pop()); } } void startLambdaFunctionDef(PackageID pkgID) { // Passing zero for annotation count as Lambdas can't have annotations. startFunctionDef(0); BLangFunction lambdaFunction = (BLangFunction) this.invokableNodeStack.peek(); lambdaFunction.setName(createIdentifier(anonymousModelHelper.getNextAnonymousFunctionKey(pkgID))); lambdaFunction.addFlag(Flag.LAMBDA); } void addLambdaFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, boolean paramsAvail, boolean retParamsAvail, boolean restParamAvail) { BLangFunction lambdaFunction = (BLangFunction) this.invokableNodeStack.peek(); lambdaFunction.pos = pos; endCallableUnitSignature(pos, ws, lambdaFunction.getName().value, pos, paramsAvail, retParamsAvail, restParamAvail); BLangLambdaFunction lambdaExpr = (BLangLambdaFunction) TreeBuilder.createLambdaFunctionNode(); lambdaExpr.function = lambdaFunction; lambdaExpr.pos = pos; addExpressionNode(lambdaExpr); // TODO: is null correct here endFunctionDef(pos, null, false, false, false, false, true, false, true); } void addArrowFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, PackageID pkgID) { BLangArrowFunction arrowFunctionNode = (BLangArrowFunction) TreeBuilder.createArrowFunctionNode(); arrowFunctionNode.pos = pos; arrowFunctionNode.addWS(ws); arrowFunctionNode.functionName = createIdentifier(anonymousModelHelper.getNextAnonymousFunctionKey(pkgID)); varListStack.pop().forEach(var -> arrowFunctionNode.params.add((BLangSimpleVariable) var)); arrowFunctionNode.expression = (BLangExpression) this.exprNodeStack.pop(); addExpressionNode(arrowFunctionNode); } void markLastInvocationAsAsync(DiagnosticPos pos) { final ExpressionNode expressionNode = this.exprNodeStack.peek(); if (expressionNode.getKind() == NodeKind.INVOCATION) { ((BLangInvocation) this.exprNodeStack.peek()).async = true; } else { dlog.error(pos, DiagnosticCode.START_REQUIRE_INVOCATION); } } void addSimpleVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isFinal, boolean isExpressionAvailable, boolean isDeclaredWithVar) { BLangSimpleVariableDef varDefNode = createSimpleVariableDef(pos, ws, identifier, isFinal, isExpressionAvailable, isDeclaredWithVar); if (this.bindingPatternIdentifierWS.size() > 0) { varDefNode.addWS(this.bindingPatternIdentifierWS.pop()); } addStmtToCurrentBlock(varDefNode); } void addBindingPatternNameWhitespace(Set<Whitespace> ws) { this.bindingPatternIdentifierWS.push(ws); } private BLangSimpleVariableDef createSimpleVariableDef(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isFinal, boolean isExpressionAvailable, boolean isDeclaredWithVar) { BLangSimpleVariable var = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); BLangSimpleVariableDef varDefNode = (BLangSimpleVariableDef) TreeBuilder .createSimpleVariableDefinitionNode(); var.pos = pos; var.addWS(ws); var.setName(this.createIdentifier(identifier)); if (isFinal) { markVariableAsFinal(var); } if (isDeclaredWithVar) { var.isDeclaredWithVar = true; } else { var.setTypeNode(this.typeNodeStack.pop()); } if (isExpressionAvailable) { var.setInitialExpression(this.exprNodeStack.pop()); } varDefNode.pos = pos; varDefNode.setVariable(var); varDefNode.addWS(ws); return varDefNode; } void addTupleVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean isFinal, boolean isDeclaredWithVar) { BLangTupleVariableDef varDefNode = createTupleVariableDef(pos, ws, isFinal, true, isDeclaredWithVar); addStmtToCurrentBlock(varDefNode); } void addErrorVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean isFinal, boolean isDeclaredWithVar) { BLangErrorVariableDef varDefNode = createErrorVariableDef(pos, ws, isFinal, true, isDeclaredWithVar); addStmtToCurrentBlock(varDefNode); } private BLangTupleVariableDef createTupleVariableDef(DiagnosticPos pos, Set<Whitespace> ws, boolean isFinal, boolean isExpressionAvailable, boolean isDeclaredWithVar) { BLangTupleVariable var = (BLangTupleVariable) this.varStack.pop(); if (isFinal) { markVariableAsFinal(var); } BLangTupleVariableDef varDefNode = (BLangTupleVariableDef) TreeBuilder.createTupleVariableDefinitionNode(); if (isExpressionAvailable) { var.setInitialExpression(this.exprNodeStack.pop()); } varDefNode.pos = pos; varDefNode.setVariable(var); varDefNode.addWS(ws); var.isDeclaredWithVar = isDeclaredWithVar; if (!isDeclaredWithVar) { var.setTypeNode(this.typeNodeStack.pop()); } return varDefNode; } private BLangErrorVariableDef createErrorVariableDef(DiagnosticPos pos, Set<Whitespace> ws, boolean isFinal, boolean isExpressionAvailable, boolean isDeclaredWithVar) { BLangErrorVariable var = (BLangErrorVariable) this.varStack.pop(); if (isFinal) { markVariableAsFinal(var); } BLangErrorVariableDef varDefNode = (BLangErrorVariableDef) TreeBuilder.createErrorVariableDefinitionNode(); if (isExpressionAvailable) { var.setInitialExpression(this.exprNodeStack.pop()); } varDefNode.pos = pos; varDefNode.setVariable(var); varDefNode.addWS(ws); var.isDeclaredWithVar = isDeclaredWithVar; if (!isDeclaredWithVar) { var.setTypeNode(this.typeNodeStack.pop()); } return varDefNode; } void addRecordVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean isFinal, boolean isDeclaredWithVar) { BLangRecordVariableDef varDefNode = createRecordVariableDef(pos, ws, isFinal, true, isDeclaredWithVar); addStmtToCurrentBlock(varDefNode); } private BLangRecordVariableDef createRecordVariableDef(DiagnosticPos pos, Set<Whitespace> ws, boolean isFinal, boolean isExpressionAvailable, boolean isDeclaredWithVar) { BLangRecordVariableDef varDefNode = (BLangRecordVariableDef) TreeBuilder .createRecordVariableDefinitionNode(); BLangRecordVariable var = (BLangRecordVariable) this.varStack.pop(); if (isFinal) { markVariableAsFinal(var); } if (isExpressionAvailable) { var.setInitialExpression(this.exprNodeStack.pop()); } varDefNode.pos = pos; varDefNode.setVariable(var); varDefNode.addWS(ws); varDefNode.var = var; var.isDeclaredWithVar = isDeclaredWithVar; if (!isDeclaredWithVar) { var.setTypeNode(this.typeNodeStack.pop()); } return varDefNode; } void addTypeInitExpression(DiagnosticPos pos, Set<Whitespace> ws, String initName, boolean typeAvailable, boolean exprAvailable) { BLangTypeInit initNode = (BLangTypeInit) TreeBuilder.createInitNode(); initNode.pos = pos; initNode.addWS(ws); if (typeAvailable) { initNode.userDefinedType = (BLangUserDefinedType) typeNodeStack.pop(); } BLangInvocation invocationNode = (BLangInvocation) TreeBuilder.createInvocationNode(); invocationNode.pos = pos; invocationNode.addWS(ws); if (exprAvailable) { List<ExpressionNode> exprNodes = exprNodeListStack.pop(); Set<Whitespace> cws = commaWsStack.pop(); exprNodes.forEach(exprNode -> { invocationNode.argExprs.add((BLangExpression) exprNode); initNode.argsExpr.add((BLangExpression) exprNode); }); invocationNode.addWS(cws); initNode.addWS(cws); } //TODO check whether pkgName can be be empty IdentifierNode pkgNameNode = TreeBuilder.createIdentifierNode(); IdentifierNode nameNode = createIdentifier(initName); BLangNameReference nameReference = new BLangNameReference(pos, ws, pkgNameNode, nameNode); invocationNode.name = (BLangIdentifier) nameReference.name; invocationNode.addWS(nameReference.ws); invocationNode.pkgAlias = (BLangIdentifier) nameReference.pkgAlias; initNode.initInvocation = invocationNode; this.addExpressionNode(initNode); } private void markVariableAsFinal(BLangVariable variable) { // Set the final flag to the variable. variable.flagSet.add(Flag.FINAL); switch (variable.getKind()) { case TUPLE_VARIABLE: // If the variable is a tuple variable, we need to set the final flag to the all member variables. ((BLangTupleVariable) variable).memberVariables.forEach(this::markVariableAsFinal); break; case RECORD_VARIABLE: // If the variable is a record variable, we need to set the final flag to the all the variables in // the record. ((BLangRecordVariable) variable).variableList.stream().map(BLangRecordVariableKeyValue::getValue) .forEach(this::markVariableAsFinal); break; } } void addErrorConstructor(DiagnosticPos pos, Set<Whitespace> ws, boolean detailsExprAvailable) { BLangErrorConstructorExpr errorConstExpr = (BLangErrorConstructorExpr) TreeBuilder .createErrorConstructorNode(); errorConstExpr.pos = pos; errorConstExpr.addWS(ws); if (detailsExprAvailable) { errorConstExpr.detailsExpr = (BLangExpression) exprNodeStack.pop(); } errorConstExpr.reasonExpr = (BLangExpression) exprNodeStack.pop(); this.addExpressionNode(errorConstExpr); } private void addStmtToCurrentBlock(StatementNode statement) { this.blockNodeStack.peek().addStatement(statement); } void startTryCatchFinallyStmt() { this.tryCatchFinallyNodesStack.push((BLangTryCatchFinally) TreeBuilder.createTryCatchFinallyNode()); startBlock(); } void addTryClause(DiagnosticPos pos) { BLangBlockStmt tryBlock = (BLangBlockStmt) this.blockNodeStack.pop(); tryBlock.pos = pos; tryCatchFinallyNodesStack.peek().tryBody = tryBlock; } void startCatchClause() { startBlock(); } void addCatchClause(DiagnosticPos poc, Set<Whitespace> ws, String paramName) { BLangSimpleVariable variableNode = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); variableNode.typeNode = (BLangType) this.typeNodeStack.pop(); variableNode.name = (BLangIdentifier) createIdentifier(paramName); variableNode.pos = variableNode.typeNode.pos; variableNode.addWS(removeNthFromLast(ws, 3)); BLangCatch catchNode = (BLangCatch) TreeBuilder.createCatchNode(); catchNode.pos = poc; catchNode.addWS(ws); catchNode.body = (BLangBlockStmt) this.blockNodeStack.pop(); catchNode.param = variableNode; tryCatchFinallyNodesStack.peek().catchBlocks.add(catchNode); } void startFinallyBlock() { startBlock(); } void addFinallyBlock(DiagnosticPos poc, Set<Whitespace> ws) { BLangBlockStmt blockNode = (BLangBlockStmt) this.blockNodeStack.pop(); BLangTryCatchFinally rootTry = tryCatchFinallyNodesStack.peek(); rootTry.finallyBody = blockNode; rootTry.addWS(ws); blockNode.pos = poc; } void addTryCatchFinallyStmt(DiagnosticPos poc, Set<Whitespace> ws) { BLangTryCatchFinally stmtNode = tryCatchFinallyNodesStack.pop(); stmtNode.pos = poc; stmtNode.addWS(ws); addStmtToCurrentBlock(stmtNode); } void addThrowStmt(DiagnosticPos poc, Set<Whitespace> ws) { ExpressionNode throwExpr = this.exprNodeStack.pop(); BLangThrow throwNode = (BLangThrow) TreeBuilder.createThrowNode(); throwNode.pos = poc; throwNode.addWS(ws); throwNode.expr = (BLangExpression) throwExpr; addStmtToCurrentBlock(throwNode); } void addPanicStmt(DiagnosticPos poc, Set<Whitespace> ws) { ExpressionNode errorExpr = this.exprNodeStack.pop(); BLangPanic panicNode = (BLangPanic) TreeBuilder.createPanicNode(); panicNode.pos = poc; panicNode.addWS(ws); panicNode.expr = (BLangExpression) errorExpr; addStmtToCurrentBlock(panicNode); } private void addExpressionNode(ExpressionNode expressionNode) { this.exprNodeStack.push(expressionNode); } void addLiteralValue(DiagnosticPos pos, Set<Whitespace> ws, int typeTag, Object value) { addLiteralValue(pos, ws, typeTag, value, String.valueOf(value)); } void addLiteralValue(DiagnosticPos pos, Set<Whitespace> ws, int typeTag, Object value, String originalValue) { BLangLiteral litExpr; // If numeric literal create a numeric literal expression; otherwise create a literal expression if (typeTag < TypeTags.DECIMAL) { litExpr = (BLangNumericLiteral) TreeBuilder.createNumericLiteralExpression(); } else { litExpr = (BLangLiteral) TreeBuilder.createLiteralExpression(); } litExpr.addWS(ws); litExpr.pos = pos; litExpr.type = symTable.getTypeFromTag(typeTag); litExpr.type.tag = typeTag; litExpr.value = value; litExpr.originalValue = originalValue; addExpressionNode(litExpr); } void addArrayInitExpr(DiagnosticPos pos, Set<Whitespace> ws, boolean argsAvailable) { List<ExpressionNode> argExprList; BLangArrayLiteral arrayLiteral = (BLangArrayLiteral) TreeBuilder.createArrayLiteralNode(); if (argsAvailable) { arrayLiteral.addWS(commaWsStack.pop()); argExprList = exprNodeListStack.pop(); } else { argExprList = new ArrayList<>(0); } arrayLiteral.exprs = argExprList.stream().map(expr -> (BLangExpression) expr).collect(Collectors.toList()); arrayLiteral.pos = pos; arrayLiteral.addWS(ws); addExpressionNode(arrayLiteral); } void addKeyValueRecord(Set<Whitespace> ws) { BLangRecordKeyValue keyValue = (BLangRecordKeyValue) TreeBuilder.createRecordKeyValue(); keyValue.addWS(ws); keyValue.valueExpr = (BLangExpression) exprNodeStack.pop(); keyValue.key = new BLangRecordKey((BLangExpression) exprNodeStack.pop()); recordLiteralNodes.peek().keyValuePairs.add(keyValue); } void addMapStructLiteral(DiagnosticPos pos, Set<Whitespace> ws) { BLangRecordLiteral recordTypeLiteralNode = recordLiteralNodes.pop(); recordTypeLiteralNode.pos = pos; recordTypeLiteralNode.addWS(ws); addExpressionNode(recordTypeLiteralNode); } void startTableLiteral() { final BLangTableLiteral tableLiteral = (BLangTableLiteral) TreeBuilder.createTableLiteralNode(); tableLiteralNodes.push(tableLiteral); } void endTableColumnDefinition(Set<Whitespace> ws) { BLangTableLiteral tableLiteral = this.tableLiteralNodes.peek(); tableLiteral.addWS(ws); } void addTableColumn(String columnName, DiagnosticPos pos, Set<Whitespace> ws) { BLangTableLiteral.BLangTableColumn tableColumn = new BLangTableLiteral.BLangTableColumn(columnName); tableColumn.pos = pos; tableColumn.addWS(ws); this.tableLiteralNodes.peek().columns.add(tableColumn); } void markPrimaryKeyColumn(String columnName) { BLangTableLiteral tableLiteral = this.tableLiteralNodes.peek(); BLangTableLiteral.BLangTableColumn column = tableLiteral.getColumn(columnName); if (column != null) { column.flagSet.add(TableColumnFlag.PRIMARYKEY); } } void endTableDataList(DiagnosticPos pos, Set<Whitespace> ws) { BLangRecordLiteral recordLiteral = (BLangRecordLiteral) TreeBuilder.createRecordLiteralNode(); List<BLangTableLiteral.BLangTableColumn> keyNames = tableLiteralNodes.peek().columns; List<ExpressionNode> recordValues = exprNodeListStack.pop(); if (keyNames.size() == recordValues.size()) { int index = 0; for (ExpressionNode expr : recordValues) { BLangRecordKeyValue keyValue = (BLangRecordKeyValue) TreeBuilder.createRecordKeyValue(); //Value keyValue.valueExpr = (BLangExpression) expr; //key BLangSimpleVarRef keyExpr = (BLangSimpleVarRef) TreeBuilder.createSimpleVariableReferenceNode(); keyExpr.pos = pos; IdentifierNode identifierNode = TreeBuilder.createIdentifierNode(); identifierNode.setValue(keyNames.get(index).columnName); keyExpr.variableName = (BLangIdentifier) identifierNode; keyValue.key = new BLangRecordKey(keyExpr); //Key-Value pair recordLiteral.keyValuePairs.add(keyValue); ++index; } recordLiteral.addWS(ws); recordLiteral.pos = pos; if (commaWsStack.size() > 0) { recordLiteral.addWS(commaWsStack.pop()); } this.tableLiteralNodes.peek().tableDataRows.add(recordLiteral); } } void endTableDataArray(Set<Whitespace> ws) { BLangTableLiteral tableLiteral = this.tableLiteralNodes.peek(); tableLiteral.addWS(ws); } void endTableDataRow(Set<Whitespace> ws) { List<ExpressionNode> argExprList = exprNodeListStack.pop(); BLangTableLiteral tableLiteral = this.tableLiteralNodes.peek(); tableLiteral.addWS(ws); if (commaWsStack.size() > 0) { tableLiteral.addWS(commaWsStack.pop()); } tableLiteral.tableDataRows = argExprList.stream().map(expr -> (BLangExpression) expr) .collect(Collectors.toList()); } void addTableLiteral(DiagnosticPos pos, Set<Whitespace> ws) { final BLangTableLiteral tableLiteral = tableLiteralNodes.pop(); tableLiteral.addWS(ws); tableLiteral.pos = pos; addExpressionNode(tableLiteral); } void startMapStructLiteral() { BLangRecordLiteral literalNode = (BLangRecordLiteral) TreeBuilder.createRecordLiteralNode(); recordLiteralNodes.push(literalNode); } void startExprNodeList() { this.exprNodeListStack.push(new ArrayList<>()); } void endExprNodeList(Set<Whitespace> ws, int exprCount) { commaWsStack.push(ws); List<ExpressionNode> exprList = exprNodeListStack.peek(); addExprToExprNodeList(exprList, exprCount); } private void addExprToExprNodeList(List<ExpressionNode> exprList, int n) { if (exprNodeStack.empty()) { throw new IllegalStateException("Expression stack cannot be empty in processing an ExpressionList"); } ExpressionNode expr = exprNodeStack.pop(); if (n > 1) { addExprToExprNodeList(exprList, n - 1); } exprList.add(expr); } void createSimpleVariableReference(DiagnosticPos pos, Set<Whitespace> ws) { BLangNameReference nameReference = nameReferenceStack.pop(); BLangSimpleVarRef varRef = (BLangSimpleVarRef) TreeBuilder.createSimpleVariableReferenceNode(); varRef.pos = pos; varRef.addWS(ws); varRef.addWS(nameReference.ws); varRef.pkgAlias = (BLangIdentifier) nameReference.pkgAlias; varRef.variableName = (BLangIdentifier) nameReference.name; this.exprNodeStack.push(varRef); } void createFunctionInvocation(DiagnosticPos pos, Set<Whitespace> ws, boolean argsAvailable) { BLangInvocation invocationNode = (BLangInvocation) TreeBuilder.createInvocationNode(); invocationNode.pos = pos; invocationNode.addWS(ws); if (argsAvailable) { List<ExpressionNode> exprNodes = exprNodeListStack.pop(); exprNodes.forEach(exprNode -> invocationNode.argExprs.add((BLangExpression) exprNode)); invocationNode.addWS(commaWsStack.pop()); } BLangNameReference nameReference = nameReferenceStack.pop(); invocationNode.name = (BLangIdentifier) nameReference.name; invocationNode.addWS(this.invocationWsStack.pop()); invocationNode.addWS(nameReference.ws); invocationNode.pkgAlias = (BLangIdentifier) nameReference.pkgAlias; addExpressionNode(invocationNode); } void startInvocationNode(Set<Whitespace> ws) { invocationWsStack.push(ws); } void createInvocationNode(DiagnosticPos pos, Set<Whitespace> ws, String invocation, boolean argsAvailable, boolean safeNavigate) { BLangInvocation invocationNode = (BLangInvocation) TreeBuilder.createInvocationNode(); invocationNode.pos = pos; invocationNode.addWS(ws); invocationNode.addWS(invocationWsStack.pop()); invocationNode.safeNavigate = safeNavigate; if (argsAvailable) { List<ExpressionNode> exprNodes = exprNodeListStack.pop(); exprNodes.forEach(exprNode -> invocationNode.argExprs.add((BLangExpression) exprNode)); invocationNode.addWS(commaWsStack.pop()); } invocationNode.expr = (BLangExpression) exprNodeStack.pop(); invocationNode.name = (BLangIdentifier) createIdentifier(invocation); invocationNode.pkgAlias = (BLangIdentifier) createIdentifier(null); addExpressionNode(invocationNode); } void createActionInvocationNode(DiagnosticPos pos, Set<Whitespace> ws, boolean async) { BLangInvocation invocationExpr = (BLangInvocation) exprNodeStack.pop(); invocationExpr.actionInvocation = true; invocationExpr.pos = pos; invocationExpr.addWS(ws); invocationExpr.async = async; invocationExpr.expr = (BLangExpression) exprNodeStack.pop(); exprNodeStack.push(invocationExpr); } void createFieldBasedAccessNode(DiagnosticPos pos, Set<Whitespace> ws, String fieldName, FieldKind fieldType, boolean safeNavigate) { BLangFieldBasedAccess fieldBasedAccess = (BLangFieldBasedAccess) TreeBuilder.createFieldBasedAccessNode(); fieldBasedAccess.pos = pos; fieldBasedAccess.addWS(ws); fieldBasedAccess.field = (BLangIdentifier) createIdentifier(fieldName); fieldBasedAccess.expr = (BLangVariableReference) exprNodeStack.pop(); fieldBasedAccess.fieldKind = fieldType; fieldBasedAccess.safeNavigate = safeNavigate; addExpressionNode(fieldBasedAccess); } void createIndexBasedAccessNode(DiagnosticPos pos, Set<Whitespace> ws) { BLangIndexBasedAccess indexBasedAccess = (BLangIndexBasedAccess) TreeBuilder.createIndexBasedAccessNode(); indexBasedAccess.pos = pos; indexBasedAccess.addWS(ws); indexBasedAccess.indexExpr = (BLangExpression) exprNodeStack.pop(); indexBasedAccess.expr = (BLangVariableReference) exprNodeStack.pop(); addExpressionNode(indexBasedAccess); } void createBracedOrTupleExpression(DiagnosticPos pos, Set<Whitespace> ws, int numberOfExpressions) { final BLangBracedOrTupleExpr expr = (BLangBracedOrTupleExpr) TreeBuilder.createBracedOrTupleExpression(); expr.pos = pos; expr.addWS(ws); for (int i = 0; i < numberOfExpressions; i++) { expr.expressions.add(0, (BLangExpression) exprNodeStack.pop()); } addExpressionNode(expr); } void createBinaryExpr(DiagnosticPos pos, Set<Whitespace> ws, String operator) { BLangBinaryExpr binaryExpressionNode = (BLangBinaryExpr) TreeBuilder.createBinaryExpressionNode(); binaryExpressionNode.pos = pos; binaryExpressionNode.addWS(ws); binaryExpressionNode.rhsExpr = (BLangExpression) exprNodeStack.pop(); binaryExpressionNode.lhsExpr = (BLangExpression) exprNodeStack.pop(); binaryExpressionNode.opKind = OperatorKind.valueFrom(operator); addExpressionNode(binaryExpressionNode); } void createElvisExpr(DiagnosticPos pos, Set<Whitespace> ws) { BLangElvisExpr elvisExpr = (BLangElvisExpr) TreeBuilder.createElvisExpressionNode(); elvisExpr.pos = pos; elvisExpr.addWS(ws); elvisExpr.rhsExpr = (BLangExpression) exprNodeStack.pop(); elvisExpr.lhsExpr = (BLangExpression) exprNodeStack.pop(); addExpressionNode(elvisExpr); } void createTypeAccessExpr(DiagnosticPos pos, Set<Whitespace> ws) { BLangTypedescExpr typeAccessExpr = (BLangTypedescExpr) TreeBuilder.createTypeAccessNode(); typeAccessExpr.pos = pos; typeAccessExpr.addWS(ws); typeAccessExpr.typeNode = (BLangType) typeNodeStack.pop(); addExpressionNode(typeAccessExpr); } void createTypeConversionExpr(DiagnosticPos pos, Set<Whitespace> ws) { BLangTypeConversionExpr typeConversionNode = (BLangTypeConversionExpr) TreeBuilder .createTypeConversionNode(); typeConversionNode.pos = pos; typeConversionNode.addWS(ws); typeConversionNode.typeNode = (BLangType) typeNodeStack.pop(); typeConversionNode.expr = (BLangExpression) exprNodeStack.pop(); addExpressionNode(typeConversionNode); } void createUnaryExpr(DiagnosticPos pos, Set<Whitespace> ws, String operator) { BLangUnaryExpr unaryExpressionNode = (BLangUnaryExpr) TreeBuilder.createUnaryExpressionNode(); unaryExpressionNode.pos = pos; unaryExpressionNode.addWS(ws); unaryExpressionNode.expr = (BLangExpression) exprNodeStack.pop(); unaryExpressionNode.operator = OperatorKind.valueFrom(operator); addExpressionNode(unaryExpressionNode); } void createTernaryExpr(DiagnosticPos pos, Set<Whitespace> ws) { BLangTernaryExpr ternaryExpr = (BLangTernaryExpr) TreeBuilder.createTernaryExpressionNode(); ternaryExpr.pos = pos; ternaryExpr.addWS(ws); ternaryExpr.elseExpr = (BLangExpression) exprNodeStack.pop(); ternaryExpr.thenExpr = (BLangExpression) exprNodeStack.pop(); ternaryExpr.expr = (BLangExpression) exprNodeStack.pop(); if (ternaryExpr.expr.getKind() == NodeKind.TERNARY_EXPR) { // Re-organizing ternary expression tree if there nested ternary expressions. BLangTernaryExpr root = (BLangTernaryExpr) ternaryExpr.expr; BLangTernaryExpr parent = root; while (parent.elseExpr.getKind() == NodeKind.TERNARY_EXPR) { parent = (BLangTernaryExpr) parent.elseExpr; } ternaryExpr.expr = parent.elseExpr; parent.elseExpr = ternaryExpr; ternaryExpr = root; } addExpressionNode(ternaryExpr); } void createCheckedExpr(DiagnosticPos pos, Set<Whitespace> ws) { BLangCheckedExpr checkedExpr = (BLangCheckedExpr) TreeBuilder.createCheckExpressionNode(); checkedExpr.pos = pos; checkedExpr.addWS(ws); checkedExpr.expr = (BLangExpression) exprNodeStack.pop(); addExpressionNode(checkedExpr); } void createTrapExpr(DiagnosticPos pos, Set<Whitespace> ws) { BLangTrapExpr trapExpr = (BLangTrapExpr) TreeBuilder.createTrapExpressionNode(); trapExpr.pos = pos; trapExpr.addWS(ws); trapExpr.expr = (BLangExpression) exprNodeStack.pop(); addExpressionNode(trapExpr); } void endFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, boolean publicFunc, boolean remoteFunc, boolean nativeFunc, boolean privateFunc, boolean bodyExists, boolean isReceiverAttached, boolean isLambda) { BLangFunction function = (BLangFunction) this.invokableNodeStack.pop(); function.pos = pos; function.addWS(ws); if (!isLambda) { function.addWS(invocationWsStack.pop()); } if (publicFunc) { function.flagSet.add(Flag.PUBLIC); } else if (privateFunc) { function.flagSet.add(Flag.PRIVATE); } if (remoteFunc) { function.flagSet.add(Flag.REMOTE); } if (nativeFunc) { function.flagSet.add(Flag.NATIVE); } if (!bodyExists) { function.body = null; } if (isReceiverAttached) { //Get type node for this attached function TypeNode typeNode = this.typeNodeStack.pop(); //Create and add receiver to attached functions BLangSimpleVariable receiver = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); receiver.pos = pos; IdentifierNode name = createIdentifier(Names.SELF.getValue()); receiver.setName(name); receiver.setTypeNode(typeNode); function.receiver = receiver; function.flagSet.add(Flag.ATTACHED); } if (!function.deprecatedAttachments.isEmpty()) { function.flagSet.add(Flag.DEPRECATED); } this.compUnit.addTopLevelNode(function); } void startWorker(PackageID pkgID) { this.startLambdaFunctionDef(pkgID); BLangFunction lambdaFunction = (BLangFunction) this.invokableNodeStack.peek(); lambdaFunction.addFlag(Flag.WORKER); this.startBlock(); } void addWorker(DiagnosticPos pos, Set<Whitespace> ws, String workerName, boolean retParamsAvail) { // Merge worker definition whitespaces and worker declaration whitespaces. if (this.workerDefinitionWSStack.size() > 0 && ws != null) { ws.addAll(this.workerDefinitionWSStack.pop()); } endCallableUnitBody(ws); // change default worker name ((BLangFunction) this.invokableNodeStack.peek()).defaultWorkerName.value = workerName; addLambdaFunctionDef(pos, ws, false, retParamsAvail, false); String workerLambdaName = WORKER_LAMBDA_VAR_PREFIX + workerName; addSimpleVariableDefStatement(pos, null, workerLambdaName, true, true, true); // Check if the worker is in a fork. If so add the lambda function to the worker list in fork, else ignore. if (!this.forkJoinNodesStack.empty()) { List<? extends StatementNode> stmtsAdded = this.blockNodeStack.peek().getStatements(); BLangSimpleVariableDef lamdaWrkr = (BLangSimpleVariableDef) stmtsAdded.get(stmtsAdded.size() - 1); this.forkJoinNodesStack.peek().addWorkers(lamdaWrkr); } addNameReference(pos, null, null, workerLambdaName); createSimpleVariableReference(pos, null); startInvocationNode(null); createInvocationNode(pos, null, BLangBuiltInMethod.CALL.toString(), false, false); markLastInvocationAsAsync(pos); addSimpleVariableDefStatement(pos, null, workerName, true, true, true); } void attachWorkerWS(Set<Whitespace> ws) { this.workerDefinitionWSStack.push(ws); } void startForkJoinStmt() { this.forkJoinNodesStack.push(TreeBuilder.createForkJoinNode()); } void addForkJoinStmt(DiagnosticPos pos, Set<Whitespace> ws) { BLangForkJoin forkJoin = (BLangForkJoin) this.forkJoinNodesStack.pop(); forkJoin.pos = pos; forkJoin.addWS(ws); this.addStmtToCurrentBlock(forkJoin); } void endCallableUnitBody(Set<Whitespace> ws) { BlockNode block = this.blockNodeStack.pop(); InvokableNode invokableNode = this.invokableNodeStack.peek(); invokableNode.addWS(ws); invokableNode.setBody(block); } void addImportPackageDeclaration(DiagnosticPos pos, Set<Whitespace> ws, String orgName, List<String> nameComps, String version, String alias) { List<BLangIdentifier> pkgNameComps = new ArrayList<>(); nameComps.forEach(e -> pkgNameComps.add((BLangIdentifier) this.createIdentifier(e))); BLangIdentifier versionNode = (BLangIdentifier) this.createIdentifier(version); BLangIdentifier aliasNode = (alias != null && !alias.isEmpty()) ? (BLangIdentifier) this.createIdentifier(alias) : pkgNameComps.get(pkgNameComps.size() - 1); BLangImportPackage importDcl = (BLangImportPackage) TreeBuilder.createImportPackageNode(); importDcl.pos = pos; importDcl.addWS(ws); importDcl.pkgNameComps = pkgNameComps; importDcl.version = versionNode; importDcl.orgName = (BLangIdentifier) this.createIdentifier(orgName); importDcl.alias = aliasNode; this.compUnit.addTopLevelNode(importDcl); if (this.imports.contains(importDcl)) { this.dlog.warning(pos, DiagnosticCode.REDECLARED_IMPORT_MODULE, importDcl.getQualifiedPackageName()); } else { this.imports.add(importDcl); } } private VariableNode generateBasicVarNodeWithoutType(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isExpressionAvailable) { BLangSimpleVariable var = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); var.pos = pos; IdentifierNode name = this.createIdentifier(identifier); var.setName(name); var.addWS(ws); if (isExpressionAvailable) { var.setInitialExpression(this.exprNodeStack.pop()); } return var; } private LiteralNode generateConstantNode(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isTypeAvailable) { BLangConstant constantNode = (BLangConstant) TreeBuilder.createConstantNode(); constantNode.pos = pos; BLangIdentifier name = (BLangIdentifier) TreeBuilder.createIdentifierNode(); name.value = identifier; constantNode.setName(name); constantNode.addWS(ws); if (isTypeAvailable) { constantNode.setTypeNode(this.typeNodeStack.pop()); } constantNode.setValue(this.exprNodeStack.pop()); return constantNode; } private VariableNode generateBasicVarNode(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isExpressionAvailable) { return generateBasicVarNode(pos, ws, identifier, false, isExpressionAvailable); } private VariableNode generateBasicVarNode(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isDeclaredWithVar, boolean isExpressionAvailable) { BLangSimpleVariable var = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); var.pos = pos; IdentifierNode name = this.createIdentifier(identifier); var.setName(name); var.addWS(ws); if (isDeclaredWithVar) { var.isDeclaredWithVar = true; } else { var.setTypeNode(this.typeNodeStack.pop()); } if (isExpressionAvailable) { var.setInitialExpression(this.exprNodeStack.pop()); } return var; } void addConstant(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isPublic, boolean isTypeAvailable) { BLangConstant constantNode = (BLangConstant) this.generateConstantNode(pos, ws, identifier, isTypeAvailable); attachAnnotations(constantNode); constantNode.flagSet.add(Flag.CONSTANT); if (isPublic) { constantNode.flagSet.add(Flag.PUBLIC); } attachMarkdownDocumentations(constantNode); attachDeprecatedNode(constantNode); this.compUnit.addTopLevelNode(constantNode); // Check whether the value is a literal. If it is not a literal, it is an invalid case. So we don't need to // consider it. NodeKind nodeKind = ((BLangExpression) constantNode.value).getKind(); if (nodeKind == NodeKind.LITERAL || nodeKind == NodeKind.NUMERIC_LITERAL) { // Note - If the RHS is a literal, we need to create an anonymous type definition which can later be used // in type definitions. // Create a new literal. BLangLiteral literal = nodeKind == NodeKind.LITERAL ? (BLangLiteral) TreeBuilder.createLiteralExpression() : (BLangLiteral) TreeBuilder.createNumericLiteralExpression(); literal.setValue(((BLangLiteral) constantNode.value).value); literal.type = ((BLangLiteral) constantNode.value).type; literal.isConstant = true; // Create a new finite type node. BLangFiniteTypeNode finiteTypeNode = (BLangFiniteTypeNode) TreeBuilder.createFiniteTypeNode(); finiteTypeNode.valueSpace.add(literal); // Create a new anonymous type definition. BLangTypeDefinition typeDef = (BLangTypeDefinition) TreeBuilder.createTypeDefinition(); String genName = anonymousModelHelper.getNextAnonymousTypeKey(pos.src.pkgID); IdentifierNode anonTypeGenName = createIdentifier(genName); typeDef.setName(anonTypeGenName); typeDef.flagSet.add(Flag.PUBLIC); typeDef.typeNode = finiteTypeNode; typeDef.pos = pos; // We add this type definition to the `associatedTypeDefinition` field of the constant node. Then when we // visit the constant node, we visit this type definition as well. By doing this, we don't need to change // any of the type def visiting logic in symbol enter. constantNode.associatedTypeDefinition = typeDef; } } void addGlobalVariable(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isPublic, boolean isFinal, boolean isDeclaredWithVar, boolean isExpressionAvailable, boolean isListenerVar) { BLangVariable var = (BLangVariable) this.generateBasicVarNode(pos, ws, identifier, isDeclaredWithVar, isExpressionAvailable); if (isPublic) { var.flagSet.add(Flag.PUBLIC); } if (isFinal) { var.flagSet.add(Flag.FINAL); } if (isListenerVar) { var.flagSet.add(Flag.LISTENER); } attachAnnotations(var); attachMarkdownDocumentations(var); attachDeprecatedNode(var); this.compUnit.addTopLevelNode(var); } void startRecordType() { BLangRecordTypeNode recordTypeNode = (BLangRecordTypeNode) TreeBuilder.createRecordTypeNode(); typeNodeStack.push(recordTypeNode); startVarList(); } void startObjectType() { BLangObjectTypeNode objectTypeNode = (BLangObjectTypeNode) TreeBuilder.createObjectTypeNode(); typeNodeStack.push(objectTypeNode); startVarList(); startFieldBlockList(); } void addObjectType(DiagnosticPos pos, Set<Whitespace> ws, boolean isFieldAnalyseRequired, boolean isAnonymous, boolean isAbstract, boolean isClient, boolean isService) { BLangObjectTypeNode objectTypeNode = populateObjectTypeNode(pos, ws, isAnonymous); objectTypeNode.addWS(this.objectFieldBlockWs.pop()); objectTypeNode.isFieldAnalyseRequired = isFieldAnalyseRequired; if (isAbstract) { objectTypeNode.flagSet.add(Flag.ABSTRACT); } if (isClient) { objectTypeNode.flagSet.add(Flag.CLIENT); } if (isService) { objectTypeNode.flagSet.add(Flag.SERVICE); } if (!isAnonymous) { addType(objectTypeNode); return; } BLangTypeDefinition typeDef = (BLangTypeDefinition) TreeBuilder.createTypeDefinition(); // Generate a name for the anonymous object String genName = anonymousModelHelper.getNextAnonymousTypeKey(pos.src.pkgID); IdentifierNode anonTypeGenName = createIdentifier(genName); typeDef.setName(anonTypeGenName); typeDef.flagSet.add(Flag.PUBLIC); typeDef.typeNode = objectTypeNode; typeDef.pos = pos; this.compUnit.addTopLevelNode(typeDef); addType(createUserDefinedType(pos, ws, (BLangIdentifier) TreeBuilder.createIdentifierNode(), typeDef.name)); } private BLangObjectTypeNode populateObjectTypeNode(DiagnosticPos pos, Set<Whitespace> ws, boolean isAnonymous) { BLangObjectTypeNode objectTypeNode = (BLangObjectTypeNode) typeNodeStack.pop(); objectTypeNode.pos = pos; objectTypeNode.addWS(ws); objectTypeNode.isAnonymous = isAnonymous; this.varListStack.pop().forEach(variableNode -> { objectTypeNode.addField((SimpleVariableNode) variableNode); }); return objectTypeNode; } void startFieldBlockList() { this.objectFieldBlockWs.push(new TreeSet<>()); } void endFiniteType(Set<Whitespace> ws) { finiteTypeWsStack.push(ws); } void endTypeDefinition(DiagnosticPos pos, Set<Whitespace> ws, String identifier, DiagnosticPos identifierPos, boolean publicType) { BLangTypeDefinition typeDefinition = (BLangTypeDefinition) TreeBuilder.createTypeDefinition(); BLangIdentifier identifierNode = (BLangIdentifier) this.createIdentifier(identifier); identifierNode.pos = identifierPos; typeDefinition.setName(identifierNode); if (publicType) { typeDefinition.flagSet.add(Flag.PUBLIC); } BLangUnionTypeNode members = (BLangUnionTypeNode) TreeBuilder.createUnionTypeNode(); while (!typeNodeStack.isEmpty()) { BLangType memberType = (BLangType) typeNodeStack.pop(); if (memberType.getKind() == NodeKind.UNION_TYPE_NODE) { members.memberTypeNodes.addAll(((BLangUnionTypeNode) memberType).memberTypeNodes); members.addWS(memberType.getWS()); } else { members.memberTypeNodes.add(memberType); } } if (!exprNodeStack.isEmpty()) { BLangFiniteTypeNode finiteTypeNode = (BLangFiniteTypeNode) TreeBuilder.createFiniteTypeNode(); finiteTypeNode.addWS(finiteTypeWsStack.pop()); while (!exprNodeStack.isEmpty()) { finiteTypeNode.valueSpace.add((BLangExpression) exprNodeStack.pop()); } // Reverse the collection so that they would appear in the correct order. Collections.reverse(finiteTypeNode.valueSpace); if (!members.memberTypeNodes.isEmpty()) { BLangTypeDefinition typeDef = (BLangTypeDefinition) TreeBuilder.createTypeDefinition(); // Generate a name for the anonymous object String genName = anonymousModelHelper.getNextAnonymousTypeKey(pos.src.pkgID); IdentifierNode anonTypeGenName = createIdentifier(genName); typeDef.setName(anonTypeGenName); typeDef.flagSet.add(Flag.PUBLIC); typeDef.typeNode = finiteTypeNode; typeDef.pos = pos; this.compUnit.addTopLevelNode(typeDef); members.memberTypeNodes.add(createUserDefinedType(pos, ws, (BLangIdentifier) TreeBuilder.createIdentifierNode(), typeDef.name)); } else { members.memberTypeNodes.add(finiteTypeNode); } } if (members.memberTypeNodes.isEmpty()) { typeDefinition.typeNode = null; } else if (members.memberTypeNodes.size() == 1) { BLangType[] memberArray = new BLangType[1]; members.memberTypeNodes.toArray(memberArray); typeDefinition.typeNode = memberArray[0]; } else { typeDefinition.typeNode = members; } if (finiteTypeWsStack.size() > 0) { typeDefinition.addWS(finiteTypeWsStack.pop()); } typeDefinition.pos = pos; typeDefinition.addWS(ws); Collections.reverse(markdownDocumentationStack); attachMarkdownDocumentations(typeDefinition); attachDeprecatedNode(typeDefinition); attachAnnotations(typeDefinition); this.compUnit.addTopLevelNode(typeDefinition); } void endObjectAttachedFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, boolean publicFunc, boolean privateFunc, boolean remoteFunc, boolean resourceFunc, boolean nativeFunc, boolean bodyExists, boolean markdownDocPresent, boolean deprecatedDocPresent, int annCount) { BLangFunction function = (BLangFunction) this.invokableNodeStack.pop(); function.pos = pos; function.addWS(ws); function.addWS(this.invocationWsStack.pop()); function.flagSet.add(Flag.ATTACHED); if (publicFunc) { function.flagSet.add(Flag.PUBLIC); } else if (privateFunc) { function.flagSet.add(Flag.PRIVATE); } if (remoteFunc) { function.flagSet.add(Flag.REMOTE); } if (resourceFunc) { function.flagSet.add(Flag.RESOURCE); } if (nativeFunc) { function.flagSet.add(Flag.NATIVE); } if (!bodyExists) { function.body = null; if (!nativeFunc) { function.flagSet.add(Flag.INTERFACE); function.interfaceFunction = true; } } function.attachedFunction = true; attachAnnotations(function, annCount); if (markdownDocPresent) { attachMarkdownDocumentations(function); } if (deprecatedDocPresent) { attachDeprecatedNode(function); } if (!function.deprecatedAttachments.isEmpty()) { function.flagSet.add(Flag.DEPRECATED); } BLangObjectTypeNode objectNode = (BLangObjectTypeNode) this.typeNodeStack.peek(); if (Names.OBJECT_INIT_SUFFIX.value.equals(function.name.value)) { function.objInitFunction = true; if (objectNode.initFunction == null) { objectNode.initFunction = function; return; } } objectNode.addFunction(function); } void endObjectOuterFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, boolean publicFunc, boolean privateFunc, boolean remoteFunc, boolean nativeFunc, boolean bodyExists, String objectName) { BLangFunction function = (BLangFunction) this.invokableNodeStack.pop(); function.pos = pos; function.addWS(ws); function.addWS(invocationWsStack.pop()); if (publicFunc) { function.flagSet.add(Flag.PUBLIC); } else if (privateFunc) { function.flagSet.add(Flag.PRIVATE); } if (remoteFunc) { function.flagSet.add(Flag.REMOTE); } if (nativeFunc) { function.flagSet.add(Flag.NATIVE); } if (!bodyExists) { function.body = null; } // Create an user defined type with object type TypeNode objectType = createUserDefinedType(pos, ws, (BLangIdentifier) TreeBuilder.createIdentifierNode(), (BLangIdentifier) createIdentifier(objectName)); //Create and add receiver to attached functions BLangSimpleVariable receiver = (BLangSimpleVariable) TreeBuilder.createSimpleVariableNode(); receiver.pos = pos; IdentifierNode name = createIdentifier(Names.SELF.getValue()); receiver.setName(name); receiver.setTypeNode(objectType); function.receiver = receiver; function.flagSet.add(Flag.ATTACHED); function.attachedOuterFunction = true; if (!function.deprecatedAttachments.isEmpty()) { function.flagSet.add(Flag.DEPRECATED); } this.compUnit.addTopLevelNode(function); } void startAnnotationDef(DiagnosticPos pos) { BLangAnnotation annotNode = (BLangAnnotation) TreeBuilder.createAnnotationNode(); annotNode.pos = pos; attachAnnotations(annotNode); attachMarkdownDocumentations(annotNode); attachDeprecatedNode(annotNode); this.annotationStack.add(annotNode); } void endAnnotationDef(Set<Whitespace> ws, String identifier, DiagnosticPos identifierPos, boolean publicAnnotation, boolean isTypeAttached) { BLangAnnotation annotationNode = (BLangAnnotation) this.annotationStack.pop(); annotationNode.addWS(ws); BLangIdentifier identifierNode = (BLangIdentifier) this.createIdentifier(identifier); identifierNode.pos = identifierPos; annotationNode.setName(identifierNode); if (publicAnnotation) { annotationNode.flagSet.add(Flag.PUBLIC); } while (!attachPointStack.empty()) { annotationNode.attachPoints.add(attachPointStack.pop()); } if (isTypeAttached) { annotationNode.typeNode = (BLangType) this.typeNodeStack.pop(); } this.compUnit.addTopLevelNode(annotationNode); } void startMarkdownDocumentationString(DiagnosticPos currentPos) { BLangMarkdownDocumentation markdownDocumentationNode = (BLangMarkdownDocumentation) TreeBuilder .createMarkdownDocumentationNode(); markdownDocumentationNode.pos = currentPos; markdownDocumentationStack.push(markdownDocumentationNode); } void endMarkdownDocumentationString(Set<Whitespace> ws) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); markdownDocumentationNode.addWS(ws); } void endMarkDownDocumentLine(Set<Whitespace> ws) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); markdownDocumentationNode.addWS(ws); } void endMarkdownDocumentationText(DiagnosticPos pos, Set<Whitespace> ws, String text) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); BLangMarkdownDocumentationLine documentationDescription = (BLangMarkdownDocumentationLine) TreeBuilder .createMarkdownDocumentationTextNode(); documentationDescription.text = text; documentationDescription.pos = pos; documentationDescription.addWS(ws); markdownDocumentationNode.addDocumentationLine(documentationDescription); } void endParameterDocumentationLine(Set<Whitespace> ws) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); markdownDocumentationNode.addWS(ws); } void endParameterDocumentation(DiagnosticPos pos, Set<Whitespace> ws, String parameterName, String description) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); BLangMarkdownParameterDocumentation parameterDocumentationNode = (BLangMarkdownParameterDocumentation) TreeBuilder .createMarkdownParameterDocumentationNode(); parameterDocumentationNode.parameterName = (BLangIdentifier) createIdentifier(parameterName); parameterDocumentationNode.pos = pos; parameterDocumentationNode.addWS(ws); parameterDocumentationNode.addParameterDocumentationLine(description); markdownDocumentationNode.addParameter(parameterDocumentationNode); } void endParameterDocumentationDescription(Set<Whitespace> ws, String description) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); BLangMarkdownParameterDocumentation parameterDocumentation = markdownDocumentationNode.getParameters() .getLast(); parameterDocumentation.addWS(ws); parameterDocumentation.addParameterDocumentationLine(description); } void endReturnParameterDocumentation(DiagnosticPos pos, Set<Whitespace> ws, String description) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); BLangMarkdownReturnParameterDocumentation returnParameterDocumentation = (BLangMarkdownReturnParameterDocumentation) TreeBuilder .createMarkdownReturnParameterDocumentationNode(); returnParameterDocumentation.pos = pos; returnParameterDocumentation.addWS(ws); returnParameterDocumentation.addReturnParameterDocumentationLine(description); markdownDocumentationNode.setReturnParameter(returnParameterDocumentation); } void endReturnParameterDocumentationDescription(Set<Whitespace> ws, String description) { MarkdownDocumentationNode markdownDocumentationNode = markdownDocumentationStack.peek(); BLangMarkdownReturnParameterDocumentation returnParameter = markdownDocumentationNode.getReturnParameter(); returnParameter.addWS(ws); returnParameter.addReturnParameterDocumentationLine(description); } void createDeprecatedNode(DiagnosticPos pos, Set<Whitespace> ws, String content) { BLangDeprecatedNode deprecatedNode = (BLangDeprecatedNode) TreeBuilder.createDeprecatedNode(); deprecatedNode.pos = pos; deprecatedNode.addWS(ws); deprecatedNode.documentationText = content; deprecatedAttachmentStack.push(deprecatedNode); } void startAnnotationAttachment(DiagnosticPos currentPos) { BLangAnnotationAttachment annotAttachmentNode = (BLangAnnotationAttachment) TreeBuilder .createAnnotAttachmentNode(); annotAttachmentNode.pos = currentPos; annotAttachmentStack.push(annotAttachmentNode); } void setAnnotationAttachmentName(Set<Whitespace> ws, boolean hasExpr, DiagnosticPos currentPos, boolean popAnnAttachment) { BLangNameReference nameReference = nameReferenceStack.pop(); BLangAnnotationAttachment bLangAnnotationAttachment = (BLangAnnotationAttachment) annotAttachmentStack .peek(); bLangAnnotationAttachment.pos = currentPos; bLangAnnotationAttachment.addWS(nameReference.ws); bLangAnnotationAttachment.addWS(ws); bLangAnnotationAttachment.setAnnotationName(nameReference.name); bLangAnnotationAttachment.setPackageAlias(nameReference.pkgAlias); if (hasExpr) { bLangAnnotationAttachment.setExpression(exprNodeStack.pop()); } if (popAnnAttachment) { annotAttachmentStack.pop(); } } private void attachAnnotations(AnnotatableNode annotatableNode) { annotAttachmentStack.forEach(annotatableNode::addAnnotationAttachment); annotAttachmentStack.clear(); } private void attachMarkdownDocumentations(DocumentableNode documentableNode) { if (!markdownDocumentationStack.empty()) { documentableNode.setMarkdownDocumentationAttachment(markdownDocumentationStack.pop()); } } private void attachDeprecatedNode(DocumentableNode documentableNode) { if (!deprecatedAttachmentStack.empty()) { documentableNode.addDeprecatedAttachment(deprecatedAttachmentStack.pop()); } } private void attachAnnotations(AnnotatableNode annotatableNode, int count) { if (count == 0 || annotAttachmentStack.empty()) { return; } List<AnnotationAttachmentNode> tempAnnotAttachments = new ArrayList<>(count); for (int i = 0; i < count; i++) { if (annotAttachmentStack.empty()) { break; } tempAnnotAttachments.add(annotAttachmentStack.pop()); } // reversing the collected annotations to preserve the original order Collections.reverse(tempAnnotAttachments); tempAnnotAttachments.forEach(annotatableNode::addAnnotationAttachment); } void addAssignmentStatement(DiagnosticPos pos, Set<Whitespace> ws) { ExpressionNode rExprNode = exprNodeStack.pop(); ExpressionNode lExprNode = exprNodeStack.pop(); BLangAssignment assignmentNode = (BLangAssignment) TreeBuilder.createAssignmentNode(); assignmentNode.setExpression(rExprNode); assignmentNode.pos = pos; assignmentNode.addWS(ws); assignmentNode.varRef = ((BLangVariableReference) lExprNode); addStmtToCurrentBlock(assignmentNode); } void addTupleDestructuringStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangTupleDestructure stmt = (BLangTupleDestructure) TreeBuilder.createTupleDestructureStatementNode(); stmt.pos = pos; stmt.addWS(ws); stmt.expr = (BLangExpression) exprNodeStack.pop(); stmt.varRef = (BLangTupleVarRef) exprNodeStack.pop(); stmt.addWS(stmt.varRef.getWS()); addStmtToCurrentBlock(stmt); } void addRecordDestructuringStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangRecordDestructure stmt = (BLangRecordDestructure) TreeBuilder.createRecordDestructureStatementNode(); stmt.pos = pos; stmt.addWS(ws); stmt.expr = (BLangExpression) exprNodeStack.pop(); stmt.varRef = (BLangRecordVarRef) exprNodeStack.pop(); addStmtToCurrentBlock(stmt); } void addErrorDestructuringStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangErrorDestructure stmt = (BLangErrorDestructure) TreeBuilder.createErrorDestructureStatementNode(); stmt.pos = pos; stmt.addWS(ws); stmt.expr = (BLangExpression) exprNodeStack.pop(); stmt.varRef = (BLangErrorVarRef) exprNodeStack.pop(); addStmtToCurrentBlock(stmt); } void startForeachStatement() { startBlock(); } void addCompoundAssignmentStatement(DiagnosticPos pos, Set<Whitespace> ws, String operator) { BLangCompoundAssignment assignmentNode = (BLangCompoundAssignment) TreeBuilder .createCompoundAssignmentNode(); assignmentNode.setExpression(exprNodeStack.pop()); assignmentNode.setVariable((BLangVariableReference) exprNodeStack.pop()); assignmentNode.pos = pos; assignmentNode.addWS(ws); assignmentNode.addWS(this.operatorWs.pop()); assignmentNode.opKind = OperatorKind.valueFrom(operator); addStmtToCurrentBlock(assignmentNode); } void addCompoundOperator(Set<Whitespace> ws) { this.operatorWs.push(ws); } void addForeachStatementWithSimpleVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean isDeclaredWithVar) { BLangSimpleVariableDef variableDefinitionNode = createSimpleVariableDef(pos, ws, identifier, false, false, isDeclaredWithVar); if (this.bindingPatternIdentifierWS.size() > 0) { variableDefinitionNode.addWS(this.bindingPatternIdentifierWS.pop()); } addForeachStatement(pos, ws, variableDefinitionNode, isDeclaredWithVar); } void addForeachStatementWithRecordVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean isDeclaredWithVar) { BLangRecordVariableDef variableDefinitionNode = createRecordVariableDef(pos, ws, false, false, isDeclaredWithVar); addForeachStatement(pos, ws, variableDefinitionNode, isDeclaredWithVar); } void addForeachStatementWithTupleVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean isDeclaredWithVar) { BLangTupleVariableDef variableDefinitionNode = createTupleVariableDef(pos, ws, false, false, isDeclaredWithVar); addForeachStatement(pos, ws, variableDefinitionNode, isDeclaredWithVar); } void addForeachStatementWithErrorVariableDefStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean isDeclaredWithVar) { BLangErrorVariableDef variableDefinitionNode = createErrorVariableDef(pos, ws, false, false, isDeclaredWithVar); addForeachStatement(pos, ws, variableDefinitionNode, isDeclaredWithVar); } private void addForeachStatement(DiagnosticPos pos, Set<Whitespace> ws, VariableDefinitionNode variableDefinitionNode, boolean isDeclaredWithVar) { BLangForeach foreach = (BLangForeach) TreeBuilder.createForeachNode(); foreach.addWS(ws); foreach.pos = pos; foreach.setVariableDefinitionNode(variableDefinitionNode); foreach.setCollection(this.exprNodeStack.pop()); foreach.isDeclaredWithVar = isDeclaredWithVar; BLangBlockStmt foreachBlock = (BLangBlockStmt) this.blockNodeStack.pop(); foreachBlock.pos = pos; foreach.setBody(foreachBlock); addStmtToCurrentBlock(foreach); } void startWhileStmt() { startBlock(); } void addWhileStmt(DiagnosticPos pos, Set<Whitespace> ws) { BLangWhile whileNode = (BLangWhile) TreeBuilder.createWhileNode(); whileNode.setCondition(exprNodeStack.pop()); whileNode.pos = pos; whileNode.addWS(ws); BLangBlockStmt whileBlock = (BLangBlockStmt) this.blockNodeStack.pop(); whileBlock.pos = pos; whileNode.setBody(whileBlock); addStmtToCurrentBlock(whileNode); } void startLockStmt() { startBlock(); } void addLockStmt(DiagnosticPos pos, Set<Whitespace> ws) { BLangLock lockNode = (BLangLock) TreeBuilder.createLockNode(); lockNode.pos = pos; lockNode.addWS(ws); BLangBlockStmt lockBlock = (BLangBlockStmt) this.blockNodeStack.pop(); lockBlock.pos = pos; lockNode.setBody(lockBlock); addStmtToCurrentBlock(lockNode); } public void addContinueStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangContinue nextNode = (BLangContinue) TreeBuilder.createContinueNode(); nextNode.pos = pos; nextNode.addWS(ws); addStmtToCurrentBlock(nextNode); } void addBreakStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangBreak breakNode = (BLangBreak) TreeBuilder.createBreakNode(); breakNode.pos = pos; breakNode.addWS(ws); addStmtToCurrentBlock(breakNode); } void addReturnStatement(DiagnosticPos pos, Set<Whitespace> ws, boolean exprAvailable) { BLangReturn retStmt = (BLangReturn) TreeBuilder.createReturnNode(); retStmt.pos = pos; retStmt.addWS(ws); if (exprAvailable) { retStmt.expr = (BLangExpression) this.exprNodeStack.pop(); } else { BLangLiteral nilLiteral = (BLangLiteral) TreeBuilder.createLiteralExpression(); nilLiteral.pos = pos; nilLiteral.value = Names.NIL_VALUE; nilLiteral.type = symTable.nilType; retStmt.expr = nilLiteral; } addStmtToCurrentBlock(retStmt); } void startTransactionStmt() { transactionNodeStack.push(TreeBuilder.createTransactionNode()); startBlock(); } void addTransactionBlock(DiagnosticPos pos, Set<Whitespace> ws) { TransactionNode transactionNode = transactionNodeStack.peek(); BLangBlockStmt transactionBlock = (BLangBlockStmt) this.blockNodeStack.pop(); transactionBlock.pos = pos; transactionNode.addWS(ws); transactionNode.setTransactionBody(transactionBlock); } void endTransactionPropertyInitStatementList(Set<Whitespace> ws) { TransactionNode transactionNode = transactionNodeStack.peek(); transactionNode.addWS(ws); } void startOnretryBlock() { startBlock(); } void addOnretryBlock(DiagnosticPos pos, Set<Whitespace> ws) { TransactionNode transactionNode = transactionNodeStack.peek(); BLangBlockStmt onretryBlock = (BLangBlockStmt) this.blockNodeStack.pop(); onretryBlock.pos = pos; transactionNode.addWS(ws); transactionNode.setOnRetryBody(onretryBlock); } public void startCommittedBlock() { startBlock(); } public void endCommittedBlock(DiagnosticPos currentPos, Set<Whitespace> ws) { TransactionNode transactionNode = transactionNodeStack.peek(); BLangBlockStmt committedBlock = (BLangBlockStmt) this.blockNodeStack.pop(); committedBlock.pos = currentPos; transactionNode.addWS(ws); transactionNode.setCommittedBody(committedBlock); } public void startAbortedBlock() { startBlock(); } public void endAbortedBlock(DiagnosticPos currentPos, Set<Whitespace> ws) { TransactionNode transactionNode = transactionNodeStack.peek(); BLangBlockStmt abortedBlock = (BLangBlockStmt) this.blockNodeStack.pop(); abortedBlock.pos = currentPos; transactionNode.addWS(ws); transactionNode.setAbortedBody(abortedBlock); } void endTransactionStmt(DiagnosticPos pos, Set<Whitespace> ws) { BLangTransaction transaction = (BLangTransaction) transactionNodeStack.pop(); transaction.pos = pos; transaction.addWS(ws); addStmtToCurrentBlock(transaction); // TODO This is a temporary workaround to flag coordinator service start String value = compilerOptions.get(CompilerOptionName.TRANSACTION_EXISTS); if (value != null) { return; } compilerOptions.put(CompilerOptionName.TRANSACTION_EXISTS, "true"); List<String> nameComps = getPackageNameComps(Names.TRANSACTION_PACKAGE.value); addImportPackageDeclaration(pos, null, Names.TRANSACTION_ORG.value, nameComps, Names.DEFAULT_VERSION.value, Names.DOT.value + nameComps.get(nameComps.size() - 1)); } void addAbortStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangAbort abortNode = (BLangAbort) TreeBuilder.createAbortNode(); abortNode.pos = pos; abortNode.addWS(ws); addStmtToCurrentBlock(abortNode); } void addRetryStatement(DiagnosticPos pos, Set<Whitespace> ws) { BLangRetry retryNode = (BLangRetry) TreeBuilder.createRetryNode(); retryNode.pos = pos; retryNode.addWS(ws); addStmtToCurrentBlock(retryNode); } void addRetryCountExpression(Set<Whitespace> ws) { BLangTransaction transaction = (BLangTransaction) transactionNodeStack.peek(); transaction.addWS(ws); transaction.retryCount = (BLangExpression) exprNodeStack.pop(); } void startIfElseNode(DiagnosticPos pos) { BLangIf ifNode = (BLangIf) TreeBuilder.createIfElseStatementNode(); ifNode.pos = pos; ifElseStatementStack.push(ifNode); startBlock(); } void addIfBlock(DiagnosticPos pos, Set<Whitespace> ws) { IfNode ifNode = ifElseStatementStack.peek(); ((BLangIf) ifNode).pos = pos; ifNode.addWS(ws); ifNode.setCondition(exprNodeStack.pop()); ifNode.setBody(blockNodeStack.pop()); } void addElseIfBlock(DiagnosticPos pos, Set<Whitespace> ws) { IfNode elseIfNode = ifElseStatementStack.pop(); ((BLangIf) elseIfNode).pos = pos; elseIfNode.setCondition(exprNodeStack.pop()); elseIfNode.setBody(blockNodeStack.pop()); elseIfNode.addWS(ws); IfNode parentIfNode = ifElseStatementStack.peek(); while (parentIfNode.getElseStatement() != null) { parentIfNode = (IfNode) parentIfNode.getElseStatement(); } parentIfNode.setElseStatement(elseIfNode); } void addElseBlock(DiagnosticPos pos, Set<Whitespace> ws) { IfNode ifNode = ifElseStatementStack.peek(); while (ifNode.getElseStatement() != null) { ifNode = (IfNode) ifNode.getElseStatement(); } BlockNode elseBlock = blockNodeStack.pop(); elseBlock.addWS(ws); ((BLangBlockStmt) elseBlock).pos = pos; ifNode.setElseStatement(elseBlock); } void endIfElseNode(Set<Whitespace> ws) { IfNode ifNode = ifElseStatementStack.pop(); ifNode.addWS(ws); addStmtToCurrentBlock(ifNode); } void createMatchNode(DiagnosticPos pos) { if (this.matchStmtStack == null) { this.matchStmtStack = new ArrayDeque<>(); } BLangMatch matchStmt = (BLangMatch) TreeBuilder.createMatchStatement(); matchStmt.pos = pos; this.matchStmtStack.addFirst(matchStmt); } void completeMatchNode(DiagnosticPos pos, Set<Whitespace> ws) { BLangMatch matchStmt = this.matchStmtStack.removeFirst(); matchStmt.pos = pos; matchStmt.addWS(ws); matchStmt.expr = (BLangExpression) this.exprNodeStack.pop(); addStmtToCurrentBlock(matchStmt); } void startMatchStmtPattern() { startBlock(); } void addMatchStmtStaticBindingPattern(DiagnosticPos pos, Set<Whitespace> ws) { BLangMatchStaticBindingPatternClause patternClause = (BLangMatchStaticBindingPatternClause) TreeBuilder .createMatchStatementStaticBindingPattern(); patternClause.pos = pos; patternClause.addWS(ws); patternClause.literal = (BLangExpression) this.exprNodeStack.pop(); patternClause.body = (BLangBlockStmt) blockNodeStack.pop(); patternClause.body.pos = pos; this.matchStmtStack.peekFirst().patternClauses.add(patternClause); } void addMatchStmtStructuredBindingPattern(DiagnosticPos pos, Set<Whitespace> ws, boolean isTypeGuardPresent) { BLangMatchStructuredBindingPatternClause patternClause = (BLangMatchStructuredBindingPatternClause) TreeBuilder .createMatchStatementStructuredBindingPattern(); patternClause.pos = pos; patternClause.addWS(ws); if (this.bindingPatternIdentifierWS.size() > 0) { patternClause.addWS(this.bindingPatternIdentifierWS.pop()); } patternClause.bindingPatternVariable = this.varStack.pop(); patternClause.body = (BLangBlockStmt) blockNodeStack.pop(); patternClause.body.pos = pos; if (isTypeGuardPresent) { patternClause.typeGuardExpr = (BLangExpression) exprNodeStack.pop(); } this.matchStmtStack.peekFirst().patternClauses.add(patternClause); } void addWorkerSendStmt(DiagnosticPos pos, Set<Whitespace> ws, String workerName, boolean hasKey) { BLangWorkerSend workerSendNode = (BLangWorkerSend) TreeBuilder.createWorkerSendNode(); workerSendNode.setWorkerName(this.createIdentifier(workerName)); workerSendNode.expr = (BLangExpression) exprNodeStack.pop(); workerSendNode.pos = pos; workerSendNode.addWS(ws); //added to use for channels as well if (hasKey) { workerSendNode.keyExpr = workerSendNode.expr; workerSendNode.expr = (BLangExpression) exprNodeStack.pop(); workerSendNode.isChannel = true; } addStmtToCurrentBlock(workerSendNode); } void addWorkerReceiveExpr(DiagnosticPos pos, Set<Whitespace> ws, String workerName, boolean hasKey) { BLangWorkerReceive workerReceiveExpr = (BLangWorkerReceive) TreeBuilder.createWorkerReceiveNode(); workerReceiveExpr.setWorkerName(this.createIdentifier(workerName)); workerReceiveExpr.pos = pos; workerReceiveExpr.addWS(ws); //if there are two expressions, this is a channel receive and the top expression is the key if (hasKey) { workerReceiveExpr.keyExpr = (BLangExpression) exprNodeStack.pop(); workerReceiveExpr.isChannel = true; } addExpressionNode(workerReceiveExpr); } void addWorkerFlushExpr(DiagnosticPos pos, Set<Whitespace> ws, String workerName) { BLangWorkerFlushExpr workerFlushExpr = TreeBuilder.createWorkerFlushExpressionNode(); if (workerName != null) { workerFlushExpr.workerIdentifier = (BLangIdentifier) createIdentifier(workerName); } workerFlushExpr.pos = pos; workerFlushExpr.addWS(ws); addExpressionNode(workerFlushExpr); } void addWorkerSendSyncExpr(DiagnosticPos pos, Set<Whitespace> ws, String workerName) { BLangWorkerSyncSendExpr workerSendExpr = TreeBuilder.createWorkerSendSyncExprNode(); workerSendExpr.setWorkerName(this.createIdentifier(workerName)); workerSendExpr.expr = (BLangExpression) exprNodeStack.pop(); workerSendExpr.pos = pos; workerSendExpr.addWS(ws); addExpressionNode(workerSendExpr); } void addExpressionStmt(DiagnosticPos pos, Set<Whitespace> ws) { BLangExpressionStmt exprStmt = (BLangExpressionStmt) TreeBuilder.createExpressionStatementNode(); exprStmt.pos = pos; exprStmt.addWS(ws); exprStmt.expr = (BLangExpression) exprNodeStack.pop(); addStmtToCurrentBlock(exprStmt); } void startServiceDef(DiagnosticPos pos) { BLangService serviceNode = (BLangService) TreeBuilder.createServiceNode(); serviceNode.pos = pos; attachAnnotations(serviceNode); attachMarkdownDocumentations(serviceNode); attachDeprecatedNode(serviceNode); serviceNodeStack.push(serviceNode); } void endServiceDef(DiagnosticPos pos, Set<Whitespace> ws, String serviceName, DiagnosticPos identifierPos, boolean isAnonServiceValue) { // Any Service can be represented in two major components. // 1) A anonymous type node (Object) // 2) Variable assignment with "serviceName". // This is a global variable if the service is defined in module level. // Otherwise (isAnonServiceValue = true) it is a local variable definition, which is written by user. BLangService serviceNode = (BLangService) serviceNodeStack.pop(); serviceNode.pos = pos; serviceNode.addWS(ws); serviceNode.isAnonymousServiceValue = isAnonServiceValue; if (serviceName == null) { serviceName = this.anonymousModelHelper.getNextAnonymousServiceVarKey(pos.src.pkgID); identifierPos = pos; } String serviceTypeName = this.anonymousModelHelper.getNextAnonymousServiceTypeKey(pos.src.pkgID, serviceName); BLangIdentifier serviceVar = (BLangIdentifier) createIdentifier(serviceName); serviceVar.pos = identifierPos; serviceNode.setName(serviceVar); if (!isAnonServiceValue) { this.exprNodeListStack.pop().forEach(expr -> serviceNode.attachedExprs.add((BLangExpression) expr)); if (this.commaWsStack.size() > 0) { serviceNode.addWS(this.commaWsStack.pop()); } } // We add all service nodes to top level, only for future reference. this.compUnit.addTopLevelNode(serviceNode); // 1) Define type nodeDefinition for service type. BLangTypeDefinition typeDef = (BLangTypeDefinition) TreeBuilder.createTypeDefinition(); BLangIdentifier serviceTypeID = (BLangIdentifier) createIdentifier(serviceTypeName); serviceTypeID.pos = pos; typeDef.setName(serviceTypeID); typeDef.flagSet.add(Flag.SERVICE); typeDef.typeNode = (BLangType) this.typeNodeStack.pop(); typeDef.pos = pos; serviceNode.serviceTypeDefinition = typeDef; this.compUnit.addTopLevelNode(typeDef); // 2) Create service constructor. final BLangServiceConstructorExpr serviceConstNode = (BLangServiceConstructorExpr) TreeBuilder .createServiceConstructorNode(); serviceConstNode.serviceNode = serviceNode; serviceConstNode.pos = pos; serviceConstNode.addWS(ws); addExpressionNode(serviceConstNode); // Crate Global variable for service. if (!isAnonServiceValue) { BLangSimpleVariable var = (BLangSimpleVariable) generateBasicVarNodeWithoutType(identifierPos, Collections.emptySet(), serviceName, true); var.flagSet.add(Flag.FINAL); var.flagSet.add(Flag.SERVICE); var.typeNode = createUserDefinedType(pos, ws, (BLangIdentifier) TreeBuilder.createIdentifierNode(), typeDef.name); serviceNode.variableNode = var; this.compUnit.addTopLevelNode(var); } } void createXMLQName(DiagnosticPos pos, Set<Whitespace> ws, String localname, String prefix) { BLangXMLQName qname = (BLangXMLQName) TreeBuilder.createXMLQNameNode(); qname.localname = (BLangIdentifier) createIdentifier(localname); qname.prefix = (BLangIdentifier) createIdentifier(prefix); qname.pos = pos; qname.addWS(ws); addExpressionNode(qname); } void createXMLAttribute(DiagnosticPos pos, Set<Whitespace> ws) { BLangXMLAttribute xmlAttribute = (BLangXMLAttribute) TreeBuilder.createXMLAttributeNode(); xmlAttribute.value = (BLangXMLQuotedString) exprNodeStack.pop(); xmlAttribute.name = (BLangExpression) exprNodeStack.pop(); xmlAttribute.pos = pos; xmlAttribute.addWS(ws); xmlAttributeNodeStack.push(xmlAttribute); } void attachXmlLiteralWS(Set<Whitespace> ws) { this.exprNodeStack.peek().addWS(ws); } void startXMLElement(DiagnosticPos pos, Set<Whitespace> ws, boolean isRoot) { BLangXMLElementLiteral xmlElement = (BLangXMLElementLiteral) TreeBuilder.createXMLElementLiteralNode(); BLangExpression startTag = (BLangExpression) exprNodeStack.pop(); xmlElement.addWS(ws); xmlElement.startTagName = startTag; xmlElement.pos = pos; xmlElement.isRoot = isRoot; xmlAttributeNodeStack.forEach(xmlElement::addAttribute); xmlAttributeNodeStack.clear(); addExpressionNode(xmlElement); } void endXMLElement(Set<Whitespace> ws) { BLangExpression endTag = (BLangExpression) exprNodeStack.pop(); BLangXMLElementLiteral xmlElement = (BLangXMLElementLiteral) exprNodeStack.peek(); xmlElement.addWS(ws); xmlElement.endTagName = endTag; } void createXMLQuotedLiteral(DiagnosticPos pos, Set<Whitespace> ws, Stack<String> precedingTextFragments, String endingText, QuoteType quoteType) { List<BLangExpression> templateExprs = getExpressionsInTemplate(pos, ws, precedingTextFragments, endingText); BLangXMLQuotedString quotedString = (BLangXMLQuotedString) TreeBuilder.createXMLQuotedStringNode(); quotedString.pos = pos; quotedString.quoteType = quoteType; quotedString.textFragments = templateExprs; addExpressionNode(quotedString); } void addChildToXMLElement(Set<Whitespace> ws) { XMLLiteralNode child = (XMLLiteralNode) exprNodeStack.pop(); child.addWS(ws); BLangXMLElementLiteral parentXMLExpr = (BLangXMLElementLiteral) exprNodeStack.peek(); parentXMLExpr.addChild(child); } void createXMLTextLiteral(DiagnosticPos pos, Set<Whitespace> ws, Stack<String> precedingTextFragments, String endingText) { BLangXMLTextLiteral xmlTextLiteral = (BLangXMLTextLiteral) TreeBuilder.createXMLTextLiteralNode(); xmlTextLiteral.textFragments = getExpressionsInTemplate(pos, ws, precedingTextFragments, endingText); xmlTextLiteral.pos = pos; addExpressionNode(xmlTextLiteral); } void addXMLTextToElement(DiagnosticPos pos, Set<Whitespace> ws, Stack<String> precedingTextFragments, String endingText) { List<BLangExpression> templateExprs = getExpressionsInTemplate(pos, ws, precedingTextFragments, endingText); BLangXMLElementLiteral parentElement = (BLangXMLElementLiteral) exprNodeStack.peek(); templateExprs.forEach(parentElement::addChild); } void createXMLCommentLiteral(DiagnosticPos pos, Set<Whitespace> ws, Stack<String> precedingTextFragments, String endingText) { BLangXMLCommentLiteral xmlCommentLiteral = (BLangXMLCommentLiteral) TreeBuilder .createXMLCommentLiteralNode(); xmlCommentLiteral.textFragments = getExpressionsInTemplate(pos, null, precedingTextFragments, endingText); xmlCommentLiteral.pos = pos; xmlCommentLiteral.addWS(ws); addExpressionNode(xmlCommentLiteral); } void createXMLPILiteral(DiagnosticPos pos, Set<Whitespace> ws, String targetQName, Stack<String> precedingTextFragments, String endingText) { List<BLangExpression> dataExprs = getExpressionsInTemplate(pos, ws, precedingTextFragments, endingText); addLiteralValue(pos, ws, TypeTags.STRING, targetQName); BLangXMLProcInsLiteral xmlProcInsLiteral = (BLangXMLProcInsLiteral) TreeBuilder .createXMLProcessingIntsructionLiteralNode(); xmlProcInsLiteral.pos = pos; xmlProcInsLiteral.dataFragments = dataExprs; xmlProcInsLiteral.target = (BLangLiteral) exprNodeStack.pop(); addExpressionNode(xmlProcInsLiteral); } void addXMLNSDeclaration(DiagnosticPos pos, Set<Whitespace> ws, String namespaceUri, String prefix, boolean isTopLevel) { BLangXMLNS xmlns = (BLangXMLNS) TreeBuilder.createXMLNSNode(); BLangIdentifier prefixIdentifer = (BLangIdentifier) TreeBuilder.createIdentifierNode(); prefixIdentifer.pos = pos; prefixIdentifer.value = prefix; addLiteralValue(pos, removeNthFromStart(ws, 1), TypeTags.STRING, namespaceUri); xmlns.namespaceURI = (BLangLiteral) exprNodeStack.pop(); xmlns.prefix = prefixIdentifer; xmlns.pos = pos; xmlns.addWS(ws); if (isTopLevel) { this.compUnit.addTopLevelNode(xmlns); return; } BLangXMLNSStatement xmlnsStmt = (BLangXMLNSStatement) TreeBuilder.createXMLNSDeclrStatementNode(); xmlnsStmt.xmlnsDecl = xmlns; xmlnsStmt.pos = pos; addStmtToCurrentBlock(xmlnsStmt); } void createStringTemplateLiteral(DiagnosticPos pos, Set<Whitespace> ws, Stack<String> precedingTextFragments, String endingText) { BLangStringTemplateLiteral stringTemplateLiteral = (BLangStringTemplateLiteral) TreeBuilder .createStringTemplateLiteralNode(); stringTemplateLiteral.exprs = getExpressionsInTemplate(pos, null, precedingTextFragments, endingText); stringTemplateLiteral.addWS(ws); stringTemplateLiteral.pos = pos; addExpressionNode(stringTemplateLiteral); } void createXmlAttributesRefExpr(DiagnosticPos pos, Set<Whitespace> ws, boolean singleAttribute) { BLangXMLAttributeAccess xmlAttributeAccess = (BLangXMLAttributeAccess) TreeBuilder .createXMLAttributeAccessNode(); xmlAttributeAccess.pos = pos; xmlAttributeAccess.addWS(ws); if (singleAttribute) { xmlAttributeAccess.indexExpr = (BLangExpression) exprNodeStack.pop(); } xmlAttributeAccess.expr = (BLangVariableReference) exprNodeStack.pop(); addExpressionNode(xmlAttributeAccess); } void addIntRangeExpression(DiagnosticPos pos, Set<Whitespace> ws, boolean includeStart, boolean includeEnd, boolean noUpperBound) { BLangIntRangeExpression intRangeExpr = (BLangIntRangeExpression) TreeBuilder.createIntRangeExpression(); intRangeExpr.pos = pos; intRangeExpr.addWS(ws); if (!noUpperBound) { intRangeExpr.endExpr = (BLangExpression) this.exprNodeStack.pop(); } intRangeExpr.startExpr = (BLangExpression) this.exprNodeStack.pop(); intRangeExpr.includeStart = includeStart; intRangeExpr.includeEnd = includeEnd; exprNodeStack.push(intRangeExpr); } void addNamedArgument(DiagnosticPos pos, Set<Whitespace> ws, String name) { BLangNamedArgsExpression namedArg = (BLangNamedArgsExpression) TreeBuilder.createNamedArgNode(); namedArg.pos = pos; namedArg.addWS(ws); namedArg.name = (BLangIdentifier) this.createIdentifier(name); namedArg.expr = (BLangExpression) this.exprNodeStack.pop(); addExpressionNode(namedArg); } void addRestArgument(DiagnosticPos pos, Set<Whitespace> ws) { BLangRestArgsExpression varArgs = (BLangRestArgsExpression) TreeBuilder.createVarArgsNode(); varArgs.pos = pos; varArgs.addWS(ws); varArgs.expr = (BLangExpression) this.exprNodeStack.pop(); addExpressionNode(varArgs); } void addDefaultableParam(DiagnosticPos pos, Set<Whitespace> ws) { BLangSimpleVariableDef defaultableParam = (BLangSimpleVariableDef) TreeBuilder .createSimpleVariableDefinitionNode(); defaultableParam.pos = pos; defaultableParam.addWS(ws); List<BLangVariable> params = this.varListStack.peek(); BLangSimpleVariable var = (BLangSimpleVariable) params.remove(params.size() - 1); var.expr = (BLangExpression) this.exprNodeStack.pop(); defaultableParam.var = var; this.defaultableParamsList.add(defaultableParam); } void addRestParam(DiagnosticPos pos, Set<Whitespace> ws, String identifier, int annotCount) { BLangSimpleVariable restParam = (BLangSimpleVariable) this.generateBasicVarNode(pos, ws, identifier, false); attachAnnotations(restParam, annotCount); restParam.pos = pos; BLangArrayType typeNode = (BLangArrayType) TreeBuilder.createArrayTypeNode(); typeNode.elemtype = restParam.typeNode; typeNode.dimensions = 1; restParam.typeNode = typeNode; this.restParamStack.push(restParam); } // Private methods private List<BLangExpression> getExpressionsInTemplate(DiagnosticPos pos, Set<Whitespace> ws, Stack<String> precedingTextFragments, String endingText) { List<BLangExpression> expressions = new ArrayList<>(); String originalValue = endingText; endingText = endingText == null ? "" : StringEscapeUtils.unescapeJava(endingText); addLiteralValue(pos, ws, TypeTags.STRING, endingText, originalValue); expressions.add((BLangExpression) exprNodeStack.pop()); while (!precedingTextFragments.empty()) { expressions.add((BLangExpression) exprNodeStack.pop()); String textFragment = precedingTextFragments.pop(); originalValue = textFragment; textFragment = textFragment == null ? "" : StringEscapeUtils.unescapeJava(textFragment); addLiteralValue(pos, ws, TypeTags.STRING, textFragment, originalValue); expressions.add((BLangExpression) exprNodeStack.pop()); } Collections.reverse(expressions); return expressions; } void endCompilationUnit(Set<Whitespace> ws) { compUnit.addWS(ws); } void endCallableParamList(Set<Whitespace> ws) { this.invokableNodeStack.peek().addWS(ws); } void endFuncTypeParamList(Set<Whitespace> ws) { this.commaWsStack.push(ws); } private Set<Whitespace> removeNthFromLast(Set<Whitespace> ws, int n) { if (ws == null) { return null; } return removeNth(((TreeSet<Whitespace>) ws).descendingIterator(), n); } private Set<Whitespace> removeNthFromStart(Set<Whitespace> ws, int n) { if (ws == null) { return null; } return removeNth(ws.iterator(), n); } private Set<Whitespace> removeNth(Iterator<Whitespace> iterator, int n) { int i = 0; while (iterator.hasNext()) { Whitespace next = iterator.next(); if (i++ == n) { Set<Whitespace> varWS = new TreeSet<>(); varWS.add(next); iterator.remove(); return varWS; } } return null; } private BLangUserDefinedType createUserDefinedType(DiagnosticPos pos, Set<Whitespace> ws, BLangIdentifier pkgAlias, BLangIdentifier name) { BLangUserDefinedType userDefinedType = (BLangUserDefinedType) TreeBuilder.createUserDefinedTypeNode(); userDefinedType.pos = pos; userDefinedType.addWS(ws); userDefinedType.pkgAlias = pkgAlias; userDefinedType.typeName = name; return userDefinedType; } private List<String> getPackageNameComps(String sourcePkg) { String[] pkgParts = sourcePkg.split("\\.|\\\\|\\/"); return Arrays.asList(pkgParts); } void startOrderByClauseNode(DiagnosticPos pos) { OrderByNode orderByNode = TreeBuilder.createOrderByNode(); ((BLangOrderBy) orderByNode).pos = pos; this.orderByClauseStack.push(orderByNode); } void endOrderByClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { OrderByNode orderByNode = this.orderByClauseStack.peek(); ((BLangOrderBy) orderByNode).pos = pos; orderByNode.addWS(ws); Collections.reverse(orderByVariableStack); while (!this.orderByVariableStack.empty()) { orderByNode.addOrderByVariable(this.orderByVariableStack.pop()); } } void startOrderByVariableNode(DiagnosticPos pos) { OrderByVariableNode orderByVariableNode = TreeBuilder.createOrderByVariableNode(); ((BLangOrderByVariable) orderByVariableNode).pos = pos; this.orderByVariableStack.push(orderByVariableNode); } void endOrderByVariableNode(DiagnosticPos pos, Set<Whitespace> ws, boolean isAscending, boolean isDescending) { OrderByVariableNode orderByVariableNode = this.orderByVariableStack.peek(); ((BLangOrderByVariable) orderByVariableNode).pos = pos; orderByVariableNode.addWS(ws); orderByVariableNode.setVariableReference(this.exprNodeStack.pop()); orderByVariableNode.setOrderByType(isAscending, isDescending); } void startLimitClauseNode(DiagnosticPos pos) { LimitNode limitNode = TreeBuilder.createLimitNode(); ((BLangLimit) limitNode).pos = pos; this.limitClauseStack.push(limitNode); } void endLimitClauseNode(DiagnosticPos pos, Set<Whitespace> ws, String limitValue) { LimitNode limitNode = this.limitClauseStack.peek(); ((BLangLimit) limitNode).pos = pos; limitNode.addWS(ws); limitNode.setLimitValue(limitValue); } void startGroupByClauseNode(DiagnosticPos pos) { GroupByNode groupByNode = TreeBuilder.createGroupByNode(); ((BLangGroupBy) groupByNode).pos = pos; this.groupByClauseStack.push(groupByNode); } void endGroupByClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { GroupByNode groupByNode = this.groupByClauseStack.peek(); ((BLangGroupBy) groupByNode).pos = pos; groupByNode.addWS(ws); groupByNode.addWS(commaWsStack.pop()); this.exprNodeListStack.pop().forEach(groupByNode::addVariableReference); } void startHavingClauseNode(DiagnosticPos pos) { HavingNode havingNode = TreeBuilder.createHavingNode(); ((BLangHaving) havingNode).pos = pos; this.havingClauseStack.push(havingNode); } void endHavingClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { HavingNode havingNode = this.havingClauseStack.peek(); ((BLangHaving) havingNode).pos = pos; havingNode.addWS(ws); havingNode.setExpression(this.exprNodeStack.pop()); } void startSelectExpressionNode(DiagnosticPos pos) { SelectExpressionNode selectExpr = TreeBuilder.createSelectExpressionNode(); ((BLangSelectExpression) selectExpr).pos = pos; this.selectExpressionsStack.push(selectExpr); } void endSelectExpressionNode(String identifier, DiagnosticPos pos, Set<Whitespace> ws) { SelectExpressionNode selectExpression = this.selectExpressionsStack.peek(); selectExpression.setExpression(exprNodeStack.pop()); ((BLangSelectExpression) selectExpression).pos = pos; selectExpression.addWS(ws); selectExpression.setIdentifier(identifier); } void startSelectExpressionList() { this.selectExpressionsListStack.push(new ArrayList<>()); } void endSelectExpressionList(Set<Whitespace> ws, int selectExprCount) { commaWsStack.push(ws); List<SelectExpressionNode> selectExprList = this.selectExpressionsListStack.peek(); addSelectExprToSelectExprNodeList(selectExprList, selectExprCount); } private void addSelectExprToSelectExprNodeList(List<SelectExpressionNode> selectExprList, int n) { if (this.selectExpressionsStack.empty()) { throw new IllegalStateException("Select expression stack cannot be empty in processing a SelectClause"); } SelectExpressionNode expr = this.selectExpressionsStack.pop(); if (n > 1) { addSelectExprToSelectExprNodeList(selectExprList, n - 1); } selectExprList.add(expr); } void startWhereClauseNode(DiagnosticPos pos) { WhereNode whereNode = TreeBuilder.createWhereNode(); ((BLangWhere) whereNode).pos = pos; this.whereClauseStack.push(whereNode); } void endWhereClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { WhereNode whereNode = this.whereClauseStack.peek(); ((BLangWhere) whereNode).pos = pos; whereNode.addWS(ws); whereNode.setExpression(exprNodeStack.pop()); } void startSelectClauseNode(DiagnosticPos pos) { SelectClauseNode selectClauseNode = TreeBuilder.createSelectClauseNode(); ((BLangSelectClause) selectClauseNode).pos = pos; this.selectClausesStack.push(selectClauseNode); } void endSelectClauseNode(boolean isSelectAll, boolean isGroupByAvailable, boolean isHavingAvailable, DiagnosticPos pos, Set<Whitespace> ws) { SelectClauseNode selectClauseNode = this.selectClausesStack.peek(); ((BLangSelectClause) selectClauseNode).pos = pos; selectClauseNode.addWS(ws); if (!isSelectAll) { selectClauseNode.addWS(commaWsStack.pop()); selectClauseNode.setSelectExpressions(this.selectExpressionsListStack.pop()); } else { selectClauseNode.setSelectAll(true); } if (isGroupByAvailable) { selectClauseNode.setGroupBy(this.groupByClauseStack.pop()); } if (isHavingAvailable) { selectClauseNode.setHaving(this.havingClauseStack.pop()); } } void startWindowClauseNode(DiagnosticPos pos) { WindowClauseNode windowClauseNode = TreeBuilder.createWindowClauseNode(); ((BLangWindow) windowClauseNode).pos = pos; this.windowClausesStack.push(windowClauseNode); } void endWindowsClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { WindowClauseNode windowClauseNode = this.windowClausesStack.peek(); ((BLangWindow) windowClauseNode).pos = pos; windowClauseNode.addWS(ws); windowClauseNode.setFunctionInvocation(this.exprNodeStack.pop()); if (this.exprNodeStack.size() > 1) { // contains other than the streaming input name reference List<ExpressionNode> exprList = new ArrayList<>(); addExprToExprNodeList(exprList, this.exprNodeStack.size() - 1); StreamingInput streamingInput = this.streamingInputStack.peek(); streamingInput.setPreFunctionInvocations(exprList); } if (!this.whereClauseStack.empty()) { this.streamingInputStack.peek().setWindowTraversedAfterWhere(true); } else { this.streamingInputStack.peek().setWindowTraversedAfterWhere(false); } } void startStreamingInputNode(DiagnosticPos pos) { StreamingInput streamingInput = TreeBuilder.createStreamingInputNode(); ((BLangStreamingInput) streamingInput).pos = pos; this.streamingInputStack.push(streamingInput); } void endStreamingInputNode(String alias, DiagnosticPos pos, Set<Whitespace> ws) { BLangStreamingInput streamingInput = (BLangStreamingInput) this.streamingInputStack.peek(); streamingInput.pos = pos; streamingInput.addWS(ws); if (this.whereClauseStack.size() == 2) { streamingInput.setAfterStreamingCondition(this.whereClauseStack.pop()); streamingInput.setBeforeStreamingCondition(this.whereClauseStack.pop()); } else if (this.whereClauseStack.size() == 1) { if (streamingInput.isWindowTraversedAfterWhere()) { streamingInput.setBeforeStreamingCondition(this.whereClauseStack.pop()); } else { streamingInput.setAfterStreamingCondition(this.whereClauseStack.pop()); } } if (this.exprNodeStack.size() > 1) { List<ExpressionNode> exprList = new ArrayList<>(); while (this.exprNodeStack.peek().getKind() == NodeKind.INVOCATION) { exprList.add(this.exprNodeStack.pop()); } if (exprList.size() > 0) { streamingInput.setPostFunctionInvocations(exprList); } } if (!this.windowClausesStack.empty()) { streamingInput.setWindowClause(this.windowClausesStack.pop()); } streamingInput.setStreamReference(this.exprNodeStack.pop()); streamingInput.setAlias(alias); } void startJoinStreamingInputNode(DiagnosticPos pos) { JoinStreamingInput joinStreamingInput = TreeBuilder.createJoinStreamingInputNode(); ((BLangJoinStreamingInput) joinStreamingInput).pos = pos; this.joinStreamingInputsStack.push(joinStreamingInput); } void endJoinStreamingInputNode(DiagnosticPos pos, Set<Whitespace> ws, boolean isUnidirectionalBeforeJoin, boolean isUnidirectionalAfterJoin, String joinType) { JoinStreamingInput joinStreamingInput = this.joinStreamingInputsStack.peek(); ((BLangJoinStreamingInput) joinStreamingInput).pos = pos; joinStreamingInput.addWS(ws); joinStreamingInput.setStreamingInput(this.streamingInputStack.pop()); if (this.exprNodeStack.size() > 0) { joinStreamingInput.setOnExpression(this.exprNodeStack.pop()); } joinStreamingInput.setUnidirectionalBeforeJoin(isUnidirectionalBeforeJoin); joinStreamingInput.setUnidirectionalAfterJoin(isUnidirectionalAfterJoin); joinStreamingInput.setJoinType(joinType); } void endJoinType(Set<Whitespace> ws) { JoinStreamingInput joinStreamingInput = this.joinStreamingInputsStack.peek(); joinStreamingInput.addWS(ws); } void startTableQueryNode(DiagnosticPos pos) { TableQuery tableQuery = TreeBuilder.createTableQueryNode(); ((BLangTableQuery) tableQuery).pos = pos; this.tableQueriesStack.push(tableQuery); } void endTableQueryNode(boolean isJoinClauseAvailable, boolean isSelectClauseAvailable, boolean isOrderByClauseAvailable, boolean isLimitClauseAvailable, DiagnosticPos pos, Set<Whitespace> ws) { BLangTableQuery tableQuery = (BLangTableQuery) this.tableQueriesStack.peek(); tableQuery.pos = pos; tableQuery.addWS(ws); tableQuery.setStreamingInput(this.streamingInputStack.pop()); if (isJoinClauseAvailable) { tableQuery.setJoinStreamingInput(this.joinStreamingInputsStack.pop()); } if (isSelectClauseAvailable) { tableQuery.setSelectClause(this.selectClausesStack.pop()); } if (isOrderByClauseAvailable) { tableQuery.setOrderByClause(this.orderByClauseStack.pop()); } if (isLimitClauseAvailable) { tableQuery.setLimitClause(this.limitClauseStack.pop()); } } void addTableQueryExpression(DiagnosticPos pos, Set<Whitespace> ws) { TableQueryExpression tableQueryExpression = TreeBuilder.createTableQueryExpression(); ((BLangTableQueryExpression) tableQueryExpression).pos = pos; tableQueryExpression.addWS(ws); tableQueryExpression.setTableQuery(tableQueriesStack.pop()); this.exprNodeStack.push(tableQueryExpression); } void startSetAssignmentClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { SetAssignmentNode setAssignmentNode = TreeBuilder.createSetAssignmentNode(); ((BLangSetAssignment) setAssignmentNode).pos = pos; setAssignmentNode.addWS(ws); this.setAssignmentStack.push(setAssignmentNode); } void endSetAssignmentClauseNode(DiagnosticPos pos, Set<Whitespace> ws) { if (this.exprNodeStack.empty()) { throw new IllegalStateException( "Expression stack cannot be empty in processing a Set Assignment Clause"); } SetAssignmentNode setAssignmentNode = this.setAssignmentStack.peek(); ((BLangSetAssignment) setAssignmentNode).pos = pos; setAssignmentNode.addWS(ws); setAssignmentNode.setExpression(exprNodeStack.pop()); setAssignmentNode.setVariableReference(exprNodeStack.pop()); } void startSetClauseNode() { this.setAssignmentListStack.push(new ArrayList<>()); } void endSetClauseNode(Set<Whitespace> ws, int selectExprCount) { List<SetAssignmentNode> setAssignmentNodeList = this.setAssignmentListStack.peek(); addSetAssignmentToSelectAssignmentNodeList(setAssignmentNodeList, selectExprCount); } private void addSetAssignmentToSelectAssignmentNodeList(List<SetAssignmentNode> setAssignmentNodeList, int n) { if (this.setAssignmentStack.empty()) { throw new IllegalStateException("Set expression stack cannot be empty in processing a SelectClause"); } SetAssignmentNode expr = this.setAssignmentStack.pop(); if (n > 1) { addSetAssignmentToSelectAssignmentNodeList(setAssignmentNodeList, n - 1); } setAssignmentNodeList.add(expr); } void startStreamActionNode(DiagnosticPos pos, PackageID packageID) { StreamActionNode streamActionNode = TreeBuilder.createStreamActionNode(); ((BLangStreamAction) streamActionNode).pos = pos; this.streamActionNodeStack.push(streamActionNode); this.startLambdaFunctionDef(packageID); this.startBlock(); } void endStreamActionNode(DiagnosticPos pos, Set<Whitespace> ws) { endCallableUnitBody(ws); StreamActionNode streamActionNode = this.streamActionNodeStack.peek(); ((BLangStreamAction) streamActionNode).pos = pos; streamActionNode.addWS(ws); this.varListStack.push(new ArrayList<>()); this.varListStack.peek().add(this.varStack.pop()); this.commaWsStack.push(ws); this.addLambdaFunctionDef(pos, ws, true, false, false); streamActionNode.setInvokableBody((BLangLambdaFunction) this.exprNodeStack.pop()); } void startPatternStreamingEdgeInputNode(DiagnosticPos pos) { PatternStreamingEdgeInputNode patternStreamingEdgeInputNode = TreeBuilder .createPatternStreamingEdgeInputNode(); ((BLangPatternStreamingEdgeInput) patternStreamingEdgeInputNode).pos = pos; this.patternStreamingEdgeInputStack.push(patternStreamingEdgeInputNode); } void endPatternStreamingEdgeInputNode(DiagnosticPos pos, Set<Whitespace> ws, String alias) { PatternStreamingEdgeInputNode patternStreamingEdgeInputNode = this.patternStreamingEdgeInputStack.peek(); ((BLangPatternStreamingEdgeInput) patternStreamingEdgeInputNode).pos = pos; patternStreamingEdgeInputNode.addWS(ws); if (exprNodeStack.size() == 2) { patternStreamingEdgeInputNode.setExpression(exprNodeStack.pop()); patternStreamingEdgeInputNode.setStreamReference(exprNodeStack.pop()); } else if (exprNodeStack.size() == 1) { patternStreamingEdgeInputNode.setStreamReference(exprNodeStack.pop()); } if (!whereClauseStack.empty()) { patternStreamingEdgeInputNode.setWhereClause(whereClauseStack.pop()); } patternStreamingEdgeInputNode.setAliasIdentifier(alias); } void startPatternStreamingInputNode(DiagnosticPos pos) { PatternStreamingInputNode patternStreamingInputNode = TreeBuilder.createPatternStreamingInputNode(); ((BLangPatternStreamingInput) patternStreamingInputNode).pos = pos; this.patternStreamingInputStack.push(patternStreamingInputNode); } void endPatternStreamingInputNode(DiagnosticPos pos, Set<Whitespace> ws, boolean isFollowedBy, boolean enclosedInParenthesis, boolean andWithNotAvailable, boolean forWithNotAvailable, boolean onlyAndAvailable, boolean onlyOrAvailable, boolean commaSeparated, String timeDurationValue, String timeScale) { if (!this.patternStreamingInputStack.empty()) { PatternStreamingInputNode patternStreamingInputNode = this.patternStreamingInputStack.pop(); ((BLangPatternStreamingInput) patternStreamingInputNode).pos = pos; patternStreamingInputNode.addWS(ws); if (isFollowedBy) { processFollowedByPattern(patternStreamingInputNode); } if (enclosedInParenthesis) { processEnclosedPattern(patternStreamingInputNode); } if (andWithNotAvailable) { processNegationPattern(patternStreamingInputNode); } if (onlyAndAvailable) { processPatternWithAndCondition(patternStreamingInputNode); } if (onlyOrAvailable) { processPatternWithOrCondition(patternStreamingInputNode); } if (forWithNotAvailable) { processNegationPatternWithTimeDuration(patternStreamingInputNode, timeDurationValue, timeScale); } if (commaSeparated) { processCommaSeparatedSequence(patternStreamingInputNode); } if (!(isFollowedBy || enclosedInParenthesis || forWithNotAvailable || onlyAndAvailable || onlyOrAvailable || andWithNotAvailable || commaSeparated)) { patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); this.recentStreamingPatternInputNode = patternStreamingInputNode; } } if (this.patternStreamingInputStack.empty()) { this.patternStreamingInputStack.push(this.recentStreamingPatternInputNode); this.recentStreamingPatternInputNode = null; } } private void processCommaSeparatedSequence(PatternStreamingInputNode patternStreamingInputNode) { patternStreamingInputNode.setCommaSeparated(true); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); patternStreamingInputNode.setPatternStreamingInput(this.recentStreamingPatternInputNode); this.recentStreamingPatternInputNode = patternStreamingInputNode; } private void processNegationPatternWithTimeDuration(PatternStreamingInputNode patternStreamingInputNode, String timeDurationValue, String timeScale) { patternStreamingInputNode.setForWithNot(true); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); patternStreamingInputNode.setTimeDurationValue(timeDurationValue); patternStreamingInputNode.setTimeScale(timeScale); this.recentStreamingPatternInputNode = patternStreamingInputNode; } private void processPatternWithOrCondition(PatternStreamingInputNode patternStreamingInputNode) { patternStreamingInputNode.setOrOnly(true); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); this.recentStreamingPatternInputNode = patternStreamingInputNode; } private void processPatternWithAndCondition(PatternStreamingInputNode patternStreamingInputNode) { patternStreamingInputNode.setAndOnly(true); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); this.recentStreamingPatternInputNode = patternStreamingInputNode; } private void processNegationPattern(PatternStreamingInputNode patternStreamingInputNode) { patternStreamingInputNode.setAndWithNot(true); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); this.recentStreamingPatternInputNode = patternStreamingInputNode; } private void processEnclosedPattern(PatternStreamingInputNode patternStreamingInputNode) { patternStreamingInputNode.setEnclosedInParenthesis(true); patternStreamingInputNode.setPatternStreamingInput(this.recentStreamingPatternInputNode); this.recentStreamingPatternInputNode = patternStreamingInputNode; } private void processFollowedByPattern(PatternStreamingInputNode patternStreamingInputNode) { patternStreamingInputNode.setFollowedBy(true); patternStreamingInputNode.addPatternStreamingEdgeInput(this.patternStreamingEdgeInputStack.pop()); patternStreamingInputNode.setPatternStreamingInput(this.recentStreamingPatternInputNode); this.recentStreamingPatternInputNode = patternStreamingInputNode; } void startStreamingQueryStatementNode(DiagnosticPos pos) { StreamingQueryStatementNode streamingQueryStatementNode = TreeBuilder.createStreamingQueryStatementNode(); ((BLangStreamingQueryStatement) streamingQueryStatementNode).pos = pos; this.streamingQueryStatementStack.push(streamingQueryStatementNode); } void endStreamingQueryStatementNode(DiagnosticPos pos, Set<Whitespace> ws) { StreamingQueryStatementNode streamingQueryStatementNode = this.streamingQueryStatementStack.peek(); ((BLangStreamingQueryStatement) streamingQueryStatementNode).pos = pos; streamingQueryStatementNode.addWS(ws); if (!streamingInputStack.empty()) { streamingQueryStatementNode.setStreamingInput(streamingInputStack.pop()); if (!joinStreamingInputsStack.empty()) { streamingQueryStatementNode.setJoinStreamingInput(joinStreamingInputsStack.pop()); } } else if (!patternClauseStack.empty()) { streamingQueryStatementNode.setPatternClause(patternClauseStack.pop()); } if (!selectClausesStack.empty()) { streamingQueryStatementNode.setSelectClause(selectClausesStack.pop()); } else { SelectClauseNode selectClauseNode = new BLangSelectClause(); selectClauseNode.setSelectAll(true); streamingQueryStatementNode.setSelectClause(selectClauseNode); } if (!orderByClauseStack.empty()) { streamingQueryStatementNode.setOrderByClause(orderByClauseStack.pop()); } if (!outputRateLimitStack.empty()) { streamingQueryStatementNode.setOutputRateLimitNode(outputRateLimitStack.pop()); } streamingQueryStatementNode.setStreamingAction(streamActionNodeStack.pop()); } void startOutputRateLimitNode(DiagnosticPos pos) { OutputRateLimitNode outputRateLimit = TreeBuilder.createOutputRateLimitNode(); ((BLangOutputRateLimit) outputRateLimit).pos = pos; this.outputRateLimitStack.push(outputRateLimit); } void endOutputRateLimitNode(DiagnosticPos pos, Set<Whitespace> ws, boolean isSnapshotOutputRateLimit, boolean isFirst, boolean isLast, boolean isAll, String timeScale, String rateLimitValue) { OutputRateLimitNode outputRateLimit = this.outputRateLimitStack.peek(); ((BLangOutputRateLimit) outputRateLimit).pos = pos; outputRateLimit.addWS(ws); outputRateLimit.setSnapshot(isSnapshotOutputRateLimit); outputRateLimit.setOutputRateType(isFirst, isLast, isAll); outputRateLimit.setTimeScale(timeScale); outputRateLimit.setRateLimitValue(rateLimitValue); } void startWithinClause(DiagnosticPos pos) { WithinClause withinClause = TreeBuilder.createWithinClause(); ((BLangWithinClause) withinClause).pos = pos; this.withinClauseStack.push(withinClause); } void endWithinClause(DiagnosticPos pos, Set<Whitespace> ws, String timeDurationValue, String timeScale) { WithinClause withinClause = this.withinClauseStack.peek(); ((BLangWithinClause) withinClause).pos = pos; withinClause.addWS(ws); withinClause.setTimeDurationValue(timeDurationValue); withinClause.setTimeScale(timeScale); } void startPatternClause(DiagnosticPos pos) { PatternClause patternClause = TreeBuilder.createPatternClause(); ((BLangPatternClause) patternClause).pos = pos; this.patternClauseStack.push(patternClause); } void endPatternClause(boolean isForEvents, boolean isWithinClauseAvailable, DiagnosticPos pos, Set<Whitespace> ws) { PatternClause patternClause = this.patternClauseStack.peek(); ((BLangPatternClause) patternClause).pos = pos; patternClause.addWS(ws); patternClause.setForAllEvents(isForEvents); patternClause.setPatternStreamingInputNode(this.patternStreamingInputStack.pop()); if (isWithinClauseAvailable) { patternClause.setWithinClause(this.withinClauseStack.pop()); } } void startForeverNode(DiagnosticPos pos, boolean isSiddhiRuntimeEnabled) { ForeverNode foreverNode = TreeBuilder.createForeverNode(isSiddhiRuntimeEnabled); ((BLangForever) foreverNode).pos = pos; this.foreverNodeStack.push(foreverNode); } void endForeverNode(DiagnosticPos pos, Set<Whitespace> ws) { ForeverNode foreverNode = this.foreverNodeStack.pop(); ((BLangForever) foreverNode).pos = pos; foreverNode.addWS(ws); if (!this.varListStack.empty()) { this.varListStack.pop().forEach(param -> foreverNode.addParameter((SimpleVariableNode) param)); } Collections.reverse(streamingQueryStatementStack); while (!streamingQueryStatementStack.empty()) { foreverNode.addStreamingQueryStatement(streamingQueryStatementStack.pop()); } addStmtToCurrentBlock(foreverNode); // implicit import of streams module, user doesn't want to import explicitly if (!foreverNode.isSiddhiRuntimeEnabled()) { List<String> nameComps = getPackageNameComps(Names.STREAMS_MODULE.value); addImportPackageDeclaration(pos, null, Names.STREAMS_ORG.value, nameComps, null, nameComps.get(nameComps.size() - 1)); } } BLangLambdaFunction getScopesFunctionDef(DiagnosticPos pos, Set<Whitespace> ws, boolean bodyExists, String name) { BLangFunction function = (BLangFunction) this.invokableNodeStack.pop(); function.pos = pos; function.addWS(ws); //always a public function function.flagSet.add(Flag.PUBLIC); function.flagSet.add(Flag.LAMBDA); if (!bodyExists) { function.body = null; } BLangIdentifier nameId = new BLangIdentifier(); nameId.setValue(Names.GEN_VAR_PREFIX + name); function.name = nameId; BLangValueType typeNode = (BLangValueType) TreeBuilder.createValueTypeNode(); typeNode.pos = pos; typeNode.typeKind = TypeKind.NIL; function.returnTypeNode = typeNode; function.receiver = null; BLangLambdaFunction lambda = (BLangLambdaFunction) TreeBuilder.createLambdaFunctionNode(); lambda.function = function; return lambda; } public void addTypeReference(DiagnosticPos currentPos, Set<Whitespace> ws) { TypeNode typeRef = typeNodeStack.pop(); typeRef.addWS(ws); BLangStructureTypeNode structureTypeNode = (BLangStructureTypeNode) typeNodeStack.peek(); structureTypeNode.addTypeReference(typeRef); } public void createTypeTestExpression(DiagnosticPos pos, Set<Whitespace> ws) { BLangTypeTestExpr typeTestExpr = (BLangTypeTestExpr) TreeBuilder.createTypeTestExpressionNode(); typeTestExpr.expr = (BLangExpression) this.exprNodeStack.pop(); typeTestExpr.typeNode = (BLangType) this.typeNodeStack.pop(); typeTestExpr.pos = pos; typeTestExpr.addWS(ws); addExpressionNode(typeTestExpr); } void handleWait(DiagnosticPos currentPos, Set<Whitespace> ws) { BLangWaitExpr waitExpr = TreeBuilder.createWaitExpressionNode(); waitExpr.exprList = Collections.singletonList((BLangExpression) this.exprNodeStack.pop()); waitExpr.pos = currentPos; waitExpr.addWS(ws); addExpressionNode(waitExpr); } void startWaitForAll() { BLangWaitForAllExpr bLangWaitForAll = TreeBuilder.createWaitForAllExpressionNode(); waitCollectionStack.push(bLangWaitForAll); } void handleWaitForAll(DiagnosticPos pos, Set<Whitespace> ws) { BLangWaitForAllExpr waitForAllExpr = waitCollectionStack.pop(); waitForAllExpr.pos = pos; waitForAllExpr.addWS(ws); addExpressionNode(waitForAllExpr); } void addKeyValueToWaitForAll(DiagnosticPos pos, Set<Whitespace> ws, String identifier, boolean containsExpr) { BLangWaitForAllExpr.BLangWaitKeyValue keyValue = TreeBuilder.createWaitKeyValueNode(); keyValue.addWS(ws); keyValue.pos = pos; // Add the key as an identifier BLangIdentifier key = (BLangIdentifier) TreeBuilder.createIdentifierNode(); key.setLiteral(false); key.setValue(identifier); keyValue.key = key; // Add the value. If it is a Identifier:expr pair then add the value by popping the expr from the expression // stack else the value is not assigned. if (containsExpr) { keyValue.valueExpr = (BLangExpression) exprNodeStack.pop(); } else { BLangSimpleVarRef varRef = (BLangSimpleVarRef) TreeBuilder.createSimpleVariableReferenceNode(); varRef.pos = pos; varRef.variableName = key; varRef.addWS(ws); varRef.pkgAlias = (BLangIdentifier) TreeBuilder.createIdentifierNode(); keyValue.keyExpr = varRef; } waitCollectionStack.peek().keyValuePairs.add(keyValue); } }