// Calls returns the calls to a given function or method // specified as a qualified name (e.g. gnd.la/i18n.T or // gnd.la/app.Context.T). func Calls(fset *token.FileSet, f *ast.File, fn string) ([]*ast.CallExpr, error) { pkg, fname := pkgutil.SplitQualifiedName(fn) pname, ok := Imports(f, pkg) if !ok { // Not imported return nil, nil } dot := strings.Index(fname, ".") if dot == -1 { // function call return funcCalls(fset, f, pname, fname) } // method call return methodCalls(fset, f, pname, fname[:dot], fname[dot+1:]) }
func (p *Package) href(word string, scope string) string { slash := strings.IndexByte(word, '/') dot := strings.IndexByte(word, '.') if slash > 0 || dot > 0 { // Check if there's a type or function mentioned // after the package. if pn, tn := pkgutil.SplitQualifiedName(word); pn != "" && tn != "" { if pn[0] == '*' { pn = pn[1:] } if pkg, err := p.env.ImportPackage(pn); err == nil { if sr := pkg.symbolHref(tn); sr != "" { return p.env.reverseDoc(pn) + sr } } if pn == p.dpkg.Name { return p.symbolHref(tn) } } else if _, err := p.env.Context.Import(word, "", build.FindOnly); err == nil { return p.env.reverseDoc(word) } } if dot > 0 { // Check the package imports, to see if any of them matches // TODO: Check for packages imported with a different local // name. base := word[:dot] for _, v := range p.bpkg.Imports { if path.Base(v) == base && v != base { return p.href(v+"."+word[dot+1:], scope) } } } if word[0]&0x20 == 0 { // Uppercase if scope != "" { if href := p.symbolHref(scope + "." + word); href != "" { return href } } return p.symbolHref(word) } return "" }
// Strings returns a list of string declarations of the given type // (as a qualified name). func Strings(fset *token.FileSet, f *ast.File, typ string) ([]*String, error) { pkg, tname := pkgutil.SplitQualifiedName(typ) pname, ok := Imports(f, pkg) if !ok { // Not imported return nil, nil } var strings []*String ast.Inspect(f, func(n ast.Node) bool { switch x := n.(type) { case *ast.ValueSpec: p, t := Selector(x.Type) if p == pname && t == tname { for _, v := range x.Values { if s, pos := StringLiteral(fset, v); s != "" && pos != nil { strings = append(strings, &String{s, pos}) } } } } return true }) return strings, nil }