mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-25 07:56:16 +00:00
feat(rlp/rlpgen): support alias types (#154)
## Why this should be merged To be able to generate RLP code using type aliases (defined e.g. in `coreth`). This can and should be PR-ed upstream as well I think. ## How this works Call `types.Unalias()` at the start of `buildContext.makeOp()`. The alternative of adding a `case` to the switch statement adds unnecessary recursive calls while `types.Unalias()` is a no-op if not an alias. ## How this was tested New `rlpgen` unit test with aliases of well-known types that have special handling—these make their proper handling easy to spot when inspecting generated code. A recursive alias in the same test also demonstrates full alias resolution. --------- Co-authored-by: Arran Schlosberg <me@arranschlosberg.com>
This commit is contained in:
parent
9f410ecc7e
commit
739ba847f6
4 changed files with 67 additions and 2 deletions
|
|
@ -673,7 +673,7 @@ func (op sliceOp) genDecode(ctx *genContext) (string, string) {
|
|||
}
|
||||
|
||||
func (bctx *buildContext) makeOp(name *types.Named, typ types.Type, tags rlpstruct.Tags) (op, error) {
|
||||
switch typ := typ.(type) {
|
||||
switch typ := types.Unalias(typ).(type) {
|
||||
case *types.Named:
|
||||
if isBigInt(typ) {
|
||||
return bigIntOp{}, nil
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
var tests = []string{"uints", "nil", "rawvalue", "optional", "bigint", "uint256"}
|
||||
var tests = []string{"uints", "nil", "rawvalue", "optional", "bigint", "uint256", "alias"}
|
||||
|
||||
func TestOutput(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
|
|
|
|||
22
rlp/rlpgen/testdata/alias.in.txt
vendored
Normal file
22
rlp/rlpgen/testdata/alias.in.txt
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// -*- mode: go -*-
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
// Alias types chosen because their originals have special handling that is easy
|
||||
// to spot when inspecting generated output.
|
||||
type (
|
||||
Big = big.Int
|
||||
// Demonstrate recursive unaliasing
|
||||
intermediate = uint256.Int
|
||||
Uint256 = intermediate
|
||||
)
|
||||
|
||||
type Test struct {
|
||||
BigAlias Big
|
||||
Uint256Alias Uint256
|
||||
}
|
||||
43
rlp/rlpgen/testdata/alias.out.txt
vendored
Normal file
43
rlp/rlpgen/testdata/alias.out.txt
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package test
|
||||
|
||||
import "github.com/ava-labs/libevm/rlp"
|
||||
import "github.com/holiman/uint256"
|
||||
import "io"
|
||||
|
||||
func (obj *Test) EncodeRLP(_w io.Writer) error {
|
||||
w := rlp.NewEncoderBuffer(_w)
|
||||
_tmp0 := w.List()
|
||||
if obj.BigAlias.Sign() == -1 {
|
||||
return rlp.ErrNegativeBigInt
|
||||
}
|
||||
w.WriteBigInt(&obj.BigAlias)
|
||||
w.WriteUint256(&obj.Uint256Alias)
|
||||
w.ListEnd(_tmp0)
|
||||
return w.Flush()
|
||||
}
|
||||
|
||||
func (obj *Test) DecodeRLP(dec *rlp.Stream) error {
|
||||
var _tmp0 Test
|
||||
{
|
||||
if _, err := dec.List(); err != nil {
|
||||
return err
|
||||
}
|
||||
// BigAlias:
|
||||
_tmp1, err := dec.BigInt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_tmp0.BigAlias = (*_tmp1)
|
||||
// Uint256Alias:
|
||||
var _tmp2 uint256.Int
|
||||
if err := dec.ReadUint256(&_tmp2); err != nil {
|
||||
return err
|
||||
}
|
||||
_tmp0.Uint256Alias = _tmp2
|
||||
if err := dec.ListEnd(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*obj = _tmp0
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in a new issue