use of org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType 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.semantics.model.types.BTupleType 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.semantics.model.types.BTupleType in project ballerina by ballerina-lang.
the class IterableCodeDesugar method createIteratorResultVariables.
private List<BLangVariable> createIteratorResultVariables(IterableContext ctx, BLangVariable lastOperationArg, BLangFunction funcNode) {
List<BLangVariable> resultVariables = new ArrayList<>();
if (lastOperationArg.type.tag != TypeTags.TUPLE) {
resultVariables.add(lastOperationArg);
defineVariable(lastOperationArg, ctx.env.enclPkg.symbol.pkgID, funcNode);
return resultVariables;
}
final List<BType> tupleTypes = ((BTupleType) lastOperationArg.type).tupleTypes;
int index = 0;
for (BType type : tupleTypes) {
String varName = VAR_RESULT_VAL + index++;
final BLangVariable variable = ASTBuilderUtil.createVariable(funcNode.pos, varName, type);
resultVariables.add(variable);
defineVariable(variable, ctx.env.enclPkg.symbol.pkgID, funcNode);
}
return resultVariables;
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType in project ballerina by ballerina-lang.
the class TypeChecker method visit.
@Override
public void visit(BLangBracedOrTupleExpr bracedOrTupleExpr) {
// Handle Tuple Expression.
if (!expTypes.isEmpty() && expTypes.get(0).tag == TypeTags.TUPLE) {
BTupleType tupleType = (BTupleType) this.expTypes.get(0);
// Fix this.
List<BType> expTypes = getListWithErrorTypes(bracedOrTupleExpr.expressions.size());
if (tupleType.tupleTypes.size() != bracedOrTupleExpr.expressions.size()) {
dlog.error(bracedOrTupleExpr.pos, DiagnosticCode.SYNTAX_ERROR, "tuple and expression size does not match");
} else {
expTypes = tupleType.tupleTypes;
}
List<BType> results = new ArrayList<>();
for (int i = 0; i < bracedOrTupleExpr.expressions.size(); i++) {
results.add(checkExpr(bracedOrTupleExpr.expressions.get(i), env, Lists.of(expTypes.get(i))).get(0));
}
resultTypes = Lists.of(new BTupleType(results));
} else if (bracedOrTupleExpr.expressions.size() > 1) {
// This is a tuple.
List<BType> results = new ArrayList<>();
for (int i = 0; i < bracedOrTupleExpr.expressions.size(); i++) {
results.add(checkExpr(bracedOrTupleExpr.expressions.get(i), env, Lists.of(symTable.noType)).get(0));
}
resultTypes = Lists.of(new BTupleType(results));
} else {
// This is a braced expression.
bracedOrTupleExpr.isBracedExpr = true;
final BLangExpression expr = bracedOrTupleExpr.expressions.get(0);
final BType actualType = checkExpr(expr, env, Lists.of(symTable.noType)).get(0);
types.setImplicitCastExpr(expr, actualType, expTypes.get(0));
resultTypes = Lists.of(actualType);
}
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType in project ballerina by ballerina-lang.
the class IterableCodeDesugar method createForeachVariables.
/* Some Utils methods */
private List<BLangVariable> createForeachVariables(IterableContext ctx, BLangVariable firstOperationArg, BLangFunction funcNode) {
List<BLangVariable> foreachVariables = new ArrayList<>();
if (firstOperationArg.type.tag != TypeTags.TUPLE) {
foreachVariables.add(firstOperationArg);
defineVariable(firstOperationArg, ctx.env.enclPkg.symbol.pkgID, funcNode);
return foreachVariables;
}
final List<BType> tupleTypes = ((BTupleType) firstOperationArg.type).tupleTypes;
int index = 0;
for (BType type : tupleTypes) {
String varName = VAR_FOREACH_VAL + index++;
final BLangVariable variable = ASTBuilderUtil.createVariable(funcNode.pos, varName, type);
foreachVariables.add(variable);
defineVariable(variable, ctx.env.enclPkg.symbol.pkgID, funcNode);
}
return foreachVariables;
}
Aggregations