Search in sources :

Example 1 with BLangFieldBasedAccess

use of org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess 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);
    }
}
Also used : BLangIndexBasedAccess(org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess) BPackageSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol) BLangFieldBasedAccess(org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess) BLangVariableReference(org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference)

Example 2 with BLangFieldBasedAccess

use of org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess in project ballerina by ballerina-lang.

the class SemanticAnalyzer method visit.

public void visit(BLangFieldBasedAccess fieldAccessExpr) {
    VariableReferenceNode variableReferenceNode = fieldAccessExpr.getExpression();
    ((BLangVariableReference) variableReferenceNode).accept(this);
}
Also used : BLangVariableReference(org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference) VariableReferenceNode(org.ballerinalang.model.tree.expressions.VariableReferenceNode)

Example 3 with BLangFieldBasedAccess

use of org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess 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);
}
Also used : BLangFieldBasedAccess(org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BLangVariableReference(org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference) ArrayList(java.util.ArrayList) BTupleType(org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)

Example 4 with BLangFieldBasedAccess

use of org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess in project ballerina by ballerina-lang.

the class TypeChecker method visit.

public void visit(BLangFieldBasedAccess fieldAccessExpr) {
    // First analyze the variable reference expression.
    BType actualType = symTable.errType;
    BType varRefType = getTypeOfExprInFieldAccess(fieldAccessExpr.expr);
    if (fieldAccessExpr.fieldType == FieldType.ALL && varRefType.tag != TypeTags.XML) {
        dlog.error(fieldAccessExpr.pos, DiagnosticCode.CANNOT_GET_ALL_FIELDS, varRefType);
    }
    Name fieldName = names.fromIdNode(fieldAccessExpr.field);
    switch(varRefType.tag) {
        case TypeTags.STRUCT:
            actualType = checkStructFieldAccess(fieldAccessExpr, fieldName, varRefType);
            break;
        case TypeTags.MAP:
            actualType = ((BMapType) varRefType).getConstraint();
            break;
        case TypeTags.JSON:
            BType constraintType = ((BJSONType) varRefType).constraint;
            if (constraintType.tag == TypeTags.STRUCT) {
                BType fieldType = checkStructFieldAccess(fieldAccessExpr, fieldName, constraintType);
                // If the type of the field is struct, treat it as constraint JSON type.
                if (fieldType.tag == TypeTags.STRUCT) {
                    actualType = new BJSONType(TypeTags.JSON, fieldType, symTable.jsonType.tsymbol);
                    break;
                }
            }
            actualType = symTable.jsonType;
            break;
        case TypeTags.ENUM:
            // Enumerator access expressions only allow enum type name as the first part e.g state.INSTALLED,
            BEnumType enumType = (BEnumType) varRefType;
            if (fieldAccessExpr.expr.getKind() != NodeKind.SIMPLE_VARIABLE_REF || !((BLangSimpleVarRef) fieldAccessExpr.expr).variableName.value.equals(enumType.tsymbol.name.value)) {
                dlog.error(fieldAccessExpr.pos, DiagnosticCode.INVALID_ENUM_EXPR, enumType.tsymbol.name.value);
                break;
            }
            BSymbol symbol = symResolver.lookupMemberSymbol(fieldAccessExpr.pos, enumType.tsymbol.scope, this.env, fieldName, SymTag.VARIABLE);
            if (symbol == symTable.notFoundSymbol) {
                dlog.error(fieldAccessExpr.pos, DiagnosticCode.UNDEFINED_SYMBOL, fieldName.value);
                break;
            }
            fieldAccessExpr.symbol = (BVarSymbol) symbol;
            actualType = fieldAccessExpr.expr.type;
            break;
        case TypeTags.XML:
            if (fieldAccessExpr.lhsVar) {
                dlog.error(fieldAccessExpr.pos, DiagnosticCode.CANNOT_UPDATE_XML_SEQUENCE);
                break;
            }
            actualType = symTable.xmlType;
            break;
        case TypeTags.ERROR:
            // Do nothing
            break;
        default:
            dlog.error(fieldAccessExpr.pos, DiagnosticCode.OPERATION_DOES_NOT_SUPPORT_FIELD_ACCESS, varRefType);
    }
    resultTypes = types.checkTypes(fieldAccessExpr, Lists.of(actualType), this.expTypes);
}
Also used : BLangSimpleVarRef(org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef) BSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BJSONType(org.wso2.ballerinalang.compiler.semantics.model.types.BJSONType) BLangXMLQName(org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQName) Name(org.wso2.ballerinalang.compiler.util.Name) BEnumType(org.wso2.ballerinalang.compiler.semantics.model.types.BEnumType)

Example 5 with BLangFieldBasedAccess

use of org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess in project ballerina by ballerina-lang.

the class Desugar method visit.

@Override
public void visit(BLangFieldBasedAccess fieldAccessExpr) {
    BLangVariableReference targetVarRef = fieldAccessExpr;
    if (fieldAccessExpr.expr.type.tag == TypeTags.ENUM) {
        targetVarRef = new BLangEnumeratorAccessExpr(fieldAccessExpr.pos, fieldAccessExpr.field, fieldAccessExpr.symbol);
    } else {
        fieldAccessExpr.expr = rewriteExpr(fieldAccessExpr.expr);
        BType varRefType = fieldAccessExpr.expr.type;
        if (varRefType.tag == TypeTags.STRUCT) {
            targetVarRef = new BLangStructFieldAccessExpr(fieldAccessExpr.pos, fieldAccessExpr.expr, fieldAccessExpr.symbol);
        } else if (varRefType.tag == TypeTags.MAP) {
            BLangLiteral stringLit = createStringLiteral(fieldAccessExpr.pos, fieldAccessExpr.field.value);
            targetVarRef = new BLangMapAccessExpr(fieldAccessExpr.pos, fieldAccessExpr.expr, stringLit);
        } else if (varRefType.tag == TypeTags.JSON) {
            BLangLiteral stringLit = createStringLiteral(fieldAccessExpr.pos, fieldAccessExpr.field.value);
            targetVarRef = new BLangJSONAccessExpr(fieldAccessExpr.pos, fieldAccessExpr.expr, stringLit);
        } else if (varRefType.tag == TypeTags.XML) {
            BLangLiteral stringLit = createStringLiteral(fieldAccessExpr.pos, fieldAccessExpr.field.value);
            targetVarRef = new BLangXMLAccessExpr(fieldAccessExpr.pos, fieldAccessExpr.expr, stringLit, fieldAccessExpr.fieldType);
        }
    }
    targetVarRef.lhsVar = fieldAccessExpr.lhsVar;
    targetVarRef.type = fieldAccessExpr.type;
    result = targetVarRef;
}
Also used : BLangStructFieldAccessExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess.BLangStructFieldAccessExpr) BLangLiteral(org.wso2.ballerinalang.compiler.tree.expressions.BLangLiteral) BLangEnumeratorAccessExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess.BLangEnumeratorAccessExpr) BLangVariableReference(org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BLangMapAccessExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess.BLangMapAccessExpr) BLangXMLAccessExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess.BLangXMLAccessExpr) BLangJSONAccessExpr(org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess.BLangJSONAccessExpr)

