Search in sources :

Example 1 with Ident

use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.

the class ContainerTest method ToQualifiedName.

@Test
void ToQualifiedName() {
    Expr ident = Expr.newBuilder().setId(0).setIdentExpr(Ident.newBuilder().setName("var")).build();
    String idName = toQualifiedName(ident);
    assertThat(idName).isEqualTo("var");
    Expr sel = Expr.newBuilder().setId(0).setSelectExpr(Select.newBuilder().setOperand(ident).setField("qualifier")).build();
    String qualName = toQualifiedName(sel);
    assertThat(qualName).isEqualTo("var.qualifier");
    sel = Expr.newBuilder().setId(0).setSelectExpr(Select.newBuilder().setOperand(ident).setField("qualifier").setTestOnly(true)).build();
    assertThat(toQualifiedName(sel)).isNull();
    Expr unary = Expr.newBuilder().setId(0).setCallExpr(Call.newBuilder().setFunction("!_").addArgs(ident)).build();
    sel = Expr.newBuilder().setId(0).setSelectExpr(Select.newBuilder().setOperand(unary).setField("qualifier")).build();
    assertThat(toQualifiedName(sel)).isNull();
}
Also used : Expr(com.google.api.expr.v1alpha1.Expr) Test(org.junit.jupiter.api.Test)

Example 2 with Ident

use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.

the class Checker method checkSelect.

void checkSelect(Expr.Builder e) {
    Select.Builder sel = e.getSelectExprBuilder();
    // Before traversing down the tree, try to interpret as qualified name.
    String qname = Container.toQualifiedName(e.build());
    if (qname != null) {
        Decl ident = env.lookupIdent(qname);
        if (ident != null) {
            if (sel.getTestOnly()) {
                errors.expressionDoesNotSelectField(location(e));
                setType(e, Decls.Bool);
                return;
            }
            // Rewrite the node to be a variable reference to the resolved fully-qualified
            // variable name.
            setType(e, ident.getIdent().getType());
            setReference(e, newIdentReference(ident.getName(), ident.getIdent().getValue()));
            String identName = ident.getName();
            e.getIdentExprBuilder().setName(identName);
            return;
        }
    }
    // Interpret as field selection, first traversing down the operand.
    check(sel.getOperandBuilder());
    Type targetType = getType(sel.getOperandBuilder());
    // Assume error type by default as most types do not support field selection.
    Type resultType = Decls.Error;
    switch(kindOf(targetType)) {
        case kindMap:
            // Maps yield their value type as the selection result type.
            MapType mapType = targetType.getMapType();
            resultType = mapType.getValueType();
            break;
        case kindObject:
            // Objects yield their field type declaration as the selection result type, but only if
            // the field is defined.
            FieldType fieldType = lookupFieldType(location(e), targetType.getMessageType(), sel.getField());
            if (fieldType != null) {
                resultType = fieldType.type;
            }
            break;
        case kindTypeParam:
            // Set the operand type to DYN to prevent assignment to a potentionally incorrect type
            // at a later point in type-checking. The isAssignable call will update the type
            // substitutions for the type param under the covers.
            isAssignable(Decls.Dyn, targetType);
            // Also, set the result type to DYN.
            resultType = Decls.Dyn;
            break;
        default:
            // in order to allow forward progress on the check.
            if (isDynOrError(targetType)) {
                resultType = Decls.Dyn;
            } else {
                errors.typeDoesNotSupportFieldSelection(location(e), targetType);
            }
            break;
    }
    if (sel.getTestOnly()) {
        resultType = Decls.Bool;
    }
    setType(e, resultType);
}
Also used : CheckerEnv.getObjectWellKnownType(org.projectnessie.cel.checker.CheckerEnv.getObjectWellKnownType) CheckerEnv.isObjectWellKnownType(org.projectnessie.cel.checker.CheckerEnv.isObjectWellKnownType) CheckerEnv.dynElementType(org.projectnessie.cel.checker.CheckerEnv.dynElementType) Type(com.google.api.expr.v1alpha1.Type) MapType(com.google.api.expr.v1alpha1.Type.MapType) FieldType(org.projectnessie.cel.common.types.ref.FieldType) Select(com.google.api.expr.v1alpha1.Expr.Select) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl) Decl(com.google.api.expr.v1alpha1.Decl) MapType(com.google.api.expr.v1alpha1.Type.MapType) FieldType(org.projectnessie.cel.common.types.ref.FieldType)

Example 3 with Ident

use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.

the class CheckerEnv method lookupIdent.

/**
 * LookupIdent returns a Decl proto for typeName as an identifier in the Env. Returns nil if no
 * such identifier is found in the Env.
 */
public Decl lookupIdent(String name) {
    for (String candidate : container.resolveCandidateNames(name)) {
        Decl ident = declarations.findIdent(candidate);
        if (ident != null) {
            return ident;
        }
        // Next try to import the name as a reference to a message type. If found,
        // the declaration is added to the outest (global) scope of the
        // environment, so next time we can access it faster.
        Type t = provider.findType(candidate);
        if (t != null) {
            Decl decl = Decls.newVar(candidate, t);
            declarations.addIdent(decl);
            return decl;
        }
        // Next try to import this as an enum value by splitting the name in a type prefix and
        // the enum inside.
        Val enumValue = provider.enumValue(candidate);
        if (enumValue.type() != ErrType) {
            Decl decl = Decls.newIdent(candidate, Decls.Int, Constant.newBuilder().setInt64Value(enumValue.intValue()).build());
            declarations.addIdent(decl);
            return decl;
        }
    }
    return null;
}
Also used : Val(org.projectnessie.cel.common.types.ref.Val) Types.formatCheckedType(org.projectnessie.cel.checker.Types.formatCheckedType) Type(com.google.api.expr.v1alpha1.Type) ErrType(org.projectnessie.cel.common.types.Err.ErrType) FunctionDecl(com.google.api.expr.v1alpha1.Decl.FunctionDecl) Decl(com.google.api.expr.v1alpha1.Decl) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl)

