blob: 97c7544b6e99c74910649e11cc54542495452dce [file] [log] [blame]
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package importer
import (
"go/ast"
"path"
"strconv"
"strings"
"unicode"
"unicode/utf8"
)
// SimpleImporter returns a (dummy) package object named by the last path element,
// stripping off any major version suffix or go- prefix.
// This is sufficient to resolve most package identifiers without doing an actual
// import. It never returns an error.
//
//lint:ignore SA1019 We had a preexisting dependency on ast.Object.
func SimpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) {
pkg := imports[path]
if pkg == nil {
name := importPathToAssumedName(path)
pkg = ast.NewObj(ast.Pkg, name)
pkg.Data = ast.NewScope(nil) // required by ast.NewPackage for dot-import
imports[path] = pkg
}
return pkg, nil
}
// importPathToAssumedName is a copy of golang.org/x/tools/internal/imports.ImportPathToAssumedName
func importPathToAssumedName(importPath string) string {
base := path.Base(importPath)
if strings.HasPrefix(base, "v") {
if _, err := strconv.Atoi(base[1:]); err == nil {
dir := path.Dir(importPath)
if dir != "." {
base = path.Base(dir)
}
}
}
base = strings.TrimPrefix(base, "go-")
if i := strings.IndexFunc(base, notIdentifier); i >= 0 {
base = base[:i]
}
return base
}
// notIdentifier reports whether ch is an invalid identifier character.
func notIdentifier(ch rune) bool {
return !('a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' ||
'0' <= ch && ch <= '9' ||
ch == '_' ||
ch >= utf8.RuneSelf && (unicode.IsLetter(ch) || unicode.IsDigit(ch)))
}