golangci-lint/pkg/golinters/typecheck.go
Denis Isaev a57bc83d70 On of cases for #260: fix crash in staticcheck
1. Fix crash if deps of analyzed packages weren't compiled.
2. Print deps typechecking errors
3. Fix all issues filtering because of empty go env GOCACHE for go < 1.10
2018-11-07 10:06:55 +03:00

79 lines
1.7 KiB
Go

package golinters
import (
"context"
"fmt"
"go/token"
"strconv"
"strings"
"github.com/pkg/errors"
"golang.org/x/tools/go/packages"
"github.com/golangci/golangci-lint/pkg/lint/linter"
libpackages "github.com/golangci/golangci-lint/pkg/packages"
"github.com/golangci/golangci-lint/pkg/result"
)
type TypeCheck struct{}
func (TypeCheck) Name() string {
return "typecheck"
}
func (TypeCheck) Desc() string {
return "Like the front-end of a Go compiler, parses and type-checks Go code"
}
func (lint TypeCheck) parseError(srcErr packages.Error) (*result.Issue, error) {
// file:line(<optional>:colon)
parts := strings.Split(srcErr.Pos, ":")
if len(parts) == 1 {
return nil, errors.New("no colons")
}
file := parts[0]
line, err := strconv.Atoi(parts[1])
if err != nil {
return nil, fmt.Errorf("can't parse line number %q: %s", parts[1], err)
}
var column int
if len(parts) == 3 { // no column
column, err = strconv.Atoi(parts[2])
if err != nil {
return nil, errors.Wrapf(err, "failed to parse column from %q", parts[2])
}
}
return &result.Issue{
Pos: token.Position{
Filename: file,
Line: line,
Column: column,
},
Text: srcErr.Msg,
FromLinter: lint.Name(),
}, nil
}
func (lint TypeCheck) Run(ctx context.Context, lintCtx *linter.Context) ([]result.Issue, error) {
var res []result.Issue
for _, pkg := range lintCtx.NotCompilingPackages {
errors := libpackages.ExtractErrors(pkg)
for _, err := range errors {
i, perr := lint.parseError(err)
if perr != nil {
res = append(res, result.Issue{
Text: err.Msg,
FromLinter: lint.Name(),
})
} else {
res = append(res, *i)
}
}
}
return res, nil
}