github.com/expr-lang/expr@v1.16.9/test/patch/change_ident_test.go (about)

     1  package patch_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/expr-lang/expr/internal/testify/require"
     7  
     8  	"github.com/expr-lang/expr"
     9  	"github.com/expr-lang/expr/ast"
    10  	"github.com/expr-lang/expr/vm"
    11  	"github.com/expr-lang/expr/vm/runtime"
    12  )
    13  
    14  func TestPatch_change_ident(t *testing.T) {
    15  	program, err := expr.Compile(
    16  		`foo`,
    17  		expr.Env(Env{}),
    18  		expr.Patch(changeIdent{}),
    19  	)
    20  	require.NoError(t, err)
    21  
    22  	expected := &vm.Program{
    23  		Bytecode: []vm.Opcode{
    24  			vm.OpLoadField,
    25  		},
    26  		Arguments: []int{
    27  			0,
    28  		},
    29  		Constants: []any{
    30  			&runtime.Field{
    31  				Path:  []string{"bar"},
    32  				Index: []int{1},
    33  			},
    34  		},
    35  	}
    36  
    37  	require.Equal(t, expected.Disassemble(), program.Disassemble())
    38  }
    39  
    40  type Env struct {
    41  	Foo int `expr:"foo"`
    42  	Bar int `expr:"bar"`
    43  }
    44  
    45  type changeIdent struct{}
    46  
    47  func (changeIdent) Visit(node *ast.Node) {
    48  	id, ok := (*node).(*ast.IdentifierNode)
    49  	if !ok {
    50  		return
    51  	}
    52  	if id.Value == "foo" {
    53  		// A correct way to patch the node:
    54  		//
    55  		//	newNode := &ast.IdentifierNode{Value: "bar"}
    56  		//	ast.Patch(node, newNode)
    57  		//
    58  		// But we can do it in a wrong way:
    59  		id.Value = "bar"
    60  	}
    61  }