Skip to content

Commit

Permalink
Add 'floatcompare' linter
Browse files Browse the repository at this point in the history
  • Loading branch information
mweb committed Apr 5, 2022
1 parent a2e6c76 commit dc69689
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .golangci.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ linters-settings:
- '*.Test'
- 'example.com/package.ExampleStruct'

floatcompare:
# Search only for == and != no other comparisons
# Default: false
equal-only: true

forbidigo:
# Forbid the following identifiers (list of regexp).
forbid:
Expand Down Expand Up @@ -1726,6 +1731,7 @@ linters:
- exhaustive
- exhaustivestruct
- exportloopref
- floatcompare
- forbidigo
- forcetypeassert
- funlen
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/go-ps v1.0.0
github.com/moricho/tparallel v0.2.1
github.com/mweb/floatcompare v1.0.3
github.com/nakabonne/nestif v0.3.1
github.com/nishanths/exhaustive v0.7.11
github.com/nishanths/predeclared v0.2.1
Expand Down Expand Up @@ -162,7 +163,7 @@ require (
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.27.1 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ type LintersSettings struct {
ErrorLint ErrorLintSettings
Exhaustive ExhaustiveSettings
ExhaustiveStruct ExhaustiveStructSettings
FloatCompare FloatCompareSettings
Forbidigo ForbidigoSettings
Funlen FunlenSettings
Gci GciSettings
Expand Down Expand Up @@ -255,6 +256,10 @@ type ExhaustiveStructSettings struct {
StructPatterns []string `mapstructure:"struct-patterns"`
}

type FloatCompareSettings struct {
EqualOnly bool `mapstructure:"equal-only"`
}

type ForbidigoSettings struct {
Forbid []string `mapstructure:"forbid"`
ExcludeGodocExamples bool `mapstructure:"exclude-godoc-examples"`
Expand Down
29 changes: 29 additions & 0 deletions pkg/golinters/floatcompare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package golinters

import (
"github.com/mweb/floatcompare"
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
)

func NewFloatCompare(settings *config.FloatCompareSettings) *goanalysis.Linter {
a := floatcompare.NewAnalyzer()

var cfg map[string]map[string]interface{}
if settings != nil {
d := map[string]interface{}{
"equalOnly": settings.EqualOnly,
}

cfg = map[string]map[string]interface{}{a.Name: d}
}

return goanalysis.NewLinter(
a.Name,
a.Doc,
[]*analysis.Analyzer{a},
cfg,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
8 changes: 8 additions & 0 deletions pkg/lint/lintersdb/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
var errorlintCfg *config.ErrorLintSettings
var exhaustiveCfg *config.ExhaustiveSettings
var exhaustiveStructCfg *config.ExhaustiveStructSettings
var floatCompareStructCfg *config.FloatCompareSettings
var gciCfg *config.GciSettings
var goModDirectivesCfg *config.GoModDirectivesSettings
var goMndCfg *config.GoMndSettings
Expand Down Expand Up @@ -140,6 +141,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
floatCompareStructCfg = &m.cfg.LintersSettings.FloatCompare
gciCfg = &m.cfg.LintersSettings.Gci
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
goMndCfg = &m.cfg.LintersSettings.Gomnd
Expand Down Expand Up @@ -289,6 +291,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithLoadForGoAnalysis().
WithURL("https://github.com/kyoh86/exportloopref"),

linter.NewConfig(golinters.NewFloatCompare(floatCompareStructCfg)).
WithSince("v1.46.0").
WithPresets(linter.PresetBugs).
WithLoadForGoAnalysis().
WithURL("https://github.com/mweb/floatcompare"),

linter.NewConfig(golinters.NewForbidigo()).
WithSince("v1.34.0").
WithPresets(linter.PresetStyle).
Expand Down
71 changes: 71 additions & 0 deletions test/testdata/floatcompare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// args: -Efloatcompare
package testdata

import "fmt"

func EqualCompareIfFloats() {
x, y := 400., 500.
if 300. == 100. { // ERROR `float comparison found "300. == 100."`
dummy()
}
if x == y { // ERROR `float comparison found "x == y"`
dummy()
}
if 300.+200. == 10. { // ERROR `float comparison found "300.+200. == 10."`
dummy()
}
if 300 == 200 {
dummy()
}
}

func NotEqualCompareIfFloats() {
x, y := 400., 500.
if 300. != 100. { // ERROR `float comparison found "300. != 100."`

dummy()
}
if x != y { // ERROR `float comparison found "x != y"`
dummy()
}
}

func EqualCompareIfCustomType() {
type number float64
var x, y number = 300., 400.
if x == y { // ERROR `float comparison found "x == y"`
dummy()
}
}

func GreaterLessCompareIfFloats() {
if 300. >= 100. { // ERROR `float comparison found "300. >= 100."`
dummy()
}
if 300. <= 100. { // ERROR `float comparison found "300. <= 100."`
dummy()
}
if 300. < 100. { // ERROR `float comparison found "300. < 100."`
dummy()
}
if 300. > 100. { // ERROR `float comparison found "300. > 100."`
dummy()
}
}

func SwitchStmtWithFloat() {
switch 300. { // ERROR "float comparison with switch statement"
case 100.:
case 200:
}
}

func EqualCompareSwitchFloats() {
switch {
case 100. == 200.: // ERROR `float comparison found "100. == 200."`
}
}

func dummy() {
fmt.Println("dummy()")
}

0 comments on commit dc69689

Please sign in to comment.