use of org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation in project ballerina by ballerina-lang.
the class SymbolEnter method createInitFuncInvocationStmt.
private BLangExpressionStmt createInitFuncInvocationStmt(BLangImportPackage importPackage, BInvokableSymbol initFunctionSymbol) {
BLangInvocation invocationNode = (BLangInvocation) TreeBuilder.createInvocationNode();
invocationNode.pos = importPackage.pos;
invocationNode.addWS(importPackage.getWS());
BLangIdentifier funcName = (BLangIdentifier) TreeBuilder.createIdentifierNode();
funcName.value = initFunctionSymbol.name.value;
invocationNode.name = funcName;
invocationNode.pkgAlias = importPackage.alias;
BLangExpressionStmt exprStmt = (BLangExpressionStmt) TreeBuilder.createExpressionStatementNode();
exprStmt.pos = importPackage.pos;
exprStmt.addWS(importPackage.getWS());
exprStmt.expr = invocationNode;
return exprStmt;
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation in project ballerina by ballerina-lang.
the class TaintAnalyzer method analyzeInvocation.
// Private methods relevant to invocation analysis.
private void analyzeInvocation(BLangInvocation invocationExpr) {
BInvokableSymbol invokableSymbol = (BInvokableSymbol) invocationExpr.symbol;
Map<Integer, TaintRecord> taintTable = invokableSymbol.taintTable;
List<Boolean> returnTaintedStatus = new ArrayList<>();
TaintRecord allParamsUntaintedRecord = taintTable.get(ALL_UNTAINTED_TABLE_ENTRY_INDEX);
if (allParamsUntaintedRecord.taintError != null && allParamsUntaintedRecord.taintError.size() > 0) {
// This can occur when there is a error regardless of tainted status of parameters.
// Example: Tainted value returned by function is passed to another functions's sensitive parameter.
addTaintError(allParamsUntaintedRecord.taintError);
} else {
returnTaintedStatus = new ArrayList<>(taintTable.get(ALL_UNTAINTED_TABLE_ENTRY_INDEX).retParamTaintedStatus);
}
if (invocationExpr.argExprs != null) {
for (int argIndex = 0; argIndex < invocationExpr.argExprs.size(); argIndex++) {
BLangExpression argExpr = invocationExpr.argExprs.get(argIndex);
argExpr.accept(this);
// return-tainted-status when the given argument is in tainted state.
if (getObservedTaintedStatus()) {
TaintRecord taintRecord = taintTable.get(argIndex);
if (taintRecord == null) {
// This is when current parameter is "sensitive". Therefore, providing a tainted
// value to a sensitive parameter is invalid and should return a compiler error.
int requiredParamCount = invokableSymbol.params.size();
int defaultableParamCount = invokableSymbol.defaultableParams.size();
int totalParamCount = requiredParamCount + defaultableParamCount + (invokableSymbol.restParam == null ? 0 : 1);
BVarSymbol paramSymbol = getParamSymbol(invokableSymbol, argIndex, requiredParamCount, defaultableParamCount);
addTaintError(argExpr.pos, paramSymbol.name.value, DiagnosticCode.TAINTED_VALUE_PASSED_TO_SENSITIVE_PARAMETER);
} else if (taintRecord.taintError != null && taintRecord.taintError.size() > 0) {
// This is when current parameter is derived to be sensitive. The error already generated
// during taint-table generation will be used.
addTaintError(taintRecord.taintError);
} else {
// status of all returns to get accumulated tainted status of all returns for the invocation.
for (int returnIndex = 0; returnIndex < returnTaintedStatus.size(); returnIndex++) {
if (taintRecord.retParamTaintedStatus.get(returnIndex)) {
returnTaintedStatus.set(returnIndex, true);
}
}
}
if (stopAnalysis) {
break;
}
}
}
}
if (invocationExpr.expr != null) {
// When an invocation like stringValue.trim() happens, if stringValue is tainted, the result will
// also be tainted.
// TODO: TaintedIf annotation, so that it's possible to define what can taint or untaint the return.
invocationExpr.expr.accept(this);
for (int i = 0; i < returnTaintedStatus.size(); i++) {
if (getObservedTaintedStatus()) {
returnTaintedStatus.set(i, getObservedTaintedStatus());
}
}
}
taintedStatusList = returnTaintedStatus;
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation in project ballerina by ballerina-lang.
the class TaintAnalyzer method analyzeLambdaExpressions.
private void analyzeLambdaExpressions(BLangInvocation invocationExpr, BLangExpression argExpr) {
BLangFunction function = ((BLangLambdaFunction) argExpr).function;
if (function.symbol.taintTable == null) {
addToBlockedList(invocationExpr);
} else {
int requiredParamCount = function.requiredParams.size();
int defaultableParamCount = function.defaultableParams.size();
int totalParamCount = requiredParamCount + defaultableParamCount + (function.restParam == null ? 0 : 1);
Map<Integer, TaintRecord> taintTable = function.symbol.taintTable;
for (int paramIndex = 0; paramIndex < totalParamCount; paramIndex++) {
TaintRecord taintRecord = taintTable.get(paramIndex);
BLangVariable param = getParam(function, paramIndex, requiredParamCount, defaultableParamCount);
if (taintRecord == null) {
addTaintError(argExpr.pos, param.name.value, DiagnosticCode.TAINTED_VALUE_PASSED_TO_SENSITIVE_PARAMETER);
} else if (taintRecord.taintError != null && taintRecord.taintError.size() > 0) {
addTaintError(taintRecord.taintError);
}
if (stopAnalysis) {
break;
}
}
}
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation 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.ballerinalang.compiler.tree.expressions.BLangInvocation in project ballerina by ballerina-lang.
the class CodeAnalyzer method visit.
public void visit(BLangInvocation invocationExpr) {
analyzeExpr(invocationExpr.expr);
analyzeExprs(invocationExpr.requiredArgs);
analyzeExprs(invocationExpr.namedArgs);
analyzeExprs(invocationExpr.restArgs);
checkDuplicateNamedArgs(invocationExpr.namedArgs);
// Null check is to ignore Negative path where symbol does not get resolved at TypeChecker.
if ((invocationExpr.symbol != null) && invocationExpr.symbol.kind == SymbolKind.FUNCTION) {
BSymbol funcSymbol = invocationExpr.symbol;
if (Symbols.isFlagOn(funcSymbol.flags, Flags.DEPRECATED)) {
dlog.warning(invocationExpr.pos, DiagnosticCode.USAGE_OF_DEPRECATED_FUNCTION, names.fromIdNode(invocationExpr.name));
}
}
}
Aggregations