github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/compiler/vardecl_test.go (about) 1 package compiler_test 2 3 import ( 4 "math/big" 5 "testing" 6 7 "github.com/nspcc-dev/neo-go/pkg/vm/opcode" 8 ) 9 10 func TestGenDeclWithMultiRet(t *testing.T) { 11 t.Run("global var decl", func(t *testing.T) { 12 src := `package foo 13 func Main() int { 14 var a, b = f() 15 return a + b 16 } 17 func f() (int, int) { 18 return 1, 2 19 }` 20 eval(t, src, big.NewInt(3)) 21 }) 22 t.Run("local var decl", func(t *testing.T) { 23 src := `package foo 24 var a, b = f() 25 func Main() int { 26 return a + b 27 } 28 func f() (int, int) { 29 return 1, 2 30 }` 31 eval(t, src, big.NewInt(3)) 32 }) 33 } 34 35 func TestUnderscoreLocalVarDontEmitCode(t *testing.T) { 36 src := `package foo 37 type Foo struct { Int int } 38 func Main() int { 39 var _ int 40 var _ = 1 41 var ( 42 A = 2 43 _ = A + 3 44 _, B, _ = 4, 5, 6 45 _, _, _ = f(A, B) // unused, but has function call, so the code is expected 46 _, C, _ = f(A, B) 47 ) 48 var D = 7 // unused but named, so the code is expected 49 _ = D 50 var _ = Foo{ Int: 5 } 51 var fo = Foo{ Int: 3 } 52 var _ = 1 + A + fo.Int 53 var _ = fo.GetInt() // unused, but has method call, so the code is expected 54 return C 55 } 56 func f(a, b int) (int, int, int) { 57 return 8, 9, 10 58 } 59 func (fo Foo) GetInt() int { 60 return fo.Int 61 }` 62 eval(t, src, big.NewInt(9), []any{opcode.INITSLOT, []byte{5, 0}}, // local slot for A, B, C, D, fo 63 opcode.PUSH2, opcode.STLOC0, // store A 64 opcode.PUSH5, opcode.STLOC1, // store B 65 opcode.LDLOC0, opcode.LDLOC1, opcode.SWAP, []any{opcode.CALL, []byte{27}}, // evaluate f() first time 66 opcode.DROP, opcode.DROP, opcode.DROP, // drop all values from f 67 opcode.LDLOC0, opcode.LDLOC1, opcode.SWAP, []any{opcode.CALL, []byte{19}}, // evaluate f() second time 68 opcode.DROP, opcode.STLOC2, opcode.DROP, // store C 69 opcode.PUSH7, opcode.STLOC3, // store D 70 opcode.LDLOC3, opcode.DROP, // empty assignment 71 opcode.PUSH3, opcode.PUSH1, opcode.PACKSTRUCT, opcode.STLOC4, // fo decl 72 opcode.LDLOC4, []any{opcode.CALL, []byte{12}}, opcode.DROP, // fo.GetInt() 73 opcode.LDLOC2, opcode.RET, // return C 74 []any{opcode.INITSLOT, []byte{0, 2}}, opcode.PUSH10, opcode.PUSH9, opcode.PUSH8, opcode.RET, // f 75 []any{opcode.INITSLOT, []byte{0, 1}}, opcode.LDARG0, opcode.PUSH0, opcode.PICKITEM, opcode.RET) // (fo Foo) GetInt() int 76 }