diff --git a/getters.go b/getters.go index de3d06e..7a90a5e 100644 --- a/getters.go +++ b/getters.go @@ -36,36 +36,22 @@ func newParsedFile(file *ast.File, fset *token.FileSet) (*parsedFile, error) { file: file, } - var err error - // Read original file. This is necessary for making a replacements for // inline comments. I couldn't find a better way to get original line // with code and comment without reading the file. Function `Format` // from "go/format" won't help here if the original file is not gofmt-ed. - pf.lines, err = readFile(file, fset) - if err != nil { - return nil, fmt.Errorf("read file: %w", err) - } - // Dirty hack. For some cases Go generates temporary files during - // compilation process if there is a cgo block in the source file. Some of - // these temporary files are just copies of original source files but with - // new generated comments at the top. Because of them the content differs - // from AST. For some reason it differs only in golangci-lint. I failed to - // find out the exact description of the process, so let's just skip files - // generated by cgo. - if isCgoGenerated(pf.lines) { - return nil, errUnsuitableInput + filename := getFilename(fset, file) + + if !strings.HasSuffix(filename, ".go") { + return nil, errEmptyInput } - // Check consistency to avoid checking slice indexes in each function. - // Note that `PositionFor` is used with `adjusted=false` to skip `//line` - // directives that can set references to other files (e.g. templates) - // instead of the real ones, and break consistency here. - // Issue: https://github.com/tetafro/godot/issues/32 - lastComment := pf.file.Comments[len(pf.file.Comments)-1] - if p := pf.fset.PositionFor(lastComment.End(), false); len(pf.lines) < p.Line { - return nil, fmt.Errorf("inconsistency between file and AST: %s", p.Filename) + var err error + + pf.lines, err = readFile(filename) + if err != nil { + return nil, fmt.Errorf("read file: %w", err) } return &pf, nil @@ -244,12 +230,12 @@ func getText(comment *ast.CommentGroup, exclude []*regexp.Regexp) (s string) { } // readFile reads file and returns its lines as strings. -func readFile(file *ast.File, fset *token.FileSet) ([]string, error) { - fname := fset.File(file.Package) - f, err := os.ReadFile(fname.Name()) +func readFile(filename string) ([]string, error) { + f, err := os.ReadFile(filename) if err != nil { return nil, err //nolint:wrapcheck } + return strings.Split(string(f), "\n"), nil } @@ -275,11 +261,11 @@ func matchAny(s string, rr []*regexp.Regexp) bool { return false } -func isCgoGenerated(lines []string) bool { - for i := range lines { - if strings.Contains(lines[i], "Code generated by cmd/cgo") { - return true - } +func getFilename(fset *token.FileSet, file *ast.File) string { + filename := fset.PositionFor(file.Pos(), true).Filename + if !strings.HasSuffix(filename, ".go") { + return fset.PositionFor(file.Pos(), false).Filename } - return false + + return filename } diff --git a/getters_test.go b/getters_test.go index 07b6b0a..27fc211 100644 --- a/getters_test.go +++ b/getters_test.go @@ -1,7 +1,6 @@ package godot import ( - "errors" "go/ast" "go/parser" "go/token" @@ -70,26 +69,6 @@ func TestGetComments(t *testing.T) { } }) } - - t.Run("try to get comments from cgo generated file", func(t *testing.T) { - testFile := filepath.Join("testdata", "get", "cgo.go") - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, testFile, nil, parser.ParseComments) - if err != nil { - t.Fatalf("Failed to parse input file: %v", err) - } - - pf, err := newParsedFile(file, fset) - if pf != nil { - t.Fatalf("Unexpected file content") - } - if !errors.Is(err, errUnsuitableInput) { - t.Fatalf( - "Unexpected error:\n expected: %v\n got: %v", - errUnsuitableInput, err, - ) - } - }) } func TestGetText(t *testing.T) { diff --git a/testdata/get/cgo.go b/testdata/get/cgo.go deleted file mode 100644 index 046d248..0000000 --- a/testdata/get/cgo.go +++ /dev/null @@ -1,6 +0,0 @@ -package example - -// Code generated by cmd/cgo; DO NOT EDIT. - -// Variable is a variable with comment -var Variable = 10