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 }