use of org.wso2.carbon.apimgt.core.models.Function in project ballerina by ballerina-lang.
the class TaintAnalyzer method updatedReturnTaintedStatusBasedOnAnnotations.
private void updatedReturnTaintedStatusBasedOnAnnotations(List<BLangVariable> retParams) {
if (returnTaintedStatusList != null) {
for (int paramIndex = 0; paramIndex < retParams.size(); paramIndex++) {
BLangVariable param = retParams.get(paramIndex);
// Analyzing a function that does not have any return statement and instead have a throw statement.
boolean observedReturnTaintedStatus = false;
if (returnTaintedStatusList.size() > paramIndex) {
observedReturnTaintedStatus = returnTaintedStatusList.get(paramIndex);
}
if (observedReturnTaintedStatus) {
// If return is tainted, but return is marked as untainted, overwrite the value.
if (hasAnnotation(param, ANNOTATION_UNTAINTED)) {
returnTaintedStatusList.set(paramIndex, false);
}
} else {
// If return is not tainted, but return is marked as tainted, overwrite the value.
if (hasAnnotation(param, ANNOTATION_TAINTED)) {
returnTaintedStatusList.set(paramIndex, true);
}
}
}
} else {
returnTaintedStatusList = new ArrayList<>();
}
}
use of org.wso2.carbon.apimgt.core.models.Function 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.carbon.apimgt.core.models.Function in project ballerina by ballerina-lang.
the class CodeAnalyzer method visitInvocable.
private void visitInvocable(BLangInvokableNode invNode) {
this.resetFunction();
this.initNewWorkerActionSystem();
if (Symbols.isNative(invNode.symbol)) {
return;
}
boolean invokableReturns = invNode.retParams.size() > 0;
if (invNode.workers.isEmpty()) {
invNode.body.accept(this);
/* the function returns, but none of the statements surely returns */
if (invokableReturns && !this.statementReturns) {
this.dlog.error(invNode.pos, DiagnosticCode.INVOKABLE_MUST_RETURN, invNode.getKind().toString().toLowerCase());
}
} else {
boolean workerReturns = false;
for (BLangWorker worker : invNode.workers) {
worker.accept(this);
workerReturns = workerReturns || this.statementReturns;
this.resetStatementReturns();
}
if (invokableReturns && !workerReturns) {
this.dlog.error(invNode.pos, DiagnosticCode.ATLEAST_ONE_WORKER_MUST_RETURN, invNode.getKind().toString().toLowerCase());
}
}
this.finalizeCurrentWorkerActionSystem();
}
use of org.wso2.carbon.apimgt.core.models.Function in project ballerina by ballerina-lang.
the class TypeChecker method checkInvocationParam.
private List<BType> checkInvocationParam(BLangInvocation iExpr) {
List<BType> paramTypes = ((BInvokableType) iExpr.symbol.type).getParameterTypes();
int requiredParamsCount;
if (iExpr.symbol.tag == SymTag.VARIABLE) {
// Here we assume function pointers can have only required params.
// And assume that named params and rest params are not supported.
requiredParamsCount = paramTypes.size();
} else {
requiredParamsCount = ((BInvokableSymbol) iExpr.symbol).params.size();
}
// Split the different argument types: required args, named args and rest args
int i = 0;
BLangExpression vararg = null;
for (BLangExpression expr : iExpr.argExprs) {
switch(expr.getKind()) {
case NAMED_ARGS_EXPR:
iExpr.namedArgs.add((BLangNamedArgsExpression) expr);
break;
case REST_ARGS_EXPR:
vararg = expr;
break;
default:
if (i < requiredParamsCount) {
iExpr.requiredArgs.add(expr);
} else {
iExpr.restArgs.add(expr);
}
i++;
break;
}
}
return checkInvocationArgs(iExpr, paramTypes, requiredParamsCount, vararg);
}
use of org.wso2.carbon.apimgt.core.models.Function in project ballerina by ballerina-lang.
the class TypeChecker method checkInvocationArgs.
private List<BType> checkInvocationArgs(BLangInvocation iExpr, List<BType> paramTypes, int requiredParamsCount, BLangExpression vararg) {
List<BType> actualTypes = getListWithErrorTypes(expTypes.size());
BInvokableSymbol invocableSymbol = (BInvokableSymbol) iExpr.symbol;
// Check whether the expected param count and the actual args counts are matching.
if (requiredParamsCount > iExpr.requiredArgs.size()) {
dlog.error(iExpr.pos, DiagnosticCode.NOT_ENOUGH_ARGS_FUNC_CALL, iExpr.name.value);
return actualTypes;
} else if (invocableSymbol.restParam == null && (vararg != null || !iExpr.restArgs.isEmpty())) {
dlog.error(iExpr.pos, DiagnosticCode.TOO_MANY_ARGS_FUNC_CALL, iExpr.name.value);
return actualTypes;
}
// formal parameters of the outer function.
if (iExpr.argExprs.size() == 1 && iExpr.argExprs.get(0).getKind() == NodeKind.INVOCATION) {
checkExpr(iExpr.requiredArgs.get(0), this.env, ((BInvokableType) invocableSymbol.type).paramTypes);
} else {
checkRequiredArgs(iExpr.requiredArgs, paramTypes);
}
checkNamedArgs(iExpr.namedArgs, invocableSymbol.defaultableParams);
checkRestArgs(iExpr.restArgs, vararg, invocableSymbol.restParam);
if (iExpr.async) {
return Arrays.asList(this.generateFutureType(invocableSymbol));
} else {
return invocableSymbol.type.getReturnTypes();
}
}
Aggregations