mirror of
https://github.com/golang/go
synced 2024-11-18 18:44:42 -07:00
go.tools/cmd/godex: fix prefix generation, filtering, formatting
Details: - auto-generate prefixes for std lib (e.g., "godex big" works now) - apply filtering to package-level objects only - nicer formatting of single-entry const, var, or type declaration TBR=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/81360046
This commit is contained in:
parent
069e8474de
commit
700390eaed
@ -76,12 +76,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// filter objects if needed
|
// filter objects if needed
|
||||||
filter := types.Object.Exported
|
var filter func(types.Object) bool
|
||||||
if name != "" {
|
if name != "" {
|
||||||
f := filter
|
|
||||||
filter = func(obj types.Object) bool {
|
filter = func(obj types.Object) bool {
|
||||||
// TODO(gri) perhaps use regular expression matching here?
|
// TODO(gri) perhaps use regular expression matching here?
|
||||||
return f(obj) && obj.Name() == name
|
return obj.Name() == name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +175,8 @@ func lookup(src string) types.Importer {
|
|||||||
func genPrefixes(out chan string) {
|
func genPrefixes(out chan string) {
|
||||||
out <- "" // try no prefix
|
out <- "" // try no prefix
|
||||||
platform := build.Default.GOOS + "_" + build.Default.GOARCH
|
platform := build.Default.GOOS + "_" + build.Default.GOARCH
|
||||||
for _, dirname := range filepath.SplitList(build.Default.GOPATH) {
|
dirnames := append([]string{build.Default.GOROOT}, filepath.SplitList(build.Default.GOPATH)...)
|
||||||
|
for _, dirname := range dirnames {
|
||||||
walkDir(filepath.Join(dirname, "pkg", platform), "", out)
|
walkDir(filepath.Join(dirname, "pkg", platform), "", out)
|
||||||
}
|
}
|
||||||
close(out)
|
close(out)
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
"code.google.com/p/go.tools/go/types"
|
"code.google.com/p/go.tools/go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(gri) filter unexported fields of struct types?
|
|
||||||
// TODO(gri) use tabwriter for alignment?
|
// TODO(gri) use tabwriter for alignment?
|
||||||
|
// TODO(gri) should print intuitive method sets
|
||||||
|
|
||||||
func print(w io.Writer, pkg *types.Package, filter func(types.Object) bool) {
|
func print(w io.Writer, pkg *types.Package, filter func(types.Object) bool) {
|
||||||
var p printer
|
var p printer
|
||||||
@ -62,7 +62,10 @@ func (p *printer) printPackage(pkg *types.Package, filter func(types.Object) boo
|
|||||||
)
|
)
|
||||||
scope := pkg.Scope()
|
scope := pkg.Scope()
|
||||||
for _, name := range scope.Names() {
|
for _, name := range scope.Names() {
|
||||||
if obj := scope.Lookup(name); filter(obj) {
|
obj := scope.Lookup(name)
|
||||||
|
if obj.Exported() {
|
||||||
|
// collect top-level exported and possibly filtered objects
|
||||||
|
if filter == nil || filter(obj) {
|
||||||
switch obj := obj.(type) {
|
switch obj := obj.(type) {
|
||||||
case *types.Const:
|
case *types.Const:
|
||||||
consts = append(consts, obj)
|
consts = append(consts, obj)
|
||||||
@ -82,8 +85,9 @@ func (p *printer) printPackage(pkg *types.Package, filter func(types.Object) boo
|
|||||||
// for unsafe.Sizeof, etc.
|
// for unsafe.Sizeof, etc.
|
||||||
builtins = append(builtins, obj)
|
builtins = append(builtins, obj)
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// type is filtered out but may contain visible methods
|
} else if filter == nil {
|
||||||
|
// no filtering: collect top-level unexported types with methods
|
||||||
if obj, _ := obj.(*types.TypeName); obj != nil {
|
if obj, _ := obj.(*types.TypeName); obj != nil {
|
||||||
// see case *types.TypeName above
|
// see case *types.TypeName above
|
||||||
if named, _ := obj.Type().(*types.Named); named != nil && named.NumMethods() > 0 {
|
if named, _ := obj.Type().(*types.Named); named != nil && named.NumMethods() > 0 {
|
||||||
@ -93,75 +97,88 @@ func (p *printer) printPackage(pkg *types.Package, filter func(types.Object) boo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.printf("package %s // %q\n\n", pkg.Name(), pkg.Path())
|
p.printf("package %s // %q\n", pkg.Name(), pkg.Path())
|
||||||
|
|
||||||
if len(consts) > 0 {
|
p.printDecl("const", len(consts), func() {
|
||||||
p.print("const (\n")
|
|
||||||
p.indent++
|
|
||||||
for _, obj := range consts {
|
for _, obj := range consts {
|
||||||
p.printObj(obj)
|
p.printObj(obj)
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
}
|
}
|
||||||
p.indent--
|
})
|
||||||
p.print(")\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(vars) > 0 {
|
p.printDecl("var", len(vars), func() {
|
||||||
p.print("var (\n")
|
|
||||||
p.indent++
|
|
||||||
for _, obj := range vars {
|
for _, obj := range vars {
|
||||||
p.printObj(obj)
|
p.printObj(obj)
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
}
|
}
|
||||||
p.indent--
|
})
|
||||||
p.print(")\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(typez) > 0 {
|
p.printDecl("type", len(typez), func() {
|
||||||
p.print("type (\n")
|
|
||||||
p.indent++
|
|
||||||
for _, obj := range typez {
|
for _, obj := range typez {
|
||||||
p.printf("%s ", obj.Name())
|
p.printf("%s ", obj.Name())
|
||||||
p.writeType(p.pkg, obj.Type().Underlying())
|
p.writeType(p.pkg, obj.Type().Underlying())
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
}
|
}
|
||||||
p.indent--
|
})
|
||||||
p.print(")\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, typ := range typem {
|
for _, typ := range typem {
|
||||||
hasEntries := false
|
first := true
|
||||||
if obj := typ.Obj(); filter(obj) {
|
if obj := typ.Obj(); obj.Exported() {
|
||||||
|
if first {
|
||||||
|
p.print("\n")
|
||||||
|
first = false
|
||||||
|
}
|
||||||
p.printf("type %s ", obj.Name())
|
p.printf("type %s ", obj.Name())
|
||||||
p.writeType(p.pkg, typ.Underlying())
|
p.writeType(p.pkg, typ.Underlying())
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
hasEntries = true
|
|
||||||
}
|
}
|
||||||
for i, n := 0, typ.NumMethods(); i < n; i++ {
|
for i, n := 0, typ.NumMethods(); i < n; i++ {
|
||||||
if obj := typ.Method(i); filter(obj) {
|
if obj := typ.Method(i); obj.Exported() {
|
||||||
|
if first {
|
||||||
|
p.print("\n")
|
||||||
|
first = false
|
||||||
|
}
|
||||||
p.printFunc(obj)
|
p.printFunc(obj)
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
hasEntries = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hasEntries {
|
|
||||||
p.print("\n")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(funcs) > 0 {
|
||||||
|
p.print("\n")
|
||||||
for _, obj := range funcs {
|
for _, obj := range funcs {
|
||||||
p.printFunc(obj)
|
p.printFunc(obj)
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(gri) better handling of builtins (package unsafe only)
|
// TODO(gri) better handling of builtins (package unsafe only)
|
||||||
|
if len(builtins) > 0 {
|
||||||
|
p.print("\n")
|
||||||
for _, obj := range builtins {
|
for _, obj := range builtins {
|
||||||
p.printf("func %s() // builtin\n", obj.Name())
|
p.printf("func %s() // builtin\n", obj.Name())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p.print("\n")
|
p.print("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *printer) printDecl(keyword string, n int, printGroup func()) {
|
||||||
|
switch n {
|
||||||
|
case 0:
|
||||||
|
// nothing to do
|
||||||
|
case 1:
|
||||||
|
p.printf("\n%s ", keyword)
|
||||||
|
printGroup()
|
||||||
|
default:
|
||||||
|
p.printf("\n%s (\n", keyword)
|
||||||
|
p.indent++
|
||||||
|
printGroup()
|
||||||
|
p.indent--
|
||||||
|
p.print(")\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *printer) printObj(obj types.Object) {
|
func (p *printer) printObj(obj types.Object) {
|
||||||
p.printf("%s", obj.Name())
|
p.printf("%s", obj.Name())
|
||||||
// don't write untyped types (for constants)
|
// don't write untyped types (for constants)
|
||||||
@ -170,6 +187,7 @@ func (p *printer) printObj(obj types.Object) {
|
|||||||
p.writeType(p.pkg, typ)
|
p.writeType(p.pkg, typ)
|
||||||
}
|
}
|
||||||
// write constant value
|
// write constant value
|
||||||
|
// TODO(gri) use floating-point notation for exact floating-point numbers (fractions)
|
||||||
if obj, ok := obj.(*types.Const); ok {
|
if obj, ok := obj.(*types.Const); ok {
|
||||||
p.printf(" = %s", obj.Val())
|
p.printf(" = %s", obj.Val())
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,6 @@ func (p *printer) writeTypeInternal(this *types.Package, typ types.Type, visited
|
|||||||
p.writeTypeInternal(this, t.Elem(), visited)
|
p.writeTypeInternal(this, t.Elem(), visited)
|
||||||
|
|
||||||
case *types.Struct:
|
case *types.Struct:
|
||||||
// TODO(gri) filter fields?
|
|
||||||
n := t.NumFields()
|
n := t.NumFields()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
p.print("struct{}")
|
p.print("struct{}")
|
||||||
@ -110,7 +109,6 @@ func (p *printer) writeTypeInternal(this *types.Package, typ types.Type, visited
|
|||||||
// m() interface{ T }
|
// m() interface{ T }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// TODO(gri) filter methods?
|
|
||||||
n := t.NumMethods()
|
n := t.NumMethods()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
p.print("interface{}")
|
p.print("interface{}")
|
||||||
|
Loading…
Reference in New Issue
Block a user