2018-03-13 07:32:44 +03:00
|
|
|
// 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"
|
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
|
|
|
|
"github.com/visualfc/gotools/command"
|
2018-03-13 08:19:03 +03:00
|
|
|
"github.com/visualfc/gotools/oracle/oracle"
|
2018-03-13 07:32:44 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
//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:]
|
2018-03-13 08:19:03 +03:00
|
|
|
// 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}
|
|
|
|
// }
|
|
|
|
// }
|
2018-03-13 07:32:44 +03:00
|
|
|
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
|
|
|
|
}
|
2018-03-13 08:19:03 +03:00
|
|
|
|
2018-03-13 07:32:44 +03:00
|
|
|
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
|
|
|
|
}
|