Skip to content

Commit fc726fd

Browse files
committed
refactor: define Expr interface
Instead of exporting Expr struct directly, define Expr interface and hide impl. Pros. * Does not allow `Expr{ ... }` construction * No need to write a lots of useless GoDoc comments on exported struct methods Cons. * Little bit bothersome, but it's better than Java :p
1 parent 1ea2781 commit fc726fd

File tree

9 files changed

+44
-30
lines changed

9 files changed

+44
-30
lines changed

dsl/deparse.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"github.com/vim-volt/volt/dsl/types"
99
)
1010

11-
// Deparse deparses *types.Expr.
11+
// Deparse deparses types.Expr.
1212
// ["@", 1, 2, 3] becomes [1, 2, 3]
13-
func Deparse(expr *types.Expr) (interface{}, error) {
13+
func Deparse(expr types.Expr) (interface{}, error) {
1414
value, err := deparse(expr)
1515
if err != nil {
1616
return nil, err
@@ -38,7 +38,7 @@ func deparse(value types.Value) (interface{}, error) {
3838
m[k] = v
3939
}
4040
return m, nil
41-
case *types.Expr:
41+
case types.Expr:
4242
a := make([]interface{}, 0, len(val.Args())+1)
4343
// Do not include "@" in array literal
4444
if val.Op().String() != ops.ArrayOp.String() {

dsl/execute.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const (
2424
)
2525

2626
// Execute executes given expr with given ctx.
27-
func Execute(ctx context.Context, expr *types.Expr) (val types.Value, rollback func(), err error) {
27+
func Execute(ctx context.Context, expr types.Expr) (val types.Value, rollback func(), err error) {
2828
for _, required := range []struct {
2929
key CtxKeyType
3030
validate func(interface{}) error

dsl/ops/func_do.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func (*doOp) IsMacro() bool {
2626
return false
2727
}
2828

29-
func (*doOp) Bind(args ...types.Value) (*types.Expr, error) {
29+
func (*doOp) Bind(args ...types.Value) (types.Expr, error) {
3030
sig := make([]types.Type, 0, len(args))
3131
for i := 0; i < len(args); i++ {
3232
sig = append(sig, types.AnyValue)

dsl/ops/macro_array.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (op *arrayOp) InvertExpr(args []types.Value) (types.Value, error) {
2121
return op.macroInvertExpr(op.EvalExpr(context.Background(), args))
2222
}
2323

24-
func (*arrayOp) Bind(args ...types.Value) (*types.Expr, error) {
24+
func (*arrayOp) Bind(args ...types.Value) (types.Expr, error) {
2525
expr := types.NewExpr(ArrayOp, args, types.NewArrayType(types.AnyValue))
2626
return expr, nil
2727
}

dsl/ops/macro_eval.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func (op *evalOp) InvertExpr(args []types.Value) (types.Value, error) {
2222
return op.macroInvertExpr(op.EvalExpr(context.Background(), args))
2323
}
2424

25-
func (*evalOp) Bind(args ...types.Value) (*types.Expr, error) {
25+
func (*evalOp) Bind(args ...types.Value) (types.Expr, error) {
2626
expr := types.NewExpr(ArrayOp, args, types.NewArrayType(types.AnyValue))
2727
return expr, nil
2828
}

dsl/ops/macro_invert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func (op *invertOp) InvertExpr(args []types.Value) (types.Value, error) {
2222
return op.macroInvertExpr(op.EvalExpr(context.Background(), args))
2323
}
2424

25-
func (*invertOp) Bind(args ...types.Value) (*types.Expr, error) {
25+
func (*invertOp) Bind(args ...types.Value) (types.Expr, error) {
2626
expr := types.NewExpr(ArrayOp, args, types.NewArrayType(types.AnyValue))
2727
return expr, nil
2828
}

dsl/parse.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
// 1. Split to operation and its arguments
1515
// 2. Do semantic analysis recursively for its arguments
1616
// 3. Convert to *Expr
17-
func Parse(content []byte) (*types.Expr, error) {
17+
func Parse(content []byte) (types.Expr, error) {
1818
var value interface{}
1919
if err := json.Unmarshal(content, value); err != nil {
2020
return nil, err
@@ -29,7 +29,7 @@ func Parse(content []byte) (*types.Expr, error) {
2929
}
3030
// If expression's operator is a macro, return value may not be an array
3131
// (e.g. ["macro", 1, 2])
32-
expr, ok := arrayValue.(*types.Expr)
32+
expr, ok := arrayValue.(types.Expr)
3333
if !ok {
3434
return nil, errors.New("the result must be an expression")
3535
}

dsl/types/expr.go

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,58 @@ package types
33
import "context"
44

55
// Expr has an operation and its arguments
6-
type Expr struct {
6+
type Expr interface {
7+
// Op returns operator of Expr
8+
Op() Op
9+
10+
// Args returns arguments of Expr
11+
Args() []Value
12+
13+
// RetType returns return type of Expr
14+
RetType() Type
15+
16+
// Eval evaluates given expression expr with given transaction ID trxID.
17+
Eval(ctx context.Context) (val Value, rollback func(), err error)
18+
19+
// Invert inverts this expression.
20+
// This just calls Op().InvertExpr() with saved arguments.
21+
Invert() (Value, error)
22+
23+
// Type returns the type.
24+
Type() Type
25+
}
26+
27+
// NewExpr creates Expr instance
28+
func NewExpr(op Op, args []Value, retType Type) Expr {
29+
return &expr{op: op, args: args, retType: retType}
30+
}
31+
32+
type expr struct {
733
op Op
834
args []Value
935
retType Type
1036
}
1137

12-
// Op returns operator of Expr
13-
func (expr *Expr) Op() Op {
38+
func (expr *expr) Op() Op {
1439
return expr.op
1540
}
1641

17-
// Args returns arguments of Expr
18-
func (expr *Expr) Args() []Value {
42+
func (expr *expr) Args() []Value {
1943
return expr.args
2044
}
2145

22-
// RetType returns return type of Expr
23-
func (expr *Expr) RetType() Type {
46+
func (expr *expr) RetType() Type {
2447
return expr.retType
2548
}
2649

27-
// NewExpr creates Expr instance
28-
func NewExpr(op Op, args []Value, retType Type) *Expr {
29-
return &Expr{op: op, args: args, retType: retType}
30-
}
31-
32-
// Eval evaluates given expression expr with given transaction ID trxID.
33-
func (expr *Expr) Eval(ctx context.Context) (val Value, rollback func(), err error) {
50+
func (expr *expr) Eval(ctx context.Context) (val Value, rollback func(), err error) {
3451
return expr.op.EvalExpr(ctx, expr.args)
3552
}
3653

37-
// Invert inverts this expression.
38-
// This just calls Op().InvertExpr() with saved arguments.
39-
func (expr *Expr) Invert() (Value, error) {
54+
func (expr *expr) Invert() (Value, error) {
4055
return expr.op.InvertExpr(expr.args)
4156
}
4257

43-
// Type returns the type.
44-
func (expr *Expr) Type() Type {
58+
func (expr *expr) Type() Type {
4559
return expr.retType
4660
}

dsl/types/op.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type Op interface {
1111
InvertExpr(args []Value) (Value, error)
1212

1313
// Bind binds its arguments, and check if the types of values are correct
14-
Bind(args ...Value) (*Expr, error)
14+
Bind(args ...Value) (Expr, error)
1515

1616
// EvalExpr evaluates expression (this operator + given arguments).
1717
// If this operator is a function, it executes the operation and returns its

0 commit comments

Comments
 (0)