golang.org/x/tools@v0.21.0/go/analysis/passes/usesgenerics/usesgenerics.go (about)

     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  package usesgenerics
     6  
     7  import (
     8  	_ "embed"
     9  	"reflect"
    10  
    11  	"golang.org/x/tools/go/analysis"
    12  	"golang.org/x/tools/go/analysis/passes/inspect"
    13  	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
    14  	"golang.org/x/tools/go/ast/inspector"
    15  	"golang.org/x/tools/internal/typeparams/genericfeatures"
    16  )
    17  
    18  //go:embed doc.go
    19  var doc string
    20  
    21  var Analyzer = &analysis.Analyzer{
    22  	Name:       "usesgenerics",
    23  	Doc:        analysisutil.MustExtractDoc(doc, "usesgenerics"),
    24  	URL:        "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/usesgenerics",
    25  	Requires:   []*analysis.Analyzer{inspect.Analyzer},
    26  	Run:        run,
    27  	ResultType: reflect.TypeOf((*Result)(nil)),
    28  	FactTypes:  []analysis.Fact{new(featuresFact)},
    29  }
    30  
    31  type Features = genericfeatures.Features
    32  
    33  const (
    34  	GenericTypeDecls  = genericfeatures.GenericTypeDecls
    35  	GenericFuncDecls  = genericfeatures.GenericFuncDecls
    36  	EmbeddedTypeSets  = genericfeatures.EmbeddedTypeSets
    37  	TypeInstantiation = genericfeatures.TypeInstantiation
    38  	FuncInstantiation = genericfeatures.FuncInstantiation
    39  )
    40  
    41  // Result is the usesgenerics analyzer result type. The Direct field records
    42  // features used directly by the package being analyzed (i.e. contained in the
    43  // package source code). The Transitive field records any features used by the
    44  // package or any of its transitive imports.
    45  type Result struct {
    46  	Direct, Transitive Features
    47  }
    48  
    49  type featuresFact struct {
    50  	Features Features
    51  }
    52  
    53  func (f *featuresFact) AFact()         {}
    54  func (f *featuresFact) String() string { return f.Features.String() }
    55  
    56  func run(pass *analysis.Pass) (interface{}, error) {
    57  	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
    58  
    59  	direct := genericfeatures.ForPackage(inspect, pass.TypesInfo)
    60  
    61  	transitive := direct | importedTransitiveFeatures(pass)
    62  	if transitive != 0 {
    63  		pass.ExportPackageFact(&featuresFact{transitive})
    64  	}
    65  
    66  	return &Result{
    67  		Direct:     direct,
    68  		Transitive: transitive,
    69  	}, nil
    70  }
    71  
    72  // importedTransitiveFeatures computes features that are used transitively via
    73  // imports.
    74  func importedTransitiveFeatures(pass *analysis.Pass) Features {
    75  	var feats Features
    76  	for _, imp := range pass.Pkg.Imports() {
    77  		var importedFact featuresFact
    78  		if pass.ImportPackageFact(imp, &importedFact) {
    79  			feats |= importedFact.Features
    80  		}
    81  	}
    82  	return feats
    83  }