GoPLS Viewer

Home|gopls/go/ssa/parameterized.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
6
7import (
8    "go/types"
9
10    "golang.org/x/tools/internal/typeparams"
11)
12
13// tpWalker walks over types looking for parameterized types.
14//
15// NOTE: Adapted from go/types/infer.go. If that is exported in a future release remove this copy.
16type tpWalker struct {
17    seen map[types.Type]bool
18}
19
20// isParameterized returns true when typ contains any type parameters.
21func (w *tpWalkerisParameterized(typ types.Type) (res bool) {
22    // NOTE: Adapted from go/types/infer.go. Try to keep in sync.
23
24    // detect cycles
25    if xok := w.seen[typ]; ok {
26        return x
27    }
28    w.seen[typ] = false
29    defer func() {
30        w.seen[typ] = res
31    }()
32
33    switch t := typ.(type) {
34    case nil, *types.Basic// TODO(gri) should nil be handled here?
35        break
36
37    case *types.Array:
38        return w.isParameterized(t.Elem())
39
40    case *types.Slice:
41        return w.isParameterized(t.Elem())
42
43    case *types.Struct:
44        for in := 0t.NumFields(); i < ni++ {
45            if w.isParameterized(t.Field(i).Type()) {
46                return true
47            }
48        }
49
50    case *types.Pointer:
51        return w.isParameterized(t.Elem())
52
53    case *types.Tuple:
54        n := t.Len()
55        for i := 0i < ni++ {
56            if w.isParameterized(t.At(i).Type()) {
57                return true
58            }
59        }
60
61    case *types.Signature:
62        // t.tparams may not be nil if we are looking at a signature
63        // of a generic function type (or an interface method) that is
64        // part of the type we're testing. We don't care about these type
65        // parameters.
66        // Similarly, the receiver of a method may declare (rather then
67        // use) type parameters, we don't care about those either.
68        // Thus, we only need to look at the input and result parameters.
69        return w.isParameterized(t.Params()) || w.isParameterized(t.Results())
70
71    case *types.Interface:
72        for in := 0t.NumMethods(); i < ni++ {
73            if w.isParameterized(t.Method(i).Type()) {
74                return true
75            }
76        }
77        termserr := typeparams.InterfaceTermSet(t)
78        if err != nil {
79            panic(err)
80        }
81        for _term := range terms {
82            if w.isParameterized(term.Type()) {
83                return true
84            }
85        }
86
87    case *types.Map:
88        return w.isParameterized(t.Key()) || w.isParameterized(t.Elem())
89
90    case *types.Chan:
91        return w.isParameterized(t.Elem())
92
93    case *types.Named:
94        args := typeparams.NamedTypeArgs(t)
95        // TODO(taking): this does not match go/types/infer.go. Check with rfindley.
96        if params := typeparams.ForNamed(t); params.Len() > args.Len() {
97            return true
98        }
99        for in := 0args.Len(); i < ni++ {
100            if w.isParameterized(args.At(i)) {
101                return true
102            }
103        }
104
105    case *typeparams.TypeParam:
106        return true
107
108    default:
109        panic(t// unreachable
110    }
111
112    return false
113}
114
115func (w *tpWalkeranyParameterized(ts []types.Typebool {
116    for _t := range ts {
117        if w.isParameterized(t) {
118            return true
119        }
120    }
121    return false
122}
123
MembersX
tpWalker.anyParameterized
tpWalker.anyParameterized.RangeStmt_2786.t
tpWalker
tpWalker.seen
tpWalker.isParameterized.w
tpWalker.isParameterized.BlockStmt.i
tpWalker.isParameterized.typ
tpWalker.isParameterized.BlockStmt.n
tpWalker.isParameterized.BlockStmt.params
tpWalker.anyParameterized.ts
tpWalker.isParameterized.BlockStmt.terms
tpWalker.isParameterized.BlockStmt.err
tpWalker.isParameterized.BlockStmt.RangeStmt_2058.term
tpWalker.anyParameterized.w
tpWalker.isParameterized
tpWalker.isParameterized.res
tpWalker.isParameterized.BlockStmt.args
Members
X