Skip to content

Commit a37fc26

Browse files
committed
Support a generator for composite literals
1 parent de042fc commit a37fc26

2 files changed

Lines changed: 143 additions & 0 deletions

File tree

generator/composite_literal.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package generator
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type compositeLiteralField struct {
9+
key string
10+
value Statement
11+
}
12+
13+
// CompositeLiteral represents a code generator for composite literal.
14+
// Please see also: https://golang.org/doc/effective_go.html#composite_literals
15+
type CompositeLiteral struct {
16+
typ string
17+
fields []*compositeLiteralField
18+
}
19+
20+
// NewCompositeLiteral returns a new `CompositeLiteral`.
21+
func NewCompositeLiteral(typ string) *CompositeLiteral {
22+
return &CompositeLiteral{
23+
typ: typ,
24+
}
25+
}
26+
27+
// AddField adds a field as `Statement` to `ComposeLiteral`.
28+
// This method returns a *new* `Struct`; it means this method acts as immutable.
29+
func (c *CompositeLiteral) AddField(key string, value Statement) *CompositeLiteral {
30+
return &CompositeLiteral{
31+
typ: c.typ,
32+
fields: append(c.fields, &compositeLiteralField{
33+
key: key,
34+
value: value,
35+
}),
36+
}
37+
}
38+
39+
// AddFieldStr adds a field as string to `ComposeLiteral`.
40+
// This method returns a *new* `Struct`; it means this method acts as immutable.
41+
func (c *CompositeLiteral) AddFieldStr(key string, value string) *CompositeLiteral {
42+
return &CompositeLiteral{
43+
typ: c.typ,
44+
fields: append(c.fields, &compositeLiteralField{
45+
key: key,
46+
value: NewRawStatement(fmt.Sprintf(`"%s"`, value)),
47+
}),
48+
}
49+
}
50+
51+
// AddFieldRaw adds a field as raw text to `ComposeLiteral`.
52+
// This method returns a *new* `Struct`; it means this method acts as immutable.
53+
func (c *CompositeLiteral) AddFieldRaw(key string, value interface{}) *CompositeLiteral {
54+
return &CompositeLiteral{
55+
typ: c.typ,
56+
fields: append(c.fields, &compositeLiteralField{
57+
key: key,
58+
value: NewRawStatement(fmt.Sprintf("%v", value)),
59+
}),
60+
}
61+
}
62+
63+
// Generate generates composite literal block as golang code.
64+
func (c *CompositeLiteral) Generate(indentLevel int) (string, error) {
65+
indent := buildIndent(indentLevel)
66+
nextLevelIndent := buildIndent(indentLevel + 1)
67+
68+
stmt := fmt.Sprintf("%s%s{\n", indent, c.typ)
69+
for _, field := range c.fields {
70+
genValue, err := field.value.Generate(indentLevel + 1)
71+
if err != nil {
72+
return "", err
73+
}
74+
75+
genValue = strings.TrimSpace(genValue)
76+
77+
stmt += fmt.Sprintf("%s%s: %s,\n", nextLevelIndent, field.key, genValue)
78+
}
79+
stmt += fmt.Sprintf("%s}\n", indent)
80+
81+
return stmt, nil
82+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package generator
2+
3+
import (
4+
"testing"
5+
6+
"github.com/moznion/gowrtr/internal/errmsg"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestShouldGenerateCompositeLiteralBeSuccess(t *testing.T) {
12+
composeGenerator := NewCompositeLiteral("&Struct").
13+
AddField("foo", NewRawStatement(`"foo-value"`)).
14+
AddFieldStr("bar", "bar-value").
15+
AddField("buz", NewAnonymousFunc(
16+
false,
17+
NewAnonymousFuncSignature().ReturnTypes("bool"),
18+
NewReturnStatement("true"),
19+
).Invocation(NewFuncInvocation())).
20+
AddFieldRaw("qux", 12345).
21+
AddFieldRaw("foobar", false)
22+
23+
{
24+
gen, err := composeGenerator.Generate(0)
25+
26+
assert.NoError(t, err)
27+
expected := `&Struct{
28+
foo: "foo-value",
29+
bar: "bar-value",
30+
buz: func() bool {
31+
return true
32+
}(),
33+
qux: 12345,
34+
foobar: false,
35+
}
36+
`
37+
assert.Equal(t, expected, gen)
38+
}
39+
40+
{
41+
gen, err := composeGenerator.Generate(2)
42+
43+
assert.NoError(t, err)
44+
expected := ` &Struct{
45+
foo: "foo-value",
46+
bar: "bar-value",
47+
buz: func() bool {
48+
return true
49+
}(),
50+
qux: 12345,
51+
foobar: false,
52+
}
53+
`
54+
assert.Equal(t, expected, gen)
55+
}
56+
}
57+
58+
func TestShouldGenerateCompositeLiteralRaiseError(t *testing.T) {
59+
_, err := NewCompositeLiteral("").AddField("foo", NewIf("")).Generate(0)
60+
assert.EqualError(t, err, errmsg.IfConditionIsEmptyError().Error())
61+
}

0 commit comments

Comments
 (0)