Aggregations

BLangFieldBasedAccess (org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess)5 BLangVariableReference (org.wso2.ballerinalang.compiler.tree.expressions.BLangVariableReference)5 BLangSimpleVarRef (org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef)4 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)3 BLangIndexBasedAccess (org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess)3 ArrayList (java.util.ArrayList)1 VariableReferenceNode (org.ballerinalang.model.tree.expressions.VariableReferenceNode)1 BPackageSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol)1 BSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol)1 BEnumType (org.wso2.ballerinalang.compiler.semantics.model.types.BEnumType)1 BJSONType (org.wso2.ballerinalang.compiler.semantics.model.types.BJSONType)1 BTupleType (org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType)1 BLangExpression (org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)1 BLangEnumeratorAccessExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess.BLangEnumeratorAccessExpr)1 BLangStructFieldAccessExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess.BLangStructFieldAccessExpr)1 BLangJSONAccessExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess.BLangJSONAccessExpr)1 BLangMapAccessExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess.BLangMapAccessExpr)1 BLangXMLAccessExpr (org.wso2.ballerinalang.compiler.tree.expressions.BLangIndexBasedAccess.BLangXMLAccessExpr)1 BFunctionPointerInvocation (org.wso2.ballerinalang.compiler.tree.expressions.BLangInvocation.BFunctionPointerInvocation)1 BLangLiteral (org.wso2.ballerinalang.compiler.tree.expressions.BLangLiteral)1