Example 4 with Ident

use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.

the class Checker method checkCreateMessage.

void checkCreateMessage(Expr.Builder e) {
    CreateStruct.Builder msgVal = e.getStructExprBuilder();
    // Determine the type of the message.
    Type messageType = Decls.Error;
    Decl decl = env.lookupIdent(msgVal.getMessageName());
    if (decl == null) {
        errors.undeclaredReference(location(e), env.container.name(), msgVal.getMessageName());
        return;
    }
    // Ensure the type name is fully qualified in the AST.
    msgVal.setMessageName(decl.getName());
    setReference(e, newIdentReference(decl.getName(), null));
    IdentDecl ident = decl.getIdent();
    Types.Kind identKind = kindOf(ident.getType());
    if (identKind != Kind.kindError) {
        if (identKind != Kind.kindType) {
            errors.notAType(location(e), ident.getType());
        } else {
            messageType = ident.getType().getType();
            if (kindOf(messageType) != Kind.kindObject) {
                errors.notAMessageType(location(e), messageType);
                messageType = Decls.Error;
            }
        }
    }
    if (isObjectWellKnownType(messageType)) {
        setType(e, getObjectWellKnownType(messageType));
    } else {
        setType(e, messageType);
    }
    // Check the field initializers.
    for (Entry.Builder ent : msgVal.getEntriesBuilderList()) {
        String field = ent.getFieldKey();
        Expr.Builder value = ent.getValueBuilder();
        check(value);
        Type fieldType = Decls.Error;
        FieldType t = lookupFieldType(locationByID(ent.getId()), messageType.getMessageType(), field);
        if (t != null) {
            fieldType = t.type;
        }
        if (!isAssignable(fieldType, getType(value))) {
            errors.fieldTypeMismatch(locationByID(ent.getId()), field, fieldType, getType(value));
        }
    }
}
Also used : CreateStruct(com.google.api.expr.v1alpha1.Expr.CreateStruct) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl) Decl(com.google.api.expr.v1alpha1.Decl) FieldType(org.projectnessie.cel.common.types.ref.FieldType) CheckerEnv.getObjectWellKnownType(org.projectnessie.cel.checker.CheckerEnv.getObjectWellKnownType) CheckerEnv.isObjectWellKnownType(org.projectnessie.cel.checker.CheckerEnv.isObjectWellKnownType) CheckerEnv.dynElementType(org.projectnessie.cel.checker.CheckerEnv.dynElementType) Type(com.google.api.expr.v1alpha1.Type) MapType(com.google.api.expr.v1alpha1.Type.MapType) FieldType(org.projectnessie.cel.common.types.ref.FieldType) Entry(com.google.api.expr.v1alpha1.Expr.CreateStruct.Entry) Expr(com.google.api.expr.v1alpha1.Expr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) Kind(org.projectnessie.cel.checker.Types.Kind) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl)

Example 5 with Ident

use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.

the class Checker method checkIdent.

void checkIdent(Expr.Builder e) {
    Ident.Builder identExpr = e.getIdentExprBuilder();
    // Check to see if the identifier is declared.
    Decl ident = env.lookupIdent(identExpr.getName());
    if (ident != null) {
        setType(e, ident.getIdent().getType());
        setReference(e, newIdentReference(ident.getName(), ident.getIdent().getValue()));
        // Overwrite the identifier with its fully qualified name.
        identExpr.setName(ident.getName());
        return;
    }
    setType(e, Decls.Error);
    errors.undeclaredReference(location(e), env.container.name(), identExpr.getName());
}
Also used : Ident(com.google.api.expr.v1alpha1.Expr.Ident) IdentDecl(com.google.api.expr.v1alpha1.Decl.IdentDecl) Decl(com.google.api.expr.v1alpha1.Decl)

Aggregations

Decl (com.google.api.expr.v1alpha1.Decl)5 IdentDecl (com.google.api.expr.v1alpha1.Decl.IdentDecl)4 Type (com.google.api.expr.v1alpha1.Type)4 Expr (com.google.api.expr.v1alpha1.Expr)2 MapType (com.google.api.expr.v1alpha1.Type.MapType)2 CheckerEnv.dynElementType (org.projectnessie.cel.checker.CheckerEnv.dynElementType)2 CheckerEnv.getObjectWellKnownType (org.projectnessie.cel.checker.CheckerEnv.getObjectWellKnownType)2 CheckerEnv.isObjectWellKnownType (org.projectnessie.cel.checker.CheckerEnv.isObjectWellKnownType)2 FieldType (org.projectnessie.cel.common.types.ref.FieldType)2 CheckedExpr (com.google.api.expr.v1alpha1.CheckedExpr)1 FunctionDecl (com.google.api.expr.v1alpha1.Decl.FunctionDecl)1 CreateStruct (com.google.api.expr.v1alpha1.Expr.CreateStruct)1 Entry (com.google.api.expr.v1alpha1.Expr.CreateStruct.Entry)1 Ident (com.google.api.expr.v1alpha1.Expr.Ident)1 Select (com.google.api.expr.v1alpha1.Expr.Select)1 Test (org.junit.jupiter.api.Test)1 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)1 MethodSource (org.junit.jupiter.params.provider.MethodSource)1 CheckResult (org.projectnessie.cel.checker.Checker.CheckResult)1 CheckerEnv.newCheckerEnv (org.projectnessie.cel.checker.CheckerEnv.newCheckerEnv)1