Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions common/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,14 @@ func (td *TypeDesc) Validate() error {
return fmt.Errorf("invalid type: optional_type expects 1 parameter, got %d", len(td.Params))
}
return td.Params[0].Validate()
case "type":
if len(td.Params) == 0 {
return nil
}
if len(td.Params) != 1 {
return fmt.Errorf("invalid type: type expects 0 or 1 parameters, got %d", len(td.Params))
}
return td.Params[0].Validate()
default:
}
return nil
Expand Down Expand Up @@ -832,6 +840,15 @@ func (td *TypeDesc) AsCELType(tp types.Provider) (*types.Type, error) {
return nil, err
}
return types.NewOptionalType(et), nil
case "type":
if len(td.Params) == 0 {
return types.TypeType, nil
}
pt, err := td.Params[0].AsCELType(tp)
if err != nil {
return nil, err
}
return types.NewTypeTypeWithParam(pt), nil
default:
if td.IsTypeParam {
return types.NewTypeParamType(td.TypeName), nil
Expand Down
42 changes: 41 additions & 1 deletion common/env/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,30 @@ func TestVariableAsCELVariable(t *testing.T) {
},
want: errors.New("undefined type name"),
},
{
name: "simple type",
v: &Variable{
Name: "t",
TypeDesc: &TypeDesc{TypeName: "type"},
},
want: decls.NewVariable("t", types.TypeType),
},
{
name: "type with param",
v: &Variable{
Name: "t",
TypeDesc: &TypeDesc{TypeName: "type", Params: []*TypeDesc{NewTypeParam("T")}},
},
want: decls.NewVariable("t", types.NewTypeTypeWithParam(types.NewTypeParamType("T"))),
},
{
name: "type with too many params",
v: &Variable{
Name: "t",
TypeDesc: &TypeDesc{TypeName: "type", Params: []*TypeDesc{NewTypeParam("T"), NewTypeParam("U")}},
},
want: errors.New("expects 0 or 1 parameters"),
},
{
name: "int type",
v: NewVariable("int_var", NewTypeDesc("int")),
Expand Down Expand Up @@ -648,6 +672,7 @@ func TestTypeDescString(t *testing.T) {
}{
{desc: NewTypeDesc("string"), want: "string"},
{desc: NewTypeDesc("list", NewTypeParam("T")), want: "list(T)"},
{desc: NewTypeDesc("type", NewTypeParam("T")), want: "type(T)"},
{desc: NewTypeDesc("map", NewTypeDesc("string"), NewTypeParam("T")), want: "map(string,T)"},
}
for _, tc := range tests {
Expand Down Expand Up @@ -766,7 +791,7 @@ func TestFunctionAsCELFunction(t *testing.T) {
want: mustNewFunction(t, "size", decls.MemberOverload("string_size", []*types.Type{types.StringType}, types.IntType)),
},
{
name: "member function",
name: "member function with examples",
f: &Function{Name: "size",
Description: "return the number of unicode code points in a string",
Overloads: []*Overload{{
Expand All @@ -786,6 +811,21 @@ func TestFunctionAsCELFunction(t *testing.T) {
`'hello'.size() // 5`,
`'hello world'.size() // 11`))),
},
{
name: "function with type containing params",
f: &Function{Name: "asType",
Overloads: []*Overload{
{ID: "bytes_asType_type(T)",
Target: &TypeDesc{TypeName: "bytes"},
Args: []*TypeDesc{NewTypeDesc("type", NewTypeParam("T"))},
Return: NewTypeParam("T")},
},
},
want: mustNewFunction(t, "asType",
decls.MemberOverload("bytes_asType_type(T)",
[]*types.Type{types.BytesType, types.NewTypeTypeWithParam(types.NewTypeParamType("T"))},
types.NewTypeParamType("T"))),
},
}
tp, err := types.NewRegistry()
if err != nil {
Expand Down