mirror of
https://github.com/golang/go
synced 2024-11-18 15:14:44 -07:00
go.tools/cmd/godex: better argument handling
1) Split a path.name argument at the last '.' that is not part of the path. 2) Try various importers always in the same order for consistent results (use lists instead of maps). LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/80790043
This commit is contained in:
parent
8648e1a481
commit
03478d3d3e
@ -9,21 +9,21 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.google.com/p/go.tools/go/types"
|
"code.google.com/p/go.tools/go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BUG(gri) cannot specify package paths with dots (code.google.com/p/go.tools/cmd/ssadump)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
source = flag.String("s", "", "only consider packages from this source")
|
source = flag.String("s", "", "only consider packages from this source")
|
||||||
verbose = flag.Bool("v", false, "verbose mode")
|
verbose = flag.Bool("v", false, "verbose mode")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
sources []string // sources of export data corresponding to importers
|
||||||
|
importers []types.Importer // importers for corresponding sources
|
||||||
importFailed = errors.New("import failed")
|
importFailed = errors.New("import failed")
|
||||||
importers = make(map[string]types.Importer)
|
|
||||||
packages = make(map[string]*types.Package)
|
packages = make(map[string]*types.Package)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,29 +48,16 @@ func main() {
|
|||||||
|
|
||||||
imp := tryImport
|
imp := tryImport
|
||||||
if *source != "" {
|
if *source != "" {
|
||||||
imp = importers[*source]
|
imp = lookup(*source)
|
||||||
if imp == nil {
|
if imp == nil {
|
||||||
report("source must be one of: " + importersList())
|
report("source (-s argument) must be one of: " + strings.Join(sources, ", "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, arg := range flag.Args() {
|
for _, arg := range flag.Args() {
|
||||||
|
path, name := splitPathIdent(arg)
|
||||||
if *verbose {
|
if *verbose {
|
||||||
fmt.Fprintf(os.Stderr, "(processing %s)\n", arg)
|
fmt.Fprintf(os.Stderr, "(processing %q: path = %q, name = %s)\n", arg, path, name)
|
||||||
}
|
|
||||||
|
|
||||||
// determine import path, object name
|
|
||||||
var path, name string
|
|
||||||
elems := strings.Split(arg, ".")
|
|
||||||
switch len(elems) {
|
|
||||||
case 2:
|
|
||||||
name = elems[1]
|
|
||||||
fallthrough
|
|
||||||
case 1:
|
|
||||||
path = elems[0]
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(os.Stderr, "ignoring %q: invalid path or (qualified) identifier\n", arg)
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// import package
|
// import package
|
||||||
@ -81,7 +68,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// filter objects if needed
|
// filter objects if needed
|
||||||
filter := exportFilter
|
filter := types.Object.Exported
|
||||||
if name != "" {
|
if name != "" {
|
||||||
f := filter
|
f := filter
|
||||||
filter = func(obj types.Object) bool {
|
filter = func(obj types.Object) bool {
|
||||||
@ -109,9 +96,9 @@ func protect(imp types.Importer) types.Importer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tryImport(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
|
func tryImport(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
|
||||||
for source, imp := range importers {
|
for i, imp := range importers {
|
||||||
if *verbose {
|
if *verbose {
|
||||||
fmt.Fprintf(os.Stderr, "(trying as %s)\n", source)
|
fmt.Fprintf(os.Stderr, "(trying source: %s)\n", sources[i])
|
||||||
}
|
}
|
||||||
pkg, err = imp(packages, path)
|
pkg, err = imp(packages, path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -121,25 +108,36 @@ func tryImport(packages map[string]*types.Package, path string) (pkg *types.Pack
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func register(source string, imp types.Importer) {
|
// splitPathIdent splits a path.name argument into its components.
|
||||||
if _, ok := importers[source]; ok {
|
// All but the last path element may contain dots.
|
||||||
panic(source + " importer already registered")
|
// TODO(gri) document this also in doc.go.
|
||||||
}
|
func splitPathIdent(arg string) (path, name string) {
|
||||||
importers[source] = imp
|
const sep = string(filepath.Separator)
|
||||||
}
|
if i := strings.LastIndex(arg, "."); i >= 0 {
|
||||||
|
if j := strings.LastIndex(arg, sep); j < i {
|
||||||
func importersList() string {
|
// '.' is not part of path
|
||||||
var s string
|
path = arg[:i]
|
||||||
for n := range importers {
|
name = arg[i+1:]
|
||||||
if len(s) == 0 {
|
return
|
||||||
s = n
|
|
||||||
} else {
|
|
||||||
s = s + ", " + n
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s
|
path = arg
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportFilter(obj types.Object) bool {
|
func register(src string, imp types.Importer) {
|
||||||
return obj.Exported()
|
if lookup(src) != nil {
|
||||||
|
panic(src + " importer already registered")
|
||||||
|
}
|
||||||
|
sources = append(sources, src)
|
||||||
|
importers = append(importers, imp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func lookup(src string) types.Importer {
|
||||||
|
for i, s := range sources {
|
||||||
|
if s == src {
|
||||||
|
return importers[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user