Search in sources :

Example 11 with Type

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

the class Checker method checkCreateMap.

void checkCreateMap(Expr.Builder e) {
    CreateStruct.Builder mapVal = e.getStructExprBuilder();
    Type keyType = null;
    Type valueType = null;
    for (Entry.Builder ent : mapVal.getEntriesBuilderList()) {
        Expr.Builder key = ent.getMapKeyBuilder();
        check(key);
        keyType = joinTypes(location(key), keyType, getType(key));
        Expr.Builder val = ent.getValueBuilder();
        check(val);
        valueType = joinTypes(location(val), valueType, getType(val));
    }
    if (keyType == null) {
        // If the map is empty, assign free type variables to typeKey and value type.
        keyType = newTypeVar();
        valueType = newTypeVar();
    }
    setType(e, Decls.newMapType(keyType, valueType));
}
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) Entry(com.google.api.expr.v1alpha1.Expr.CreateStruct.Entry) CreateStruct(com.google.api.expr.v1alpha1.Expr.CreateStruct) Expr(com.google.api.expr.v1alpha1.Expr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr)

Example 12 with Type

use of com.google.api.expr.v1alpha1.Type 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 13 with Type

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

the class Checker method resolveOverload.

OverloadResolution resolveOverload(Location loc, Decl fn, Expr.Builder target, List<Expr.Builder> args) {
    List<Type> argTypes = new ArrayList<>();
    if (target != null) {
        Type argType = getType(target);
        if (argType == null) {
            throw new ErrException("Could not resolve type for target '%s'", target);
        }
        argTypes.add(argType);
    }
    for (int i = 0; i < args.size(); i++) {
        Expr.Builder arg = args.get(i);
        Type argType = getType(arg);
        if (argType == null) {
            throw new ErrException("Could not resolve type for argument %d '%s'", i, arg);
        }
        argTypes.add(argType);
    }
    Type resultType = null;
    Reference checkedRef = null;
    for (Overload overload : fn.getFunction().getOverloadsList()) {
        if ((target == null && overload.getIsInstanceFunction()) || (target != null && !overload.getIsInstanceFunction())) {
            // not a compatible call style.
            continue;
        }
        Type overloadType = Decls.newFunctionType(overload.getResultType(), overload.getParamsList());
        if (overload.getTypeParamsCount() > 0) {
            // Instantiate overload's type with fresh type variables.
            Mapping substitutions = newMapping();
            for (String typePar : overload.getTypeParamsList()) {
                substitutions.add(Decls.newTypeParamType(typePar), newTypeVar());
            }
            overloadType = substitute(substitutions, overloadType, false);
        }
        List<Type> candidateArgTypes = overloadType.getFunction().getArgTypesList();
        if (isAssignableList(argTypes, candidateArgTypes)) {
            if (checkedRef == null) {
                checkedRef = newFunctionReference(Collections.singletonList(overload.getOverloadId()));
            } else {
                checkedRef = checkedRef.toBuilder().addOverloadId(overload.getOverloadId()).build();
            }
            // First matching overload, determines result type.
            Type fnResultType = substitute(mappings, overloadType.getFunction().getResultType(), false);
            if (resultType == null) {
                resultType = fnResultType;
            } else if (!isDyn(resultType) && !fnResultType.equals(resultType)) {
                resultType = Decls.Dyn;
            }
        }
    }
    if (resultType == null) {
        errors.noMatchingOverload(loc, fn.getName(), argTypes, target != null);
        // resultType = Decls.Error;
        return null;
    }
    return newResolution(checkedRef, 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) Expr(com.google.api.expr.v1alpha1.Expr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) Overload(com.google.api.expr.v1alpha1.Decl.FunctionDecl.Overload) ErrException(org.projectnessie.cel.common.types.Err.ErrException) Reference(com.google.api.expr.v1alpha1.Reference) ArrayList(java.util.ArrayList) Mapping.newMapping(org.projectnessie.cel.checker.Mapping.newMapping)

Example 14 with Type

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

the class Checker method checkComprehension.

void checkComprehension(Expr.Builder e) {
    Comprehension.Builder comp = e.getComprehensionExprBuilder();
    check(comp.getIterRangeBuilder());
    check(comp.getAccuInitBuilder());
    Type accuType = getType(comp.getAccuInitBuilder());
    Type rangeType = getType(comp.getIterRangeBuilder());
    Type varType;
    switch(kindOf(rangeType)) {
        case kindList:
            varType = rangeType.getListType().getElemType();
            break;
        case kindMap:
            // Ranges over the keys.
            varType = rangeType.getMapType().getKeyType();
            break;
        case kindDyn:
        case kindError:
        case kindTypeParam:
            // Set the range 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, rangeType);
            // Set the range iteration variable to type DYN as well.
            varType = Decls.Dyn;
            break;
        default:
            errors.notAComprehensionRange(location(comp.getIterRangeBuilder()), rangeType);
            varType = Decls.Error;
            break;
    }
    // Create a scope for the comprehension since it has a local accumulation variable.
    // This scope will contain the accumulation variable used to compute the result.
    env = env.enterScope();
    env.add(Decls.newVar(comp.getAccuVar(), accuType));
    // Create a block scope for the loop.
    env = env.enterScope();
    env.add(Decls.newVar(comp.getIterVar(), varType));
    // Check the variable references in the condition and step.
    check(comp.getLoopConditionBuilder());
    assertType(comp.getLoopConditionBuilder(), Decls.Bool);
    check(comp.getLoopStepBuilder());
    assertType(comp.getLoopStepBuilder(), accuType);
    // Exit the loop's block scope before checking the result.
    env = env.exitScope();
    check(comp.getResultBuilder());
    // Exit the comprehension scope.
    env = env.exitScope();
    setType(e, getType(comp.getResultBuilder()));
}
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) Comprehension(com.google.api.expr.v1alpha1.Expr.Comprehension)

