diff --git a/_examples/mockgen/main.go b/_examples/mockgen/main.go index 28d8698..ac9682e 100644 --- a/_examples/mockgen/main.go +++ b/_examples/mockgen/main.go @@ -65,7 +65,7 @@ func run() (rerr error) { } opt := &knife.Option{ - ExtraData: map[string]interface{}{ + ExtraData: map[string]any{ "type": flag.Arg(0), }, } diff --git a/ast.go b/ast.go index 75c5dc8..d8066fd 100644 --- a/ast.go +++ b/ast.go @@ -69,7 +69,7 @@ func (n *ASTNode) Uint64Val() uint64 { } -func (n *ASTNode) Val() interface{} { +func (n *ASTNode) Val() any { return constant.Val(n.Value) } diff --git a/cmd/hagane/main.go b/cmd/hagane/main.go index 763eae9..0b30b75 100644 --- a/cmd/hagane/main.go +++ b/cmd/hagane/main.go @@ -54,7 +54,7 @@ func run() (rerr error) { return errors.New("does not find package") } - var tmpl interface{} = flagFormat + var tmpl any = flagFormat if flagTemplate != "" { tmpl, err = os.ReadFile(flagTemplate) if err != nil { diff --git a/cmd/knife/main.go b/cmd/knife/main.go index d4a69da..0c1235c 100644 --- a/cmd/knife/main.go +++ b/cmd/knife/main.go @@ -60,7 +60,7 @@ func run(args []string) error { opt.ExtraData = extraData } - var tmpl interface{} = flagFormat + var tmpl any = flagFormat if flagTemplate != "" { tmpl, err = os.ReadFile(flagTemplate) if err != nil { @@ -83,8 +83,8 @@ func run(args []string) error { return nil } -func parseExtraData(extraData string) (map[string]interface{}, error) { - m := map[string]interface{}{} +func parseExtraData(extraData string) (map[string]any, error) { + m := map[string]any{} kvs := strings.Split(extraData, ",") for i := range kvs { kv := strings.Split(strings.TrimSpace(kvs[i]), ":") diff --git a/cmd/objls/main.go b/cmd/objls/main.go index 1369cdb..947e2d7 100644 --- a/cmd/objls/main.go +++ b/cmd/objls/main.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "os" + "path/filepath" "github.com/newmo-oss/gogroup" @@ -17,11 +18,13 @@ import ( var ( flagFilter string flagExported bool + flagPos bool ) func init() { flag.StringVar(&flagFilter, "f", "all", "object filter(all|const|func|var)") flag.BoolVar(&flagExported, "exported", true, "filter only exported object") + flag.BoolVar(&flagPos, "pos", false, "print position") flag.Parse() } @@ -56,8 +59,15 @@ func run(ctx context.Context, args []string) error { } if match(flagFilter, obj) { - if _, err := fmt.Fprintf(&buf, "%s.%s\n", pkg.Path, name); err != nil { - return err + if flagPos { + pos := c.Position(obj) + if _, err := fmt.Fprintf(&buf, "%s.%s(%s:%d)\n", pkg.Path, name, filepath.Base(pos.Filename), pos.Line); err != nil { + return err + } + } else { + if _, err := fmt.Fprintf(&buf, "%s.%s\n", pkg.Path, name); err != nil { + return err + } } } } diff --git a/cmd/typels/main.go b/cmd/typels/main.go index eabcc7e..72d6090 100644 --- a/cmd/typels/main.go +++ b/cmd/typels/main.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "os" + "path/filepath" "github.com/newmo-oss/gogroup" @@ -17,11 +18,13 @@ import ( var ( flagFilter string flagExported bool + flagPos bool ) func init() { flag.StringVar(&flagFilter, "f", "all", "object filter(all|interface|func|struct|chan|array|slice|map)") flag.BoolVar(&flagExported, "exported", true, "filter only exported types") + flag.BoolVar(&flagPos, "pos", false, "print position") flag.Parse() } @@ -57,8 +60,15 @@ func run(ctx context.Context, args []string) error { } if typ.Exported && match(flagFilter, typ) { - if _, err := fmt.Fprintf(&buf, "%s.%s\n", pkg.Path, name); err != nil { - return err + if flagPos { + pos := c.Position(typ) + if _, err := fmt.Fprintf(&buf, "%s.%s(%s:%d)\n", pkg.Path, name, filepath.Base(pos.Filename), pos.Line); err != nil { + return err + } + } else { + if _, err := fmt.Fprintf(&buf, "%s.%s\n", pkg.Path, name); err != nil { + return err + } } } } diff --git a/cutter/cutter.go b/cutter/cutter.go index bd67585..fa42788 100644 --- a/cutter/cutter.go +++ b/cutter/cutter.go @@ -58,6 +58,15 @@ func (c *Cutter) Packages() []*packages.Package { return c.pkgs } +// Position returns position of v. +func (c *Cutter) Position(v any) token.Position { + n, ok := v.(interface{ Pos() token.Pos }) + if ok && c.fset != nil { + return c.fset.Position(n.Pos()) + } + return token.Position{} +} + // KnifePackages returns knife packages. func (c *Cutter) KnifePackages() []*knife.Package { return c.knifePkgs diff --git a/knife.go b/knife.go index 2660b6d..0037e6b 100644 --- a/knife.go +++ b/knife.go @@ -4,6 +4,7 @@ import ( _ "embed" "fmt" "go/ast" + "go/token" "io" "strings" @@ -21,6 +22,7 @@ func Version() string { } type Knife struct { + fset *token.FileSet pkgs []*packages.Package ins map[*packages.Package]*inspector.Inspector } @@ -28,7 +30,10 @@ type Knife struct { func New(patterns ...string) (*Knife, error) { mode := packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedDeps | packages.NeedTypesInfo - cfg := &packages.Config{Mode: mode} + cfg := &packages.Config{ + Fset: token.NewFileSet(), + Mode: mode, + } pkgs, err := packages.Load(cfg, patterns...) if err != nil { @@ -40,7 +45,11 @@ func New(patterns ...string) (*Knife, error) { ins[pkg] = inspector.New(pkg.Syntax) } - return &Knife{pkgs: pkgs, ins: ins}, nil + return &Knife{ + fset: cfg.Fset, + pkgs: pkgs, + ins: ins, + }, nil } // Packages returns packages. @@ -48,14 +57,23 @@ func (k *Knife) Packages() []*packages.Package { return k.pkgs } +// Position returns position of v. +func (k *Knife) Position(v any) token.Position { + n, ok := v.(interface{ Pos() token.Pos }) + if ok && k.fset != nil { + return k.fset.Position(n.Pos()) + } + return token.Position{} +} + // Option is a option of Execute. type Option struct { XPath string - ExtraData map[string]interface{} + ExtraData map[string]any } // Execute outputs the pkg with the format. -func (k *Knife) Execute(w io.Writer, pkg *packages.Package, tmpl interface{}, opt *Option) error { +func (k *Knife) Execute(w io.Writer, pkg *packages.Package, tmpl any, opt *Option) error { var tmplStr string switch tmpl := tmpl.(type) { @@ -85,7 +103,7 @@ func (k *Knife) Execute(w io.Writer, pkg *packages.Package, tmpl interface{}, op return fmt.Errorf("template parse: %w", err) } - var data interface{} + var data any switch { case opt != nil && opt.XPath != "": @@ -104,7 +122,7 @@ func (k *Knife) Execute(w io.Writer, pkg *packages.Package, tmpl interface{}, op return nil } -func (k *Knife) evalXPath(pkg *packages.Package, xpath string) (interface{}, error) { +func (k *Knife) evalXPath(pkg *packages.Package, xpath string) (any, error) { e := astquery.New(pkg.Fset, pkg.Syntax, k.ins[pkg]) v, err := e.Eval(xpath) if err != nil { diff --git a/objects.go b/objects.go index e14f4c9..a246cd8 100644 --- a/objects.go +++ b/objects.go @@ -303,11 +303,11 @@ func (c *Const) Uint64Val() uint64 { } -func (c *Const) Val() interface{} { +func (c *Const) Val() any { return constant.Val(c.Value) } -func Position(fset *token.FileSet, v interface{}) token.Position { +func Position(fset *token.FileSet, v any) token.Position { n, ok := v.(interface{ Pos() token.Pos }) if ok && fset != nil { return fset.Position(n.Pos()) @@ -315,7 +315,7 @@ func Position(fset *token.FileSet, v interface{}) token.Position { return token.Position{} } -func Exported(list interface{}) interface{} { +func Exported(list any) any { v := reflect.ValueOf(list) switch v.Kind() { case reflect.Slice, reflect.Array: @@ -326,7 +326,7 @@ func Exported(list interface{}) interface{} { panic("unexpected kind") } -func exportedSlice(v reflect.Value) interface{} { +func exportedSlice(v reflect.Value) any { result := reflect.MakeSlice(v.Type(), 0, 0) for i := 0; i < v.Len(); i++ { elm := v.Index(i) @@ -337,7 +337,7 @@ func exportedSlice(v reflect.Value) interface{} { return result.Interface() } -func exportedMap(v reflect.Value) interface{} { +func exportedMap(v reflect.Value) any { result := reflect.MakeMap(v.Type()) for _, key := range v.MapKeys() { elm := v.MapIndex(key) diff --git a/template.go b/template.go index 874874d..f1df548 100644 --- a/template.go +++ b/template.go @@ -19,7 +19,7 @@ type TempalteData struct { Files []*ast.File TypesInfo *types.Info Pkg *types.Package - Extra map[string]interface{} + Extra map[string]any } // NewTemplate creates new a template with funcmap. @@ -44,8 +44,8 @@ func newFuncMap(td *TempalteData) template.FuncMap { "signature": ToSignature, "slice": ToSlice, "struct": ToStruct, - "len": func(v interface{}) int { return reflect.ValueOf(v).Len() }, - "cap": func(v interface{}) int { return reflect.ValueOf(v).Cap() }, + "len": func(v any) int { return reflect.ValueOf(v).Len() }, + "cap": func(v any) int { return reflect.ValueOf(v).Cap() }, "last": td.last, "exported": Exported, "methods": Methods, @@ -53,15 +53,15 @@ func newFuncMap(td *TempalteData) template.FuncMap { "implements": implements, "identical": identical, "under": under, - "pos": func(v interface{}) token.Position { return Position(td.Fset, v) }, + "pos": func(v any) token.Position { return Position(td.Fset, v) }, "objectof": func(s string) Object { return td.objectOf(s) }, "typeof": func(s string) *Type { return td.typeOf(s) }, - "doc": func(v interface{}) string { return td.doc(cmaps, v) }, - "data": func(k string) interface{} { return td.Extra[k] }, + "doc": func(v any) string { return td.doc(cmaps, v) }, + "data": func(k string) any { return td.Extra[k] }, } } -func (td *TempalteData) names(slice interface{}) string { +func (td *TempalteData) names(slice any) string { vs := reflect.ValueOf(slice) switch vs.Kind() { case reflect.Slice, reflect.Array: @@ -149,7 +149,7 @@ func (td *TempalteData) typeOf(s string) *Type { return NewType(obj.TypesObject().Type()) } -func (td *TempalteData) doc(cmaps comment.Maps, v interface{}) string { +func (td *TempalteData) doc(cmaps comment.Maps, v any) string { node, ok := v.(interface{ Pos() token.Pos }) if !ok { return "" @@ -168,7 +168,7 @@ func (td *TempalteData) doc(cmaps comment.Maps, v interface{}) string { return "" } -func (td *TempalteData) last(v interface{}) interface{} { +func (td *TempalteData) last(v any) any { _v := reflect.ValueOf(v) return _v.Index(_v.Len() - 1).Interface() } diff --git a/types.go b/types.go index f903ef5..3e99640 100644 --- a/types.go +++ b/types.go @@ -111,7 +111,7 @@ func NewArray(a *types.Array) *Array { return &na } -func ToArray(t interface{}) *Array { +func ToArray(t any) *Array { switch t := t.(type) { case *Type: return t.Array() @@ -151,7 +151,7 @@ func NewSlice(s *types.Slice) *Slice { return &ns } -func ToSlice(t interface{}) *Slice { +func ToSlice(t any) *Slice { switch t := t.(type) { case *Type: return t.Slice() @@ -199,7 +199,7 @@ func NewStruct(s *types.Struct) *Struct { return &ns } -func ToStruct(t interface{}) *Struct { +func ToStruct(t any) *Struct { switch t := t.(type) { case *Type: return t.Struct() @@ -243,7 +243,7 @@ func NewMap(m *types.Map) *Map { return &nm } -func ToMap(t interface{}) *Map { +func ToMap(t any) *Map { switch t := t.(type) { case *Type: return t.Map() @@ -285,7 +285,7 @@ func NewPointer(p *types.Pointer) *Pointer { return &np } -func ToPointer(t interface{}) *Pointer { +func ToPointer(t any) *Pointer { switch t := t.(type) { case *Type: return t.Pointer() @@ -329,7 +329,7 @@ func NewChan(c *types.Chan) *Chan { return &nc } -func ToChan(t interface{}) *Chan { +func ToChan(t any) *Chan { switch t := t.(type) { case *Type: return t.Chan() @@ -376,7 +376,7 @@ func NewBasic(b *types.Basic) *Basic { return nb } -func ToBasic(t interface{}) *Basic { +func ToBasic(t any) *Basic { switch t := t.(type) { case *Type: return t.Basic() @@ -444,7 +444,7 @@ func NewInterface(iface *types.Interface) *Interface { return &ni } -func ToInterface(t interface{}) *Interface { +func ToInterface(t any) *Interface { switch t := t.(type) { case *Type: return t.Interface() @@ -500,7 +500,7 @@ func NewSignature(s *types.Signature) *Signature { return &ns } -func ToSignature(t interface{}) *Signature { +func ToSignature(t any) *Signature { switch t := t.(type) { case *Type: return t.Signature() @@ -552,7 +552,7 @@ func NewNamed(n *types.Named) *Named { return &nn } -func ToNamed(t interface{}) *Named { +func ToNamed(t any) *Named { switch t := t.(type) { case *Type: return t.Named() @@ -568,7 +568,7 @@ func (c *Named) String() string { return c.TypesNamed.String() } -func Methods(v interface{}) map[string]*Func { +func Methods(v any) map[string]*Func { methods := map[string]*Func{} switch t := v.(type) { case *Type: @@ -604,7 +604,7 @@ func under(t types.Type) types.Type { return t.Underlying() } -func implements(t interface{}, iface interface{}) bool { +func implements(t any, iface any) bool { if t == nil || iface == nil { return false } @@ -668,7 +668,7 @@ func implements(t interface{}, iface interface{}) bool { return types.Implements(_t, _iface) || types.Implements(types.NewPointer(_t), _iface) } -func identical(t1, t2 interface{}) bool { +func identical(t1, t2 any) bool { if t1 == nil || t2 == nil { return false }