...

Source file src/golang.org/x/tools/go/analysis/passes/usesgenerics/usesgenerics.go

Documentation: golang.org/x/tools/go/analysis/passes/usesgenerics

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

View as plain text