diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 1991cf4f..27337ddb 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,6 +5,20 @@ on: - master pull_request: jobs: + lint: + name: lint + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + - name: setup Go + uses: actions/setup-go@v4 + with: + go-version: "1.23" + - name: run linters + run: | + make lint + race-test: name: Test with -race strategy: diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e660fd93 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin/ diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..ec8d7313 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,42 @@ +run: + timeout: 5m + +linters-settings: + errcheck: + check-type-assertions: true + gci: + sections: + - "standard" + - "default" + - "prefix(github.com/goccy/go-yaml)" + - "blank" + - "dot" + gofmt: + simplify: true + govet: + disable: + - tests + misspell: + locale: US + staticcheck: + checks: ["all", "-ST1000", "-ST1005"] + +linters: + disable-all: true + enable: + - errcheck + - gci + - gofmt + - gosimple + - govet + - ineffassign + - misspell + - staticcheck + - typecheck + - unused + +issues: + exclude-rules: + - path: _test\.go + linters: + - staticcheck diff --git a/Makefile b/Makefile index 1b1d9239..02a38dd2 100644 --- a/Makefile +++ b/Makefile @@ -17,3 +17,31 @@ cover-html: cover .PHONY: ycat/build ycat/build: go build -o ycat ./cmd/ycat + +.PHONY: lint +lint: golangci-lint ## Run golangci-lint + @$(GOLANGCI_LINT) run + +.PHONY: fmt +fmt: golangci-lint ## Ensure consistent code style + @go mod tidy + @go fmt ./... + @$(GOLANGCI_LINT) run --fix + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries +GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint + +## Tool Versions +GOLANGCI_VERSION := 1.61.0 + +.PHONY: golangci-lint +.PHONY: $(GOLANGCI_LINT) +golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. +$(GOLANGCI_LINT): $(LOCALBIN) + @test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint version --format short | grep -q $(GOLANGCI_VERSION) || \ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LOCALBIN) v$(GOLANGCI_VERSION) diff --git a/ast/ast.go b/ast/ast.go index b4d5ec41..66ddfd96 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -7,8 +7,9 @@ import ( "strconv" "strings" - "github.com/goccy/go-yaml/token" "golang.org/x/xerrors" + + "github.com/goccy/go-yaml/token" ) var ( @@ -2092,10 +2093,10 @@ func Merge(dst Node, src Node) error { err := &ErrInvalidMergeType{dst: dst, src: src} switch dst.Type() { case DocumentType: - node := dst.(*DocumentNode) + node, _ := dst.(*DocumentNode) return Merge(node.Body, src) case MappingType: - node := dst.(*MappingNode) + node, _ := dst.(*MappingNode) target, ok := src.(*MappingNode) if !ok { return err @@ -2103,7 +2104,7 @@ func Merge(dst Node, src Node) error { node.Merge(target) return nil case SequenceType: - node := dst.(*SequenceNode) + node, _ := dst.(*SequenceNode) target, ok := src.(*SequenceNode) if !ok { return err diff --git a/cmd/ycat/ycat.go b/cmd/ycat/ycat.go index dbac4df9..b810b6fd 100644 --- a/cmd/ycat/ycat.go +++ b/cmd/ycat/ycat.go @@ -6,10 +6,11 @@ import ( "os" "github.com/fatih/color" + "github.com/mattn/go-colorable" + "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/printer" - "github.com/mattn/go-colorable" ) const escape = "\x1b" @@ -71,7 +72,7 @@ func _main(args []string) error { } } writer := colorable.NewColorableStdout() - writer.Write([]byte(p.PrintTokens(tokens) + "\n")) + _, _ = writer.Write([]byte(p.PrintTokens(tokens) + "\n")) return nil } diff --git a/decode.go b/decode.go index 04b94bca..ce2c751e 100644 --- a/decode.go +++ b/decode.go @@ -100,7 +100,7 @@ func (d *Decoder) castToFloat(v interface{}) interface{} { func (d *Decoder) mergeValueNode(value ast.Node) ast.Node { if value.Type() == ast.AliasType { - aliasNode := value.(*ast.AliasNode) + aliasNode, _ := value.(*ast.AliasNode) aliasName := aliasNode.Value.GetToken().Value return d.anchorNodeMap[aliasName] } @@ -360,7 +360,7 @@ func (d *Decoder) resolveAlias(node ast.Node) (ast.Node, error) { if err != nil { return nil, err } - n.Values[idx] = value.(*ast.MappingValueNode) + n.Values[idx], _ = value.(*ast.MappingValueNode) } case *ast.TagNode: value, err := d.resolveAlias(n.Value) @@ -389,7 +389,7 @@ func (d *Decoder) resolveAlias(node ast.Node) (ast.Node, error) { if err != nil { return nil, err } - n.Key = key.(ast.MapKeyNode) + n.Key, _ = key.(ast.MapKeyNode) value, err := d.resolveAlias(n.Value) if err != nil { return nil, err @@ -476,15 +476,6 @@ func (d *Decoder) getArrayNode(node ast.Node) (ast.ArrayNode, error) { return arrayNode, nil } -func (d *Decoder) fileToNode(f *ast.File) ast.Node { - for _, doc := range f.Docs { - if v := d.nodeToValue(doc.Body); v != nil { - return doc.Body - } - } - return nil -} - func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node) (reflect.Value, error) { if typ.Kind() != reflect.String { if !v.Type().ConvertibleTo(typ) { @@ -590,7 +581,7 @@ func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[st } if structField.IsInline { - d.deleteStructKeys(field.Type, unknownFields) + _ = d.deleteStructKeys(field.Type, unknownFields) } else { delete(unknownFields, structField.RenderName) } @@ -1275,7 +1266,7 @@ func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.N } continue } - d.setDefaultValueIfConflicted(newFieldValue, structFieldMap) + _ = d.setDefaultValueIfConflicted(newFieldValue, structFieldMap) fieldValue.Set(d.castToAssignableValue(newFieldValue, fieldValue.Type())) continue } @@ -1623,13 +1614,13 @@ func (d *Decoder) readersUnderDir(dir string) ([]io.Reader, error) { func (d *Decoder) readersUnderDirRecursive(dir string) ([]io.Reader, error) { readers := []io.Reader{} - if err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err := filepath.Walk(dir, func(path string, info os.FileInfo, _ error) error { if !d.isYAMLFile(path) { return nil } - reader, err := d.fileToReader(path) - if err != nil { - return errors.Wrapf(err, "failed to get reader") + reader, readerErr := d.fileToReader(path) + if readerErr != nil { + return errors.Wrapf(readerErr, "failed to get reader") } readers = append(readers, reader) return nil diff --git a/decode_test.go b/decode_test.go index 0d47a29c..cff86401 100644 --- a/decode_test.go +++ b/decode_test.go @@ -592,11 +592,11 @@ func TestDecoder(t *testing.T) { }, { "v: [A,B,C,]", - map[string][]string{"v": []string{"A", "B", "C"}}, + map[string][]string{"v": {"A", "B", "C"}}, }, { "v: [A,1,C]", - map[string][]string{"v": []string{"A", "1", "C"}}, + map[string][]string{"v": {"A", "1", "C"}}, }, { "v: [A,1,C]", @@ -610,11 +610,11 @@ func TestDecoder(t *testing.T) { }, { "v:\n - A\n - B\n - C", - map[string][]string{"v": []string{"A", "B", "C"}}, + map[string][]string{"v": {"A", "B", "C"}}, }, { "v:\n - A\n - 1\n - C", - map[string][]string{"v": []string{"A", "1", "C"}}, + map[string][]string{"v": {"A", "1", "C"}}, }, { "v:\n - A\n - 1\n - C", @@ -1470,7 +1470,7 @@ items: if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } - items := v.(map[string]interface{})["items"].([]interface{}) + items, _ := v.(map[string]interface{})["items"].([]interface{}) if len(items) != 2 { t.Fatal("failed to decode with merge key") } @@ -2152,16 +2152,16 @@ func Example_DisallowUnknownField() { const src = `--- simple: string -complecated: string +unknown: string ` err := yaml.NewDecoder(strings.NewReader(src), yaml.DisallowUnknownField()).Decode(&v) fmt.Printf("%v\n", err) // OUTPUT: - // [3:1] unknown field "complecated" + // [3:1] unknown field "unknown" // 1 | --- // 2 | simple: string - // > 3 | complecated: string + // > 3 | unknown: string // ^ } @@ -2712,22 +2712,22 @@ func TestDecoder_LiteralWithNewLine(t *testing.T) { LastNode string `yaml:"last"` } tests := []A{ - A{ + { Node: "hello\nworld", }, - A{ + { Node: "hello\nworld\n", }, - A{ + { Node: "hello\nworld\n\n", }, - A{ + { LastNode: "hello\nworld", }, - A{ + { LastNode: "hello\nworld\n", }, - A{ + { LastNode: "hello\nworld\n\n", }, } diff --git a/encode.go b/encode.go index 3b9b2981..f54040f6 100644 --- a/encode.go +++ b/encode.go @@ -12,12 +12,13 @@ import ( "strings" "time" + "golang.org/x/xerrors" + "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/parser" "github.com/goccy/go-yaml/printer" "github.com/goccy/go-yaml/token" - "golang.org/x/xerrors" ) const ( @@ -93,10 +94,10 @@ func (e *Encoder) EncodeContext(ctx context.Context, v interface{}) error { e.written = true } else { // write document separator - e.writer.Write([]byte("---\n")) + _, _ = e.writer.Write([]byte("---\n")) } var p printer.Printer - e.writer.Write(p.PrintNode(node)) + _, _ = e.writer.Write(p.PrintNode(node)) return nil } diff --git a/encode_test.go b/encode_test.go index 74388b98..7c55269c 100644 --- a/encode_test.go +++ b/encode_test.go @@ -10,10 +10,9 @@ import ( "testing" "time" - "github.com/goccy/go-yaml/parser" - "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/ast" + "github.com/goccy/go-yaml/parser" ) var zero = 0 @@ -683,12 +682,12 @@ func TestEncoder(t *testing.T) { // time value { "v: 0001-01-01T00:00:00Z\n", - map[string]time.Time{"v": time.Time{}}, + map[string]time.Time{"v": {}}, nil, }, { "v: 0001-01-01T00:00:00Z\n", - map[string]*time.Time{"v": &time.Time{}}, + map[string]*time.Time{"v": {}}, nil, }, { @@ -1078,7 +1077,7 @@ func TestEncoder_FlowRecursive(t *testing.T) { M map[string][]int `yaml:",flow"` } v.M = map[string][]int{ - "test": []int{1, 2, 3}, + "test": {1, 2, 3}, } var buf bytes.Buffer if err := yaml.NewEncoder(&buf).Encode(v); err != nil { @@ -1188,7 +1187,7 @@ func TestEncoder_MarshalAnchor(t *testing.T) { hostIdx := 1 opt := yaml.MarshalAnchor(func(anchor *ast.AnchorNode, value interface{}) error { if _, ok := value.(*Host); ok { - nameNode := anchor.Name.(*ast.StringNode) + nameNode, _ := anchor.Name.(*ast.StringNode) nameNode.Value = fmt.Sprintf("host%d", hostIdx) hostIdx++ } diff --git a/error.go b/error.go index 163dcc55..26935eb8 100644 --- a/error.go +++ b/error.go @@ -1,8 +1,9 @@ package yaml import ( - "github.com/goccy/go-yaml/ast" "golang.org/x/xerrors" + + "github.com/goccy/go-yaml/ast" ) var ( diff --git a/internal/errors/error.go b/internal/errors/error.go index 7f1ea9af..1a137c80 100644 --- a/internal/errors/error.go +++ b/internal/errors/error.go @@ -5,9 +5,10 @@ import ( "fmt" "reflect" + "golang.org/x/xerrors" + "github.com/goccy/go-yaml/printer" "github.com/goccy/go-yaml/token" - "golang.org/x/xerrors" ) const ( @@ -119,7 +120,7 @@ func (e *wrapError) FormatError(p xerrors.Printer) error { } e.chainStateAndVerb(err) if fmtErr, ok := err.(xerrors.Formatter); ok { - fmtErr.FormatError(p) + _ = fmtErr.FormatError(p) } else { p.Print(err) } @@ -143,6 +144,7 @@ func (s *wrapState) Precision() (prec int, ok bool) { } func (s *wrapState) Flag(c int) bool { + //nolint:gosimple // set true to 'printDetail' forced because when p.Detail() is false, xerrors.Printer no output any text if c == '#' { // ignore '#' keyword because xerrors.FormatError doesn't set true to printDetail. diff --git a/parser/context.go b/parser/context.go index 42cc4f8f..c4752f9f 100644 --- a/parser/context.go +++ b/parser/context.go @@ -110,13 +110,6 @@ func (c *context) nextToken() *token.Token { return c.tokens[c.idx+1] } -func (c *context) afterNextToken() *token.Token { - if c.idx+2 >= c.size { - return nil - } - return c.tokens[c.idx+2] -} - func (c *context) nextNotCommentToken() *token.Token { for i := c.idx + 1; i < c.size; i++ { tk := c.tokens[i] diff --git a/parser/parser.go b/parser/parser.go index 2bec5fea..09b38853 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -5,11 +5,12 @@ import ( "os" "strings" + "golang.org/x/xerrors" + "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/token" - "golang.org/x/xerrors" ) type parser struct{} @@ -175,7 +176,7 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken nullNode := ast.Null(nullToken) if comment != nil { - nullNode.SetComment(comment) + _ = nullNode.SetComment(comment) } else { // If there is a comment, it is already bound to the key node, // so remove the comment from the key to bind it to the null value. @@ -184,7 +185,7 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken if err := key.SetComment(nil); err != nil { return nil, err } - nullNode.SetComment(keyComment) + _ = nullNode.SetComment(keyComment) } } return nullNode, nil @@ -199,7 +200,7 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken ctx.insertToken(ctx.idx, nullToken) nullNode := ast.Null(nullToken) if comment != nil { - nullNode.SetComment(comment) + _ = nullNode.SetComment(comment) } return nullNode, nil } @@ -209,7 +210,7 @@ func (p *parser) createMapValueNode(ctx *context, key ast.MapKeyNode, colonToken return nil, errors.Wrapf(err, "failed to parse mapping 'value' node") } if comment != nil { - value.SetComment(comment) + _ = value.SetComment(comment) } return value, nil } @@ -279,7 +280,7 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) { } switch value.Type() { case ast.MappingType: - c := value.(*ast.MappingNode) + c, _ := value.(*ast.MappingNode) comment := c.GetComment() for idx, v := range c.Values { if idx == 0 && comment != nil { diff --git a/path.go b/path.go index b79c6669..010cc12e 100644 --- a/path.go +++ b/path.go @@ -534,7 +534,7 @@ func (n *selectorNode) filter(node ast.Node) (ast.Node, error) { } } case ast.MappingValueType: - value := node.(*ast.MappingValueNode) + value, _ := node.(*ast.MappingValueNode) key := value.Key.GetToken().Value if key == selector { if n.child == nil { @@ -578,7 +578,7 @@ func (n *selectorNode) replace(node ast.Node, target ast.Node) error { } } case ast.MappingValueType: - value := node.(*ast.MappingValueNode) + value, _ := node.(*ast.MappingValueNode) if err := n.replaceMapValue(value, target); err != nil { return errors.Wrapf(err, "failed to replace map value") } @@ -614,7 +614,7 @@ func (n *indexNode) filter(node ast.Node) (ast.Node, error) { if node.Type() != ast.SequenceType { return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type()) } - sequence := node.(*ast.SequenceNode) + sequence, _ := node.(*ast.SequenceNode) if n.selector >= uint(len(sequence.Values)) { return nil, errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values) } @@ -633,7 +633,7 @@ func (n *indexNode) replace(node ast.Node, target ast.Node) error { if node.Type() != ast.SequenceType { return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type()) } - sequence := node.(*ast.SequenceNode) + sequence, _ := node.(*ast.SequenceNode) if n.selector >= uint(len(sequence.Values)) { return errors.Wrapf(ErrInvalidQuery, "expected index is %d. but got sequences has %d items", n.selector, sequence.Values) } @@ -679,7 +679,7 @@ func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) { if node.Type() != ast.SequenceType { return nil, errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type()) } - sequence := node.(*ast.SequenceNode) + sequence, _ := node.(*ast.SequenceNode) if n.child == nil { return sequence, nil } @@ -699,7 +699,7 @@ func (n *indexAllNode) replace(node ast.Node, target ast.Node) error { if node.Type() != ast.SequenceType { return errors.Wrapf(ErrInvalidQuery, "expected sequence type node. but got %s", node.Type()) } - sequence := node.(*ast.SequenceNode) + sequence, _ := node.(*ast.SequenceNode) if n.child == nil { for idx := range sequence.Values { if err := sequence.Replace(idx, target); err != nil { diff --git a/printer/printer.go b/printer/printer.go index d5e25dc9..a039322a 100644 --- a/printer/printer.go +++ b/printer/printer.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/fatih/color" + "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/token" ) diff --git a/scanner/context.go b/scanner/context.go index 3aaec561..5f92a6ef 100644 --- a/scanner/context.go +++ b/scanner/context.go @@ -42,7 +42,7 @@ func createContext() *Context { } func newContext(src []rune) *Context { - ctx := ctxPool.Get().(*Context) + ctx, _ := ctxPool.Get().(*Context) ctx.reset(src) return ctx } diff --git a/scanner/scanner.go b/scanner/scanner.go index 77acb418..0c7596a3 100644 --- a/scanner/scanner.go +++ b/scanner/scanner.go @@ -142,7 +142,7 @@ func (s *Scanner) newLineCount(src []rune) int { } func (s *Scanner) updateIndentState(ctx *Context) { - indentNumBasedIndentState := s.indentState + var indentNumBasedIndentState IndentState if s.prevIndentNum < s.indentNum { s.indentLevel = s.prevIndentLevel + 1 indentNumBasedIndentState = IndentStateUp @@ -164,7 +164,7 @@ func (s *Scanner) updateIndentState(ctx *Context) { // - prevIndentColumn: 1 of 'a' // - indentNumBasedIndentState: IndentStateDown because d's indentNum(1) is less than c's indentNum(3). // Therefore, s.prevIndentColumn(1) == s.column(1) is true, but we want to treat this as IndentStateDown. - // So, we look also current indentState value by the above prevIndentNum based logic, and determins finally indentState. + // So, we look also current indentState value by the above prevIndentNum based logic, and determines finally indentState. // --- // a: // b @@ -470,7 +470,6 @@ func (s *Scanner) scanComment(ctx *Context) (tk *token.Token, pos int) { ctx.addOriginBuf('#') ctx.progress(1) // skip '#' character for idx, c := range ctx.src[ctx.idx:] { - pos = idx + 1 ctx.addOriginBuf(c) switch c { case '\n', '\r': @@ -588,7 +587,6 @@ func (s *Scanner) scanLiteralHeader(ctx *Context) (pos int, err error) { ctx.literalOpt = opt return } - break } } err = xerrors.New("invalid literal header") diff --git a/struct.go b/struct.go index a3da8ddd..9d251f3a 100644 --- a/struct.go +++ b/struct.go @@ -84,11 +84,7 @@ func isIgnoredStructField(field reflect.StructField) bool { // private field return true } - tag := getTag(field) - if tag == "-" { - return true - } - return false + return getTag(field) == "-" } type StructFieldMap map[string]*StructField diff --git a/validate_test.go b/validate_test.go index 265deb8a..d73ee3a3 100644 --- a/validate_test.go +++ b/validate_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/go-playground/validator/v10" + "github.com/goccy/go-yaml" ) diff --git a/yaml.go b/yaml.go index 25b1056f..38214a82 100644 --- a/yaml.go +++ b/yaml.go @@ -7,9 +7,10 @@ import ( "reflect" "sync" + "golang.org/x/xerrors" + "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" - "golang.org/x/xerrors" ) // BytesMarshaler interface may be implemented by types to customize their @@ -80,11 +81,11 @@ func (s MapSlice) ToMap() map[interface{}]interface{} { // of the generated document will reflect the structure of the value itself. // Maps and pointers (to struct, string, int, etc) are accepted as the in value. // -// Struct fields are only marshalled if they are exported (have an upper case -// first letter), and are marshalled using the field name lowercased as the +// Struct fields are only marshaled if they are exported (have an upper case +// first letter), and are marshaled using the field name lowercased as the // default key. Custom keys may be defined via the "yaml" name in the field // tag: the content preceding the first comma is used as the key, and the -// following comma-separated options are used to tweak the marshalling process. +// following comma-separated options are used to tweak the marshaling process. // Conflicting names result in a runtime error. // // The field tag format accepted is: @@ -161,7 +162,7 @@ func ValueToNode(v interface{}, opts ...EncodeOption) (ast.Node, error) { // lowercased as the default key. Custom keys may be defined via the // "yaml" name in the field tag: the content preceding the first comma // is used as the key, and the following comma-separated options are -// used to tweak the marshalling process (see Marshal). +// used to tweak the marshaling process (see Marshal). // Conflicting names result in a runtime error. // // For example: @@ -216,7 +217,7 @@ func FormatError(e error, colored, inclSource bool) string { var pp errors.PrettyPrinter if xerrors.As(e, &pp) { var buf bytes.Buffer - pp.PrettyPrint(&errors.Sink{&buf}, colored, inclSource) + pp.PrettyPrint(&errors.Sink{Buffer: &buf}, colored, inclSource) return buf.String() } diff --git a/yaml_test.go b/yaml_test.go index 4446d31a..61f5327a 100644 --- a/yaml_test.go +++ b/yaml_test.go @@ -325,7 +325,7 @@ b: *a if len(anchors) != 1 { t.Fatal("failed to filter node") } - anchor := anchors[0].(*ast.AnchorNode) + anchor, _ := anchors[0].(*ast.AnchorNode) if err := anchor.SetName("b"); err != nil { t.Fatal(err) } @@ -333,7 +333,7 @@ b: *a if len(anchors) != 1 { t.Fatal("failed to filter node") } - alias := aliases[0].(*ast.AliasNode) + alias, _ := aliases[0].(*ast.AliasNode) if err := alias.SetName("b"); err != nil { t.Fatal(err) }