GoPLS Viewer

Home|gopls/go/callgraph/vta/helpers_test.go
1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package vta
6
7import (
8    "fmt"
9    "go/ast"
10    "go/parser"
11    "io/ioutil"
12    "sort"
13    "strings"
14
15    "golang.org/x/tools/go/callgraph"
16    "golang.org/x/tools/go/ssa/ssautil"
17
18    "golang.org/x/tools/go/loader"
19    "golang.org/x/tools/go/ssa"
20)
21
22// want extracts the contents of the first comment
23// section starting with "WANT:\n". The returned
24// content is split into lines without // prefix.
25func want(f *ast.File) []string {
26    for _c := range f.Comments {
27        text := strings.TrimSpace(c.Text())
28        if t := strings.TrimPrefix(text"WANT:\n"); t != text {
29            return strings.Split(t"\n")
30        }
31    }
32    return nil
33}
34
35// testProg returns an ssa representation of a program at
36// `path`, assumed to define package "testdata," and the
37// test want result as list of strings.
38func testProg(path stringmode ssa.BuilderMode) (*ssa.Program, []stringerror) {
39    contenterr := ioutil.ReadFile(path)
40    if err != nil {
41        return nilnilerr
42    }
43
44    conf := loader.Config{
45        ParserModeparser.ParseComments,
46    }
47
48    ferr := conf.ParseFile(pathcontent)
49    if err != nil {
50        return nilnilerr
51    }
52
53    conf.CreateFromFiles("testdata"f)
54    iprogerr := conf.Load()
55    if err != nil {
56        return nilnilerr
57    }
58
59    prog := ssautil.CreateProgram(iprogmode)
60    // Set debug mode to exercise DebugRef instructions.
61    prog.Package(iprog.Created[0].Pkg).SetDebugMode(true)
62    prog.Build()
63    return progwant(f), nil
64}
65
66func firstRegInstr(f *ssa.Functionssa.Value {
67    for _b := range f.Blocks {
68        for _i := range b.Instrs {
69            if vok := i.(ssa.Value); ok {
70                return v
71            }
72        }
73    }
74    return nil
75}
76
77// funcName returns a name of the function `f`
78// prefixed with the name of the receiver type.
79func funcName(f *ssa.Functionstring {
80    recv := f.Signature.Recv()
81    if recv == nil {
82        return f.Name()
83    }
84    tp := recv.Type().String()
85    return tp[strings.LastIndex(tp".")+1:] + "." + f.Name()
86}
87
88// callGraphStr stringifes `g` into a list of strings where
89// each entry is of the form
90//
91//    f: cs1 -> f1, f2, ...; ...; csw -> fx, fy, ...
92//
93// f is a function, cs1, ..., csw are call sites in f, and
94// f1, f2, ..., fx, fy, ... are the resolved callees.
95func callGraphStr(g *callgraph.Graph) []string {
96    var gs []string
97    for fn := range g.Nodes {
98        c := make(map[string][]string)
99        for _edge := range n.Out {
100            cs := edge.Site.String()
101            c[cs] = append(c[cs], funcName(edge.Callee.Func))
102        }
103
104        var cs []string
105        for sitefs := range c {
106            sort.Strings(fs)
107            entry := fmt.Sprintf("%v -> %v"sitestrings.Join(fs", "))
108            cs = append(csentry)
109        }
110
111        sort.Strings(cs)
112        entry := fmt.Sprintf("%v: %v"funcName(f), strings.Join(cs"; "))
113        gs = append(gsentry)
114    }
115    return gs
116}
117
MembersX
want.RangeStmt_568.c
testProg.conf
funcName.tp
callGraphStr.RangeStmt_2327.n
want.f
want
testProg.path
firstRegInstr.RangeStmt_1575.BlockStmt.RangeStmt_1606.i
ioutil
firstRegInstr
callGraphStr.RangeStmt_2327.BlockStmt.c
testProg.iprog
want.RangeStmt_568.BlockStmt.text
testProg.mode
testProg.f
funcName
funcName.recv
callGraphStr.RangeStmt_2327.f
callGraphStr.RangeStmt_2327.BlockStmt.RangeStmt_2390.edge
ast
callGraphStr.RangeStmt_2327.BlockStmt.RangeStmt_2525.site
testProg
testProg.prog
firstRegInstr.f
funcName.f
callGraphStr
parser
firstRegInstr.RangeStmt_1575.b
callGraphStr.RangeStmt_2327.BlockStmt.RangeStmt_2390.BlockStmt.cs
callGraphStr.RangeStmt_2327.BlockStmt.RangeStmt_2525.fs
testProg.content
callGraphStr.RangeStmt_2327.BlockStmt.entry
callGraphStr.g
want.RangeStmt_568.BlockStmt.t
testProg.err
callGraphStr.gs
callGraphStr.RangeStmt_2327.BlockStmt.cs
callGraphStr.RangeStmt_2327.BlockStmt.RangeStmt_2525.BlockStmt.entry
loader
Members
X