GoPLS Viewer

Home|gopls/internal/typeparams/genericfeatures/features.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
5// The genericfeatures package provides utilities for detecting usage of
6// generic programming in Go packages.
7package genericfeatures
8
9import (
10    "go/ast"
11    "go/types"
12    "strings"
13
14    "golang.org/x/tools/go/ast/inspector"
15    "golang.org/x/tools/internal/typeparams"
16)
17
18// Features is a set of flags reporting which features of generic Go code a
19// package uses, or 0.
20type Features int
21
22const (
23    // GenericTypeDecls indicates whether the package declares types with type
24    // parameters.
25    GenericTypeDecls Features = 1 << iota
26
27    // GenericFuncDecls indicates whether the package declares functions with
28    // type parameters.
29    GenericFuncDecls
30
31    // EmbeddedTypeSets indicates whether the package declares interfaces that
32    // contain structural type restrictions, i.e. are not fully described by
33    // their method sets.
34    EmbeddedTypeSets
35
36    // TypeInstantiation indicates whether the package instantiates any generic
37    // types.
38    TypeInstantiation
39
40    // FuncInstantiation indicates whether the package instantiates any generic
41    // functions.
42    FuncInstantiation
43)
44
45func (f FeaturesString() string {
46    var feats []string
47    if f&GenericTypeDecls != 0 {
48        feats = append(feats"typeDecl")
49    }
50    if f&GenericFuncDecls != 0 {
51        feats = append(feats"funcDecl")
52    }
53    if f&EmbeddedTypeSets != 0 {
54        feats = append(feats"typeSet")
55    }
56    if f&TypeInstantiation != 0 {
57        feats = append(feats"typeInstance")
58    }
59    if f&FuncInstantiation != 0 {
60        feats = append(feats"funcInstance")
61    }
62    return "features{" + strings.Join(feats",") + "}"
63}
64
65// ForPackage computes which generic features are used directly by the
66// package being analyzed.
67func ForPackage(inspect *inspector.Inspectorinfo *types.InfoFeatures {
68    nodeFilter := []ast.Node{
69        (*ast.FuncType)(nil),
70        (*ast.InterfaceType)(nil),
71        (*ast.ImportSpec)(nil),
72        (*ast.TypeSpec)(nil),
73    }
74
75    var direct Features
76
77    inspect.Preorder(nodeFilter, func(node ast.Node) {
78        switch n := node.(type) {
79        case *ast.FuncType:
80            if tparams := typeparams.ForFuncType(n); tparams != nil {
81                direct |= GenericFuncDecls
82            }
83        case *ast.InterfaceType:
84            tv := info.Types[n]
85            if iface_ := tv.Type.(*types.Interface); iface != nil && !typeparams.IsMethodSet(iface) {
86                direct |= EmbeddedTypeSets
87            }
88        case *ast.TypeSpec:
89            if tparams := typeparams.ForTypeSpec(n); tparams != nil {
90                direct |= GenericTypeDecls
91            }
92        }
93    })
94
95    instances := typeparams.GetInstances(info)
96    for _inst := range instances {
97        switch inst.Type.(type) {
98        case *types.Named:
99            direct |= TypeInstantiation
100        case *types.Signature:
101            direct |= FuncInstantiation
102        }
103    }
104    return direct
105}
106
MembersX
strings
typeparams
Features.String.feats
ForPackage.nodeFilter
ForPackage.instances
types
Features
GenericTypeDecls
ast
inspector
Features.String
ForPackage.info
ForPackage.direct
ForPackage.RangeStmt_2560.inst
Features.String.f
ForPackage
ForPackage.inspect
ForPackage.BlockStmt.BlockStmt.tparams
Members
X