Skip to content

Commit e35cee4

Browse files
committed
Add 'floatcompare' linter
1 parent f5b92e1 commit e35cee4

File tree

7 files changed

+119
-0
lines changed

7 files changed

+119
-0
lines changed

.golangci.example.yml

Lines changed: 5 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:

go.mod

Lines changed: 1 addition & 0 deletions
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.1
6465
github.com/nakabonne/nestif v0.3.1
6566
github.com/nishanths/exhaustive v0.7.11
6667
github.com/nishanths/predeclared v0.2.1

go.sum

Lines changed: 2 additions & 0 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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
const floatcompareName = "floatcompare"
12+
13+
func NewFloatCompare(settings *config.FloatCompareSettings) *goanalysis.Linter {
14+
a := floatcompare.NewAnalyzer()
15+
16+
var cfg map[string]map[string]interface{}
17+
if settings != nil {
18+
d := map[string]interface{}{
19+
"equalOnly": settings.EqualOnly,
20+
}
21+
22+
cfg = map[string]map[string]interface{}{a.Name: d}
23+
}
24+
25+
return goanalysis.NewLinter(
26+
floatcompareName,
27+
"search for float comparison, since these are potential errors",
28+
[]*analysis.Analyzer{a},
29+
cfg,
30+
).WithLoadMode(goanalysis.LoadModeTypesInfo)
31+
}

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

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