func (p *PackageView) PrintVars(w io.Writer, vars []*ValueDoc, level int, tag string, tag_folder string) { if len(tag_folder) > 0 && len(vars) > 0 { if tag_folder == tag_value_folder { fmt.Fprintf(w, "%d,%s,Variables\n", level, tag_folder) } else if tag_folder == tag_const_folder { fmt.Fprintf(w, "%d,%s,Constants\n", level, tag_folder) } level++ } for _, v := range vars { if v.Decl == nil { continue } for _, s := range v.Decl.Specs { if m, ok := s.(*ast.ValueSpec); ok { pos := p.fset.Position(m.Pos()) for i := 0; i < len(m.Names); i++ { if p.expr && m.Type != nil { fmt.Fprintf(w, "%d,%s,%s,%s@%s\n", level, tag, m.Names[i], p.posText(pos), types.ExprString(m.Type)) } else { fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag, m.Names[i], p.posText(pos)) } } } } } }
func (p *PackageView) printFuncsHelper(w io.Writer, funcs []*FuncDoc, level int, tag string, tag_folder string) { for _, f := range funcs { pos := p.fset.Position(f.Decl.Pos()) if p.expr { fmt.Fprintf(w, "%d,%s,%s,%s@%s\n", level, tag, f.Name, p.posText(pos), types.ExprString(f.Decl.Type)) } else { fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag, f.Name, p.posText(pos)) } } }
func parseCore(dir string) (services []Service, listeners []Service, err error) { dirFile, err := os.Open(dir) if err != nil { return nil, nil, err } defer dirFile.Close() info, err := dirFile.Stat() if err != nil { return nil, nil, err } if !info.IsDir() { return nil, nil, errors.New("Path is not a directory: " + dir) } pkgs, err := parser.ParseDir(token.NewFileSet(), dir, filter, 0) if err != nil { return nil, nil, err } for _, pkg := range pkgs { for _, f := range pkg.Files { for name, object := range f.Scope.Objects { if object.Kind == ast.Typ && ast.IsExported(name) { services = append(services, Service{Name: name}) if strings.HasSuffix(strings.ToLower(name), "listener") { service := Service{Name: name} ts, t := object.Decl.(*ast.TypeSpec) if !t { continue } i, t := ts.Type.(*ast.InterfaceType) if !t { continue } // var fl FieldList fl := i.Methods // var f Field for _, f := range fl.List { // function/method name jsname := FirstToLower(f.Names[0].Name) ft := f.Type.(*ast.FuncType) var args []MethodArgs for i := 0; i < ft.Params.NumFields(); i++ { p := ft.Params.List[i] // argument name n := strings.ToLower(p.Names[0].Name) // argument type name t := types.ExprString(p.Type) args = append(args, MethodArgs{Name: n, Type: t}) } m := Method{Service: name, JsMethod: jsname, Id: name, Method: f.Names[0].Name, Args: args} service.Methods = append(service.Methods, m) } listeners = append(listeners, service) } } } } } { dirs, err := dirFile.Readdir(-1) if err != nil { return nil, nil, err } for _, info := range dirs { if info.IsDir() { t, tt, err := parseCore(path.Join(dir, info.Name())) if err != nil { return nil, nil, err } services = append(services, t...) listeners = append(listeners, tt...) } } } return services, listeners, nil }
func parseDir(dir string) ([]Service, error) { var services []Service dirFile, err := os.Open(dir) if err != nil { return nil, err } defer dirFile.Close() info, err := dirFile.Stat() if err != nil { return nil, err } if !info.IsDir() { return nil, errors.New("Path is not a directory: " + dir) } pkgs, err := parser.ParseDir(token.NewFileSet(), dir, filter, 0) if err != nil { return nil, err } for _, pkg := range pkgs { for ffname, f := range pkg.Files { fnamebase := path.Base(ffname) // file name without ext fname := strings.TrimRight(fnamebase, path.Ext(ffname)) for name, object := range f.Scope.Objects { if object.Kind == ast.Typ && ast.IsExported(name) && strings.HasPrefix(strings.ToLower(name), strings.ToLower(fname)) { service := Service{Name: name} for d := range f.Decls { // var f *ast.FuncDecl f, t := f.Decls[d].(*ast.FuncDecl) if t { if f.Recv == nil { continue } // get "m *Type" string of member function that := "" for i := 0; i < f.Recv.NumFields(); i++ { a := f.Recv.List[i].Type.(*ast.StarExpr) that = types.ExprString(a.X) } // if function is not member of structure skip it if that != name { continue } // function/method name jsname := FirstToLower(f.Name.String()) // var ft ast.FuncType ft := f.Type var args []MethodArgs for i := 0; i < ft.Params.NumFields(); i++ { // var p ast.Field p := ft.Params.List[i] // argument name n := strings.ToLower(p.Names[0].Name) // argument type name t := types.ExprString(p.Type) // does type contain word 'listener'? l := strings.Contains(strings.ToLower(t), "listener") // check if it has 'add' prefix la := l && strings.Contains(strings.ToLower(jsname), "add") // check if it has 'remove' prefix lr := l && strings.Contains(strings.ToLower(jsname), "remove") args = append(args, MethodArgs{Name: n, Type: t, Listener: l, ListenerAdd: la, ListenerRemove: lr}) } m := Method{Service: name, JsMethod: jsname, Id: name, Method: f.Name.String(), Args: args} service.Methods = append(service.Methods, m) } } services = append(services, service) } } } } { dirs, err := dirFile.Readdir(-1) if err != nil { return nil, err } for _, info := range dirs { if info.IsDir() { t, e := parseDir(path.Join(dir, info.Name())) if e != nil { return nil, e } services = append(services, t...) } } } return services, nil }
func (p *PackageView) PrintTypeFields(w io.Writer, decl *ast.GenDecl, level int) { spec, ok := decl.Specs[0].(*ast.TypeSpec) if ok == false { return } switch d := spec.Type.(type) { case *ast.StructType: for _, list := range d.Fields.List { if list.Names == nil { continue } for _, m := range list.Names { pos := p.fset.Position(m.Pos()) if list.Type != nil { fmt.Fprintf(w, "%d,%s,%s,%s@%s\n", level, tag_type_value, m.Name, p.posText(pos), types.ExprString(list.Type)) } else { fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag_type_value, m.Name, p.posText(pos)) } } } case *ast.InterfaceType: for _, list := range d.Methods.List { if list.Names == nil { continue } for _, m := range list.Names { pos := p.fset.Position(m.Pos()) fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag_type_method, m.Name, p.posText(pos)) } } } }