func doSpec(sk int, sv interface{}, dirpkg string) { //Printf("doSpec: %#v\n", sv) switch x := sv.(type) { case (*ast.ImportSpec): path := x.Path.Value path = path[1 : len(path)-1] // Omit initial & final <"> name := path j := strings.LastIndex(name, "/") if j > 0 { name = name[j+1:] } if x.Name != nil { name = x.Name.Name } //Printf("ImportSpec: NAME %s PATH %s\n", name, path) Printf("@@ %s { IMPORT %s path: %s }\n", dirpkg, name, path) case (*ast.TypeSpec): name := x.Name.Name if !ast.IsExported(x.Name.Name) { return } Printf("@@ %s { TYPE %s type: %s }\n", dirpkg, name, typeStr(x.Type)) case (*ast.ValueSpec): for _, nv := range x.Names { //Printf(" ValueSPEC [%d] %s : %s\n", nk, nv.Name, Cond(x.Type == nil, "nil", typeStr(x.Type))) if !ast.IsExported(nv.Name) { return } Printf("@@ %s { VALUE %s : %s }\n", dirpkg, nv.Name, Cond(x.Type == nil, "!", typeStr(x.Type))) } default: panic(Sprintf("doSpec: DEFAULT: %#v\n", x)) } }
func (g *Grapher) assignMethodPaths(named *types.Named, prefix []string, pkgscope bool) { for i := 0; i < named.NumMethods(); i++ { m := named.Method(i) path := append(append([]string{}, prefix...), m.Name()) g.paths[m] = path g.exported[m] = ast.IsExported(m.Name()) g.pkgscope[m] = pkgscope if s := m.Scope(); s != nil { g.assignPaths(s, path, false) } } if iface, ok := named.Underlying().(*types.Interface); ok { for i := 0; i < iface.NumExplicitMethods(); i++ { m := iface.Method(i) path := append(append([]string{}, prefix...), m.Name()) g.paths[m] = path g.exported[m] = ast.IsExported(m.Name()) g.pkgscope[m] = pkgscope if s := m.Scope(); s != nil { g.assignPaths(s, path, false) } } } }
// lintValueSpecDoc examines package-global variables and constants. // It complains if they are not individually declared, // or if they are not suitably documented in the right form (unless they are in a block that is commented). func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) { kind := "var" if gd.Tok == token.CONST { kind = "const" } if len(vs.Names) > 1 { // Check that none are exported. for _, n := range vs.Names { if ast.IsExported(n.Name) { f.errorf(vs, 1, "exported %s %s should have its own declaration", kind, n.Name) return } } } // Only one name. name := vs.Names[0].Name if !ast.IsExported(name) { return } if vs.Doc == nil { if gd.Doc == nil && !genDeclMissingComments[gd] { f.errorf(vs, 1, "exported %s %s should have comment or be unexported", kind, name) genDeclMissingComments[gd] = true } return } prefix := name + " " if !strings.HasPrefix(vs.Doc.Text(), prefix) { f.errorf(vs.Doc, 1, `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix) } }
// checkInPackageBlock performs safety checks for renames of // func/var/const/type objects in the package block. func (r *renamer) checkInPackageBlock(from types.Object) { // Check that there are no references to the name from another // package if the renaming would make it unexported. if ast.IsExported(from.Name()) && !ast.IsExported(r.to) { for pkg, info := range r.packages { if pkg == from.Pkg() { continue } if id := someUse(info, from); id != nil && !r.checkExport(id, pkg, from) { break } } } info := r.packages[from.Pkg()] // Check that in the package block, "init" is a function, and never referenced. if r.to == "init" { kind := objectKind(from) if kind == "func" { // Reject if intra-package references to it exist. for id, obj := range info.Uses { if obj == from { r.errorf(from.Pos(), "renaming this func %q to %q would make it a package initializer", from.Name(), r.to) r.errorf(id.Pos(), "\tbut references to it exist") break } } } else { r.errorf(from.Pos(), "you cannot have a %s at package level named %q", kind, r.to) } } // Check for conflicts between package block and all file blocks. for _, f := range info.Files { fileScope := info.Info.Scopes[f] b, prev := fileScope.LookupParent(r.to, token.NoPos) if b == fileScope { r.errorf(from.Pos(), "renaming this %s %q to %q would conflict", objectKind(from), from.Name(), r.to) r.errorf(prev.Pos(), "\twith this %s", objectKind(prev)) return // since checkInPackageBlock would report redundant errors } } // Check for conflicts in lexical scope. if from.Exported() { for _, info := range r.packages { r.checkInLexicalScope(from, info) } } else { r.checkInLexicalScope(from, info) } }
// checkInPackageBlock performs safety checks for renames of // func/var/const/type objects in the package block. func (r *Unexporter) checkInPackageBlock(objsToUpdate map[types.Object]string, from types.Object, to string) { // Check that there are no references to the name from another // package if the renaming would make it unexported. if ast.IsExported(from.Name()) && !ast.IsExported(to) { for pkg, info := range r.packages { if pkg == from.Pkg() { continue } if id := someUse(info, from); id != nil && !r.checkExport(id, pkg, from, to) { break } } } info := r.packages[from.Pkg()] lexinfo := r.lexInfo(info) // Check that in the package block, "init" is a function, and never referenced. if to == "init" { kind := objectKind(from) if kind == "func" { // Reject if intra-package references to it exist. if refs := lexinfo.Refs[from]; len(refs) > 0 { r.warn(from, r.errorf(from.Pos(), "renaming this func %q to %q would make it a package initializer", from.Name(), to), r.errorf(refs[0].Id.Pos(), "\tbut references to it exist")) } } else { r.warn(from, r.errorf(from.Pos(), "you cannot have a %s at package level named %q", kind, to)) } } // Check for conflicts between package block and all file blocks. for _, f := range info.Files { if prev, b := lexinfo.Blocks[f].Lookup(to); b == lexinfo.Blocks[f] { r.warn(from, r.errorf(from.Pos(), "renaming this %s %q to %q would conflict", objectKind(from), from.Name(), to), r.errorf(prev.Pos(), "\twith this %s", objectKind(prev))) return // since checkInPackageBlock would report redundant errors } } // Check for conflicts in lexical scope. if from.Exported() { for _, info := range r.packages { r.checkInLexicalScope(objsToUpdate, from, to, info) } } else { r.checkInLexicalScope(objsToUpdate, from, to, info) } }
func (p *Package) FuncLink(fn *ast.FuncDecl) string { recv := FuncReceiver(fn) if ast.IsExported(fn.Name.Name) && (recv == "" || ast.IsExported(recv)) { if recv != "" { return "#" + MethodId(recv, fn.Name.Name) } return "#" + FuncId(fn.Name.Name) } return p.ReversePos(fn) }
// interfaceMethods returns the expanded list of exported methods for an interface. // The boolean complete reports whether the list contains all methods (that is, the // interface has no unexported methods). // pkg is the complete package name ("net/http") // iname is the interface name. func (w *Walker) interfaceMethods(pkg, iname string) (methods []method, complete bool) { t, ok := w.interfaces[pkgSymbol{pkg, iname}] if !ok { log.Fatalf("failed to find interface %s.%s", pkg, iname) } complete = true for _, f := range t.Methods.List { typ := f.Type switch tv := typ.(type) { case *ast.FuncType: for _, mname := range f.Names { if ast.IsExported(mname.Name) { ft := typ.(*ast.FuncType) methods = append(methods, method{ name: mname.Name, sig: w.funcSigString(ft), }) } else { complete = false } } case *ast.Ident: embedded := typ.(*ast.Ident).Name if embedded == "error" { methods = append(methods, method{ name: "Error", sig: "() string", }) continue } if !ast.IsExported(embedded) { log.Fatalf("unexported embedded interface %q in exported interface %s.%s; confused", embedded, pkg, iname) } m, c := w.interfaceMethods(pkg, embedded) methods = append(methods, m...) complete = complete && c case *ast.SelectorExpr: lhs := w.nodeString(tv.X) rhs := w.nodeString(tv.Sel) fpkg, ok := w.selectorFullPkg[lhs] if !ok { log.Fatalf("can't resolve selector %q in interface %s.%s", lhs, pkg, iname) } m, c := w.interfaceMethods(fpkg, rhs) methods = append(methods, m...) complete = complete && c default: log.Fatalf("unknown type %T in interface field", typ) } } return }
func (v *annotationVisitor) Visit(n ast.Node) ast.Visitor { switch n := n.(type) { case *ast.TypeSpec: if n.Type != nil { ast.Walk(v, n.Type) } return nil case *ast.FuncDecl: if n.Recv != nil { ast.Walk(v, n.Recv) } if n.Type != nil { ast.Walk(v, n.Type) } return nil case *ast.Field: if n.Type != nil { ast.Walk(v, n.Type) } return nil case *ast.ValueSpec: if n.Type != nil { ast.Walk(v, n.Type) } return nil case *ast.FuncLit: if n.Type != nil { ast.Walk(v, n.Type) } return nil case *ast.CompositeLit: if n.Type != nil { ast.Walk(v, n.Type) } return nil case *ast.Ident: if !ast.IsExported(n.Name) { return nil } v.addAnnotation(n, "", n.Name) return nil case *ast.SelectorExpr: if !ast.IsExported(n.Sel.Name) { return nil } if i, ok := n.X.(*ast.Ident); ok { v.addAnnotation(n, i.Name, n.Sel.Name) return nil } } return v }
func getGenSpecs(opts *options, structArgs []*structArg) (genSpecs []*genSpec) { fset := token.NewFileSet() types := getAllTypes(fset) for _, structArg := range structArgs { g := newGenSpec(structArg.Pointer, structArg.Package, structArg.Name) genSpecs = append(genSpecs, g) key := joinName(structArg.Package, structArg.Name) typ, known := types[key] if known { g.Methods = getMethods(typ) s, err := getStructType(typ) if err == nil { fieldSpecs := getFieldSpecs(s, fset, opts) g.AddFieldSpecs(fieldSpecs) } } else { addError(fmt.Sprintf("%s is not a known struct type", key)) g.Methods = getMethods(nil) } if opts.ExportedOnly { if ast.IsExported(structArg.Name) { notes = append(notes, fmt.Sprintf("the %s type is already exported; the -e[xported] flag is redundant (ignored)", structArg.Name)) } else { addError(fmt.Sprintf("the %s type is not exported; the -e[xported] flag conflicts", structArg.Name)) } } } if opts.All { for key, typ := range types { pkg, name := splitName(key) if !opts.ExportedOnly || ast.IsExported(name) { g := newGenSpec(opts.AllPointer, pkg, name) g.Methods = getMethods(typ) s, err := getStructType(typ) if err == nil { fieldSpecs := getFieldSpecs(s, fset, opts) g.AddFieldSpecs(fieldSpecs) } genSpecs = append(genSpecs, g) } } } for _, g := range genSpecs { g.DetermineImports() } return }
// lintValueSpecDoc examines package-global variables and constants. // It complains if they are not individually declared, // or if they are not suitably documented in the right form (unless they are in a block that is commented). func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) { kind := "var" if gd.Tok == token.CONST { kind = "const" } if len(vs.Names) > 1 { // Check that none are exported except for the first. for _, n := range vs.Names[1:] { if ast.IsExported(n.Name) { f.errorf(vs, 1, category("comments"), "exported %s %s should have its own declaration", kind, n.Name) return } } } // Only one name. name := vs.Names[0].Name if !ast.IsExported(name) { return } if vs.Doc == nil && gd.Doc == nil { if genDeclMissingComments[gd] { return } block := "" if kind == "const" && gd.Lparen.IsValid() { block = " (or a comment on this block)" } f.errorf(vs, 1, link(docCommentsLink), category("comments"), "exported %s %s should have comment%s or be unexported", kind, name, block) genDeclMissingComments[gd] = true return } // If this GenDecl has parens and a comment, we don't check its comment form. if gd.Lparen.IsValid() && gd.Doc != nil { return } // The relevant text to check will be on either vs.Doc or gd.Doc. // Use vs.Doc preferentially. doc := vs.Doc if doc == nil { doc = gd.Doc } prefix := name + " " if !strings.HasPrefix(doc.Text(), prefix) { f.errorf(doc, 1, link(docCommentsLink), category("comments"), `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix) } }
func astFieldListToDecls(f *ast.FieldList, class int, flags int, scope *Scope) map[string]*Decl { count := 0 for _, field := range f.List { count += len(field.Names) } if count == 0 { return nil } decls := make(map[string]*Decl, count) for _, field := range f.List { for _, name := range field.Names { if flags&DECL_FOREIGN != 0 && !ast.IsExported(name.Name()) { continue } d := new(Decl) d.Name = name.Name() d.Type = field.Type d.Class = int16(class) d.Flags = int16(flags) d.Children = astTypeToChildren(field.Type, flags, scope) d.Embedded = astTypeToEmbedded(field.Type) d.Scope = scope d.ValueIndex = -1 d.init() decls[d.Name] = d } // add anonymous field as a child (type embedding) if class == DECL_VAR && field.Names == nil { tp := typePath(field.Type) if flags&DECL_FOREIGN != 0 && !ast.IsExported(tp.name) { continue } d := new(Decl) d.Name = tp.name d.Type = field.Type d.Class = int16(class) d.Flags = int16(flags) d.Scope = scope d.ValueIndex = -1 d.init() decls[d.Name] = d } } return decls }
func (scope *Scope) getPrimaryKey() string { var indirectValue reflect.Value indirectValue = reflect.Indirect(reflect.ValueOf(scope.Value)) if indirectValue.Kind() == reflect.Slice { indirectValue = reflect.New(indirectValue.Type().Elem()).Elem() } if !indirectValue.IsValid() { return "id" } scopeTyp := indirectValue.Type() for i := 0; i < scopeTyp.NumField(); i++ { fieldStruct := scopeTyp.Field(i) if !ast.IsExported(fieldStruct.Name) { continue } // if primaryKey tag found, return column name if fieldStruct.Tag.Get("primaryKey") != "" { return ToSnake(fieldStruct.Name) } } //If primaryKey tag not found, fallback to id return "id" }
// Get retrieves a single named value from the given builder. // If the value has not been set, it returns (nil, false). Otherwise, it will // return (value, true). // // If the named value was last set with Append or Extend, the returned value // will be a slice. If the given Builder has been registered with Register or // RegisterType and the given name is an exported field of the registered // struct, the returned slice will have the same type as that field. Otherwise // the slice will have type []interface{}. It will panic if the given name is a // registered struct's exported field and the value set on the Builder is not // assignable to the field. func Get(builder interface{}, name string) (interface{}, bool) { val, ok := getBuilderMap(builder).Lookup(name) if !ok { return nil, false } list, isList := val.(ps.List) if isList { arrayType := anyArrayType if ast.IsExported(name) { structType := getBuilderStructType(reflect.TypeOf(builder)) if structType != nil { field, ok := (*structType).FieldByName(name) if ok { arrayType = field.Type } } } val = listToSlice(list, arrayType).Interface() } return val, true }
func (c *compiler) VisitFuncProtoDecl(f *ast.FuncDecl) Value { var fn_type *types.Func fn_name := f.Name.String() exported := ast.IsExported(fn_name) if fn_name == "init" { // Make "init" functions anonymous. fn_name = "" // "init" functions aren't recorded by the parser, so f.Name.Obj is // not set. fn_type = &types.Func{ /* no params or result */ } } else { fn_type = f.Name.Obj.Type.(*types.Func) if c.module.Name == "main" && fn_name == "main" { exported = true } else { pkgname := c.pkgmap[f.Name.Obj] fn_name = pkgname + "." + fn_name } } llvm_fn_type := c.types.ToLLVM(fn_type).ElementType() fn := llvm.AddFunction(c.module.Module, fn_name, llvm_fn_type) if exported { fn.SetLinkage(llvm.ExternalLinkage) } result := c.NewLLVMValue(fn, fn_type) if f.Name.Obj != nil { f.Name.Obj.Data = result f.Name.Obj.Type = fn_type } return result }
func (symbols *Symbols) AddVar(d *ast.ValueSpec) { for _, name := range d.Names { if ast.IsExported(name.Name) { symbols.varcons = append(symbols.varcons, name.Name) } } }
func (w *Walker) walkVar(vs *ast.ValueSpec) { for i, ident := range vs.Names { if !ast.IsExported(ident.Name) { continue } typ := "" if vs.Type != nil { typ = w.nodeString(vs.Type) } else { if len(vs.Values) == 0 { log.Fatalf("no values for var %q", ident.Name) } if len(vs.Values) > 1 { log.Fatalf("more than 1 values in ValueSpec not handled, var %q", ident.Name) } var err error typ, err = w.varValueType(vs.Values[i]) if err != nil { log.Fatalf("unknown type of variable %q, type %T, error = %v\ncode: %s", ident.Name, vs.Values[i], err, w.nodeString(vs.Values[i])) } } w.emitFeature(fmt.Sprintf("var %s %s", ident, typ)) } }
func fillFunc(node *ast.FuncDecl, src string, fnct *Function) bool { if node.Name != nil { if !ast.IsExported(node.Name.Name) { return false } fnct.Name = node.Name.Name } else { return false } if node.Doc != nil { fnct.Doc = node.Doc.Text() } if node.Type != nil { if node.Type.Params != nil { fnct.Args = src[node.Type.Params.Pos() : node.Type.Params.End()-2] } if node.Type.Results != nil { fnct.Type = src[node.Type.Results.Pos()-1 : node.Type.Results.End()] } } if node.Recv != nil && len(node.Recv.List) > 0 { expr := node.Recv.List[0].Type recv := GetExprName(expr) if recv != "" { fnct.Recv = recv } } return true }
func (v *ControllerVisitor) Visit(node ast.Node) ast.Visitor { if node == nil { return nil } switch x := node.(type) { case *ast.GenDecl: if x.Tok == token.IMPORT { for _, s := range x.Specs { if spec, ok := s.(*ast.ImportSpec); ok { p := spec.Path.Value v.imports[p[1:len(p)-1]] = true } } // I think this is ok... there's nothing deeper in an import than what we've already gotten, right? return nil } case *ast.FuncDecl: /* This assumes that a .controller file will export only functions we want to be actions... Maybe we should annotate actions somehow? */ if x.Type.Results.NumFields() != 0 { panic(fmt.Sprintf("Could not transform %s.%s: number of result fields is not 0.", v.controllerName, x.Name.Name)) } if ast.IsExported(x.Name.Name) { transformAction(x) return &RenderFuncVisitor{} } return nil } return v }
// lintUnexportedReturn examines exported function declarations. // It complains if any return an unexported type. func (f *file) lintUnexportedReturn() { f.walk(func(n ast.Node) bool { fn, ok := n.(*ast.FuncDecl) if !ok { return true } if fn.Type.Results == nil { return false } if !fn.Name.IsExported() { return false } thing := "func" if fn.Recv != nil && len(fn.Recv.List) > 0 { thing = "method" if !ast.IsExported(receiverType(fn)) { // Don't report exported methods of unexported types, // such as private implementations of sort.Interface. return false } } for _, ret := range fn.Type.Results.List { typ := f.pkg.typeOf(ret.Type) if exportedType(typ) { continue } f.errorf(ret.Type, 0.8, category("unexported-type-in-api"), "exported %s %s returns unexported type %s, which can be annoying to use", thing, fn.Name.Name, typ) break // only flag one } return false }) }
// Objects with names containing blanks are internal and not entered into // a scope. Objects with exported names are inserted in the unsafe package // scope; other objects are inserted in the universe scope. // func def(obj Object) { name := obj.Name() if strings.Index(name, " ") >= 0 { return // nothing to do } // fix Obj link for named types if typ, ok := obj.Type().(*Named); ok { typ.obj = obj.(*TypeName) } // exported identifiers go into package unsafe scope := Universe if ast.IsExported(name) { scope = Unsafe.scope // set Pkg field switch obj := obj.(type) { case *TypeName: obj.pkg = Unsafe case *Func: obj.pkg = Unsafe default: unreachable() } } if scope.Insert(obj) != nil { panic("internal error: double declaration") } }
func (fi *funcInfo) writeStub(out io.Writer) { fmt.Fprintf(out, "func ") if fi.IsMethod() { fmt.Fprintf(out, "(%s %s) ", fi.recv.name, fi.recv.expr) } if ast.IsExported(fi.name) { fmt.Fprintf(out, "_real_") } fmt.Fprintf(out, "%s(", fi.name) for i, param := range fi.params { if i > 0 { fmt.Fprintf(out, ", ") } n := strings.Join(param.names, ", ") fmt.Fprintf(out, "%s %s", n, param.expr) } fmt.Fprintf(out, ") ") if len(fi.results) > 0 { fmt.Fprintf(out, "(") for i, result := range fi.results { if i > 0 { fmt.Fprintf(out, ", ") } n := strings.Join(result.names, ", ") fmt.Fprintf(out, "%s %s", n, result.expr) } fmt.Fprintf(out, ") ") } fmt.Fprintf(out, "{\n") fmt.Fprintf(out, "\tpanic(\"This is only a stub!\")\n") fmt.Fprintf(out, "}\n") fmt.Fprintf(out, "\n") }
func addNodeLinks(nodes map[string]*Node, line string) []byte { var buf bytes.Buffer scan := bufio.NewScanner(strings.NewReader(line)) scan.Split(bufio.ScanWords) for scan.Scan() { word := strings.TrimFunc(scan.Text(), unicode.IsPunct) parts := strings.Split(word, ".") node := word method := "" if len(parts) == 2 { node = parts[0] method = parts[1] } if nodes[node] != nil && ast.IsExported(node) { buf.Write([]byte("[")) buf.Write(scan.Bytes()) buf.Write([]byte("](")) if method == "" { buf.Write([]byte(nodeNameToLink(node))) } else { buf.Write([]byte(methodNameToLink(node, method))) } buf.Write([]byte(") ")) } else { buf.Write(scan.Bytes()) buf.Write([]byte(" ")) } } return buf.Bytes() }
func processFields(node *Node, s *ast.StructType) { for _, field := range s.Fields.List { if shouldIgnore(field.Doc) { continue } if field.Names == nil { //Anonymous field if i, ok := field.Type.(*ast.Ident); ok { parent := i.Name node.AnonFields = append(node.AnonFields, parent) } else if s, ok := field.Type.(*ast.StarExpr); ok { if i, ok := s.X.(*ast.Ident); ok { parent := i.Name node.AnonFields = append(node.AnonFields, parent) } } } else if len(field.Names) == 1 { name := field.Names[0].Name if !ast.IsExported(name) { continue } ptype := resolveTypeExpr(field.Type) node.Properties[name] = &Property{ Name: name, Doc: field.Doc, Params: []Param{{"value", ptype}}, } } } }
func (fi *funcInfo) writeReal(out io.Writer) { if fi.export != "" { fmt.Fprintf(out, "//export %s\n", fi.export) } fmt.Fprintf(out, "func ") if fi.IsMethod() { fmt.Fprintf(out, "(%s %s) ", fi.recv.name, fi.recv.expr) } if ast.IsExported(fi.name) { fmt.Fprintf(out, "_real_") } fmt.Fprintf(out, "%s(", fi.name) for i, param := range fi.params { if i > 0 { fmt.Fprintf(out, ", ") } n := strings.Join(param.names, ", ") fmt.Fprintf(out, "%s %s", n, param.expr) } fmt.Fprintf(out, ") ") if len(fi.results) > 0 { fmt.Fprintf(out, "(") for i, result := range fi.results { if i > 0 { fmt.Fprintf(out, ", ") } n := strings.Join(result.names, ", ") fmt.Fprintf(out, "%s %s", n, result.expr) } fmt.Fprintf(out, ") ") } out.Write(fi.body) fmt.Fprintf(out, "\n") }
func loadExportsGoPath(dir string) map[string]bool { exports := make(map[string]bool) buildPkg, err := build.ImportDir(dir, 0) if err != nil { if strings.Contains(err.Error(), "no buildable Go source files in") { return nil } fmt.Fprintf(os.Stderr, "could not import %q: %v", dir, err) return nil } fset := token.NewFileSet() for _, file := range buildPkg.GoFiles { f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0) if err != nil { fmt.Fprintf(os.Stderr, "could not parse %q: %v", file, err) continue } for name := range f.Scope.Objects { if ast.IsExported(name) { exports[name] = true } } } return exports }
// qualifyPkgRefs qualifies all refs to non-package-qualified non-builtin types in f so that they refer to definitions in pkg. E.g., 'func(x MyType) -> func (x pkg.MyType)'. func qualifyPkgRefs(f *ast.FuncType, pkg string) { var qualify func(x ast.Expr) ast.Expr qualify = func(x ast.Expr) ast.Expr { switch y := x.(type) { case *ast.Ident: if ast.IsExported(y.Name) { return &ast.SelectorExpr{X: ast.NewIdent(pkg), Sel: y} } case *ast.StarExpr: y.X = qualify(y.X) case *ast.ArrayType: y.Elt = qualify(y.Elt) case *ast.MapType: y.Key = qualify(y.Key) y.Value = qualify(y.Value) } return x } for _, p := range f.Params.List { p.Type = qualify(p.Type) } for _, r := range f.Results.List { r.Type = qualify(r.Type) } }
func (f *File) methodSet(set *types.MethodSet) { // Build the set of things we're looking for. methods := make([]method, 0, set.Len()) docs := make([]string, set.Len()) for i := 0; i < set.Len(); i++ { if ast.IsExported(set.At(i).Obj().Name()) { m := method{ i, set.At(i), } methods = append(methods, m) } } if len(methods) == 0 { return } // Collect the docs. for _, file := range f.allFiles { visitor := &methodVisitor{ File: file, methods: methods, docs: docs, } ast.Walk(visitor, file.file) methods = visitor.methods } // Print them in order. The incoming method set is sorted by name. for _, doc := range docs { if doc != "" { fmt.Print(doc) } } }
func marshal(buf []byte, prefix string, rv reflect.Value, inArray, arrayTable bool) ([]byte, error) { rt := rv.Type() for i := 0; i < rv.NumField(); i++ { ft := rt.Field(i) if !ast.IsExported(ft.Name) { continue } colName, rest := extractTag(rt.Field(i).Tag.Get(fieldTagName)) if colName == tagSkip { continue } if colName == "" { colName = stringutil.ToSnakeCase(ft.Name) } fv := rv.Field(i) switch rest { case tagOmitempty: if fv.Interface() == reflect.Zero(ft.Type).Interface() { continue } } var err error if buf, err = encodeValue(buf, prefix, colName, fv, inArray, arrayTable); err != nil { return nil, err } } return buf, nil }
func (c *auto_complete_context) get_candidates_from_decl(cc cursor_context, class decl_class, b *out_buffers) { // propose all children of a subject declaration and for _, decl := range cc.decl.children { if cc.decl.class == decl_package && !ast.IsExported(decl.name) { continue } if cc.struct_field { // if we're autocompleting struct field init, skip all methods if _, ok := decl.typ.(*ast.FuncType); ok { continue } } b.append_decl(cc.partial, decl.name, decl, class) } // propose all children of an underlying struct/interface type adecl := advance_to_struct_or_interface(cc.decl) if adecl != nil && adecl != cc.decl { for _, decl := range adecl.children { if decl.class == decl_var { b.append_decl(cc.partial, decl.name, decl, class) } } } // propose all children of its embedded types b.append_embedded(cc.partial, cc.decl, class) }
func (p *Package) FilterCommon(typs ...DocType) ([]string, map[string]interface{}) { var ctxsize int if p.defctx { ctxsize = 1 } else { ctxsize = len(p.contexts) } var key []string cm := make(map[string]interface{}) def := contextName(&build.Default) for _, typ := range typs { if m, ok := p.keys[typ]; ok { for k, v := range m { if len(v) == ctxsize && (ast.IsExported(k) || typ == Struct) { key = append(key, k) cm[k] = v[def] } } sort.Strings(key) } } return key, cm }