blob: 954bd10126051f82b692f57c9071c6a0b10e1f8f [file] [log] [blame]
// Copyright 2011-2015 visualfc <visualfc@gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package oracle
import (
"fmt"
"go/build"
"log"
"os"
"runtime"
"github.com/visualfc/gotools/command"
"golang.org/x/tools/oracle"
)
//The mode argument determines the query to perform:
// callees show possible targets of selected function call
// callers show possible callers of selected function
// callgraph show complete callgraph of program
// callstack show path from callgraph root to selected function
// describe describe selected syntax: definition, methods, etc
// freevars show free variables of selection
// implements show 'implements' relation for selected type
// peers show send/receive corresponding to selected channel op
// referrers show all refs to entity denoted by selected identifier
// what show basic information about the selected syntax node
var Command = &command.Command{
Run: runOracle,
UsageLine: "oracle",
Short: "golang oracle util",
Long: `golang oracle util.`,
}
var (
oraclePos string
oracleReflect bool
)
func init() {
Command.Flag.StringVar(&oraclePos, "pos", "", "filename:#offset")
Command.Flag.BoolVar(&oracleReflect, "reflect", false, "Analyze reflection soundly (slow).")
}
func runOracle(cmd *command.Command, args []string) error {
if len(args) < 2 {
cmd.Usage()
return os.ErrInvalid
}
if os.Getenv("GOMAXPROCS") == "" {
n := runtime.NumCPU()
if n < 4 {
n = 4
}
runtime.GOMAXPROCS(n)
}
mode := args[0]
args = args[1:]
if args[0] == "." {
pkgPath, err := os.Getwd()
if err != nil {
log.Fatalln(err)
}
pkg, err := build.Default.ImportDir(pkgPath, 0)
if err != nil {
log.Fatalln(err)
}
args = pkg.GoFiles
//log.Println(pkg.ImportPath)
if pkg.ImportPath != "." && pkg.ImportPath != "" {
args = []string{pkg.ImportPath}
}
}
query := oracle.Query{
Mode: mode,
Pos: oraclePos,
Build: &build.Default,
Scope: args,
PTALog: nil,
Reflection: oracleReflect,
}
if err := oracle.Run(&query); err != nil {
fmt.Fprintf(os.Stderr, "oracle: %s.\n", err)
return err
}
if mode == "referrers" {
ref := query.Serial().Referrers
if ref != nil {
fmt.Fprintln(os.Stdout, ref.Desc)
fmt.Fprintln(os.Stdout, ref.ObjPos)
for _, v := range ref.Refs {
fmt.Fprintln(os.Stdout, v)
}
}
} else {
query.WriteTo(os.Stdout)
}
return nil
}