Skip to content

Commit dc69689

Browse files
committed
Add 'floatcompare' linter
1 parent a2e6c76 commit dc69689

File tree

7 files changed

+125
-3
lines changed

7 files changed

+125
-3
lines changed

.golangci.example.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,11 @@ linters-settings:
285285
- '*.Test'
286286
- 'example.com/package.ExampleStruct'
287287

288+
floatcompare:
289+
# Search only for == and != no other comparisons
290+
# Default: false
291+
equal-only: true
292+
288293
forbidigo:
289294
# Forbid the following identifiers (list of regexp).
290295
forbid:
@@ -1726,6 +1731,7 @@ linters:
17261731
- exhaustive
17271732
- exhaustivestruct
17281733
- exportloopref
1734+
- floatcompare
17291735
- forbidigo
17301736
- forcetypeassert
17311737
- funlen

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ require (
6161
github.com/mitchellh/go-homedir v1.1.0
6262
github.com/mitchellh/go-ps v1.0.0
6363
github.com/moricho/tparallel v0.2.1
64+
github.com/mweb/floatcompare v1.0.3
6465
github.com/nakabonne/nestif v0.3.1
6566
github.com/nishanths/exhaustive v0.7.11
6667
github.com/nishanths/predeclared v0.2.1
@@ -162,7 +163,7 @@ require (
162163
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect
163164
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
164165
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
165-
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect
166+
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64 // indirect
166167
golang.org/x/text v0.3.7 // indirect
167168
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
168169
google.golang.org/protobuf v1.27.1 // indirect

go.sum

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/config/linters_settings.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ type LintersSettings struct {
123123
ErrorLint ErrorLintSettings
124124
Exhaustive ExhaustiveSettings
125125
ExhaustiveStruct ExhaustiveStructSettings
126+
FloatCompare FloatCompareSettings
126127
Forbidigo ForbidigoSettings
127128
Funlen FunlenSettings
128129
Gci GciSettings
@@ -255,6 +256,10 @@ type ExhaustiveStructSettings struct {
255256
StructPatterns []string `mapstructure:"struct-patterns"`
256257
}
257258

259+
type FloatCompareSettings struct {
260+
EqualOnly bool `mapstructure:"equal-only"`
261+
}
262+
258263
type ForbidigoSettings struct {
259264
Forbid []string `mapstructure:"forbid"`
260265
ExcludeGodocExamples bool `mapstructure:"exclude-godoc-examples"`

pkg/golinters/floatcompare.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package golinters
2+
3+
import (
4+
"github.com/mweb/floatcompare"
5+
"golang.org/x/tools/go/analysis"
6+
7+
"github.com/golangci/golangci-lint/pkg/config"
8+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
9+
)
10+
11+
func NewFloatCompare(settings *config.FloatCompareSettings) *goanalysis.Linter {
12+
a := floatcompare.NewAnalyzer()
13+
14+
var cfg map[string]map[string]interface{}
15+
if settings != nil {
16+
d := map[string]interface{}{
17+
"equalOnly": settings.EqualOnly,
18+
}
19+
20+
cfg = map[string]map[string]interface{}{a.Name: d}
21+
}
22+
23+
return goanalysis.NewLinter(
24+
a.Name,
25+
a.Doc,
26+
[]*analysis.Analyzer{a},
27+
cfg,
28+
).WithLoadMode(goanalysis.LoadModeTypesInfo)
29+
}

pkg/lint/lintersdb/manager.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
107107
var errorlintCfg *config.ErrorLintSettings
108108
var exhaustiveCfg *config.ExhaustiveSettings
109109
var exhaustiveStructCfg *config.ExhaustiveStructSettings
110+
var floatCompareStructCfg *config.FloatCompareSettings
110111
var gciCfg *config.GciSettings
111112
var goModDirectivesCfg *config.GoModDirectivesSettings
112113
var goMndCfg *config.GoMndSettings
@@ -140,6 +141,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
140141
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
141142
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
142143
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
144+
floatCompareStructCfg = &m.cfg.LintersSettings.FloatCompare
143145
gciCfg = &m.cfg.LintersSettings.Gci
144146
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
145147
goMndCfg = &m.cfg.LintersSettings.Gomnd
@@ -289,6 +291,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
289291
WithLoadForGoAnalysis().
290292
WithURL("https://github.com/kyoh86/exportloopref"),
291293

294+
linter.NewConfig(golinters.NewFloatCompare(floatCompareStructCfg)).
295+
WithSince("v1.46.0").
296+
WithPresets(linter.PresetBugs).
297+
WithLoadForGoAnalysis().
298+
WithURL("https://github.com/mweb/floatcompare"),
299+
292300
linter.NewConfig(golinters.NewForbidigo()).
293301
WithSince("v1.34.0").
294302
WithPresets(linter.PresetStyle).

test/testdata/floatcompare.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// args: -Efloatcompare
2+
package testdata
3+
4+
import "fmt"
5+
6+
func EqualCompareIfFloats() {
7+
x, y := 400., 500.
8+
if 300. == 100. { // ERROR `float comparison found "300. == 100."`
9+
dummy()
10+
}
11+
if x == y { // ERROR `float comparison found "x == y"`
12+
dummy()
13+
}
14+
if 300.+200. == 10. { // ERROR `float comparison found "300.+200. == 10."`
15+
dummy()
16+
}
17+
if 300 == 200 {
18+
dummy()
19+
}
20+
}
21+
22+
func NotEqualCompareIfFloats() {
23+
x, y := 400., 500.
24+
if 300. != 100. { // ERROR `float comparison found "300. != 100."`
25+
26+
dummy()
27+
}
28+
if x != y { // ERROR `float comparison found "x != y"`
29+
dummy()
30+
}
31+
}
32+
33+
func EqualCompareIfCustomType() {
34+
type number float64
35+
var x, y number = 300., 400.
36+
if x == y { // ERROR `float comparison found "x == y"`
37+
dummy()
38+
}
39+
}
40+
41+
func GreaterLessCompareIfFloats() {
42+
if 300. >= 100. { // ERROR `float comparison found "300. >= 100."`
43+
dummy()
44+
}
45+
if 300. <= 100. { // ERROR `float comparison found "300. <= 100."`
46+
dummy()
47+
}
48+
if 300. < 100. { // ERROR `float comparison found "300. < 100."`
49+
dummy()
50+
}
51+
if 300. > 100. { // ERROR `float comparison found "300. > 100."`
52+
dummy()
53+
}
54+
}
55+
56+
func SwitchStmtWithFloat() {
57+
switch 300. { // ERROR "float comparison with switch statement"
58+
case 100.:
59+
case 200:
60+
}
61+
}
62+
63+
func EqualCompareSwitchFloats() {
64+
switch {
65+
case 100. == 200.: // ERROR `float comparison found "100. == 200."`
66+
}
67+
}
68+
69+
func dummy() {
70+
fmt.Println("dummy()")
71+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy