diff --git a/checker/checker.go b/checker/checker.go index c8f99ff5..57fb3ce5 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -18,6 +18,7 @@ package checker import ( "fmt" + "reflect" "github.com/google/cel-go/common" "github.com/google/cel-go/common/ast" @@ -78,6 +79,8 @@ func (c *checker) check(e ast.Expr) { case types.BoolType, types.BytesType, types.DoubleType, types.IntType, types.NullType, types.StringType, types.UintType: c.setType(e, literal.Type().(*types.Type)) + default: + c.errors.unexpectedASTType(e.ID(), c.location(e), "literal", literal.Type().TypeName()) } case ast.IdentKind: c.checkIdent(e) @@ -94,7 +97,7 @@ func (c *checker) check(e ast.Expr) { case ast.ComprehensionKind: c.checkComprehension(e) default: - c.errors.unexpectedASTType(e.ID(), c.location(e), e) + c.errors.unexpectedASTType(e.ID(), c.location(e), "unspecified", reflect.TypeOf(e).Name()) } } diff --git a/checker/checker_test.go b/checker/checker_test.go index 16d0f6eb..da69bd89 100644 --- a/checker/checker_test.go +++ b/checker/checker_test.go @@ -18,8 +18,10 @@ import ( "fmt" "strings" "testing" + "time" "github.com/google/cel-go/common" + "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/containers" "github.com/google/cel-go/common/decls" "github.com/google/cel-go/common/stdlib" @@ -2542,6 +2544,23 @@ func TestCheckErrorData(t *testing.T) { } } +func TestCheckInvalidLiteral(t *testing.T) { + fac := ast.NewExprFactory() + durLiteral := fac.NewLiteral(1, types.Duration{Duration: time.Second}) + // This is not valid syntax, just for illustration purposes. + src := common.NewTextSource(`1s`) + parsed := ast.NewAST(durLiteral, ast.NewSourceInfo(src)) + reg := newTestRegistry(t) + env, err := NewEnv(containers.DefaultContainer, reg) + if err != nil { + t.Fatalf("NewEnv(cont, reg) failed: %v", err) + } + _, iss := Check(parsed, src, env) + if !strings.Contains(iss.ToDisplayString(), "unexpected literal type") { + t.Errorf("got %s, wanted 'unexpected literal type'", iss.ToDisplayString()) + } +} + func testFunction(t testing.TB, name string, opts ...decls.FunctionOpt) *decls.FunctionDecl { t.Helper() fn, err := decls.NewFunction(name, opts...) diff --git a/checker/errors.go b/checker/errors.go index c7032590..8b3bf0b8 100644 --- a/checker/errors.go +++ b/checker/errors.go @@ -15,8 +15,6 @@ package checker import ( - "reflect" - "github.com/google/cel-go/common" "github.com/google/cel-go/common/ast" "github.com/google/cel-go/common/types" @@ -85,6 +83,6 @@ func (e *typeErrors) unexpectedFailedResolution(id int64, l common.Location, typ e.errs.ReportErrorAtID(id, l, "unexpected failed resolution of '%s'", typeName) } -func (e *typeErrors) unexpectedASTType(id int64, l common.Location, ex ast.Expr) { - e.errs.ReportErrorAtID(id, l, "unrecognized ast type: %v", reflect.TypeOf(ex)) +func (e *typeErrors) unexpectedASTType(id int64, l common.Location, kind, typeName string) { + e.errs.ReportErrorAtID(id, l, "unexpected %s type: %v", kind, typeName) }