Search in sources :

Example 51 with Function

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<>();
    }
}
Also used : BLangEndpoint(org.wso2.ballerinalang.compiler.tree.BLangEndpoint) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable)

Example 52 with Function

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.
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BLangXMLQName(org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQName) Name(org.wso2.ballerinalang.compiler.util.Name)

Example 53 with Function

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();
}
Also used : BLangWorker(org.wso2.ballerinalang.compiler.tree.BLangWorker)

Example 54 with Function

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);
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol) BInvokableType(org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)

Example 55 with Function

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();
    }
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BInvokableSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)

Aggregations

Test (org.testng.annotations.Test)94 HTTPCarbonMessage (org.wso2.transport.http.netty.message.HTTPCarbonMessage)49 HTTPTestRequest (org.ballerinalang.test.services.testutils.HTTPTestRequest)44 HttpMessageDataStreamer (org.wso2.transport.http.netty.message.HttpMessageDataStreamer)39 ArrayList (java.util.ArrayList)37 BLangFunction (org.wso2.ballerinalang.compiler.tree.BLangFunction)35 BString (org.ballerinalang.model.values.BString)30 BLangPackage (org.wso2.ballerinalang.compiler.tree.BLangPackage)29 BLangEndpoint (org.wso2.ballerinalang.compiler.tree.BLangEndpoint)26 BLangVariable (org.wso2.ballerinalang.compiler.tree.BLangVariable)25 BInvokableSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol)20 BSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol)20 BJSON (org.ballerinalang.model.values.BJSON)19 BLangExpression (org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)19 List (java.util.List)18 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)18 BLangStruct (org.wso2.ballerinalang.compiler.tree.BLangStruct)16 BStructSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)15 BPackageSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol)14 BLangSimpleVarRef (org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef)14