use of org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment 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.ballerinalang.compiler.tree.statements.BLangAssignment 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.statements.BLangAssignment 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);
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
public void visit(BLangAssignment assignNode) {
List<BLangExpression> lhrExprs = assignNode.varRefs;
if (assignNode.declaredWithVar) {
lhrExprs.stream().filter(lhsExr -> lhsExr.type.tag != TypeTags.NONE).map(lhsExr -> (BLangVariableReference) lhsExr).forEach(varRef -> {
visitVarSymbol(varRef.symbol, lvIndexes, localVarAttrInfo);
});
}
// Calculate the register indexes of lhs expressions.
int nLHSExpr = lhrExprs.size();
RegIndex[] regIndexes = new RegIndex[nLHSExpr];
for (int i = 0; i < nLHSExpr; i++) {
BLangExpression lExpr = lhrExprs.get(i);
if (lExpr.type.tag == TypeTags.NONE) {
continue;
}
if (lExpr.getKind() == NodeKind.SIMPLE_VARIABLE_REF && lExpr instanceof BLangLocalVarRef) {
lExpr.regIndex = ((BLangVariableReference) lExpr).symbol.varIndex;
regIndexes[i] = lExpr.regIndex;
}
}
// Set calculated reg indexes and visit rhs expression
BLangExpression rhsExpr = assignNode.expr;
rhsExpr.regIndex = regIndexes[0];
genNode(rhsExpr, this.env);
// Set the reg indexes generated by visiting rhs expression to lhs expression
regIndexes[0] = rhsExpr.regIndex;
for (int i = 0; i < lhrExprs.size(); i++) {
BLangExpression lExpr = lhrExprs.get(i);
if (lExpr.type.tag == TypeTags.NONE) {
continue;
}
if (lExpr.getKind() == NodeKind.SIMPLE_VARIABLE_REF && lExpr instanceof BLangLocalVarRef) {
continue;
}
varAssignment = true;
lExpr.regIndex = regIndexes[i];
genNode(lExpr, this.env);
varAssignment = false;
}
}
use of org.wso2.ballerinalang.compiler.tree.statements.BLangAssignment in project ballerina by ballerina-lang.
the class ASTBuilderUtil method createAssignmentStmt.
static BLangAssignment createAssignmentStmt(DiagnosticPos pos, BLangBlockStmt target) {
final BLangAssignment assignment = (BLangAssignment) TreeBuilder.createAssignmentNode();
assignment.pos = pos;
target.addStatement(assignment);
return assignment;
}
Aggregations