Merge pull request #1103 from nspcc-dev/feature/omittypes
Allow to omit types and struct field names in contracts
This commit is contained in:
commit
6910e77a1e
3 changed files with 50 additions and 9 deletions
|
@ -594,15 +594,11 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
case *ast.CompositeLit:
|
case *ast.CompositeLit:
|
||||||
typ := c.typeOf(n.Type).Underlying()
|
switch typ := c.typeOf(n).Underlying().(type) {
|
||||||
switch n.Type.(type) {
|
|
||||||
case *ast.Ident, *ast.SelectorExpr, *ast.MapType:
|
|
||||||
switch typ.(type) {
|
|
||||||
case *types.Struct:
|
case *types.Struct:
|
||||||
c.convertStruct(n)
|
c.convertStruct(n)
|
||||||
case *types.Map:
|
case *types.Map:
|
||||||
c.convertMap(n)
|
c.convertMap(n)
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
ln := len(n.Elts)
|
ln := len(n.Elts)
|
||||||
// ByteArrays needs a different approach than normal arrays.
|
// ByteArrays needs a different approach than normal arrays.
|
||||||
|
@ -1257,12 +1253,25 @@ func (c *codegen) convertStruct(lit *ast.CompositeLit) {
|
||||||
emit.Int(c.prog.BinWriter, int64(strct.NumFields()))
|
emit.Int(c.prog.BinWriter, int64(strct.NumFields()))
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.NEWSTRUCT)
|
emit.Opcode(c.prog.BinWriter, opcode.NEWSTRUCT)
|
||||||
|
|
||||||
|
keyedLit := len(lit.Elts) > 0
|
||||||
|
if keyedLit {
|
||||||
|
_, ok := lit.Elts[0].(*ast.KeyValueExpr)
|
||||||
|
keyedLit = keyedLit && ok
|
||||||
|
}
|
||||||
// We need to locally store all the fields, even if they are not initialized.
|
// We need to locally store all the fields, even if they are not initialized.
|
||||||
// We will initialize all fields to their "zero" value.
|
// We will initialize all fields to their "zero" value.
|
||||||
for i := 0; i < strct.NumFields(); i++ {
|
for i := 0; i < strct.NumFields(); i++ {
|
||||||
sField := strct.Field(i)
|
sField := strct.Field(i)
|
||||||
fieldAdded := false
|
fieldAdded := false
|
||||||
|
|
||||||
|
if !keyedLit {
|
||||||
|
emit.Opcode(c.prog.BinWriter, opcode.DUP)
|
||||||
|
emit.Int(c.prog.BinWriter, int64(i))
|
||||||
|
ast.Walk(c, lit.Elts[i])
|
||||||
|
emit.Opcode(c.prog.BinWriter, opcode.SETITEM)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Fields initialized by the program.
|
// Fields initialized by the program.
|
||||||
for _, field := range lit.Elts {
|
for _, field := range lit.Elts {
|
||||||
f := field.(*ast.KeyValueExpr)
|
f := field.(*ast.KeyValueExpr)
|
||||||
|
|
|
@ -222,6 +222,27 @@ var sliceTestCases = []testCase{
|
||||||
}`,
|
}`,
|
||||||
big.NewInt(42),
|
big.NewInt(42),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"nested slice omitted type (slice)",
|
||||||
|
`package foo
|
||||||
|
func Main() int {
|
||||||
|
a := [][]int{{1, 2}, {3, 4}}
|
||||||
|
a[1][0] = 42
|
||||||
|
return a[1][0]
|
||||||
|
}`,
|
||||||
|
big.NewInt(42),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested slice omitted type (struct)",
|
||||||
|
`package foo
|
||||||
|
type pair struct { a, b int }
|
||||||
|
func Main() int {
|
||||||
|
a := []pair{{a: 1, b: 2}, {a: 3, b: 4}}
|
||||||
|
a[1].a = 42
|
||||||
|
return a[1].a
|
||||||
|
}`,
|
||||||
|
big.NewInt(42),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSliceOperations(t *testing.T) {
|
func TestSliceOperations(t *testing.T) {
|
||||||
|
|
|
@ -394,6 +394,17 @@ var structTestCases = []testCase{
|
||||||
}`,
|
}`,
|
||||||
big.NewInt(42),
|
big.NewInt(42),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"omit field names",
|
||||||
|
`package foo
|
||||||
|
type pair struct { a, b int }
|
||||||
|
func Main() int {
|
||||||
|
p := pair{1, 2}
|
||||||
|
x := p.a * 10
|
||||||
|
return x + p.b
|
||||||
|
}`,
|
||||||
|
big.NewInt(12),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStructs(t *testing.T) {
|
func TestStructs(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue