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 }