Skip to content

Commit 9c73035

Browse files
committed
Provide type checker with function for type to search for
1 parent cd3fb27 commit 9c73035

File tree

6 files changed

+39
-18
lines changed

6 files changed

+39
-18
lines changed

pkg/analysis/integers/analyzer.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func run(pass *analysis.Pass) (any, error) {
4949
(*ast.TypeSpec)(nil),
5050
}
5151

52-
typeChecker := utils.NewTypeChecker(checkIntegers)
52+
typeChecker := utils.NewTypeChecker(utils.IsBasicType, checkIntegers)
5353

5454
// Preorder visits all the nodes of the AST in depth-first order. It calls
5555
// f(n) for each node n before it visits n's children.
@@ -63,7 +63,12 @@ func run(pass *analysis.Pass) (any, error) {
6363
}
6464

6565
// checkIntegers looks for known type of integers that do not match the allowed `int32` or `int64` requirements.
66-
func checkIntegers(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string) {
66+
func checkIntegers(pass *analysis.Pass, expr ast.Expr, node ast.Node, prefix string) {
67+
ident, ok := expr.(*ast.Ident)
68+
if !ok {
69+
return
70+
}
71+
6772
switch ident.Name {
6873
case "int32", "int64":
6974
// Valid cases

pkg/analysis/nobools/analyzer.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func run(pass *analysis.Pass) (any, error) {
4949
(*ast.TypeSpec)(nil),
5050
}
5151

52-
typeChecker := utils.NewTypeChecker(checkBool)
52+
typeChecker := utils.NewTypeChecker(utils.IsBasicType, checkBool)
5353

5454
// Preorder visits all the nodes of the AST in depth-first order. It calls
5555
// f(n) for each node n before it visits n's children.
@@ -62,7 +62,12 @@ func run(pass *analysis.Pass) (any, error) {
6262
return nil, nil //nolint:nilnil
6363
}
6464

65-
func checkBool(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string) {
65+
func checkBool(pass *analysis.Pass, expr ast.Expr, node ast.Node, prefix string) {
66+
ident, ok := expr.(*ast.Ident)
67+
if !ok {
68+
return
69+
}
70+
6671
if ident.Name == "bool" {
6772
pass.Reportf(node.Pos(), "%s should not use a bool. Use a string type with meaningful constant values as an enum.", prefix)
6873
}

pkg/analysis/nofloats/analyzer.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func run(pass *analysis.Pass) (any, error) {
4949
(*ast.TypeSpec)(nil),
5050
}
5151

52-
typeChecker := utils.NewTypeChecker(checkFloat)
52+
typeChecker := utils.NewTypeChecker(utils.IsBasicType, checkFloat)
5353

5454
// Preorder visits all the nodes of the AST in depth-first order. It calls
5555
// f(n) for each node n before it visits n's children.
@@ -62,7 +62,12 @@ func run(pass *analysis.Pass) (any, error) {
6262
return nil, nil //nolint:nilnil
6363
}
6464

65-
func checkFloat(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string) {
65+
func checkFloat(pass *analysis.Pass, expr ast.Expr, node ast.Node, prefix string) {
66+
ident, ok := expr.(*ast.Ident)
67+
if !ok {
68+
return
69+
}
70+
6671
if ident.Name == "float32" || ident.Name == "float64" {
6772
pass.Reportf(node.Pos(), "%s should not use a float value because they cannot be reliably round-tripped.", prefix)
6873
}

pkg/analysis/utils/type_check.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ type TypeChecker interface {
3131
}
3232

3333
// NewTypeChecker returns a new TypeChecker with the provided checkFunc.
34-
func NewTypeChecker(checkFunc func(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string)) TypeChecker {
34+
func NewTypeChecker(isTypeFunc func(pass *analysis.Pass, ident ast.Expr) bool, checkFunc func(pass *analysis.Pass, expr ast.Expr, node ast.Node, prefix string)) TypeChecker {
3535
return &typeChecker{
36-
checkFunc: checkFunc,
36+
isTypeFunc: isTypeFunc,
37+
checkFunc: checkFunc,
3738
}
3839
}
3940

4041
type typeChecker struct {
41-
checkFunc func(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string)
42+
isTypeFunc func(pass *analysis.Pass, expr ast.Expr) bool
43+
checkFunc func(pass *analysis.Pass, expr ast.Expr, node ast.Node, prefix string)
4244
}
4345

4446
// CheckNode checks the provided node for built-in types.
@@ -84,6 +86,11 @@ func (t *typeChecker) checkTypeSpec(pass *analysis.Pass, tSpec *ast.TypeSpec, no
8486
}
8587

8688
func (t *typeChecker) checkTypeExpr(pass *analysis.Pass, typeExpr ast.Expr, node ast.Node, prefix string) {
89+
if t.isTypeFunc(pass, typeExpr) {
90+
t.checkFunc(pass, typeExpr, node, prefix)
91+
return
92+
}
93+
8794
switch typ := typeExpr.(type) {
8895
case *ast.Ident:
8996
t.checkIdent(pass, typ, node, prefix)
@@ -100,12 +107,6 @@ func (t *typeChecker) checkTypeExpr(pass *analysis.Pass, typeExpr ast.Expr, node
100107
// checkIdent calls the checkFunc with the ident, when we have hit a built-in type.
101108
// If the ident is not a built in, we look at the underlying type until we hit a built-in type.
102109
func (t *typeChecker) checkIdent(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string) {
103-
if IsBasicType(pass, ident) {
104-
// We've hit a built-in type, no need to check further.
105-
t.checkFunc(pass, ident, node, prefix)
106-
return
107-
}
108-
109110
tSpec, ok := LookupTypeSpec(pass, ident)
110111
if !ok {
111112
return

pkg/analysis/utils/type_check_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ func testAnalyzer() *analysis.Analyzer {
5353
(*ast.TypeSpec)(nil),
5454
}
5555

56-
typeChecker := utils.NewTypeChecker(func(pass *analysis.Pass, ident *ast.Ident, node ast.Node, prefix string) {
56+
typeChecker := utils.NewTypeChecker(utils.IsBasicType, func(pass *analysis.Pass, expr ast.Expr, node ast.Node, prefix string) {
57+
ident, ok := expr.(*ast.Ident)
58+
if !ok {
59+
return
60+
}
61+
5762
if ident.Name == "string" {
5863
pass.Reportf(node.Pos(), "%s is a string", prefix)
5964
}

pkg/analysis/utils/utils.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import (
3131

3232
// IsBasicType checks if the type of the given identifier is a basic type.
3333
// Basic types are types like int, string, bool, etc.
34-
func IsBasicType(pass *analysis.Pass, ident *ast.Ident) bool {
35-
_, ok := pass.TypesInfo.TypeOf(ident).(*types.Basic)
34+
func IsBasicType(pass *analysis.Pass, expr ast.Expr) bool {
35+
_, ok := pass.TypesInfo.TypeOf(expr).(*types.Basic)
3636
return ok
3737
}
3838

0 commit comments

Comments
 (0)