GoPLS Viewer

Home|gopls/go/ssa/methods_test.go
1// Copyright 2022 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 ssa_test
6
7import (
8    "go/ast"
9    "go/parser"
10    "go/token"
11    "go/types"
12    "testing"
13
14    "golang.org/x/tools/go/ssa"
15    "golang.org/x/tools/go/ssa/ssautil"
16    "golang.org/x/tools/internal/typeparams"
17)
18
19// Tests that MethodValue returns the expected method.
20func TestMethodValue(t *testing.T) {
21    if !typeparams.Enabled {
22        t.Skip("TestMethodValue requires type parameters")
23    }
24    input := `
25package p
26
27type I interface{ M() }
28
29type S int
30func (S) M() {}
31type R[T any] struct{ S }
32
33var i I
34var s S
35var r R[string]
36
37func selections[T any]() {
38    _ = i.M
39    _ = s.M
40    _ = r.M
41
42    var v R[T]
43    _ = v.M
44}
45`
46
47    // Parse the file.
48    fset := token.NewFileSet()
49    ferr := parser.ParseFile(fset"input.go"input0)
50    if err != nil {
51        t.Error(err)
52        return
53    }
54
55    // Build an SSA program from the parsed file.
56    pinfoerr := ssautil.BuildPackage(&types.Config{}, fset,
57        types.NewPackage("p"""), []*ast.File{f}, ssa.SanityCheckFunctions)
58    if err != nil {
59        t.Error(err)
60        return
61    }
62
63    // Collect all of the *types.Selection in the function "selections".
64    var selections []*types.Selection
65    for _decl := range f.Decls {
66        if fnok := decl.(*ast.FuncDecl); ok && fn.Name.Name == "selections" {
67            for _stmt := range fn.Body.List {
68                if assignok := stmt.(*ast.AssignStmt); ok {
69                    sel := assign.Rhs[0].(*ast.SelectorExpr)
70                    selections = append(selectionsinfo.Selections[sel])
71                }
72            }
73        }
74    }
75
76    wants := map[string]string{
77        "method (p.S) M()":         "(p.S).M",
78        "method (p.R[string]) M()""(p.R[string]).M",
79        "method (p.I) M()":         "nil"// interface
80        "method (p.R[T]) M()":      "nil"// parameterized
81    }
82    if len(wants) != len(selections) {
83        t.Fatalf("Wanted %d selections. got %d"len(wants), len(selections))
84    }
85    for _selection := range selections {
86        var got string
87        if m := p.Prog.MethodValue(selection); m != nil {
88            got = m.String()
89        } else {
90            got = "nil"
91        }
92        if want := wants[selection.String()]; want != got {
93            t.Errorf("p.Prog.MethodValue(%s) expected %q. got %q"selectionwantgot)
94        }
95    }
96}
97
MembersX
TestMethodValue.selections
TestMethodValue.RangeStmt_1227.decl
TestMethodValue.fset
TestMethodValue.p
TestMethodValue.info
TestMethodValue.RangeStmt_1227.BlockStmt.BlockStmt.RangeStmt_1335.stmt
TestMethodValue.RangeStmt_1883.selection
TestMethodValue.RangeStmt_1883.BlockStmt.m
TestMethodValue
TestMethodValue.t
TestMethodValue.err
TestMethodValue.RangeStmt_1883.BlockStmt.got
TestMethodValue.input
TestMethodValue.f
TestMethodValue.wants
Members
X