forked from TrueCloudLab/linters
111 lines
2 KiB
Go
111 lines
2 KiB
Go
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
|
|
}
|