Example 15 with Type

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

the class Checker method Check.

/**
 * Check performs type checking, giving a typed AST. The input is a ParsedExpr proto and an env
 * which encapsulates type binding of variables, declarations of built-in functions, descriptions
 * of protocol buffers, and a registry for errors. Returns a CheckedExpr proto, which might not be
 * usable if there are errors in the error registry.
 */
public static CheckResult Check(ParseResult parsedExpr, Source source, CheckerEnv env) {
    TypeErrors errors = new TypeErrors(source);
    Checker c = new Checker(env, errors, newMapping(), 0, parsedExpr.getSourceInfo());
    Expr.Builder b = parsedExpr.getExpr().toBuilder();
    c.check(b);
    Expr e = b.build();
    // Walk over the final type map substituting any type parameters either by their bound value or
    // by DYN.
    Map<Long, Type> m = new HashMap<>();
    c.types.forEach((k, v) -> m.put(k, substitute(c.mappings, v, true)));
    CheckedExpr checkedExpr = CheckedExpr.newBuilder().setExpr(e).setSourceInfo(parsedExpr.getSourceInfo()).putAllTypeMap(m).putAllReferenceMap(c.references).build();
    return new CheckResult(checkedExpr, errors);
}
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) Expr(com.google.api.expr.v1alpha1.Expr) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr) HashMap(java.util.HashMap) CheckedExpr(com.google.api.expr.v1alpha1.CheckedExpr)

Aggregations

Type (com.google.api.expr.v1alpha1.Type)30 Test (org.junit.Test)16 MapType (com.google.api.expr.v1alpha1.Type.MapType)15 Type (edu.stanford.CVC4.Type)14 Type (com.google.spanner.v1.Type)12 Test (org.junit.jupiter.api.Test)12 CheckedExpr (com.google.api.expr.v1alpha1.CheckedExpr)11 ByteString (com.google.protobuf.ByteString)11 ArrayType (edu.stanford.CVC4.ArrayType)11 BitVectorType (edu.stanford.CVC4.BitVectorType)11 Expr (edu.stanford.CVC4.Expr)11 ArrayList (java.util.ArrayList)11 Type (org.apache.xbean.asm9.Type)10 Expr (com.google.api.expr.v1alpha1.Expr)9 CVC4.vectorExpr (edu.stanford.CVC4.vectorExpr)9 FieldType (org.projectnessie.cel.common.types.ref.FieldType)8 ListValue (com.google.protobuf.ListValue)7 ExecuteSqlRequest (com.google.spanner.v1.ExecuteSqlRequest)7 CheckerEnv.dynElementType (org.projectnessie.cel.checker.CheckerEnv.dynElementType)7 CheckerEnv.getObjectWellKnownType (org.projectnessie.cel.checker.CheckerEnv.getObjectWellKnownType)7