예제 #1
0
파일: oracle.go 프로젝트: tintohill/pythia
func newOracle(iprog *loader.Program, ptalog io.Writer, needs int, reflection bool) (*Oracle, error) {
	o := &Oracle{fset: iprog.Fset}

	// Retain type info for all ASTs in the program.
	if needs&needRetainTypeInfo != 0 {
		o.typeInfo = iprog.AllPackages
	}

	// Create SSA package for the initial packages and their dependencies.
	if needs&needSSA != 0 {
		var mode ssa.BuilderMode
		if needs&needSSADebug != 0 {
			mode |= ssa.GlobalDebug
		}
		prog := ssa.Create(iprog, mode)

		// For each initial package (specified on the command line),
		// if it has a main function, analyze that,
		// otherwise analyze its tests, if any.
		var testPkgs, mains []*ssa.Package
		for _, info := range iprog.InitialPackages() {
			initialPkg := prog.Package(info.Pkg)

			// Add package to the pointer analysis scope.
			if initialPkg.Func("main") != nil {
				mains = append(mains, initialPkg)
			} else {
				testPkgs = append(testPkgs, initialPkg)
			}
		}
		if testPkgs != nil {
			if p := prog.CreateTestMainPackage(testPkgs...); p != nil {
				mains = append(mains, p)
			}
		}
		if mains == nil {
			return nil, fmt.Errorf("analysis scope has no main and no tests")
		}
		o.ptaConfig.Log = ptalog
		o.ptaConfig.Reflection = reflection
		o.ptaConfig.Mains = mains

		o.prog = prog
	}

	return o, nil
}
예제 #2
0
파일: oracle.go 프로젝트: tintohill/pythia
// ParseQueryPos parses the source query position pos.
// If needExact, it must identify a single AST subtree;
// this is appropriate for queries that allow fairly arbitrary syntax,
// e.g. "describe".
//
func ParseQueryPos(iprog *loader.Program, posFlag string, needExact bool) (*QueryPos, error) {
	filename, startOffset, endOffset, err := parsePosFlag(posFlag)
	if err != nil {
		return nil, err
	}
	start, end, err := findQueryPos(iprog.Fset, filename, startOffset, endOffset)
	if err != nil {
		return nil, err
	}
	info, path, exact := iprog.PathEnclosingInterval(start, end)
	if path == nil {
		return nil, fmt.Errorf("no syntax here")
	}
	if needExact && !exact {
		return nil, fmt.Errorf("ambiguous selection within %s", astutil.NodeDescription(path[0]))
	}
	return &QueryPos{iprog.Fset, start, end, path, exact, info}, nil
}