diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml index e8819223a0c0..865ea147c67c 100644 --- a/.golangci.next.reference.yml +++ b/.golangci.next.reference.yml @@ -77,6 +77,7 @@ linters: - interfacebloat - intrange - iotamixing + - iotyper - ireturn - lll - loggercheck @@ -192,6 +193,7 @@ linters: - interfacebloat - intrange - iotamixing + - iotyper - ireturn - lll - loggercheck diff --git a/go.mod b/go.mod index d92e2aa46fb1..24d97b147ce1 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/Antonboom/nilnil v1.1.1 github.com/Antonboom/testifylint v1.6.4 github.com/BurntSushi/toml v1.5.0 + github.com/CyberAgent/iotyper-lint v0.0.0-20251126071057-12b4d357612a github.com/Djarvur/go-err113 v0.1.1 github.com/MirrexOne/unqueryvet v1.3.0 github.com/OpenPeeDeeP/depguard/v2 v2.2.1 @@ -218,7 +219,7 @@ require ( go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/exp/typeparams v0.0.0-20251023183803-a4bb9ffd2546 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/tools/go/expect v0.1.1-deprecated // indirect golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect google.golang.org/protobuf v1.36.8 // indirect diff --git a/go.sum b/go.sum index 9d289bb4ef30..947cd25d352a 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CyberAgent/iotyper-lint v0.0.0-20251126071057-12b4d357612a h1:MycPcaT0AIP43P8ne/tKl74k7da+vCB6nPzSJLVbWHw= +github.com/CyberAgent/iotyper-lint v0.0.0-20251126071057-12b4d357612a/go.mod h1:hYLyrPjHVG50ftzpjPFRXuLg4lbwUao6I1wJQmT6flo= github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g= github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= @@ -324,8 +326,8 @@ github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXS github.com/gostaticanalysis/nilerr v0.1.2 h1:S6nk8a9N8g062nsx63kUkF6AzbHGw7zzyHMcpu52xQU= github.com/gostaticanalysis/nilerr v0.1.2/go.mod h1:A19UHhoY3y8ahoL7YKz6sdjDtduwTSI4CsymaC2htPA= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= -github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8= -github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs= +github.com/gostaticanalysis/testutil v0.6.1 h1:DeKCG96QlhtNAz+/z2jjO3gIHFV+lHEwELddAsLohxg= +github.com/gostaticanalysis/testutil v0.6.1/go.mod h1:XfUs9IH5sPfXbPIq+kHR64fCpB6pBf5mYeaZQdaTBpw= github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= @@ -454,12 +456,14 @@ github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= -github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= +github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs= +github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -579,8 +583,9 @@ github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/tenntenn/text/transform v0.0.0-20250402111347-ba836492e880 h1:hAkmx/iqQVHL6cWVkmEe7rsqdepWsU7m3yDh/P7faig= +github.com/tenntenn/text/transform v0.0.0-20250402111347-ba836492e880/go.mod h1:gHKdSzW72+xrCRfwqH2NCHKK2Mrh9Zf+sU5fzzGeTUw= github.com/tetafro/godot v1.5.4 h1:u1ww+gqpRLiIA16yF2PV1CV1n/X3zhyezbNXC3E14Sg= github.com/tetafro/godot v1.5.4/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU= github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk= @@ -841,8 +846,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/golinters/iotyper/iotyper.go b/pkg/golinters/iotyper/iotyper.go new file mode 100644 index 000000000000..98ef035e0961 --- /dev/null +++ b/pkg/golinters/iotyper/iotyper.go @@ -0,0 +1,13 @@ +package iotyper + +import ( + "github.com/CyberAgent/iotyper-lint" + + "github.com/golangci/golangci-lint/v2/pkg/goanalysis" +) + +func New() *goanalysis.Linter { + return goanalysis. + NewLinterFromAnalyzer(iotyper.Analyzer). + WithLoadMode(goanalysis.LoadModeSyntax) +} diff --git a/pkg/golinters/iotyper/iotyper_integration_test.go b/pkg/golinters/iotyper/iotyper_integration_test.go new file mode 100644 index 000000000000..da1a76c7220d --- /dev/null +++ b/pkg/golinters/iotyper/iotyper_integration_test.go @@ -0,0 +1,11 @@ +package iotyper + +import ( + "testing" + + "github.com/golangci/golangci-lint/v2/test/testshared/integration" +) + +func TestFromTestdata(t *testing.T) { + integration.RunTestdata(t) +} diff --git a/pkg/golinters/iotyper/testdata/iotyper.go b/pkg/golinters/iotyper/testdata/iotyper.go new file mode 100644 index 000000000000..108503ec56ae --- /dev/null +++ b/pkg/golinters/iotyper/testdata/iotyper.go @@ -0,0 +1,45 @@ +//golangcitest:args -Eiotyper +package testdata + +// Basic iota without type +const ( + BasicWithoutType = iota // want "iota used without type specification" +) + +// Single-line const declarations +const SingleLineWithoutType = iota // want "iota used without type specification" +const SingleLineWithType int = iota // OK: has type + +// Multiple constants with inherited iota +const ( + FirstInGroup = iota // want "iota used without type specification" + SecondInGroup // No warning: inherits iota value but doesn't use iota directly + ThirdInGroup // No warning: same as above +) + +// Non-iota constants (no warnings expected) +const ( + PlainNumber = 42 + PlainString = "hello" + PlainBool = true +) + +// iota in expressions +const ( + IotaPlusOne = iota + 1 // want "iota used without type specification" + IotaShifted = 1 << iota // want "iota used without type specification" + IotaMultiple = iota * 2 // want "iota used without type specification" +) + +// iota with explicit type +const ( + WithTypeInt int = iota // OK: explicit int type + WithTypeIntAgain int = iota // OK: explicit int type +) + +// Mixed type specifications +const ( + MixedWithType int = iota // OK: has type + MixedWithoutType = iota // want "iota used without type specification" + MixedAgainWithType int = iota // OK: has type +) diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 6e9cef1d1b36..b8a2b53d52ff 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -65,6 +65,7 @@ import ( "github.com/golangci/golangci-lint/v2/pkg/golinters/interfacebloat" "github.com/golangci/golangci-lint/v2/pkg/golinters/intrange" "github.com/golangci/golangci-lint/v2/pkg/golinters/iotamixing" + "github.com/golangci/golangci-lint/v2/pkg/golinters/iotyper" "github.com/golangci/golangci-lint/v2/pkg/golinters/ireturn" "github.com/golangci/golangci-lint/v2/pkg/golinters/lll" "github.com/golangci/golangci-lint/v2/pkg/golinters/loggercheck" @@ -457,6 +458,10 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithSince("v2.5.0"). WithURL("https://github.com/AdminBenni/iota-mixing"), + linter.NewConfig(iotyper.New()). + WithSince("v2.7.0"). + WithURL("https://github.com/CyberAgent/iotyper-lint"), + linter.NewConfig(ireturn.New(&cfg.Linters.Settings.Ireturn)). WithSince("v1.43.0"). WithLoadForGoAnalysis().