Search in sources :

Example 1 with FieldType

use of org.wso2.ballerinalang.compiler.util.FieldType 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 2 with FieldType

use of org.wso2.ballerinalang.compiler.util.FieldType in project ballerina by ballerina-lang.

the class TypeChecker method visit.

public void visit(BLangIndexBasedAccess indexBasedAccessExpr) {
    BType actualType = symTable.errType;
    // First analyze the variable reference expression.
    checkExpr(indexBasedAccessExpr.expr, this.env, Lists.of(symTable.noType));
    BType indexExprType;
    BType varRefType = indexBasedAccessExpr.expr.type;
    BLangExpression indexExpr = indexBasedAccessExpr.indexExpr;
    switch(varRefType.tag) {
        case TypeTags.STRUCT:
            indexExprType = checkIndexExprForStructFieldAccess(indexExpr);
            if (indexExprType.tag == TypeTags.STRING) {
                String fieldName = (String) ((BLangLiteral) indexExpr).value;
                actualType = checkStructFieldAccess(indexBasedAccessExpr, names.fromString(fieldName), varRefType);
            }
            break;
        case TypeTags.MAP:
            indexExprType = checkExpr(indexExpr, this.env, Lists.of(symTable.stringType)).get(0);
            if (indexExprType.tag == TypeTags.STRING) {
                actualType = ((BMapType) varRefType).getConstraint();
            }
            break;
        case TypeTags.JSON:
            BType constraintType = ((BJSONType) varRefType).constraint;
            if (constraintType.tag == TypeTags.STRUCT) {
                indexExprType = checkIndexExprForStructFieldAccess(indexExpr);
                if (indexExprType.tag != TypeTags.STRING) {
                    break;
                }
                String fieldName = (String) ((BLangLiteral) indexExpr).value;
                BType fieldType = checkStructFieldAccess(indexBasedAccessExpr, names.fromString(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;
                }
            } else {
                indexExprType = checkExpr(indexExpr, this.env, Lists.of(symTable.noType)).get(0);
                if (indexExprType.tag != TypeTags.STRING && indexExprType.tag != TypeTags.INT) {
                    dlog.error(indexExpr.pos, DiagnosticCode.INCOMPATIBLE_TYPES, symTable.stringType, indexExprType);
                    break;
                }
            }
            actualType = symTable.jsonType;
            break;
        case TypeTags.ARRAY:
            indexExprType = checkExpr(indexExpr, this.env, Lists.of(symTable.intType)).get(0);
            if (indexExprType.tag == TypeTags.INT) {
                actualType = ((BArrayType) varRefType).getElementType();
            }
            break;
        case TypeTags.XML:
            if (indexBasedAccessExpr.lhsVar) {
                dlog.error(indexBasedAccessExpr.pos, DiagnosticCode.CANNOT_UPDATE_XML_SEQUENCE);
                break;
            }
            checkExpr(indexExpr, this.env).get(0);
            actualType = symTable.xmlType;
            break;
        case TypeTags.ERROR:
            // Do nothing
            break;
        default:
            dlog.error(indexBasedAccessExpr.pos, DiagnosticCode.OPERATION_DOES_NOT_SUPPORT_INDEXING, indexBasedAccessExpr.expr.type);
    }
    resultTypes = types.checkTypes(indexBasedAccessExpr, Lists.of(actualType), this.expTypes);
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BJSONType(org.wso2.ballerinalang.compiler.semantics.model.types.BJSONType) BLangXMLQuotedString(org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQuotedString) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)

Example 3 with FieldType

use of org.wso2.ballerinalang.compiler.util.FieldType in project ballerina by ballerina-lang.

the class BLangPackageBuilder method createFieldBasedAccessNode.

public void createFieldBasedAccessNode(DiagnosticPos pos, Set<Whitespace> ws, String fieldName, FieldType fieldType) {
    BLangFieldBasedAccess fieldBasedAccess = (BLangFieldBasedAccess) TreeBuilder.createFieldBasedAccessNode();
    fieldBasedAccess.pos = pos;
    fieldBasedAccess.addWS(ws);
    fieldBasedAccess.field = (BLangIdentifier) createIdentifier(fieldName);
    fieldBasedAccess.expr = (BLangVariableReference) exprNodeStack.pop();
    fieldBasedAccess.fieldType = fieldType;
    addExpressionNode(fieldBasedAccess);
}
Also used : BLangFieldBasedAccess(org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess)

Example 4 with FieldType

use of org.wso2.ballerinalang.compiler.util.FieldType in project ballerina by ballerina-lang.

the class BLangParserListener method exitFieldVariableReference.

@Override
public void exitFieldVariableReference(BallerinaParser.FieldVariableReferenceContext ctx) {
    if (ctx.exception != null) {
        return;
    }
    FieldContext field = ctx.field();
    String fieldName;
    FieldType fieldType;
    if (field.Identifier() != null) {
        fieldName = field.Identifier().getText();
        fieldType = FieldType.SINGLE;
    } else {
        fieldName = field.MUL().getText();
        fieldType = FieldType.ALL;
    }
    this.pkgBuilder.createFieldBasedAccessNode(getCurrentPos(ctx), getWS(ctx), fieldName, fieldType);
}
Also used : FieldContext(org.wso2.ballerinalang.compiler.parser.antlr4.BallerinaParser.FieldContext) FieldType(org.wso2.ballerinalang.compiler.util.FieldType)

Example 5 with FieldType

use of org.wso2.ballerinalang.compiler.util.FieldType in project ballerina by ballerina-lang.

the class TypeChecker method checkRecLiteralKeyValue.

private void checkRecLiteralKeyValue(BLangRecordKeyValue keyValuePair, BType recType) {
    BType fieldType = symTable.errType;
    BLangExpression valueExpr = keyValuePair.valueExpr;
    switch(recType.tag) {
        case TypeTags.STRUCT:
            fieldType = checkStructLiteralKeyExpr(keyValuePair.key, recType, RecordKind.STRUCT);
            break;
        case TypeTags.MAP:
            fieldType = checkMapLiteralKeyExpr(keyValuePair.key.expr, recType, RecordKind.MAP);
            break;
        case TypeTags.JSON:
            fieldType = checkJSONLiteralKeyExpr(keyValuePair.key, recType, RecordKind.JSON);
            // If the field is again a struct, treat that literal expression as another constraint JSON.
            if (fieldType.tag == TypeTags.STRUCT) {
                fieldType = new BJSONType(TypeTags.JSON, fieldType, symTable.jsonType.tsymbol);
            }
            // First visit the expression having field type, as the expected type.
            checkExpr(valueExpr, this.env, Lists.of(fieldType));
            // Again check the type compatibility with JSON
            if (valueExpr.impConversionExpr == null) {
                types.checkTypes(valueExpr, Lists.of(valueExpr.type), Lists.of(symTable.jsonType));
            } else {
                BType valueType = valueExpr.type;
                types.checkTypes(valueExpr, valueExpr.impConversionExpr.types, Lists.of(symTable.jsonType));
                valueExpr.type = valueType;
            }
            resultTypes = Lists.of(valueExpr.type);
            return;
    }
    checkExpr(valueExpr, this.env, Lists.of(fieldType));
}
Also used : BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType) BJSONType(org.wso2.ballerinalang.compiler.semantics.model.types.BJSONType) BLangExpression(org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)

Aggregations

BJSONType (org.wso2.ballerinalang.compiler.semantics.model.types.BJSONType)3 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)3 BLangExpression (org.wso2.ballerinalang.compiler.tree.expressions.BLangExpression)2 FieldContext (org.wso2.ballerinalang.compiler.parser.antlr4.BallerinaParser.FieldContext)1 BSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol)1 BEnumType (org.wso2.ballerinalang.compiler.semantics.model.types.BEnumType)1 BLangFieldBasedAccess (org.wso2.ballerinalang.compiler.tree.expressions.BLangFieldBasedAccess)1 BLangSimpleVarRef (org.wso2.ballerinalang.compiler.tree.expressions.BLangSimpleVarRef)1 BLangXMLQName (org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQName)1 BLangXMLQuotedString (org.wso2.ballerinalang.compiler.tree.expressions.BLangXMLQuotedString)1 FieldType (org.wso2.ballerinalang.compiler.util.FieldType)1 Name (org.wso2.ballerinalang.compiler.util.Name)1