Example #1
0
// 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:])
}
Example #2
0
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 ""
}
Example #3
0
// 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
}