linters/pkg/ast-utils/ast.go

112 lines
2 KiB
Go
Raw Permalink Normal View History

package astutils
import (
"go/ast"
"go/token"
"strings"
"sync"
"golang.org/x/tools/go/analysis"
)
type aliasCacheKey struct {
File *ast.File
PkgName string
}
var (
aliasCache = sync.Map{}
)
func IsTargetMethod(expr ast.Expr, targetMethods []string) (bool, string) {
sel, ok := expr.(*ast.SelectorExpr)
if !ok {
return false, ""
}
for _, method := range targetMethods {
if IsIdent(sel.Sel, method) {
return true, method
}
}
return false, ""
}
func IsIdent(expr ast.Expr, ident string) bool {
id, ok := expr.(*ast.Ident)
if ok && id.Name == ident {
return true
}
return false
}
func IsStringValue(expr ast.Expr) bool {
basicLit, ok := expr.(*ast.BasicLit)
return ok && basicLit.Kind == token.STRING
}
func GetAliasByPkgName(file *ast.File, pkgName string) (string, error) {
key := aliasCacheKey{File: file, PkgName: pkgName}
if alias, ok := aliasCache.Load(key); ok {
return alias.(string), nil
}
var alias string
specs := file.Imports
for _, spec := range specs {
alias = GetAliasFromImportSpec(spec, pkgName)
if alias != "" {
break
}
}
aliasCache.Store(key, alias)
return alias, nil
}
func GetAliasFromImportSpec(spec *ast.ImportSpec, pkgName string) string {
if spec == nil {
return ""
}
importName := strings.Replace(spec.Path.Value, "\"", "", -1)
if importName != pkgName {
return ""
}
split := strings.Split(importName, "/")
if len(split) == 0 {
return ""
}
alias := split[len(split)-1]
if spec.Name != nil {
alias = spec.Name.Name
}
return alias
}
func GetPackageName(expr ast.Expr) string {
if selectorExpr, ok := expr.(*ast.SelectorExpr); ok {
if ident, ok := selectorExpr.X.(*ast.Ident); ok {
return ident.Name
}
}
return ""
}
func HasNoLintComment(pass *analysis.Pass, pos token.Pos) bool {
for _, commentGroup := range pass.Files[0].Comments {
if commentGroup.End() < pos {
for _, comment := range commentGroup.List {
if strings.Contains(comment.Text, "nolint") {
return true
}
}
}
}
return false
}