use of org.wso2.siddhi.query.api.expression.Expression in project ballerina by ballerina-lang.
the class ServiceProtoUtils method getInvocationExpression.
private static BLangInvocation getInvocationExpression(BlockNode body) {
if (body == null) {
return null;
}
for (StatementNode statementNode : body.getStatements()) {
BLangExpression expression = null;
// example : conn.send inside while block.
if (statementNode instanceof BLangWhile) {
BLangWhile langWhile = (BLangWhile) statementNode;
BLangInvocation invocExp = getInvocationExpression(langWhile.getBody());
if (invocExp != null) {
return invocExp;
}
}
// example : conn.send inside for block.
if (statementNode instanceof BLangForeach) {
BLangForeach langForeach = (BLangForeach) statementNode;
BLangInvocation invocExp = getInvocationExpression(langForeach.getBody());
if (invocExp != null) {
return invocExp;
}
}
// example : conn.send inside if block.
if (statementNode instanceof BLangIf) {
BLangIf langIf = (BLangIf) statementNode;
BLangInvocation invocExp = getInvocationExpression(langIf.getBody());
if (invocExp != null) {
return invocExp;
}
invocExp = getInvocationExpression((BLangBlockStmt) langIf.getElseStatement());
if (invocExp != null) {
return invocExp;
}
}
// example : _ = conn.send(msg);
if (statementNode instanceof BLangAssignment) {
BLangAssignment assignment = (BLangAssignment) statementNode;
expression = assignment.getExpression();
}
// example : grpc:HttpConnectorError err = conn.send(msg);
if (statementNode instanceof BLangVariableDef) {
BLangVariableDef variableDef = (BLangVariableDef) statementNode;
BLangVariable variable = variableDef.getVariable();
expression = variable.getInitialExpression();
}
if (expression != null && expression instanceof BLangInvocation) {
BLangInvocation invocation = (BLangInvocation) expression;
if ("send".equals(invocation.getName().getValue())) {
return invocation;
}
}
}
return null;
}
use of org.wso2.siddhi.query.api.expression.Expression in project ballerina by ballerina-lang.
the class TaintAnalyzer method visit.
public void visit(BLangReturn returnNode) {
List<Boolean> returnTaintedStatus = new ArrayList<>();
if (returnNode.namedReturnVariables == null) {
// If named returns are not used, evaluate each expression to identify the tainted status.
for (BLangExpression expr : returnNode.exprs) {
expr.accept(this);
returnTaintedStatus.addAll(taintedStatusList);
}
} else {
// If named returns are used, report back the tainted status of each variable.
for (BLangVariable var : returnNode.namedReturnVariables) {
returnTaintedStatus.add(var.symbol.tainted);
}
}
if (returnTaintedStatusList == null) {
returnTaintedStatusList = returnTaintedStatus;
} else {
// collective tainted status of returns.
for (int i = 0; i < returnTaintedStatusList.size(); i++) {
if (returnTaintedStatus.size() > i && returnTaintedStatus.get(i)) {
returnTaintedStatusList.set(i, true);
}
}
}
taintedStatusList = returnTaintedStatusList;
}
use of org.wso2.siddhi.query.api.expression.Expression in project ballerina by ballerina-lang.
the class TypeChecker method visit.
public void visit(BLangInvocation iExpr) {
// e.g. foo();, foo(), foo().k;
if (iExpr.expr == null) {
// This is a function invocation expression. e.g. foo()
checkFunctionInvocationExpr(iExpr);
return;
}
Name pkgAlias = names.fromIdNode(iExpr.pkgAlias);
if (pkgAlias != Names.EMPTY) {
dlog.error(iExpr.pos, DiagnosticCode.PKG_ALIAS_NOT_ALLOWED_HERE);
return;
}
// Find the variable reference expression type
final List<BType> exprTypes = checkExpr(iExpr.expr, this.env, Lists.of(symTable.noType));
if (isIterableOperationInvocation(iExpr)) {
iExpr.iterableOperationInvocation = true;
iterableAnalyzer.handlerIterableOperation(iExpr, expTypes.isEmpty() ? symTable.voidType : expTypes.get(0), env);
if (iExpr.iContext.operations.getLast().resultType == symTable.voidType) {
resultTypes = Collections.emptyList();
} else {
resultTypes = Lists.of(iExpr.iContext.operations.getLast().resultType);
}
return;
}
if (iExpr.actionInvocation) {
if (exprTypes.size() != 1) {
dlog.error(iExpr.expr.pos, DiagnosticCode.SINGLE_VALUE_RETURN_EXPECTED);
}
checkActionInvocationExpr(iExpr, exprTypes.size() > 0 ? exprTypes.get(0) : symTable.errType);
return;
}
switch(iExpr.expr.type.tag) {
case TypeTags.STRUCT:
// Invoking a function bound to a struct
// First check whether there exist a function with this name
// Then perform arg and param matching
checkFunctionInvocationExpr(iExpr, (BStructType) iExpr.expr.type);
break;
case TypeTags.CONNECTOR:
dlog.error(iExpr.pos, DiagnosticCode.INVALID_ACTION_INVOCATION_SYNTAX);
resultTypes = getListWithErrorTypes(expTypes.size());
return;
case TypeTags.BOOLEAN:
case TypeTags.STRING:
case TypeTags.INT:
case TypeTags.FLOAT:
case TypeTags.BLOB:
case TypeTags.XML:
checkFunctionInvocationExpr(iExpr, iExpr.expr.type);
break;
case TypeTags.JSON:
checkFunctionInvocationExpr(iExpr, symTable.jsonType);
break;
case TypeTags.TABLE:
checkFunctionInvocationExpr(iExpr, symTable.tableType);
break;
case TypeTags.STREAM:
checkFunctionInvocationExpr(iExpr, symTable.streamType);
break;
case TypeTags.FUTURE:
checkFunctionInvocationExpr(iExpr, symTable.futureType);
break;
case TypeTags.NONE:
dlog.error(iExpr.pos, DiagnosticCode.UNDEFINED_FUNCTION, iExpr.name);
break;
case TypeTags.MAP:
// allow map function for both constrained / un constrained maps
checkFunctionInvocationExpr(iExpr, this.symTable.mapType);
break;
case TypeTags.ERROR:
break;
case TypeTags.INTERMEDIATE_COLLECTION:
dlog.error(iExpr.pos, DiagnosticCode.INVALID_FUNCTION_INVOCATION_WITH_NAME, iExpr.name, iExpr.expr.type);
resultTypes = getListWithErrorTypes(expTypes.size());
break;
default:
dlog.error(iExpr.pos, DiagnosticCode.INVALID_FUNCTION_INVOCATION, iExpr.expr.type);
resultTypes = getListWithErrorTypes(expTypes.size());
break;
}
// TODO other types of invocation expressions
// TODO pkg alias should be null or empty here.
}
use of org.wso2.siddhi.query.api.expression.Expression in project ballerina by ballerina-lang.
the class CodeAnalyzer method visit.
@Override
public void visit(BLangMatch matchStmt) {
this.returnWithintransactionCheckStack.push(true);
boolean unmatchedExprTypesAvailable = false;
analyzeExpr(matchStmt.expr);
// TODO Handle **any** as a expr type.. special case it..
// TODO Complete the exhaustive tests with any, struct and connector types
// TODO Handle the case where there are incompatible types. e.g. input string : pattern int and pattern string
List<BType> unmatchedExprTypes = new ArrayList<>();
for (BType exprType : matchStmt.exprTypes) {
boolean assignable = false;
for (BLangMatchStmtPatternClause pattern : matchStmt.patternClauses) {
BType patternType = pattern.variable.type;
if (exprType.tag == TypeTags.ERROR || patternType.tag == TypeTags.ERROR) {
return;
}
assignable = this.types.isAssignable(exprType, patternType);
if (assignable) {
pattern.matchedTypesDirect.add(exprType);
break;
} else if (exprType.tag == TypeTags.ANY) {
pattern.matchedTypesIndirect.add(exprType);
} else if (exprType.tag == TypeTags.JSON && this.types.isAssignable(patternType, exprType)) {
pattern.matchedTypesIndirect.add(exprType);
} else if (exprType.tag == TypeTags.STRUCT && this.types.isAssignable(patternType, exprType)) {
pattern.matchedTypesIndirect.add(exprType);
} else {
// TODO Support other assignable types
}
}
if (!assignable) {
unmatchedExprTypes.add(exprType);
}
}
if (!unmatchedExprTypes.isEmpty()) {
unmatchedExprTypesAvailable = true;
dlog.error(matchStmt.pos, DiagnosticCode.MATCH_STMT_CANNOT_GUARANTEE_A_MATCHING_PATTERN, unmatchedExprTypes);
}
boolean matchedPatternsAvailable = false;
for (int i = matchStmt.patternClauses.size() - 1; i >= 0; i--) {
BLangMatchStmtPatternClause pattern = matchStmt.patternClauses.get(i);
if (pattern.matchedTypesDirect.isEmpty() && pattern.matchedTypesIndirect.isEmpty()) {
if (matchedPatternsAvailable) {
dlog.error(pattern.pos, DiagnosticCode.MATCH_STMT_UNMATCHED_PATTERN);
} else {
dlog.error(pattern.pos, DiagnosticCode.MATCH_STMT_UNREACHABLE_PATTERN);
}
} else {
matchedPatternsAvailable = true;
}
}
// Execute the following block if there are no unmatched expression types
if (!unmatchedExprTypesAvailable) {
this.checkStatementExecutionValidity(matchStmt);
boolean matchStmtReturns = true;
for (BLangMatchStmtPatternClause patternClause : matchStmt.patternClauses) {
patternClause.body.accept(this);
matchStmtReturns = matchStmtReturns && this.statementReturns;
this.resetStatementReturns();
}
this.statementReturns = matchStmtReturns;
}
this.returnWithintransactionCheckStack.pop();
}
use of org.wso2.siddhi.query.api.expression.Expression in project ballerina by ballerina-lang.
the class SemanticAnalyzer method handleAssignNodeWithVar.
private void handleAssignNodeWithVar(BLangAssignment assignNode) {
int ignoredCount = 0;
int createdSymbolCount = 0;
List<Name> newVariables = new ArrayList<Name>();
List<BType> expTypes = new ArrayList<>();
// Check each LHS expression.
for (int i = 0; i < assignNode.varRefs.size(); i++) {
BLangExpression varRef = assignNode.varRefs.get(i);
// If the assignment is declared with "var", then lhs supports only simpleVarRef expressions only.
if (varRef.getKind() != NodeKind.SIMPLE_VARIABLE_REF) {
dlog.error(varRef.pos, DiagnosticCode.INVALID_VARIABLE_ASSIGNMENT, varRef);
expTypes.add(symTable.errType);
continue;
}
// Check variable symbol if exists.
BLangSimpleVarRef simpleVarRef = (BLangSimpleVarRef) varRef;
((BLangVariableReference) varRef).lhsVar = true;
Name varName = names.fromIdNode(simpleVarRef.variableName);
if (varName == Names.IGNORE) {
ignoredCount++;
simpleVarRef.type = this.symTable.noType;
expTypes.add(symTable.noType);
typeChecker.checkExpr(simpleVarRef, env);
continue;
}
BSymbol symbol = symResolver.lookupSymbol(env, varName, SymTag.VARIABLE);
if (symbol == symTable.notFoundSymbol) {
createdSymbolCount++;
newVariables.add(varName);
expTypes.add(symTable.noType);
} else {
expTypes.add(symbol.type);
}
}
if (ignoredCount == assignNode.varRefs.size() || createdSymbolCount == 0) {
dlog.error(assignNode.pos, DiagnosticCode.NO_NEW_VARIABLES_VAR_ASSIGNMENT);
}
// Check RHS expressions with expected type list.
if (assignNode.getKind() == NodeKind.TUPLE_DESTRUCTURE) {
expTypes = Lists.of(symTable.noType);
}
List<BType> rhsTypes = typeChecker.checkExpr(assignNode.expr, this.env, expTypes);
if (assignNode.safeAssignment) {
rhsTypes = Lists.of(handleSafeAssignmentWithVarDeclaration(assignNode.pos, rhsTypes.get(0)));
}
if (assignNode.getKind() == NodeKind.TUPLE_DESTRUCTURE) {
if (rhsTypes.get(0) != symTable.errType && rhsTypes.get(0).tag == TypeTags.TUPLE) {
BTupleType tupleType = (BTupleType) rhsTypes.get(0);
rhsTypes = tupleType.tupleTypes;
} else if (rhsTypes.get(0) != symTable.errType && rhsTypes.get(0).tag != TypeTags.TUPLE) {
dlog.error(assignNode.pos, DiagnosticCode.INCOMPATIBLE_TYPES_EXP_TUPLE, rhsTypes.get(0));
rhsTypes = typeChecker.getListWithErrorTypes(assignNode.varRefs.size());
}
}
// visit all lhs expressions
for (int i = 0; i < assignNode.varRefs.size(); i++) {
BLangExpression varRef = assignNode.varRefs.get(i);
if (varRef.getKind() != NodeKind.SIMPLE_VARIABLE_REF) {
continue;
}
BType actualType = rhsTypes.get(i);
BLangSimpleVarRef simpleVarRef = (BLangSimpleVarRef) varRef;
Name varName = names.fromIdNode(simpleVarRef.variableName);
if (newVariables.contains(varName)) {
// define new variables
this.symbolEnter.defineVarSymbol(simpleVarRef.pos, Collections.emptySet(), actualType, varName, env);
}
typeChecker.checkExpr(simpleVarRef, env);
}
}
Aggregations