use of org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression in project ballerina by ballerina-lang.
the class SemanticAnalyzer method handleSafeAssignment.
private void handleSafeAssignment(DiagnosticPos lhsPos, BType lhsType, BLangExpression rhsExpr, SymbolEnv env) {
// Collect all the lhs types
Set<BType> lhsTypes = lhsType.tag == TypeTags.UNION ? ((BUnionType) lhsType).memberTypes : new HashSet<BType>() {
{
add(lhsType);
}
};
// If there is at least one lhs type which assignable to the error type, then report an error.
for (BType type : lhsTypes) {
if (types.isAssignable(symTable.errStructType, type)) {
dlog.error(lhsPos, DiagnosticCode.SAFE_ASSIGN_STMT_INVALID_USAGE);
typeChecker.checkExpr(rhsExpr, env, Lists.of(symTable.errType));
return;
}
}
// Create a new union type with the error type and continue the type checking process.
lhsTypes.add(symTable.errStructType);
BUnionType lhsUnionType = new BUnionType(null, lhsTypes, lhsTypes.contains(symTable.nullType));
typeChecker.checkExpr(rhsExpr, env, Lists.of(lhsUnionType));
if (rhsExpr.type.tag == TypeTags.UNION) {
BUnionType rhsUnionType = (BUnionType) rhsExpr.type;
for (BType type : rhsUnionType.memberTypes) {
if (types.isAssignable(symTable.errStructType, type)) {
return;
}
}
} else if (rhsExpr.type.tag != TypeTags.ERROR) {
dlog.error(rhsExpr.pos, DiagnosticCode.SAFE_ASSIGN_STMT_INVALID_USAGE);
}
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangVariable varNode) {
int ownerSymTag = env.scope.owner.tag;
if ((ownerSymTag & SymTag.INVOKABLE) == SymTag.INVOKABLE) {
// If the variable is parameter then the variable symbol is already defined
if (varNode.symbol == null) {
symbolEnter.defineNode(varNode, env);
}
}
BType lhsType = varNode.symbol.type;
varNode.type = lhsType;
// Here we validate annotation attachments for package level variables.
varNode.annAttachments.forEach(a -> {
a.attachmentPoint = new BLangAnnotationAttachmentPoint(BLangAnnotationAttachmentPoint.AttachmentPoint.CONST);
a.accept(this);
});
// Here we validate document attachments for package level variables.
varNode.docAttachments.forEach(doc -> {
doc.accept(this);
});
// Analyze the init expression
BLangExpression rhsExpr = varNode.expr;
if (rhsExpr == null) {
return;
}
// Here we create a new symbol environment to catch self references by keep the current
// variable symbol in the symbol environment
// e.g. int a = x + a;
SymbolEnv varInitEnv = SymbolEnv.createVarInitEnv(varNode, env, varNode.symbol);
// It will we done during the init-function of the respective construct is visited.
if ((ownerSymTag & SymTag.PACKAGE) == SymTag.PACKAGE || (ownerSymTag & SymTag.SERVICE) == SymTag.SERVICE || (ownerSymTag & SymTag.CONNECTOR) == SymTag.CONNECTOR) {
return;
}
// Return if this not a safe assignment
if (!varNode.safeAssignment) {
typeChecker.checkExpr(rhsExpr, varInitEnv, Lists.of(lhsType));
return;
}
handleSafeAssignment(varNode.pos, lhsType, rhsExpr, varInitEnv);
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangCompoundAssignment compoundAssignment) {
List<BType> expTypes = new ArrayList<>();
BLangExpression varRef = compoundAssignment.varRef;
if (varRef.getKind() != NodeKind.SIMPLE_VARIABLE_REF && varRef.getKind() != NodeKind.INDEX_BASED_ACCESS_EXPR && varRef.getKind() != NodeKind.FIELD_BASED_ACCESS_EXPR && varRef.getKind() != NodeKind.XML_ATTRIBUTE_ACCESS_EXPR) {
dlog.error(varRef.pos, DiagnosticCode.INVALID_VARIABLE_ASSIGNMENT, varRef);
expTypes.add(symTable.errType);
} else {
this.typeChecker.checkExpr(varRef, env).get(0);
expTypes.add(varRef.type);
}
this.typeChecker.checkExpr(compoundAssignment.expr, env).get(0);
if (expTypes.get(0) != symTable.errType && compoundAssignment.expr.type != symTable.errType) {
BSymbol opSymbol = this.symResolver.resolveBinaryOperator(compoundAssignment.opKind, expTypes.get(0), compoundAssignment.expr.type);
if (opSymbol == symTable.notFoundSymbol) {
dlog.error(compoundAssignment.pos, DiagnosticCode.BINARY_OP_INCOMPATIBLE_TYPES, compoundAssignment.opKind, expTypes.get(0), compoundAssignment.expr.type);
} else {
compoundAssignment.modifiedExpr = getBinaryExpr(varRef, compoundAssignment.expr, compoundAssignment.opKind, opSymbol);
this.types.checkTypes(compoundAssignment.modifiedExpr, Lists.of(compoundAssignment.modifiedExpr.type), expTypes);
}
}
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangStreamingInput streamingInput) {
BLangExpression streamRef = (BLangExpression) streamingInput.getStreamReference();
typeChecker.checkExpr(streamRef, env);
WhereNode beforeWhereNode = streamingInput.getBeforeStreamingCondition();
if (beforeWhereNode != null) {
((BLangWhere) beforeWhereNode).accept(this);
}
WindowClauseNode windowClauseNode = streamingInput.getWindowClause();
if (windowClauseNode != null) {
((BLangWindow) windowClauseNode).accept(this);
}
WhereNode afterWhereNode = streamingInput.getAfterStreamingCondition();
if (afterWhereNode != null) {
((BLangWhere) afterWhereNode).accept(this);
}
}
use of org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangPostIncrement postIncrement) {
BLangExpression varRef = postIncrement.varRef;
if (varRef.getKind() != NodeKind.SIMPLE_VARIABLE_REF && varRef.getKind() != NodeKind.INDEX_BASED_ACCESS_EXPR && varRef.getKind() != NodeKind.FIELD_BASED_ACCESS_EXPR && varRef.getKind() != NodeKind.XML_ATTRIBUTE_ACCESS_EXPR) {
if (postIncrement.opKind == OperatorKind.ADD) {
dlog.error(varRef.pos, DiagnosticCode.OPERATOR_NOT_ALLOWED_VARIABLE, OperatorKind.INCREMENT, varRef);
} else {
dlog.error(varRef.pos, DiagnosticCode.OPERATOR_NOT_ALLOWED_VARIABLE, OperatorKind.DECREMENT, varRef);
}
return;
} else {
this.typeChecker.checkExpr(varRef, env).get(0);
}
this.typeChecker.checkExpr(postIncrement.increment, env).get(0);
if (varRef.type == symTable.intType || varRef.type == symTable.floatType) {
BSymbol opSymbol = this.symResolver.resolveBinaryOperator(postIncrement.opKind, varRef.type, postIncrement.increment.type);
postIncrement.modifiedExpr = getBinaryExpr(varRef, postIncrement.increment, postIncrement.opKind, opSymbol);
} else {
if (postIncrement.opKind == OperatorKind.ADD) {
dlog.error(varRef.pos, DiagnosticCode.OPERATOR_NOT_SUPPORTED, OperatorKind.INCREMENT, varRef.type);
} else {
dlog.error(varRef.pos, DiagnosticCode.OPERATOR_NOT_SUPPORTED, OperatorKind.DECREMENT, varRef.type);
}
}
}
Aggregations