use of org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference in project ballerina by ballerina-lang.
the class TaintAnalyzer method visitAssignment.
private void visitAssignment(BLangExpression varRefExpr, boolean varTaintedStatus, DiagnosticPos pos) {
// Generate error if a global variable has been assigned with a tainted value.
if (varTaintedStatus && varRefExpr instanceof BLangVariableReference) {
BLangVariableReference varRef = (BLangVariableReference) varRefExpr;
if (varRef.symbol != null && varRef.symbol.owner != null) {
if (varRef.symbol.owner instanceof BPackageSymbol || SymbolKind.SERVICE.equals(varRef.symbol.owner.kind) || SymbolKind.CONNECTOR.equals(varRef.symbol.owner.kind)) {
addTaintError(pos, varRef.symbol.name.value, DiagnosticCode.TAINTED_VALUE_PASSED_TO_GLOBAL_VARIABLE);
return;
}
}
}
// TODO: Re-evaluating the full data-set (array) when a change occur.
if (varRefExpr instanceof BLangIndexBasedAccess) {
nonOverridingAnalysis = true;
updatedVarRefTaintedState((BLangIndexBasedAccess) varRefExpr, varTaintedStatus);
nonOverridingAnalysis = false;
} else if (varRefExpr instanceof BLangFieldBasedAccess) {
BLangFieldBasedAccess fieldBasedAccessExpr = (BLangFieldBasedAccess) varRefExpr;
// Propagate tainted status to fields, when field symbols are present (Example: structs).
if (fieldBasedAccessExpr.symbol != null) {
setTaintedStatus(fieldBasedAccessExpr, varTaintedStatus);
}
nonOverridingAnalysis = true;
updatedVarRefTaintedState(fieldBasedAccessExpr, varTaintedStatus);
nonOverridingAnalysis = false;
} else {
BLangVariableReference varRef = (BLangVariableReference) varRefExpr;
setTaintedStatus(varRef, varTaintedStatus);
}
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference in project ballerina by ballerina-lang.
the class TaintAnalyzer method visit.
public void visit(BLangForeach foreach) {
SymbolEnv blockEnv = SymbolEnv.createBlockEnv(foreach.body, env);
// Propagate the tainted status of collection to foreach variables.
foreach.collection.accept(this);
if (getObservedTaintedStatus()) {
foreach.varRefs.forEach(varRef -> setTaintedStatus((BLangVariableReference) varRef, getObservedTaintedStatus()));
}
analyzeNode(foreach.body, blockEnv);
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangFieldBasedAccess fieldAccessExpr) {
VariableReferenceNode variableReferenceNode = fieldAccessExpr.getExpression();
((BLangVariableReference) variableReferenceNode).accept(this);
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference 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);
}
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangAssignment assignNode) {
if (assignNode.isDeclaredWithVar()) {
handleAssignNodeWithVar(assignNode);
return;
}
// Check each LHS expression.
List<BType> expTypes = new ArrayList<>();
for (BLangExpression expr : assignNode.varRefs) {
// In assignment, lhs supports only simpleVarRef, indexBasedAccess, filedBasedAccess expressions.
if (expr.getKind() != NodeKind.SIMPLE_VARIABLE_REF && expr.getKind() != NodeKind.INDEX_BASED_ACCESS_EXPR && expr.getKind() != NodeKind.FIELD_BASED_ACCESS_EXPR && expr.getKind() != NodeKind.XML_ATTRIBUTE_ACCESS_EXPR) {
dlog.error(expr.pos, DiagnosticCode.INVALID_VARIABLE_ASSIGNMENT, expr);
expTypes.add(symTable.errType);
continue;
}
// Evaluate the variable reference expression.
BLangVariableReference varRef = (BLangVariableReference) expr;
varRef.lhsVar = true;
typeChecker.checkExpr(varRef, env);
// Check whether we've got an enumerator access expression here.
if (varRef.getKind() == NodeKind.FIELD_BASED_ACCESS_EXPR && ((BLangFieldBasedAccess) varRef).expr.type.tag == TypeTags.ENUM) {
dlog.error(varRef.pos, DiagnosticCode.INVALID_VARIABLE_ASSIGNMENT, varRef);
expTypes.add(symTable.errType);
continue;
}
expTypes.add(varRef.type);
checkConstantAssignment(varRef);
}
if (assignNode.getKind() == NodeKind.TUPLE_DESTRUCTURE) {
BTupleType tupleType = new BTupleType(expTypes);
expTypes = Lists.of(tupleType);
}
if (!assignNode.safeAssignment) {
typeChecker.checkExpr(assignNode.expr, this.env, expTypes);
return;
}
// Assume that there is only one variable reference in LHS
// Continue the validate if this is a safe assignment operator
handleSafeAssignment(assignNode.pos, assignNode.varRefs.get(0).type, assignNode.expr, this.env);
}
Aggregations