diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 59574b2..41b61a1 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -24,6 +24,7 @@ const ( OSDevNullFlag = "os-dev-null" SQLIsolationLevelFlag = "sql-isolation-level" TLSSignatureSchemeFlag = "tls-signature-scheme" + ConstantKindFlag = "constant-kind" ) // New returns new usestdlibvars analyzer. @@ -49,6 +50,7 @@ func flags() flag.FlagSet { flags.Bool(OSDevNullFlag, false, "suggest the use of os.DevNull") flags.Bool(SQLIsolationLevelFlag, false, "suggest the use of sql.LevelXX.String()") flags.Bool(TLSSignatureSchemeFlag, false, "suggest the use of tls.SignatureScheme.String()") + flags.Bool(ConstantKindFlag, false, "suggest the use of constant.Kind.String()") return *flags } @@ -91,6 +93,7 @@ func run(pass *analysis.Pass) (interface{}, error) { {flag: OSDevNullFlag, checkFunc: checkOSDevNull}, {flag: SQLIsolationLevelFlag, checkFunc: checkSQLIsolationLevel}, {flag: TLSSignatureSchemeFlag, checkFunc: checkTLSSignatureScheme}, + {flag: ConstantKindFlag, checkFunc: checkConstantKind}, } { if lookupFlag(pass, c.flag) { c.checkFunc(pass, n) @@ -438,6 +441,14 @@ func checkTLSSignatureScheme(pass *analysis.Pass, basicLit *ast.BasicLit) { } } +func checkConstantKind(pass *analysis.Pass, basicLit *ast.BasicLit) { + currentVal := getBasicLitValue(basicLit) + + if newVal, ok := mapping.ConstantKind[currentVal]; ok { + report(pass, basicLit.Pos(), currentVal, newVal) + } +} + // getBasicLitFromArgs gets the *ast.BasicLit of a function argument. // // Arguments: diff --git a/pkg/analyzer/analyzer_test.go b/pkg/analyzer/analyzer_test.go index 4898d3b..94409ee 100644 --- a/pkg/analyzer/analyzer_test.go +++ b/pkg/analyzer/analyzer_test.go @@ -17,6 +17,7 @@ func TestUseStdlibVars(t *testing.T) { "a/os", "a/sql", "a/tls", + "a/constant", } a := analyzer.New() @@ -29,6 +30,7 @@ func TestUseStdlibVars(t *testing.T) { mustNil(t, a.Flags.Set(analyzer.OSDevNullFlag, "true")) mustNil(t, a.Flags.Set(analyzer.SQLIsolationLevelFlag, "true")) mustNil(t, a.Flags.Set(analyzer.TLSSignatureSchemeFlag, "true")) + mustNil(t, a.Flags.Set(analyzer.ConstantKindFlag, "true")) analysistest.Run(t, analysistest.TestData(), a, pkgs...) } diff --git a/pkg/analyzer/internal/gen.go b/pkg/analyzer/internal/gen.go index 9e5b757..18e2be5 100644 --- a/pkg/analyzer/internal/gen.go +++ b/pkg/analyzer/internal/gen.go @@ -97,10 +97,16 @@ func main() { }, { mapping: mapping.TLSSignatureScheme, - packageName: "sql_test", + packageName: "tls_test", templateName: "test-template.go.tmpl", fileName: "pkg/analyzer/testdata/src/a/tls/signaturescheme.go", }, + { + mapping: mapping.ConstantKind, + packageName: "constant_test", + templateName: "test-template.go.tmpl", + fileName: "pkg/analyzer/testdata/src/a/constant/kind.go", + }, } for _, operation := range operations { diff --git a/pkg/analyzer/internal/mapping/mapping.go b/pkg/analyzer/internal/mapping/mapping.go index ed03274..dbb6415 100644 --- a/pkg/analyzer/internal/mapping/mapping.go +++ b/pkg/analyzer/internal/mapping/mapping.go @@ -4,6 +4,7 @@ import ( "crypto" "crypto/tls" "database/sql" + "go/constant" "net/http" "net/rpc" "os" @@ -192,3 +193,12 @@ var TLSSignatureScheme = map[string]string{ tls.PKCS1WithSHA1.String(): "tls.PKCS1WithSHA1.String()", tls.ECDSAWithSHA1.String(): "tls.ECDSAWithSHA1.String()", } + +var ConstantKind = map[string]string{ + // constant.Unknown.String(): "constant.Unknown.String()", + constant.Bool.String(): "constant.Bool.String()", + constant.String.String(): "constant..String()", + constant.Int.String(): "constant..String()", + constant.Float.String(): "constant..String()", + constant.Complex.String(): "constant..String()", +} diff --git a/pkg/analyzer/testdata/src/a/constant/kind.go b/pkg/analyzer/testdata/src/a/constant/kind.go new file mode 100755 index 0000000..31b8980 --- /dev/null +++ b/pkg/analyzer/testdata/src/a/constant/kind.go @@ -0,0 +1,57 @@ +// Code generated by usestdlibvars, DO NOT EDIT. + +package constant_test + +import "fmt" + +var ( + _ = "Bool" // want `"Bool" can be replaced by constant\.Bool\.String\(\)` + _ = "Complex" // want `"Complex" can be replaced by constant\.\.String\(\)` + _ = "Float" // want `"Float" can be replaced by constant\.\.String\(\)` + _ = "Int" // want `"Int" can be replaced by constant\.\.String\(\)` + _ = "String" // want `"String" can be replaced by constant\.\.String\(\)` +) + +const ( + _ = "Bool" // want `"Bool" can be replaced by constant\.Bool\.String\(\)` + _ = "Complex" // want `"Complex" can be replaced by constant\.\.String\(\)` + _ = "Float" // want `"Float" can be replaced by constant\.\.String\(\)` + _ = "Int" // want `"Int" can be replaced by constant\.\.String\(\)` + _ = "String" // want `"String" can be replaced by constant\.\.String\(\)` +) + +func _() { + _ = func(s string) string { return s }("Bool") // want `"Bool" can be replaced by constant\.Bool\.String\(\)` + _ = func(s string) string { return s }("text before key Bool") + _ = func(s string) string { return s }("Bool text after key") + _ = func(s string) string { return s }("Complex") // want `"Complex" can be replaced by constant\.\.String\(\)` + _ = func(s string) string { return s }("text before key Complex") + _ = func(s string) string { return s }("Complex text after key") + _ = func(s string) string { return s }("Float") // want `"Float" can be replaced by constant\.\.String\(\)` + _ = func(s string) string { return s }("text before key Float") + _ = func(s string) string { return s }("Float text after key") + _ = func(s string) string { return s }("Int") // want `"Int" can be replaced by constant\.\.String\(\)` + _ = func(s string) string { return s }("text before key Int") + _ = func(s string) string { return s }("Int text after key") + _ = func(s string) string { return s }("String") // want `"String" can be replaced by constant\.\.String\(\)` + _ = func(s string) string { return s }("text before key String") + _ = func(s string) string { return s }("String text after key") +} + +func _() { + _ = fmt.Sprint("Bool") // want `"Bool" can be replaced by constant\.Bool\.String\(\)` + _ = fmt.Sprint("text before key Bool") + _ = fmt.Sprint("Bool text after key") + _ = fmt.Sprint("Complex") // want `"Complex" can be replaced by constant\.\.String\(\)` + _ = fmt.Sprint("text before key Complex") + _ = fmt.Sprint("Complex text after key") + _ = fmt.Sprint("Float") // want `"Float" can be replaced by constant\.\.String\(\)` + _ = fmt.Sprint("text before key Float") + _ = fmt.Sprint("Float text after key") + _ = fmt.Sprint("Int") // want `"Int" can be replaced by constant\.\.String\(\)` + _ = fmt.Sprint("text before key Int") + _ = fmt.Sprint("Int text after key") + _ = fmt.Sprint("String") // want `"String" can be replaced by constant\.\.String\(\)` + _ = fmt.Sprint("text before key String") + _ = fmt.Sprint("String text after key") +} diff --git a/pkg/analyzer/testdata/src/a/tls/signaturescheme.go b/pkg/analyzer/testdata/src/a/tls/signaturescheme.go index 94e1ecb..87488fa 100755 --- a/pkg/analyzer/testdata/src/a/tls/signaturescheme.go +++ b/pkg/analyzer/testdata/src/a/tls/signaturescheme.go @@ -1,6 +1,6 @@ // Code generated by usestdlibvars, DO NOT EDIT. -package sql_test +package tls_test import "fmt"