Bump cel-go to v0.12.0

This commit is contained in:
Cici Huang
2022-07-07 17:13:57 +00:00
committed by cici37
parent aebe28b5cf
commit 772a252b06
131 changed files with 3842 additions and 1769 deletions

View File

@@ -45,6 +45,10 @@ type Overload struct {
// Function defines the overload with a FunctionOp implementation. May be
// nil.
Function FunctionOp
// NonStrict specifies whether the Overload will tolerate arguments that
// are types.Err or types.Unknown.
NonStrict bool
}
// UnaryOp is a function that takes a single value and produces an output.

View File

@@ -421,12 +421,13 @@ func (zero *evalZeroArity) Args() []Interpretable {
}
type evalUnary struct {
id int64
function string
overload string
arg Interpretable
trait int
impl functions.UnaryOp
id int64
function string
overload string
arg Interpretable
trait int
impl functions.UnaryOp
nonStrict bool
}
// ID implements the Interpretable interface method.
@@ -438,12 +439,13 @@ func (un *evalUnary) ID() int64 {
func (un *evalUnary) Eval(ctx Activation) ref.Val {
argVal := un.arg.Eval(ctx)
// Early return if the argument to the function is unknown or error.
if types.IsUnknownOrError(argVal) {
strict := !un.nonStrict
if strict && types.IsUnknownOrError(argVal) {
return argVal
}
// If the implementation is bound and the argument value has the right traits required to
// invoke it, then call the implementation.
if un.impl != nil && (un.trait == 0 || argVal.Type().HasTrait(un.trait)) {
if un.impl != nil && (un.trait == 0 || (!strict && types.IsUnknownOrError(argVal)) || argVal.Type().HasTrait(un.trait)) {
return un.impl(argVal)
}
// Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the
@@ -478,13 +480,14 @@ func (un *evalUnary) Args() []Interpretable {
}
type evalBinary struct {
id int64
function string
overload string
lhs Interpretable
rhs Interpretable
trait int
impl functions.BinaryOp
id int64
function string
overload string
lhs Interpretable
rhs Interpretable
trait int
impl functions.BinaryOp
nonStrict bool
}
// ID implements the Interpretable interface method.
@@ -497,15 +500,18 @@ func (bin *evalBinary) Eval(ctx Activation) ref.Val {
lVal := bin.lhs.Eval(ctx)
rVal := bin.rhs.Eval(ctx)
// Early return if any argument to the function is unknown or error.
if types.IsUnknownOrError(lVal) {
return lVal
}
if types.IsUnknownOrError(rVal) {
return rVal
strict := !bin.nonStrict
if strict {
if types.IsUnknownOrError(lVal) {
return lVal
}
if types.IsUnknownOrError(rVal) {
return rVal
}
}
// If the implementation is bound and the argument value has the right traits required to
// invoke it, then call the implementation.
if bin.impl != nil && (bin.trait == 0 || lVal.Type().HasTrait(bin.trait)) {
if bin.impl != nil && (bin.trait == 0 || (!strict && types.IsUnknownOrError(lVal)) || lVal.Type().HasTrait(bin.trait)) {
return bin.impl(lVal, rVal)
}
// Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the
@@ -537,12 +543,13 @@ func (bin *evalBinary) Args() []Interpretable {
}
type evalVarArgs struct {
id int64
function string
overload string
args []Interpretable
trait int
impl functions.FunctionOp
id int64
function string
overload string
args []Interpretable
trait int
impl functions.FunctionOp
nonStrict bool
}
// NewCall creates a new call Interpretable.
@@ -565,16 +572,17 @@ func (fn *evalVarArgs) ID() int64 {
func (fn *evalVarArgs) Eval(ctx Activation) ref.Val {
argVals := make([]ref.Val, len(fn.args))
// Early return if any argument to the function is unknown or error.
strict := !fn.nonStrict
for i, arg := range fn.args {
argVals[i] = arg.Eval(ctx)
if types.IsUnknownOrError(argVals[i]) {
if strict && types.IsUnknownOrError(argVals[i]) {
return argVals[i]
}
}
// If the implementation is bound and the argument value has the right traits required to
// invoke it, then call the implementation.
arg0 := argVals[0]
if fn.impl != nil && (fn.trait == 0 || arg0.Type().HasTrait(fn.trait)) {
if fn.impl != nil && (fn.trait == 0 || (!strict && types.IsUnknownOrError(arg0)) || arg0.Type().HasTrait(fn.trait)) {
return fn.impl(argVals...)
}
// Otherwise, if the argument is a ReceiverType attempt to invoke the receiver method on the

View File

@@ -302,8 +302,18 @@ func (p *planner) planCall(expr *exprpb.Expr) (Interpretable, error) {
case 0:
return p.planCallZero(expr, fnName, oName, fnDef)
case 1:
// If the FunctionOp has been used, then use it as it may exist for the purposes
// of dynamic dispatch within a singleton function implementation.
if fnDef != nil && fnDef.Unary == nil && fnDef.Function != nil {
return p.planCallVarArgs(expr, fnName, oName, fnDef, args)
}
return p.planCallUnary(expr, fnName, oName, fnDef, args)
case 2:
// If the FunctionOp has been used, then use it as it may exist for the purposes
// of dynamic dispatch within a singleton function implementation.
if fnDef != nil && fnDef.Binary == nil && fnDef.Function != nil {
return p.planCallVarArgs(expr, fnName, oName, fnDef, args)
}
return p.planCallBinary(expr, fnName, oName, fnDef, args)
default:
return p.planCallVarArgs(expr, fnName, oName, fnDef, args)
@@ -334,20 +344,23 @@ func (p *planner) planCallUnary(expr *exprpb.Expr,
args []Interpretable) (Interpretable, error) {
var fn functions.UnaryOp
var trait int
var nonStrict bool
if impl != nil {
if impl.Unary == nil {
return nil, fmt.Errorf("no such overload: %s(arg)", function)
}
fn = impl.Unary
trait = impl.OperandTrait
nonStrict = impl.NonStrict
}
return &evalUnary{
id: expr.Id,
function: function,
overload: overload,
arg: args[0],
trait: trait,
impl: fn,
id: expr.Id,
function: function,
overload: overload,
arg: args[0],
trait: trait,
impl: fn,
nonStrict: nonStrict,
}, nil
}
@@ -359,21 +372,24 @@ func (p *planner) planCallBinary(expr *exprpb.Expr,
args []Interpretable) (Interpretable, error) {
var fn functions.BinaryOp
var trait int
var nonStrict bool
if impl != nil {
if impl.Binary == nil {
return nil, fmt.Errorf("no such overload: %s(lhs, rhs)", function)
}
fn = impl.Binary
trait = impl.OperandTrait
nonStrict = impl.NonStrict
}
return &evalBinary{
id: expr.Id,
function: function,
overload: overload,
lhs: args[0],
rhs: args[1],
trait: trait,
impl: fn,
id: expr.Id,
function: function,
overload: overload,
lhs: args[0],
rhs: args[1],
trait: trait,
impl: fn,
nonStrict: nonStrict,
}, nil
}
@@ -385,20 +401,23 @@ func (p *planner) planCallVarArgs(expr *exprpb.Expr,
args []Interpretable) (Interpretable, error) {
var fn functions.FunctionOp
var trait int
var nonStrict bool
if impl != nil {
if impl.Function == nil {
return nil, fmt.Errorf("no such overload: %s(...)", function)
}
fn = impl.Function
trait = impl.OperandTrait
nonStrict = impl.NonStrict
}
return &evalVarArgs{
id: expr.Id,
function: function,
overload: overload,
args: args,
trait: trait,
impl: fn,
id: expr.Id,
function: function,
overload: overload,
args: args,
trait: trait,
impl: fn,
nonStrict: nonStrict,
}, nil
}