diff --git a/go.mod b/go.mod index ce6ec0b23..489aefcfc 100644 --- a/go.mod +++ b/go.mod @@ -7,12 +7,12 @@ require ( code.cloudfoundry.org/workpool v0.0.0-20230612151832-b93da105e0e8 github.com/cheggaaa/pb/v3 v3.1.4 github.com/cloudfoundry/bosh-agent v0.0.61-0.20230301011448-4cfe06c13ad7 - github.com/cloudfoundry/bosh-davcli v0.0.300 + github.com/cloudfoundry/bosh-davcli v0.0.301 github.com/cloudfoundry/bosh-gcscli v0.0.184 - github.com/cloudfoundry/bosh-s3cli v0.0.247 - github.com/cloudfoundry/bosh-utils v0.0.419 - github.com/cloudfoundry/config-server v0.1.161 - github.com/cloudfoundry/socks5-proxy v0.2.106 + github.com/cloudfoundry/bosh-s3cli v0.0.248 + github.com/cloudfoundry/bosh-utils v0.0.420 + github.com/cloudfoundry/config-server v0.1.162 + github.com/cloudfoundry/socks5-proxy v0.2.107 github.com/cppforlife/go-patch v0.2.0 github.com/cppforlife/go-semi-semantic v0.0.0-20160921010311-576b6af77ae4 github.com/dustin/go-humanize v1.0.1 @@ -52,7 +52,7 @@ require ( github.com/Antonboom/testifylint v1.0.2 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect - github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect github.com/VividCortex/ewma v1.2.0 // indirect @@ -62,7 +62,7 @@ require ( github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect - github.com/aws/aws-sdk-go v1.49.13 // indirect + github.com/aws/aws-sdk-go v1.49.16 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -91,13 +91,13 @@ require ( github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/ghostiam/protogetter v0.3.3 // indirect - github.com/go-critic/go-critic v0.10.0 // indirect + github.com/go-critic/go-critic v0.11.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect - github.com/go-toolsmith/astequal v1.1.0 // indirect + github.com/go-toolsmith/astequal v1.2.0 // indirect github.com/go-toolsmith/astfmt v1.1.0 // indirect github.com/go-toolsmith/astp v1.1.0 // indirect github.com/go-toolsmith/strparse v1.1.0 // indirect @@ -153,12 +153,12 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/maratori/testableexamples v1.0.0 // indirect github.com/maratori/testpackage v1.1.1 // indirect - github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect + github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.3.4 // indirect + github.com/mgechev/revive v1.3.5 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.3.1 // indirect @@ -231,20 +231,20 @@ require ( go.tmz.dev/musttag v0.7.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect - golang.org/x/exp/typeparams v0.0.0-20231226003508-02704c960a9b // indirect + golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect + golang.org/x/exp/typeparams v0.0.0-20240103183307-be819d1f06fc // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/api v0.154.0 // indirect + google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect + google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect google.golang.org/grpc v1.60.1 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect @@ -252,5 +252,5 @@ require ( mvdan.cc/gofumpt v0.5.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20231227222031-fe02aa31e4f6 // indirect + mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect ) diff --git a/go.sum b/go.sum index f9ae89494..eb33e2ff1 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 h1:3ZBs7LAezy8gh0uECsA6CGU43FF3zsx5f4eah5FxTMA= -github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0/go.mod h1:rZLTje5A9kFBe0pzhpe2TdhRniBF++PRHQuRpR8esVc= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 h1:sATXp1x6/axKxz2Gjxv8MALP0bXaNRfQinEwyfMcx8c= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0/go.mod h1:Nl76DrGNJTA1KJ0LePKBw/vznBX1EHbAZX8mwjR82nI= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= @@ -98,8 +98,8 @@ github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8ger github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= -github.com/aws/aws-sdk-go v1.49.13 h1:f4mGztsgnx2dR9r8FQYa9YW/RsKb+N7bgef4UGrOW1Y= -github.com/aws/aws-sdk-go v1.49.13/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.49.16 h1:KAQwhLg296hfffRdh+itA9p7Nx/3cXS/qOa3uF9ssig= +github.com/aws/aws-sdk-go v1.49.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -143,20 +143,20 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudfoundry/bosh-agent v0.0.61-0.20230301011448-4cfe06c13ad7 h1:WqAIRLehvJrDhnDaVDS+OTjlbmHInIVU+dhVcvUWqmA= github.com/cloudfoundry/bosh-agent v0.0.61-0.20230301011448-4cfe06c13ad7/go.mod h1:FVqJVDjAlpDNjaI1k79SXdh+ymNMDWPg38jSIzYUF+4= -github.com/cloudfoundry/bosh-davcli v0.0.300 h1:snEHVXKeVSm800j9lBeokt3KJOCcE4BzD8BNP6jvhlM= -github.com/cloudfoundry/bosh-davcli v0.0.300/go.mod h1:6+KdqrvgQP7vuyEk7RY3kH0AqHEpTXJjFfIP8vUBm98= +github.com/cloudfoundry/bosh-davcli v0.0.301 h1:R3KAs7FXCVIpkSTsnb6R/bHRz/mLD/8W5U83RxuJgas= +github.com/cloudfoundry/bosh-davcli v0.0.301/go.mod h1:1g4qfaV6/Yp3dMLbkKcrAzBy37A3SJ3wo0HTROLwd9k= github.com/cloudfoundry/bosh-gcscli v0.0.184 h1:rRIj//EyOH9f/L0CB8u3kpyN+wo3oc9YXNH07L1gAiE= github.com/cloudfoundry/bosh-gcscli v0.0.184/go.mod h1:riRJ4hoo6xbjV0+7MInI/WKCsOI06w4Q/YnhzIAW5Tk= -github.com/cloudfoundry/bosh-s3cli v0.0.247 h1:V8wsJBBbi847nvJ8JGwuNOwCZrtBzNamWnnlRdOq5nU= -github.com/cloudfoundry/bosh-s3cli v0.0.247/go.mod h1:IYPlmV9/VXJ9j/SIhxXPiAiH/6GaEXmc45x2uFVC0yk= -github.com/cloudfoundry/bosh-utils v0.0.419 h1:0WLwQFRrJBtdMlggol920QBUdhExIHcSwhNFmyoR08c= -github.com/cloudfoundry/bosh-utils v0.0.419/go.mod h1:teKq7KlE/1t+yt7A4fsDXaWrZNBufiqyogJ01/KLWSE= -github.com/cloudfoundry/config-server v0.1.161 h1:+mtFW5TgYdJCyfPM+xhDIUoQx6qA1CV01/KUBEaYBoI= -github.com/cloudfoundry/config-server v0.1.161/go.mod h1:GhGgwl+FXQN9UUD8CJ40fH4pISRoOfd0Ioi9wxbiZ0M= +github.com/cloudfoundry/bosh-s3cli v0.0.248 h1:48TCa8KmIG+lD5IfAyH1ENc5BJn3ofmv5bpQ9+kLoQA= +github.com/cloudfoundry/bosh-s3cli v0.0.248/go.mod h1:MBNybNkXp6elPvj631CxvIwNFXOpzuCJV6f27hOVGaM= +github.com/cloudfoundry/bosh-utils v0.0.420 h1:XdRMFXqKQBrc8aT6eeDhhptRn5nLzWTBfUcVFyvjuCo= +github.com/cloudfoundry/bosh-utils v0.0.420/go.mod h1:Jyae6YVCKWbIad4ku3X9X2f3fGZKVdRLRl4XlKfytjg= +github.com/cloudfoundry/config-server v0.1.162 h1:XNbVShTiyhYe3UC6gIAlkrXAfRajtjoPZ3UIDdePVao= +github.com/cloudfoundry/config-server v0.1.162/go.mod h1:QZpBIz9jQD0tCjbqtTu8h+dinmGHX8ll7YyUKimZAT0= github.com/cloudfoundry/go-socks5 v0.0.0-20180221174514-54f73bdb8a8e h1:FQdRViaoDphGRfgrotl2QGsX1gbloe57dbGBS5CG6KY= github.com/cloudfoundry/go-socks5 v0.0.0-20180221174514-54f73bdb8a8e/go.mod h1:PXmcacyJB/pJjSxEl15IU6rEIKXrhZQRzsr0UTkgNNs= -github.com/cloudfoundry/socks5-proxy v0.2.106 h1:encJP5JDlSAK7mBf1dGh0ELwz46Ja1PWrnxdxg1Zkzs= -github.com/cloudfoundry/socks5-proxy v0.2.106/go.mod h1:fyji3LUZ8yjYiFbIX4LJ+FjLFZXu+1X93TIMRbVQfQc= +github.com/cloudfoundry/socks5-proxy v0.2.107 h1:uminKnlYtXkCBdzXh75ViyZxBuVJ3aCLMCj0ncBHe24= +github.com/cloudfoundry/socks5-proxy v0.2.107/go.mod h1:LuVADRx4LyaNkJ7I+Ao7EVhb5SHi/XqnZawO3a3Auwc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -207,8 +207,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghostiam/protogetter v0.3.3 h1:EvOuzB/SEifg/c4aMnwcj033Qc1lHO7Yz4QnBDbmbik= github.com/ghostiam/protogetter v0.3.3/go.mod h1:A0JgIhs0fgVnotGinjQiKaFVG3waItLJNwPmcMzDnvk= -github.com/go-critic/go-critic v0.10.0 h1:tOkke48KSKC4tSS5Dc22ICdChMy0maRj1uDgdV5vXfc= -github.com/go-critic/go-critic v0.10.0/go.mod h1:gW4noMWDewS/WQdqiuJdA0pXbRxito860jj1ucPzy7g= +github.com/go-critic/go-critic v0.11.0 h1:mARtIFX7jPtJ3SzxO9Isa5T2jd2dZxFmQHK3yNf0wrE= +github.com/go-critic/go-critic v0.11.0/go.mod h1:Cz6lr1PlkIu/0Y0U9KqJgcIJJECAF8mEwmzVjKnhbfI= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -231,8 +231,9 @@ github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4 github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw= github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw= +github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY= github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= @@ -448,8 +449,8 @@ github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 h1:Ny7cm4KSWceJLYyI1sm+aFIVDWSGXLcOJ0O0UaS5wdU= +github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -467,8 +468,8 @@ github.com/maxbrunsfeld/counterfeiter/v6 v6.7.0 h1:z0CfPybq3CxaJvrrpf7Gme1psZTqH github.com/maxbrunsfeld/counterfeiter/v6 v6.7.0/go.mod h1:RVP6/F85JyxTrbJxWIdKU2vlSvK48iCMnMXRkSz7xtg= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.3.4 h1:k/tO3XTaWY4DEHal9tWBkkUMJYO/dLDVyMmAQxmIMDc= -github.com/mgechev/revive v1.3.4/go.mod h1:W+pZCMu9qj8Uhfs1iJMQsEFLRozUfvwFwqVvRbSNLVw= +github.com/mgechev/revive v1.3.5 h1:YKiB7RAIx1/rHgwejgp4peZQTInNm0pxaT5OmDAo7JE= +github.com/mgechev/revive v1.3.5/go.mod h1:R9M+iSw2EQMpmko54t0jOlS2uXSObNdlLkkUdv1/RCY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -749,12 +750,12 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM= +golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20231226003508-02704c960a9b h1:REUlHhTOw33b7qzGmIS/hnH7exvLtryx0U+btFaq5Yk= -golang.org/x/exp/typeparams v0.0.0-20231226003508-02704c960a9b/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20240103183307-be819d1f06fc h1:jBRSxvWDmbXyeXO38AwVP1s2OAfWkntin3MkGe/9nx4= +golang.org/x/exp/typeparams v0.0.0-20240103183307-be819d1f06fc/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -849,8 +850,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -910,8 +911,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -919,8 +920,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -953,7 +954,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1025,8 +1025,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.154.0 h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050= -google.golang.org/api v0.154.0/go.mod h1:qhSMkM85hgqiokIYsrRyKxrjfBeIhgl4Z2JmeRkYylc= +google.golang.org/api v0.155.0 h1:vBmGhCYs0djJttDNynWo44zosHlPvHmA0XiN2zP2DtA= +google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1064,12 +1064,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos= -google.golang.org/genproto v0.0.0-20231212172506-995d672761c0/go.mod h1:l/k7rMz0vFTBPy+tFSGvXEd3z+BcoG1k7EHbqm+YBsY= -google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 h1:s1w3X6gQxwrLEpxnLd/qXTVLgQE2yXwaOaoa6IlY/+o= -google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1137,8 +1137,8 @@ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wp mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20231227222031-fe02aa31e4f6 h1:NgaTe+hRE7g8lY31D07tlAbZbs4LU7rAK6XoRRwHwJk= -mvdan.cc/unparam v0.0.0-20231227222031-fe02aa31e4f6/go.mod h1:ZzZjEpJDOmx8TdVU6umamY3Xy0UAQUI2DHbf05USVbI= +mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 h1:zCr3iRRgdk5eIikZNDphGcM6KGVTx3Yu+/Uu9Es254w= +mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14/go.mod h1:ZzZjEpJDOmx8TdVU6umamY3Xy0UAQUI2DHbf05USVbI= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go index d0cd2d5bb..b490f1c64 100644 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go @@ -12,16 +12,17 @@ import ( "golang.org/x/tools/go/analysis/passes/inspect" "golang.org/x/tools/go/ast/inspector" - "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields" + "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment" "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern" + "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure" ) type analyzer struct { include pattern.List `exhaustruct:"optional"` exclude pattern.List `exhaustruct:"optional"` - fieldsCache map[types.Type]fields.StructFields - fieldsCacheMu sync.RWMutex `exhaustruct:"optional"` + structFields structure.FieldsCache `exhaustruct:"optional"` + comments comment.Cache `exhaustruct:"optional"` typeProcessingNeed map[string]bool typeProcessingNeedMu sync.RWMutex `exhaustruct:"optional"` @@ -29,8 +30,8 @@ type analyzer struct { func NewAnalyzer(include, exclude []string) (*analysis.Analyzer, error) { a := analyzer{ - fieldsCache: make(map[types.Type]fields.StructFields), typeProcessingNeed: make(map[string]bool), + comments: comment.Cache{}, } var err error @@ -74,12 +75,7 @@ Anonymous structs can be matched by '' alias. func (a *analyzer) run(pass *analysis.Pass) (any, error) { insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) //nolint:forcetypeassert - insp.WithStack( - []ast.Node{ - (*ast.CompositeLit)(nil), - }, - a.newVisitor(pass), - ) + insp.WithStack([]ast.Node{(*ast.CompositeLit)(nil)}, a.newVisitor(pass)) return nil, nil //nolint:nilnil } @@ -115,7 +111,10 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(n ast.Node, push bool, s } } - pos, msg := a.processStruct(pass, lit, structTyp, typeInfo) + file := a.comments.Get(pass.Fset, stack[0].(*ast.File)) //nolint:forcetypeassert + rc := getCompositeLitRelatedComments(stack, file) + pos, msg := a.processStruct(pass, lit, structTyp, typeInfo, rc) + if pos != nil { pass.Reportf(*pos, msg) } @@ -124,6 +123,35 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(n ast.Node, push bool, s } } +// getCompositeLitRelatedComments returns all comments that are related to checked node. We +// have to traverse the stack manually as ast do not associate comments with +// [ast.CompositeLit]. +func getCompositeLitRelatedComments(stack []ast.Node, cm ast.CommentMap) []*ast.CommentGroup { + comments := make([]*ast.CommentGroup, 0) + + for i := len(stack) - 1; i >= 0; i-- { + node := stack[i] + + switch node.(type) { + case *ast.CompositeLit, // stack[len(stack)-1] + *ast.ReturnStmt, // return ... + *ast.IndexExpr, // map[enum]...{...}[key] + *ast.CallExpr, // myfunc(map...) + *ast.UnaryExpr, // &map... + *ast.AssignStmt, // variable assignment (without var keyword) + *ast.DeclStmt, // var declaration, parent of *ast.GenDecl + *ast.GenDecl, // var declaration, parent of *ast.ValueSpec + *ast.ValueSpec: // var declaration + comments = append(comments, cm[node]...) + + default: + return comments + } + } + + return comments +} + func getStructType(pass *analysis.Pass, lit *ast.CompositeLit) (*types.Struct, *TypeInfo, bool) { switch typ := pass.TypesInfo.TypeOf(lit).(type) { case *types.Named: // named type @@ -179,8 +207,15 @@ func (a *analyzer) processStruct( lit *ast.CompositeLit, structTyp *types.Struct, info *TypeInfo, + comments []*ast.CommentGroup, ) (*token.Pos, string) { - if !a.shouldProcessType(info) { + shouldProcess := a.shouldProcessType(info) + + if shouldProcess && comment.HasDirective(comments, comment.DirectiveIgnore) { + return nil, "" + } + + if !shouldProcess && !comment.HasDirective(comments, comment.DirectiveEnforce) { return nil, "" } @@ -233,24 +268,12 @@ func (a *analyzer) shouldProcessType(info *TypeInfo) bool { return res } -//revive:disable-next-line:unused-receiver func (a *analyzer) litSkippedFields( lit *ast.CompositeLit, typ *types.Struct, onlyExported bool, -) fields.StructFields { - a.fieldsCacheMu.RLock() - f, ok := a.fieldsCache[typ] - a.fieldsCacheMu.RUnlock() - - if !ok { - a.fieldsCacheMu.Lock() - f = fields.NewStructFields(typ) - a.fieldsCache[typ] = f - a.fieldsCacheMu.Unlock() - } - - return f.SkippedFields(lit, onlyExported) +) structure.Fields { + return a.structFields.Get(typ).Skipped(lit, onlyExported) } type TypeInfo struct { diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go new file mode 100644 index 000000000..88edef638 --- /dev/null +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go @@ -0,0 +1,35 @@ +package comment + +import ( + "go/ast" + "go/token" + "sync" +) + +type Cache struct { + comments map[*ast.File]ast.CommentMap + mu sync.RWMutex +} + +// Get returns a comment map for a given file. In case if a comment map is not +// found, it creates a new one. +func (c *Cache) Get(fset *token.FileSet, f *ast.File) ast.CommentMap { + c.mu.RLock() + if cm, ok := c.comments[f]; ok { + c.mu.RUnlock() + return cm + } + c.mu.RUnlock() + + c.mu.Lock() + defer c.mu.Unlock() + + if c.comments == nil { + c.comments = make(map[*ast.File]ast.CommentMap) + } + + cm := ast.NewCommentMap(fset, f, f.Comments) + c.comments[f] = cm + + return cm +} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go new file mode 100644 index 000000000..a39a8076f --- /dev/null +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go @@ -0,0 +1,28 @@ +package comment + +import ( + "go/ast" + "strings" +) + +type Directive string + +const ( + prefix = `//exhaustruct:` + DirectiveIgnore Directive = prefix + `ignore` + DirectiveEnforce Directive = prefix + `enforce` +) + +// HasDirective parses a directive from a given list of comments. +// If no directive is found, the second return value is `false`. +func HasDirective(comments []*ast.CommentGroup, expected Directive) bool { + for _, cg := range comments { + for _, commentLine := range cg.List { + if strings.HasPrefix(commentLine.Text, string(expected)) { + return true + } + } + } + + return false +} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go new file mode 100644 index 000000000..12a379692 --- /dev/null +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go @@ -0,0 +1,35 @@ +package structure + +import ( + "go/types" + "sync" +) + +type FieldsCache struct { + fields map[*types.Struct]Fields + mu sync.RWMutex +} + +// Get returns a struct fields for a given type. In case if a struct fields is +// not found, it creates a new one from type definition. +func (c *FieldsCache) Get(typ *types.Struct) Fields { + c.mu.RLock() + fields, ok := c.fields[typ] + c.mu.RUnlock() + + if ok { + return fields + } + + c.mu.Lock() + defer c.mu.Unlock() + + if c.fields == nil { + c.fields = make(map[*types.Struct]Fields) + } + + fields = NewFields(typ) + c.fields[typ] = fields + + return fields +} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields/struct.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go similarity index 64% rename from vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields/struct.go rename to vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go index af2390e87..b6b1a48c8 100644 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields/struct.go +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go @@ -1,33 +1,34 @@ -package fields +package structure import ( "go/ast" "go/types" "reflect" + "strings" ) const ( - TagName = "exhaustruct" - OptionalTagValue = "optional" + tagName = "exhaustruct" + optionalTagValue = "optional" ) -type StructField struct { +type Field struct { Name string Exported bool Optional bool } -type StructFields []*StructField +type Fields []*Field -// NewStructFields creates a new [StructFields] from a given struct type. -// StructFields items are listed in order they appear in the struct. -func NewStructFields(strct *types.Struct) StructFields { - sf := make(StructFields, 0, strct.NumFields()) +// NewFields creates a new [Fields] from a given struct type. +// Fields items are listed in order they appear in the struct. +func NewFields(strct *types.Struct) Fields { + sf := make(Fields, 0, strct.NumFields()) for i := 0; i < strct.NumFields(); i++ { f := strct.Field(i) - sf = append(sf, &StructField{ + sf = append(sf, &Field{ Name: f.Name(), Exported: f.Exported(), Optional: HasOptionalTag(strct.Tag(i)), @@ -38,27 +39,29 @@ func NewStructFields(strct *types.Struct) StructFields { } func HasOptionalTag(tags string) bool { - return reflect.StructTag(tags).Get(TagName) == OptionalTagValue + return reflect.StructTag(tags).Get(tagName) == optionalTagValue } // String returns a comma-separated list of field names. -func (sf StructFields) String() (res string) { +func (sf Fields) String() string { + b := strings.Builder{} + for i := 0; i < len(sf); i++ { - if res != "" { - res += ", " + if b.Len() != 0 { + b.WriteString(", ") } - res += sf[i].Name + b.WriteString(sf[i].Name) } - return res + return b.String() } -// SkippedFields returns a list of fields that are not present in the given +// Skipped returns a list of fields that are not present in the given // literal, but expected to. // //revive:disable-next-line:cyclomatic -func (sf StructFields) SkippedFields(lit *ast.CompositeLit, onlyExported bool) StructFields { +func (sf Fields) Skipped(lit *ast.CompositeLit, onlyExported bool) Fields { if len(lit.Elts) != 0 && !isNamedLiteral(lit) { if len(lit.Elts) == len(sf) { return nil @@ -68,7 +71,7 @@ func (sf StructFields) SkippedFields(lit *ast.CompositeLit, onlyExported bool) S } em := sf.existenceMap() - res := make(StructFields, 0, len(sf)) + res := make(Fields, 0, len(sf)) for i := 0; i < len(lit.Elts); i++ { kv, ok := lit.Elts[i].(*ast.KeyValueExpr) @@ -99,7 +102,7 @@ func (sf StructFields) SkippedFields(lit *ast.CompositeLit, onlyExported bool) S return res } -func (sf StructFields) existenceMap() map[string]bool { +func (sf Fields) existenceMap() map[string]bool { m := make(map[string]bool, len(sf)) for i := 0; i < len(sf); i++ { diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go index 604aeffde..f1f9ba4ec 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go @@ -2,6 +2,7 @@ package ec2metadata import ( "fmt" + "github.com/aws/aws-sdk-go/aws" "net/http" "sync/atomic" "time" @@ -65,7 +66,9 @@ func (t *tokenProvider) fetchTokenHandler(r *request.Request) { switch requestFailureError.StatusCode() { case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed: atomic.StoreUint32(&t.disabled, 1) - t.client.Config.Logger.Log(fmt.Sprintf("WARN: failed to get session token, falling back to IMDSv1: %v", requestFailureError)) + if t.client.Config.LogLevel.Matches(aws.LogDebugWithDeprecated) { + t.client.Config.Logger.Log(fmt.Sprintf("WARN: failed to get session token, falling back to IMDSv1: %v", requestFailureError)) + } case http.StatusBadRequest: r.Error = requestFailureError } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index fdd6c505c..632eedc6c 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -19307,12 +19307,18 @@ var awsPartition = partition{ }, "m2": service{ Endpoints: serviceEndpoints{ + endpointKey{ + Region: "af-south-1", + }: endpoint{}, endpointKey{ Region: "ap-northeast-1", }: endpoint{}, endpointKey{ Region: "ap-northeast-2", }: endpoint{}, + endpointKey{ + Region: "ap-northeast-3", + }: endpoint{}, endpointKey{ Region: "ap-south-1", }: endpoint{}, @@ -19332,6 +19338,12 @@ var awsPartition = partition{ endpointKey{ Region: "eu-central-1", }: endpoint{}, + endpointKey{ + Region: "eu-north-1", + }: endpoint{}, + endpointKey{ + Region: "eu-south-1", + }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 60703e5b9..79e23c018 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.49.13" +const SDKVersion = "1.49.16" diff --git a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go b/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go index 9d9c515db..c568df399 100644 --- a/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go +++ b/vendor/github.com/go-critic/go-critic/checkers/rulesdata/rulesdata.go @@ -363,7 +363,7 @@ var PrecompiledRules = &ir.File{ Line: 114, Name: "sloppyLen", MatcherName: "m", - DocTags: []string{"style"}, + DocTags: []string{"diagnostic"}, DocSummary: "Detects usage of `len` when result is obvious or doesn't make sense", DocBefore: "len(arr) <= 0", DocAfter: "len(arr) == 0", @@ -493,21 +493,45 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 164, - SyntaxPatterns: []ir.PatternString{{Line: 164, Value: "len($s) == 0"}}, + Line: 163, + SyntaxPatterns: []ir.PatternString{{Line: 163, Value: "len($s) > 0"}}, + ReportTemplate: "replace `$$` with `$s != \"\"`", + WhereExpr: ir.FilterExpr{ + Line: 164, + Op: ir.FilterVarTypeIsOp, + Src: "m[\"s\"].Type.Is(`string`)", + Value: "s", + Args: []ir.FilterExpr{{Line: 164, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + }, + }, + { + Line: 167, + SyntaxPatterns: []ir.PatternString{{Line: 167, Value: "len($s) == 0"}}, + ReportTemplate: "replace `$$` with `$s == \"\"`", + WhereExpr: ir.FilterExpr{ + Line: 168, + Op: ir.FilterVarTypeIsOp, + Src: "m[\"s\"].Type.Is(`string`)", + Value: "s", + Args: []ir.FilterExpr{{Line: 168, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + }, + }, + { + Line: 170, + SyntaxPatterns: []ir.PatternString{{Line: 170, Value: "len($s) <= 0"}}, ReportTemplate: "replace `$$` with `$s == \"\"`", WhereExpr: ir.FilterExpr{ - Line: 165, + Line: 171, Op: ir.FilterVarTypeIsOp, Src: "m[\"s\"].Type.Is(`string`)", Value: "s", - Args: []ir.FilterExpr{{Line: 165, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 171, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, }, }, }, { - Line: 173, + Line: 179, Name: "stringXbytes", MatcherName: "m", DocTags: []string{"performance"}, @@ -516,180 +540,180 @@ var PrecompiledRules = &ir.File{ DocAfter: "copy(b, s)", Rules: []ir.Rule{ { - Line: 174, - SyntaxPatterns: []ir.PatternString{{Line: 174, Value: "copy($_, []byte($s))"}}, + Line: 180, + SyntaxPatterns: []ir.PatternString{{Line: 180, Value: "copy($_, []byte($s))"}}, ReportTemplate: "can simplify `[]byte($s)` to `$s`", }, { - Line: 176, - SyntaxPatterns: []ir.PatternString{{Line: 176, Value: "string($b) == \"\""}}, + Line: 182, + SyntaxPatterns: []ir.PatternString{{Line: 182, Value: "string($b) == \"\""}}, ReportTemplate: "suggestion: len($b) == 0", SuggestTemplate: "len($b) == 0", WhereExpr: ir.FilterExpr{ - Line: 176, + Line: 182, Op: ir.FilterVarTypeIsOp, Src: "m[\"b\"].Type.Is(`[]byte`)", Value: "b", - Args: []ir.FilterExpr{{Line: 176, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 182, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, }, { - Line: 177, - SyntaxPatterns: []ir.PatternString{{Line: 177, Value: "string($b) != \"\""}}, + Line: 183, + SyntaxPatterns: []ir.PatternString{{Line: 183, Value: "string($b) != \"\""}}, ReportTemplate: "suggestion: len($b) != 0", SuggestTemplate: "len($b) != 0", WhereExpr: ir.FilterExpr{ - Line: 177, + Line: 183, Op: ir.FilterVarTypeIsOp, Src: "m[\"b\"].Type.Is(`[]byte`)", Value: "b", - Args: []ir.FilterExpr{{Line: 177, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 183, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, }, { - Line: 179, - SyntaxPatterns: []ir.PatternString{{Line: 179, Value: "len(string($b))"}}, + Line: 185, + SyntaxPatterns: []ir.PatternString{{Line: 185, Value: "len(string($b))"}}, ReportTemplate: "suggestion: len($b)", SuggestTemplate: "len($b)", WhereExpr: ir.FilterExpr{ - Line: 179, + Line: 185, Op: ir.FilterVarTypeIsOp, Src: "m[\"b\"].Type.Is(`[]byte`)", Value: "b", - Args: []ir.FilterExpr{{Line: 179, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 185, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, }, { - Line: 181, - SyntaxPatterns: []ir.PatternString{{Line: 181, Value: "string($x) == string($y)"}}, + Line: 187, + SyntaxPatterns: []ir.PatternString{{Line: 187, Value: "string($x) == string($y)"}}, ReportTemplate: "suggestion: bytes.Equal($x, $y)", SuggestTemplate: "bytes.Equal($x, $y)", WhereExpr: ir.FilterExpr{ - Line: 182, + Line: 188, Op: ir.FilterAndOp, Src: "m[\"x\"].Type.Is(`[]byte`) && m[\"y\"].Type.Is(`[]byte`)", Args: []ir.FilterExpr{ { - Line: 182, + Line: 188, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`[]byte`)", Value: "x", - Args: []ir.FilterExpr{{Line: 182, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 188, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, { - Line: 182, + Line: 188, Op: ir.FilterVarTypeIsOp, Src: "m[\"y\"].Type.Is(`[]byte`)", Value: "y", - Args: []ir.FilterExpr{{Line: 182, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 188, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, }, }, }, { - Line: 185, - SyntaxPatterns: []ir.PatternString{{Line: 185, Value: "string($x) != string($y)"}}, + Line: 191, + SyntaxPatterns: []ir.PatternString{{Line: 191, Value: "string($x) != string($y)"}}, ReportTemplate: "suggestion: !bytes.Equal($x, $y)", SuggestTemplate: "!bytes.Equal($x, $y)", WhereExpr: ir.FilterExpr{ - Line: 186, + Line: 192, Op: ir.FilterAndOp, Src: "m[\"x\"].Type.Is(`[]byte`) && m[\"y\"].Type.Is(`[]byte`)", Args: []ir.FilterExpr{ { - Line: 186, + Line: 192, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`[]byte`)", Value: "x", - Args: []ir.FilterExpr{{Line: 186, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 192, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, { - Line: 186, + Line: 192, Op: ir.FilterVarTypeIsOp, Src: "m[\"y\"].Type.Is(`[]byte`)", Value: "y", - Args: []ir.FilterExpr{{Line: 186, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, + Args: []ir.FilterExpr{{Line: 192, Op: ir.FilterStringOp, Src: "`[]byte`", Value: "[]byte"}}, }, }, }, }, { - Line: 189, - SyntaxPatterns: []ir.PatternString{{Line: 189, Value: "$re.Match([]byte($s))"}}, + Line: 195, + SyntaxPatterns: []ir.PatternString{{Line: 195, Value: "$re.Match([]byte($s))"}}, ReportTemplate: "suggestion: $re.MatchString($s)", SuggestTemplate: "$re.MatchString($s)", WhereExpr: ir.FilterExpr{ - Line: 190, + Line: 196, Op: ir.FilterAndOp, Src: "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)", Args: []ir.FilterExpr{ { - Line: 190, + Line: 196, Op: ir.FilterVarTypeIsOp, Src: "m[\"re\"].Type.Is(`*regexp.Regexp`)", Value: "re", - Args: []ir.FilterExpr{{Line: 190, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, + Args: []ir.FilterExpr{{Line: 196, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, }, { - Line: 190, + Line: 196, Op: ir.FilterVarTypeIsOp, Src: "m[\"s\"].Type.Is(`string`)", Value: "s", - Args: []ir.FilterExpr{{Line: 190, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 196, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, }, }, }, { - Line: 193, - SyntaxPatterns: []ir.PatternString{{Line: 193, Value: "$re.FindIndex([]byte($s))"}}, + Line: 199, + SyntaxPatterns: []ir.PatternString{{Line: 199, Value: "$re.FindIndex([]byte($s))"}}, ReportTemplate: "suggestion: $re.FindStringIndex($s)", SuggestTemplate: "$re.FindStringIndex($s)", WhereExpr: ir.FilterExpr{ - Line: 194, + Line: 200, Op: ir.FilterAndOp, Src: "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)", Args: []ir.FilterExpr{ { - Line: 194, + Line: 200, Op: ir.FilterVarTypeIsOp, Src: "m[\"re\"].Type.Is(`*regexp.Regexp`)", Value: "re", - Args: []ir.FilterExpr{{Line: 194, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, + Args: []ir.FilterExpr{{Line: 200, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, }, { - Line: 194, + Line: 200, Op: ir.FilterVarTypeIsOp, Src: "m[\"s\"].Type.Is(`string`)", Value: "s", - Args: []ir.FilterExpr{{Line: 194, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 200, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, }, }, }, { - Line: 197, - SyntaxPatterns: []ir.PatternString{{Line: 197, Value: "$re.FindAllIndex([]byte($s), $n)"}}, + Line: 203, + SyntaxPatterns: []ir.PatternString{{Line: 203, Value: "$re.FindAllIndex([]byte($s), $n)"}}, ReportTemplate: "suggestion: $re.FindAllStringIndex($s, $n)", SuggestTemplate: "$re.FindAllStringIndex($s, $n)", WhereExpr: ir.FilterExpr{ - Line: 198, + Line: 204, Op: ir.FilterAndOp, Src: "m[\"re\"].Type.Is(`*regexp.Regexp`) && m[\"s\"].Type.Is(`string`)", Args: []ir.FilterExpr{ { - Line: 198, + Line: 204, Op: ir.FilterVarTypeIsOp, Src: "m[\"re\"].Type.Is(`*regexp.Regexp`)", Value: "re", - Args: []ir.FilterExpr{{Line: 198, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, + Args: []ir.FilterExpr{{Line: 204, Op: ir.FilterStringOp, Src: "`*regexp.Regexp`", Value: "*regexp.Regexp"}}, }, { - Line: 198, + Line: 204, Op: ir.FilterVarTypeIsOp, Src: "m[\"s\"].Type.Is(`string`)", Value: "s", - Args: []ir.FilterExpr{{Line: 198, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 204, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, }, }, @@ -697,7 +721,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 207, + Line: 213, Name: "indexAlloc", MatcherName: "m", DocTags: []string{"performance"}, @@ -706,22 +730,22 @@ var PrecompiledRules = &ir.File{ DocAfter: "bytes.Index(x, []byte(y))", DocNote: "See Go issue for details: https://github.com/golang/go/issues/25864", Rules: []ir.Rule{{ - Line: 208, - SyntaxPatterns: []ir.PatternString{{Line: 208, Value: "strings.Index(string($x), $y)"}}, + Line: 214, + SyntaxPatterns: []ir.PatternString{{Line: 214, Value: "strings.Index(string($x), $y)"}}, ReportTemplate: "consider replacing $$ with bytes.Index($x, []byte($y))", WhereExpr: ir.FilterExpr{ - Line: 209, + Line: 215, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure", Args: []ir.FilterExpr{ - {Line: 209, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 209, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, + {Line: 215, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + {Line: 215, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, }, }, }}, }, { - Line: 217, + Line: 223, Name: "wrapperFunc", MatcherName: "m", DocTags: []string{"style"}, @@ -730,169 +754,169 @@ var PrecompiledRules = &ir.File{ DocAfter: "wg.Done()", Rules: []ir.Rule{ { - Line: 218, - SyntaxPatterns: []ir.PatternString{{Line: 218, Value: "$wg.Add(-1)"}}, + Line: 224, + SyntaxPatterns: []ir.PatternString{{Line: 224, Value: "$wg.Add(-1)"}}, ReportTemplate: "use WaitGroup.Done method in `$$`", WhereExpr: ir.FilterExpr{ - Line: 219, + Line: 225, Op: ir.FilterVarTypeIsOp, Src: "m[\"wg\"].Type.Is(`sync.WaitGroup`)", Value: "wg", - Args: []ir.FilterExpr{{Line: 219, Op: ir.FilterStringOp, Src: "`sync.WaitGroup`", Value: "sync.WaitGroup"}}, + Args: []ir.FilterExpr{{Line: 225, Op: ir.FilterStringOp, Src: "`sync.WaitGroup`", Value: "sync.WaitGroup"}}, }, }, { - Line: 222, - SyntaxPatterns: []ir.PatternString{{Line: 222, Value: "$buf.Truncate(0)"}}, + Line: 228, + SyntaxPatterns: []ir.PatternString{{Line: 228, Value: "$buf.Truncate(0)"}}, ReportTemplate: "use Buffer.Reset method in `$$`", WhereExpr: ir.FilterExpr{ - Line: 223, + Line: 229, Op: ir.FilterVarTypeIsOp, Src: "m[\"buf\"].Type.Is(`bytes.Buffer`)", Value: "buf", - Args: []ir.FilterExpr{{Line: 223, Op: ir.FilterStringOp, Src: "`bytes.Buffer`", Value: "bytes.Buffer"}}, + Args: []ir.FilterExpr{{Line: 229, Op: ir.FilterStringOp, Src: "`bytes.Buffer`", Value: "bytes.Buffer"}}, }, }, { - Line: 226, - SyntaxPatterns: []ir.PatternString{{Line: 226, Value: "http.HandlerFunc(http.NotFound)"}}, + Line: 232, + SyntaxPatterns: []ir.PatternString{{Line: 232, Value: "http.HandlerFunc(http.NotFound)"}}, ReportTemplate: "use http.NotFoundHandler method in `$$`", }, { - Line: 228, - SyntaxPatterns: []ir.PatternString{{Line: 228, Value: "strings.SplitN($_, $_, -1)"}}, + Line: 234, + SyntaxPatterns: []ir.PatternString{{Line: 234, Value: "strings.SplitN($_, $_, -1)"}}, ReportTemplate: "use strings.Split method in `$$`", }, { - Line: 229, - SyntaxPatterns: []ir.PatternString{{Line: 229, Value: "strings.Replace($_, $_, $_, -1)"}}, + Line: 235, + SyntaxPatterns: []ir.PatternString{{Line: 235, Value: "strings.Replace($_, $_, $_, -1)"}}, ReportTemplate: "use strings.ReplaceAll method in `$$`", }, { - Line: 230, - SyntaxPatterns: []ir.PatternString{{Line: 230, Value: "strings.Map(unicode.ToTitle, $_)"}}, + Line: 236, + SyntaxPatterns: []ir.PatternString{{Line: 236, Value: "strings.Map(unicode.ToTitle, $_)"}}, ReportTemplate: "use strings.ToTitle method in `$$`", }, { - Line: 231, + Line: 237, SyntaxPatterns: []ir.PatternString{ - {Line: 231, Value: "strings.Index($s1, $s2) >= 0"}, - {Line: 231, Value: "strings.Index($s1, $s2) != -1"}, + {Line: 237, Value: "strings.Index($s1, $s2) >= 0"}, + {Line: 237, Value: "strings.Index($s1, $s2) != -1"}, }, ReportTemplate: "suggestion: strings.Contains($s1, $s2)", SuggestTemplate: "strings.Contains($s1, $s2)", }, { - Line: 232, + Line: 238, SyntaxPatterns: []ir.PatternString{ - {Line: 232, Value: "strings.IndexAny($s1, $s2) >= 0"}, - {Line: 232, Value: "strings.IndexAny($s1, $s2) != -1"}, + {Line: 238, Value: "strings.IndexAny($s1, $s2) >= 0"}, + {Line: 238, Value: "strings.IndexAny($s1, $s2) != -1"}, }, ReportTemplate: "suggestion: strings.ContainsAny($s1, $s2)", SuggestTemplate: "strings.ContainsAny($s1, $s2)", }, { - Line: 233, + Line: 239, SyntaxPatterns: []ir.PatternString{ - {Line: 233, Value: "strings.IndexRune($s1, $s2) >= 0"}, - {Line: 233, Value: "strings.IndexRune($s1, $s2) != -1"}, + {Line: 239, Value: "strings.IndexRune($s1, $s2) >= 0"}, + {Line: 239, Value: "strings.IndexRune($s1, $s2) != -1"}, }, ReportTemplate: "suggestion: strings.ContainsRune($s1, $s2)", SuggestTemplate: "strings.ContainsRune($s1, $s2)", }, { - Line: 235, + Line: 241, SyntaxPatterns: []ir.PatternString{ - {Line: 235, Value: "$i := strings.Index($s, $sep); $*_; $x, $y = $s[:$i], $s[$i+1:]"}, - {Line: 236, Value: "$i := strings.Index($s, $sep); $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]"}, + {Line: 241, Value: "$i := strings.Index($s, $sep); $*_; $x, $y = $s[:$i], $s[$i+1:]"}, + {Line: 242, Value: "$i := strings.Index($s, $sep); $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]"}, }, ReportTemplate: "suggestion: $x, $y, _ = strings.Cut($s, $sep)", SuggestTemplate: "$x, $y, _ = strings.Cut($s, $sep)", WhereExpr: ir.FilterExpr{ - Line: 237, + Line: 243, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.18\")", Value: "1.18", }, }, { - Line: 240, + Line: 246, SyntaxPatterns: []ir.PatternString{ - {Line: 241, Value: "if $i := strings.Index($s, $sep); $i != -1 { $*_; $x, $y = $s[:$i], $s[$i+1:]; $*_ }"}, - {Line: 242, Value: "if $i := strings.Index($s, $sep); $i != -1 { $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]; $*_ }"}, - {Line: 243, Value: "if $i := strings.Index($s, $sep); $i >= 0 { $*_; $x, $y = $s[:$i], $s[$i+1:]; $*_ }"}, - {Line: 244, Value: "if $i := strings.Index($s, $sep); $i >= 0 { $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]; $*_ }"}, + {Line: 247, Value: "if $i := strings.Index($s, $sep); $i != -1 { $*_; $x, $y = $s[:$i], $s[$i+1:]; $*_ }"}, + {Line: 248, Value: "if $i := strings.Index($s, $sep); $i != -1 { $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]; $*_ }"}, + {Line: 249, Value: "if $i := strings.Index($s, $sep); $i >= 0 { $*_; $x, $y = $s[:$i], $s[$i+1:]; $*_ }"}, + {Line: 250, Value: "if $i := strings.Index($s, $sep); $i >= 0 { $*_; $x = $s[:$i]; $*_; $y = $s[$i+1:]; $*_ }"}, }, ReportTemplate: "suggestion: if $x, $y, ok = strings.Cut($s, $sep); ok { ... }", SuggestTemplate: "if $x, $y, ok = strings.Cut($s, $sep); ok { ... }", WhereExpr: ir.FilterExpr{ - Line: 245, + Line: 251, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.18\")", Value: "1.18", }, }, { - Line: 248, - SyntaxPatterns: []ir.PatternString{{Line: 248, Value: "bytes.SplitN(b, []byte(\".\"), -1)"}}, + Line: 254, + SyntaxPatterns: []ir.PatternString{{Line: 254, Value: "bytes.SplitN(b, []byte(\".\"), -1)"}}, ReportTemplate: "use bytes.Split method in `$$`", }, { - Line: 249, - SyntaxPatterns: []ir.PatternString{{Line: 249, Value: "bytes.Replace($_, $_, $_, -1)"}}, + Line: 255, + SyntaxPatterns: []ir.PatternString{{Line: 255, Value: "bytes.Replace($_, $_, $_, -1)"}}, ReportTemplate: "use bytes.ReplaceAll method in `$$`", }, { - Line: 250, - SyntaxPatterns: []ir.PatternString{{Line: 250, Value: "bytes.Map(unicode.ToUpper, $_)"}}, + Line: 256, + SyntaxPatterns: []ir.PatternString{{Line: 256, Value: "bytes.Map(unicode.ToUpper, $_)"}}, ReportTemplate: "use bytes.ToUpper method in `$$`", }, { - Line: 251, - SyntaxPatterns: []ir.PatternString{{Line: 251, Value: "bytes.Map(unicode.ToLower, $_)"}}, + Line: 257, + SyntaxPatterns: []ir.PatternString{{Line: 257, Value: "bytes.Map(unicode.ToLower, $_)"}}, ReportTemplate: "use bytes.ToLower method in `$$`", }, { - Line: 252, - SyntaxPatterns: []ir.PatternString{{Line: 252, Value: "bytes.Map(unicode.ToTitle, $_)"}}, + Line: 258, + SyntaxPatterns: []ir.PatternString{{Line: 258, Value: "bytes.Map(unicode.ToTitle, $_)"}}, ReportTemplate: "use bytes.ToTitle method in `$$`", }, { - Line: 253, + Line: 259, SyntaxPatterns: []ir.PatternString{ - {Line: 253, Value: "bytes.Index($b1, $b2) >= 0"}, - {Line: 253, Value: "bytes.Index($b1, $b2) != -1"}, + {Line: 259, Value: "bytes.Index($b1, $b2) >= 0"}, + {Line: 259, Value: "bytes.Index($b1, $b2) != -1"}, }, ReportTemplate: "suggestion: bytes.Contains($b1, $b2)", SuggestTemplate: "bytes.Contains($b1, $b2)", }, { - Line: 254, + Line: 260, SyntaxPatterns: []ir.PatternString{ - {Line: 254, Value: "bytes.IndexAny($b1, $b2) >= 0"}, - {Line: 254, Value: "bytes.IndexAny($b1, $b2) != -1"}, + {Line: 260, Value: "bytes.IndexAny($b1, $b2) >= 0"}, + {Line: 260, Value: "bytes.IndexAny($b1, $b2) != -1"}, }, ReportTemplate: "suggestion: bytes.ContainsAny($b1, $b2)", SuggestTemplate: "bytes.ContainsAny($b1, $b2)", }, { - Line: 255, + Line: 261, SyntaxPatterns: []ir.PatternString{ - {Line: 255, Value: "bytes.IndexRune($b1, $b2) >= 0"}, - {Line: 255, Value: "bytes.IndexRune($b1, $b2) != -1"}, + {Line: 261, Value: "bytes.IndexRune($b1, $b2) >= 0"}, + {Line: 261, Value: "bytes.IndexRune($b1, $b2) != -1"}, }, ReportTemplate: "suggestion: bytes.ContainsRune($b1, $b2)", SuggestTemplate: "bytes.ContainsRune($b1, $b2)", }, { - Line: 257, - SyntaxPatterns: []ir.PatternString{{Line: 257, Value: "draw.DrawMask($_, $_, $_, $_, nil, image.Point{}, $_)"}}, + Line: 263, + SyntaxPatterns: []ir.PatternString{{Line: 263, Value: "draw.DrawMask($_, $_, $_, $_, nil, image.Point{}, $_)"}}, ReportTemplate: "use draw.Draw method in `$$`", }, }, }, { - Line: 265, + Line: 271, Name: "regexpMust", MatcherName: "m", DocTags: []string{"style"}, @@ -901,22 +925,22 @@ var PrecompiledRules = &ir.File{ DocAfter: "re := regexp.MustCompile(\"const pattern\")", Rules: []ir.Rule{ { - Line: 266, - SyntaxPatterns: []ir.PatternString{{Line: 266, Value: "regexp.Compile($pat)"}}, + Line: 272, + SyntaxPatterns: []ir.PatternString{{Line: 272, Value: "regexp.Compile($pat)"}}, ReportTemplate: "for const patterns like $pat, use regexp.MustCompile", WhereExpr: ir.FilterExpr{ - Line: 267, + Line: 273, Op: ir.FilterVarConstOp, Src: "m[\"pat\"].Const", Value: "pat", }, }, { - Line: 270, - SyntaxPatterns: []ir.PatternString{{Line: 270, Value: "regexp.CompilePOSIX($pat)"}}, + Line: 276, + SyntaxPatterns: []ir.PatternString{{Line: 276, Value: "regexp.CompilePOSIX($pat)"}}, ReportTemplate: "for const patterns like $pat, use regexp.MustCompilePOSIX", WhereExpr: ir.FilterExpr{ - Line: 271, + Line: 277, Op: ir.FilterVarConstOp, Src: "m[\"pat\"].Const", Value: "pat", @@ -925,7 +949,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 279, + Line: 285, Name: "badCall", MatcherName: "m", DocTags: []string{"diagnostic"}, @@ -934,22 +958,22 @@ var PrecompiledRules = &ir.File{ DocAfter: "strings.Replace(s, from, to, -1)", Rules: []ir.Rule{ { - Line: 280, - SyntaxPatterns: []ir.PatternString{{Line: 280, Value: "strings.Replace($_, $_, $_, $zero)"}}, + Line: 286, + SyntaxPatterns: []ir.PatternString{{Line: 286, Value: "strings.Replace($_, $_, $_, $zero)"}}, ReportTemplate: "suspicious arg 0, probably meant -1", WhereExpr: ir.FilterExpr{ - Line: 281, + Line: 287, Op: ir.FilterEqOp, Src: "m[\"zero\"].Value.Int() == 0", Args: []ir.FilterExpr{ { - Line: 281, + Line: 287, Op: ir.FilterVarValueIntOp, Src: "m[\"zero\"].Value.Int()", Value: "zero", }, { - Line: 281, + Line: 287, Op: ir.FilterIntOp, Src: "0", Value: int64(0), @@ -959,22 +983,22 @@ var PrecompiledRules = &ir.File{ LocationVar: "zero", }, { - Line: 283, - SyntaxPatterns: []ir.PatternString{{Line: 283, Value: "bytes.Replace($_, $_, $_, $zero)"}}, + Line: 289, + SyntaxPatterns: []ir.PatternString{{Line: 289, Value: "bytes.Replace($_, $_, $_, $zero)"}}, ReportTemplate: "suspicious arg 0, probably meant -1", WhereExpr: ir.FilterExpr{ - Line: 284, + Line: 290, Op: ir.FilterEqOp, Src: "m[\"zero\"].Value.Int() == 0", Args: []ir.FilterExpr{ { - Line: 284, + Line: 290, Op: ir.FilterVarValueIntOp, Src: "m[\"zero\"].Value.Int()", Value: "zero", }, { - Line: 284, + Line: 290, Op: ir.FilterIntOp, Src: "0", Value: int64(0), @@ -984,22 +1008,22 @@ var PrecompiledRules = &ir.File{ LocationVar: "zero", }, { - Line: 287, - SyntaxPatterns: []ir.PatternString{{Line: 287, Value: "strings.SplitN($_, $_, $zero)"}}, + Line: 293, + SyntaxPatterns: []ir.PatternString{{Line: 293, Value: "strings.SplitN($_, $_, $zero)"}}, ReportTemplate: "suspicious arg 0, probably meant -1", WhereExpr: ir.FilterExpr{ - Line: 288, + Line: 294, Op: ir.FilterEqOp, Src: "m[\"zero\"].Value.Int() == 0", Args: []ir.FilterExpr{ { - Line: 288, + Line: 294, Op: ir.FilterVarValueIntOp, Src: "m[\"zero\"].Value.Int()", Value: "zero", }, { - Line: 288, + Line: 294, Op: ir.FilterIntOp, Src: "0", Value: int64(0), @@ -1009,22 +1033,22 @@ var PrecompiledRules = &ir.File{ LocationVar: "zero", }, { - Line: 290, - SyntaxPatterns: []ir.PatternString{{Line: 290, Value: "bytes.SplitN($_, $_, $zero)"}}, + Line: 296, + SyntaxPatterns: []ir.PatternString{{Line: 296, Value: "bytes.SplitN($_, $_, $zero)"}}, ReportTemplate: "suspicious arg 0, probably meant -1", WhereExpr: ir.FilterExpr{ - Line: 291, + Line: 297, Op: ir.FilterEqOp, Src: "m[\"zero\"].Value.Int() == 0", Args: []ir.FilterExpr{ { - Line: 291, + Line: 297, Op: ir.FilterVarValueIntOp, Src: "m[\"zero\"].Value.Int()", Value: "zero", }, { - Line: 291, + Line: 297, Op: ir.FilterIntOp, Src: "0", Value: int64(0), @@ -1034,19 +1058,19 @@ var PrecompiledRules = &ir.File{ LocationVar: "zero", }, { - Line: 294, - SyntaxPatterns: []ir.PatternString{{Line: 294, Value: "append($_)"}}, + Line: 300, + SyntaxPatterns: []ir.PatternString{{Line: 300, Value: "append($_)"}}, ReportTemplate: "no-op append call, probably missing arguments", }, { - Line: 296, - SyntaxPatterns: []ir.PatternString{{Line: 296, Value: "filepath.Join($_)"}}, + Line: 302, + SyntaxPatterns: []ir.PatternString{{Line: 302, Value: "filepath.Join($_)"}}, ReportTemplate: "suspicious Join on 1 argument", }, }, }, { - Line: 303, + Line: 309, Name: "assignOp", MatcherName: "m", DocTags: []string{"style"}, @@ -1055,87 +1079,87 @@ var PrecompiledRules = &ir.File{ DocAfter: "x *= 2", Rules: []ir.Rule{ { - Line: 304, - SyntaxPatterns: []ir.PatternString{{Line: 304, Value: "$x = $x + 1"}}, + Line: 310, + SyntaxPatterns: []ir.PatternString{{Line: 310, Value: "$x = $x + 1"}}, ReportTemplate: "replace `$$` with `$x++`", - WhereExpr: ir.FilterExpr{Line: 304, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 310, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 305, - SyntaxPatterns: []ir.PatternString{{Line: 305, Value: "$x = $x - 1"}}, + Line: 311, + SyntaxPatterns: []ir.PatternString{{Line: 311, Value: "$x = $x - 1"}}, ReportTemplate: "replace `$$` with `$x--`", - WhereExpr: ir.FilterExpr{Line: 305, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 311, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 307, - SyntaxPatterns: []ir.PatternString{{Line: 307, Value: "$x = $x + $y"}}, + Line: 313, + SyntaxPatterns: []ir.PatternString{{Line: 313, Value: "$x = $x + $y"}}, ReportTemplate: "replace `$$` with `$x += $y`", - WhereExpr: ir.FilterExpr{Line: 307, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 313, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 308, - SyntaxPatterns: []ir.PatternString{{Line: 308, Value: "$x = $x - $y"}}, + Line: 314, + SyntaxPatterns: []ir.PatternString{{Line: 314, Value: "$x = $x - $y"}}, ReportTemplate: "replace `$$` with `$x -= $y`", - WhereExpr: ir.FilterExpr{Line: 308, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 314, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 310, - SyntaxPatterns: []ir.PatternString{{Line: 310, Value: "$x = $x * $y"}}, + Line: 316, + SyntaxPatterns: []ir.PatternString{{Line: 316, Value: "$x = $x * $y"}}, ReportTemplate: "replace `$$` with `$x *= $y`", - WhereExpr: ir.FilterExpr{Line: 310, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 316, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 311, - SyntaxPatterns: []ir.PatternString{{Line: 311, Value: "$x = $x / $y"}}, + Line: 317, + SyntaxPatterns: []ir.PatternString{{Line: 317, Value: "$x = $x / $y"}}, ReportTemplate: "replace `$$` with `$x /= $y`", - WhereExpr: ir.FilterExpr{Line: 311, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 317, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 312, - SyntaxPatterns: []ir.PatternString{{Line: 312, Value: "$x = $x % $y"}}, + Line: 318, + SyntaxPatterns: []ir.PatternString{{Line: 318, Value: "$x = $x % $y"}}, ReportTemplate: "replace `$$` with `$x %= $y`", - WhereExpr: ir.FilterExpr{Line: 312, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 318, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 313, - SyntaxPatterns: []ir.PatternString{{Line: 313, Value: "$x = $x & $y"}}, + Line: 319, + SyntaxPatterns: []ir.PatternString{{Line: 319, Value: "$x = $x & $y"}}, ReportTemplate: "replace `$$` with `$x &= $y`", - WhereExpr: ir.FilterExpr{Line: 313, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 319, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 314, - SyntaxPatterns: []ir.PatternString{{Line: 314, Value: "$x = $x | $y"}}, + Line: 320, + SyntaxPatterns: []ir.PatternString{{Line: 320, Value: "$x = $x | $y"}}, ReportTemplate: "replace `$$` with `$x |= $y`", - WhereExpr: ir.FilterExpr{Line: 314, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 320, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 315, - SyntaxPatterns: []ir.PatternString{{Line: 315, Value: "$x = $x ^ $y"}}, + Line: 321, + SyntaxPatterns: []ir.PatternString{{Line: 321, Value: "$x = $x ^ $y"}}, ReportTemplate: "replace `$$` with `$x ^= $y`", - WhereExpr: ir.FilterExpr{Line: 315, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 321, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 316, - SyntaxPatterns: []ir.PatternString{{Line: 316, Value: "$x = $x << $y"}}, + Line: 322, + SyntaxPatterns: []ir.PatternString{{Line: 322, Value: "$x = $x << $y"}}, ReportTemplate: "replace `$$` with `$x <<= $y`", - WhereExpr: ir.FilterExpr{Line: 316, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 322, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 317, - SyntaxPatterns: []ir.PatternString{{Line: 317, Value: "$x = $x >> $y"}}, + Line: 323, + SyntaxPatterns: []ir.PatternString{{Line: 323, Value: "$x = $x >> $y"}}, ReportTemplate: "replace `$$` with `$x >>= $y`", - WhereExpr: ir.FilterExpr{Line: 317, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 323, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 318, - SyntaxPatterns: []ir.PatternString{{Line: 318, Value: "$x = $x &^ $y"}}, + Line: 324, + SyntaxPatterns: []ir.PatternString{{Line: 324, Value: "$x = $x &^ $y"}}, ReportTemplate: "replace `$$` with `$x &^= $y`", - WhereExpr: ir.FilterExpr{Line: 318, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 324, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, }, }, { - Line: 325, + Line: 331, Name: "preferWriteByte", MatcherName: "m", DocTags: []string{"performance", "experimental", "opinionated"}, @@ -1143,45 +1167,45 @@ var PrecompiledRules = &ir.File{ DocBefore: "w.WriteRune('\\n')", DocAfter: "w.WriteByte('\\n')", Rules: []ir.Rule{{ - Line: 329, - SyntaxPatterns: []ir.PatternString{{Line: 329, Value: "$w.WriteRune($c)"}}, + Line: 335, + SyntaxPatterns: []ir.PatternString{{Line: 335, Value: "$w.WriteRune($c)"}}, ReportTemplate: "consider writing single byte rune $c with $w.WriteByte($c)", WhereExpr: ir.FilterExpr{ - Line: 330, + Line: 336, Op: ir.FilterAndOp, Src: "m[\"w\"].Type.Implements(\"io.ByteWriter\") && (m[\"c\"].Const && m[\"c\"].Value.Int() < runeSelf)", Args: []ir.FilterExpr{ { - Line: 330, + Line: 336, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.ByteWriter\")", Value: "w", - Args: []ir.FilterExpr{{Line: 330, Op: ir.FilterStringOp, Src: "\"io.ByteWriter\"", Value: "io.ByteWriter"}}, + Args: []ir.FilterExpr{{Line: 336, Op: ir.FilterStringOp, Src: "\"io.ByteWriter\"", Value: "io.ByteWriter"}}, }, { - Line: 330, + Line: 336, Op: ir.FilterAndOp, Src: "(m[\"c\"].Const && m[\"c\"].Value.Int() < runeSelf)", Args: []ir.FilterExpr{ { - Line: 330, + Line: 336, Op: ir.FilterVarConstOp, Src: "m[\"c\"].Const", Value: "c", }, { - Line: 330, + Line: 336, Op: ir.FilterLtOp, Src: "m[\"c\"].Value.Int() < runeSelf", Args: []ir.FilterExpr{ { - Line: 330, + Line: 336, Op: ir.FilterVarValueIntOp, Src: "m[\"c\"].Value.Int()", Value: "c", }, { - Line: 330, + Line: 336, Op: ir.FilterIntOp, Src: "runeSelf", Value: int64(128), @@ -1195,7 +1219,7 @@ var PrecompiledRules = &ir.File{ }}, }, { - Line: 338, + Line: 344, Name: "preferFprint", MatcherName: "m", DocTags: []string{"performance", "experimental"}, @@ -1204,139 +1228,139 @@ var PrecompiledRules = &ir.File{ DocAfter: "fmt.Fprintf(w, \"%x\", 10)", Rules: []ir.Rule{ { - Line: 339, - SyntaxPatterns: []ir.PatternString{{Line: 339, Value: "$w.Write([]byte(fmt.Sprint($*args)))"}}, + Line: 345, + SyntaxPatterns: []ir.PatternString{{Line: 345, Value: "$w.Write([]byte(fmt.Sprint($*args)))"}}, ReportTemplate: "fmt.Fprint($w, $args) should be preferred to the $$", SuggestTemplate: "fmt.Fprint($w, $args)", WhereExpr: ir.FilterExpr{ - Line: 340, + Line: 346, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\")", Value: "w", - Args: []ir.FilterExpr{{Line: 340, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, + Args: []ir.FilterExpr{{Line: 346, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, }, }, { - Line: 344, - SyntaxPatterns: []ir.PatternString{{Line: 344, Value: "$w.Write([]byte(fmt.Sprintf($*args)))"}}, + Line: 350, + SyntaxPatterns: []ir.PatternString{{Line: 350, Value: "$w.Write([]byte(fmt.Sprintf($*args)))"}}, ReportTemplate: "fmt.Fprintf($w, $args) should be preferred to the $$", SuggestTemplate: "fmt.Fprintf($w, $args)", WhereExpr: ir.FilterExpr{ - Line: 345, + Line: 351, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\")", Value: "w", - Args: []ir.FilterExpr{{Line: 345, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, + Args: []ir.FilterExpr{{Line: 351, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, }, }, { - Line: 349, - SyntaxPatterns: []ir.PatternString{{Line: 349, Value: "$w.Write([]byte(fmt.Sprintln($*args)))"}}, + Line: 355, + SyntaxPatterns: []ir.PatternString{{Line: 355, Value: "$w.Write([]byte(fmt.Sprintln($*args)))"}}, ReportTemplate: "fmt.Fprintln($w, $args) should be preferred to the $$", SuggestTemplate: "fmt.Fprintln($w, $args)", WhereExpr: ir.FilterExpr{ - Line: 350, + Line: 356, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\")", Value: "w", - Args: []ir.FilterExpr{{Line: 350, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, + Args: []ir.FilterExpr{{Line: 356, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, }, }, { - Line: 354, - SyntaxPatterns: []ir.PatternString{{Line: 354, Value: "io.WriteString($w, fmt.Sprint($*args))"}}, + Line: 360, + SyntaxPatterns: []ir.PatternString{{Line: 360, Value: "io.WriteString($w, fmt.Sprint($*args))"}}, ReportTemplate: "suggestion: fmt.Fprint($w, $args)", SuggestTemplate: "fmt.Fprint($w, $args)", }, { - Line: 355, - SyntaxPatterns: []ir.PatternString{{Line: 355, Value: "io.WriteString($w, fmt.Sprintf($*args))"}}, + Line: 361, + SyntaxPatterns: []ir.PatternString{{Line: 361, Value: "io.WriteString($w, fmt.Sprintf($*args))"}}, ReportTemplate: "suggestion: fmt.Fprintf($w, $args)", SuggestTemplate: "fmt.Fprintf($w, $args)", }, { - Line: 356, - SyntaxPatterns: []ir.PatternString{{Line: 356, Value: "io.WriteString($w, fmt.Sprintln($*args))"}}, + Line: 362, + SyntaxPatterns: []ir.PatternString{{Line: 362, Value: "io.WriteString($w, fmt.Sprintln($*args))"}}, ReportTemplate: "suggestion: fmt.Fprintln($w, $args)", SuggestTemplate: "fmt.Fprintln($w, $args)", }, { - Line: 358, - SyntaxPatterns: []ir.PatternString{{Line: 358, Value: "$w.WriteString(fmt.Sprint($*args))"}}, + Line: 364, + SyntaxPatterns: []ir.PatternString{{Line: 364, Value: "$w.WriteString(fmt.Sprint($*args))"}}, ReportTemplate: "suggestion: fmt.Fprint($w, $args)", SuggestTemplate: "fmt.Fprint($w, $args)", WhereExpr: ir.FilterExpr{ - Line: 359, + Line: 365, Op: ir.FilterAndOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\") && m[\"w\"].Type.Implements(\"io.StringWriter\")", Args: []ir.FilterExpr{ { - Line: 359, + Line: 365, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\")", Value: "w", - Args: []ir.FilterExpr{{Line: 359, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, + Args: []ir.FilterExpr{{Line: 365, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, }, { - Line: 359, + Line: 365, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", Value: "w", - Args: []ir.FilterExpr{{Line: 359, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, + Args: []ir.FilterExpr{{Line: 365, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, }, }, }, }, { - Line: 361, - SyntaxPatterns: []ir.PatternString{{Line: 361, Value: "$w.WriteString(fmt.Sprintf($*args))"}}, + Line: 367, + SyntaxPatterns: []ir.PatternString{{Line: 367, Value: "$w.WriteString(fmt.Sprintf($*args))"}}, ReportTemplate: "suggestion: fmt.Fprintf($w, $args)", SuggestTemplate: "fmt.Fprintf($w, $args)", WhereExpr: ir.FilterExpr{ - Line: 362, + Line: 368, Op: ir.FilterAndOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\") && m[\"w\"].Type.Implements(\"io.StringWriter\")", Args: []ir.FilterExpr{ { - Line: 362, + Line: 368, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\")", Value: "w", - Args: []ir.FilterExpr{{Line: 362, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, + Args: []ir.FilterExpr{{Line: 368, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, }, { - Line: 362, + Line: 368, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", Value: "w", - Args: []ir.FilterExpr{{Line: 362, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, + Args: []ir.FilterExpr{{Line: 368, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, }, }, }, }, { - Line: 364, - SyntaxPatterns: []ir.PatternString{{Line: 364, Value: "$w.WriteString(fmt.Sprintln($*args))"}}, + Line: 370, + SyntaxPatterns: []ir.PatternString{{Line: 370, Value: "$w.WriteString(fmt.Sprintln($*args))"}}, ReportTemplate: "suggestion: fmt.Fprintln($w, $args)", SuggestTemplate: "fmt.Fprintln($w, $args)", WhereExpr: ir.FilterExpr{ - Line: 365, + Line: 371, Op: ir.FilterAndOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\") && m[\"w\"].Type.Implements(\"io.StringWriter\")", Args: []ir.FilterExpr{ { - Line: 365, + Line: 371, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.Writer\")", Value: "w", - Args: []ir.FilterExpr{{Line: 365, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, + Args: []ir.FilterExpr{{Line: 371, Op: ir.FilterStringOp, Src: "\"io.Writer\"", Value: "io.Writer"}}, }, { - Line: 365, + Line: 371, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", Value: "w", - Args: []ir.FilterExpr{{Line: 365, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, + Args: []ir.FilterExpr{{Line: 371, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, }, }, }, @@ -1344,7 +1368,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 373, + Line: 379, Name: "dupArg", MatcherName: "m", DocTags: []string{"diagnostic"}, @@ -1353,62 +1377,62 @@ var PrecompiledRules = &ir.File{ DocAfter: "copy(dst, src)", Rules: []ir.Rule{ { - Line: 374, + Line: 380, SyntaxPatterns: []ir.PatternString{ - {Line: 374, Value: "$x.Equal($x)"}, - {Line: 374, Value: "$x.Equals($x)"}, - {Line: 374, Value: "$x.Compare($x)"}, - {Line: 374, Value: "$x.Cmp($x)"}, + {Line: 380, Value: "$x.Equal($x)"}, + {Line: 380, Value: "$x.Equals($x)"}, + {Line: 380, Value: "$x.Compare($x)"}, + {Line: 380, Value: "$x.Cmp($x)"}, }, ReportTemplate: "suspicious method call with the same argument and receiver", - WhereExpr: ir.FilterExpr{Line: 375, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 381, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, { - Line: 378, + Line: 384, SyntaxPatterns: []ir.PatternString{ - {Line: 378, Value: "copy($x, $x)"}, - {Line: 379, Value: "math.Max($x, $x)"}, - {Line: 380, Value: "math.Min($x, $x)"}, - {Line: 381, Value: "reflect.Copy($x, $x)"}, - {Line: 382, Value: "reflect.DeepEqual($x, $x)"}, - {Line: 383, Value: "strings.Contains($x, $x)"}, - {Line: 384, Value: "strings.Compare($x, $x)"}, - {Line: 385, Value: "strings.EqualFold($x, $x)"}, - {Line: 386, Value: "strings.HasPrefix($x, $x)"}, - {Line: 387, Value: "strings.HasSuffix($x, $x)"}, - {Line: 388, Value: "strings.Index($x, $x)"}, - {Line: 389, Value: "strings.LastIndex($x, $x)"}, - {Line: 390, Value: "strings.Split($x, $x)"}, - {Line: 391, Value: "strings.SplitAfter($x, $x)"}, - {Line: 392, Value: "strings.SplitAfterN($x, $x, $_)"}, - {Line: 393, Value: "strings.SplitN($x, $x, $_)"}, - {Line: 394, Value: "strings.Replace($_, $x, $x, $_)"}, - {Line: 395, Value: "strings.ReplaceAll($_, $x, $x)"}, - {Line: 396, Value: "bytes.Contains($x, $x)"}, - {Line: 397, Value: "bytes.Compare($x, $x)"}, - {Line: 398, Value: "bytes.Equal($x, $x)"}, - {Line: 399, Value: "bytes.EqualFold($x, $x)"}, - {Line: 400, Value: "bytes.HasPrefix($x, $x)"}, - {Line: 401, Value: "bytes.HasSuffix($x, $x)"}, - {Line: 402, Value: "bytes.Index($x, $x)"}, - {Line: 403, Value: "bytes.LastIndex($x, $x)"}, - {Line: 404, Value: "bytes.Split($x, $x)"}, - {Line: 405, Value: "bytes.SplitAfter($x, $x)"}, - {Line: 406, Value: "bytes.SplitAfterN($x, $x, $_)"}, - {Line: 407, Value: "bytes.SplitN($x, $x, $_)"}, - {Line: 408, Value: "bytes.Replace($_, $x, $x, $_)"}, - {Line: 409, Value: "bytes.ReplaceAll($_, $x, $x)"}, - {Line: 410, Value: "types.Identical($x, $x)"}, - {Line: 411, Value: "types.IdenticalIgnoreTags($x, $x)"}, - {Line: 412, Value: "draw.Draw($x, $_, $x, $_, $_)"}, + {Line: 384, Value: "copy($x, $x)"}, + {Line: 385, Value: "math.Max($x, $x)"}, + {Line: 386, Value: "math.Min($x, $x)"}, + {Line: 387, Value: "reflect.Copy($x, $x)"}, + {Line: 388, Value: "reflect.DeepEqual($x, $x)"}, + {Line: 389, Value: "strings.Contains($x, $x)"}, + {Line: 390, Value: "strings.Compare($x, $x)"}, + {Line: 391, Value: "strings.EqualFold($x, $x)"}, + {Line: 392, Value: "strings.HasPrefix($x, $x)"}, + {Line: 393, Value: "strings.HasSuffix($x, $x)"}, + {Line: 394, Value: "strings.Index($x, $x)"}, + {Line: 395, Value: "strings.LastIndex($x, $x)"}, + {Line: 396, Value: "strings.Split($x, $x)"}, + {Line: 397, Value: "strings.SplitAfter($x, $x)"}, + {Line: 398, Value: "strings.SplitAfterN($x, $x, $_)"}, + {Line: 399, Value: "strings.SplitN($x, $x, $_)"}, + {Line: 400, Value: "strings.Replace($_, $x, $x, $_)"}, + {Line: 401, Value: "strings.ReplaceAll($_, $x, $x)"}, + {Line: 402, Value: "bytes.Contains($x, $x)"}, + {Line: 403, Value: "bytes.Compare($x, $x)"}, + {Line: 404, Value: "bytes.Equal($x, $x)"}, + {Line: 405, Value: "bytes.EqualFold($x, $x)"}, + {Line: 406, Value: "bytes.HasPrefix($x, $x)"}, + {Line: 407, Value: "bytes.HasSuffix($x, $x)"}, + {Line: 408, Value: "bytes.Index($x, $x)"}, + {Line: 409, Value: "bytes.LastIndex($x, $x)"}, + {Line: 410, Value: "bytes.Split($x, $x)"}, + {Line: 411, Value: "bytes.SplitAfter($x, $x)"}, + {Line: 412, Value: "bytes.SplitAfterN($x, $x, $_)"}, + {Line: 413, Value: "bytes.SplitN($x, $x, $_)"}, + {Line: 414, Value: "bytes.Replace($_, $x, $x, $_)"}, + {Line: 415, Value: "bytes.ReplaceAll($_, $x, $x)"}, + {Line: 416, Value: "types.Identical($x, $x)"}, + {Line: 417, Value: "types.IdenticalIgnoreTags($x, $x)"}, + {Line: 418, Value: "draw.Draw($x, $_, $x, $_, $_)"}, }, ReportTemplate: "suspicious duplicated args in $$", - WhereExpr: ir.FilterExpr{Line: 413, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + WhereExpr: ir.FilterExpr{Line: 419, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, }, }, }, { - Line: 421, + Line: 427, Name: "returnAfterHttpError", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -1416,14 +1440,14 @@ var PrecompiledRules = &ir.File{ DocBefore: "if err != nil { http.Error(...); }", DocAfter: "if err != nil { http.Error(...); return; }", Rules: []ir.Rule{{ - Line: 422, - SyntaxPatterns: []ir.PatternString{{Line: 422, Value: "if $_ { $*_; http.Error($w, $err, $code) }"}}, + Line: 428, + SyntaxPatterns: []ir.PatternString{{Line: 428, Value: "if $_ { $*_; http.Error($w, $err, $code) }"}}, ReportTemplate: "Possibly return is missed after the http.Error call", LocationVar: "w", }}, }, { - Line: 431, + Line: 437, Name: "preferFilepathJoin", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -1431,35 +1455,35 @@ var PrecompiledRules = &ir.File{ DocBefore: "x + string(os.PathSeparator) + y", DocAfter: "filepath.Join(x, y)", Rules: []ir.Rule{{ - Line: 432, - SyntaxPatterns: []ir.PatternString{{Line: 432, Value: "$x + string(os.PathSeparator) + $y"}}, + Line: 438, + SyntaxPatterns: []ir.PatternString{{Line: 438, Value: "$x + string(os.PathSeparator) + $y"}}, ReportTemplate: "filepath.Join($x, $y) should be preferred to the $$", SuggestTemplate: "filepath.Join($x, $y)", WhereExpr: ir.FilterExpr{ - Line: 433, + Line: 439, Op: ir.FilterAndOp, Src: "m[\"x\"].Type.Is(`string`) && m[\"y\"].Type.Is(`string`)", Args: []ir.FilterExpr{ { - Line: 433, + Line: 439, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`string`)", Value: "x", - Args: []ir.FilterExpr{{Line: 433, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 439, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, { - Line: 433, + Line: 439, Op: ir.FilterVarTypeIsOp, Src: "m[\"y\"].Type.Is(`string`)", Value: "y", - Args: []ir.FilterExpr{{Line: 433, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 439, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, }, }, }}, }, { - Line: 442, + Line: 448, Name: "preferStringWriter", MatcherName: "m", DocTags: []string{"performance", "experimental"}, @@ -1468,35 +1492,35 @@ var PrecompiledRules = &ir.File{ DocAfter: "w.WriteString(\"foo\")", Rules: []ir.Rule{ { - Line: 443, - SyntaxPatterns: []ir.PatternString{{Line: 443, Value: "$w.Write([]byte($s))"}}, + Line: 449, + SyntaxPatterns: []ir.PatternString{{Line: 449, Value: "$w.Write([]byte($s))"}}, ReportTemplate: "$w.WriteString($s) should be preferred to the $$", SuggestTemplate: "$w.WriteString($s)", WhereExpr: ir.FilterExpr{ - Line: 444, + Line: 450, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", Value: "w", - Args: []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, + Args: []ir.FilterExpr{{Line: 450, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, }, }, { - Line: 448, - SyntaxPatterns: []ir.PatternString{{Line: 448, Value: "io.WriteString($w, $s)"}}, + Line: 454, + SyntaxPatterns: []ir.PatternString{{Line: 454, Value: "io.WriteString($w, $s)"}}, ReportTemplate: "$w.WriteString($s) should be preferred to the $$", SuggestTemplate: "$w.WriteString($s)", WhereExpr: ir.FilterExpr{ - Line: 449, + Line: 455, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"w\"].Type.Implements(\"io.StringWriter\")", Value: "w", - Args: []ir.FilterExpr{{Line: 449, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, + Args: []ir.FilterExpr{{Line: 455, Op: ir.FilterStringOp, Src: "\"io.StringWriter\"", Value: "io.StringWriter"}}, }, }, }, }, { - Line: 458, + Line: 464, Name: "sliceClear", MatcherName: "m", DocTags: []string{"performance", "experimental"}, @@ -1504,22 +1528,22 @@ var PrecompiledRules = &ir.File{ DocBefore: "for i := 0; i < len(buf); i++ { buf[i] = 0 }", DocAfter: "for i := range buf { buf[i] = 0 }", Rules: []ir.Rule{{ - Line: 459, - SyntaxPatterns: []ir.PatternString{{Line: 459, Value: "for $i := 0; $i < len($xs); $i++ { $xs[$i] = $zero }"}}, + Line: 465, + SyntaxPatterns: []ir.PatternString{{Line: 465, Value: "for $i := 0; $i < len($xs); $i++ { $xs[$i] = $zero }"}}, ReportTemplate: "rewrite as for-range so compiler can recognize this pattern", WhereExpr: ir.FilterExpr{ - Line: 460, + Line: 466, Op: ir.FilterEqOp, Src: "m[\"zero\"].Value.Int() == 0", Args: []ir.FilterExpr{ { - Line: 460, + Line: 466, Op: ir.FilterVarValueIntOp, Src: "m[\"zero\"].Value.Int()", Value: "zero", }, { - Line: 460, + Line: 466, Op: ir.FilterIntOp, Src: "0", Value: int64(0), @@ -1529,7 +1553,7 @@ var PrecompiledRules = &ir.File{ }}, }, { - Line: 468, + Line: 474, Name: "syncMapLoadAndDelete", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -1537,33 +1561,33 @@ var PrecompiledRules = &ir.File{ DocBefore: "v, ok := m.Load(k); if ok { m.Delete($k); f(v); }", DocAfter: "v, deleted := m.LoadAndDelete(k); if deleted { f(v) }", Rules: []ir.Rule{{ - Line: 469, - SyntaxPatterns: []ir.PatternString{{Line: 469, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"}}, + Line: 475, + SyntaxPatterns: []ir.PatternString{{Line: 475, Value: "$_, $ok := $m.Load($k); if $ok { $m.Delete($k); $*_ }"}}, ReportTemplate: "use $m.LoadAndDelete to perform load+delete operations atomically", WhereExpr: ir.FilterExpr{ - Line: 470, + Line: 476, Op: ir.FilterAndOp, Src: "m.GoVersion().GreaterEqThan(\"1.15\") &&\n\tm[\"m\"].Type.Is(`*sync.Map`)", Args: []ir.FilterExpr{ { - Line: 470, + Line: 476, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.15\")", Value: "1.15", }, { - Line: 471, + Line: 477, Op: ir.FilterVarTypeIsOp, Src: "m[\"m\"].Type.Is(`*sync.Map`)", Value: "m", - Args: []ir.FilterExpr{{Line: 471, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"}}, + Args: []ir.FilterExpr{{Line: 477, Op: ir.FilterStringOp, Src: "`*sync.Map`", Value: "*sync.Map"}}, }, }, }, }}, }, { - Line: 479, + Line: 485, Name: "sprintfQuotedString", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -1571,34 +1595,34 @@ var PrecompiledRules = &ir.File{ DocBefore: "fmt.Sprintf(`\"%s\"`, s)", DocAfter: "fmt.Sprintf(`%q`, s)", Rules: []ir.Rule{{ - Line: 480, - SyntaxPatterns: []ir.PatternString{{Line: 480, Value: "fmt.Sprintf($s, $*_)"}}, + Line: 486, + SyntaxPatterns: []ir.PatternString{{Line: 486, Value: "fmt.Sprintf($s, $*_)"}}, ReportTemplate: "use %q instead of \"%s\" for quoted strings", WhereExpr: ir.FilterExpr{ - Line: 481, + Line: 487, Op: ir.FilterOrOp, Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\") ||\n\tm[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)", Args: []ir.FilterExpr{ { - Line: 481, + Line: 487, Op: ir.FilterVarTextMatchesOp, Src: "m[\"s\"].Text.Matches(\"^`.*\\\"%s\\\".*`$\")", Value: "s", - Args: []ir.FilterExpr{{Line: 481, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"}}, + Args: []ir.FilterExpr{{Line: 487, Op: ir.FilterStringOp, Src: "\"^`.*\\\"%s\\\".*`$\"", Value: "^`.*\"%s\".*`$"}}, }, { - Line: 482, + Line: 488, Op: ir.FilterVarTextMatchesOp, Src: "m[\"s\"].Text.Matches(`^\".*\\\\\"%s\\\\\".*\"$`)", Value: "s", - Args: []ir.FilterExpr{{Line: 482, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"}}, + Args: []ir.FilterExpr{{Line: 488, Op: ir.FilterStringOp, Src: "`^\".*\\\\\"%s\\\\\".*\"$`", Value: "^\".*\\\\\"%s\\\\\".*\"$"}}, }, }, }, }}, }, { - Line: 490, + Line: 496, Name: "offBy1", MatcherName: "m", DocTags: []string{"diagnostic"}, @@ -1607,80 +1631,80 @@ var PrecompiledRules = &ir.File{ DocAfter: "xs[len(xs)-1]", Rules: []ir.Rule{ { - Line: 491, - SyntaxPatterns: []ir.PatternString{{Line: 491, Value: "$x[len($x)]"}}, + Line: 497, + SyntaxPatterns: []ir.PatternString{{Line: 497, Value: "$x[len($x)]"}}, ReportTemplate: "index expr always panics; maybe you wanted $x[len($x)-1]?", SuggestTemplate: "$x[len($x)-1]", WhereExpr: ir.FilterExpr{ - Line: 492, + Line: 498, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"x\"].Type.Is(`[]$_`)", Args: []ir.FilterExpr{ - {Line: 492, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + {Line: 498, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, { - Line: 492, + Line: 498, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`[]$_`)", Value: "x", - Args: []ir.FilterExpr{{Line: 492, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, + Args: []ir.FilterExpr{{Line: 498, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, }, }, }, }, { - Line: 499, + Line: 505, SyntaxPatterns: []ir.PatternString{ - {Line: 500, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"}, - {Line: 501, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"}, - {Line: 502, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"}, - {Line: 503, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"}, + {Line: 506, Value: "$i := strings.Index($s, $_); $_ := $slicing[$i:]"}, + {Line: 507, Value: "$i := strings.Index($s, $_); $_ = $slicing[$i:]"}, + {Line: 508, Value: "$i := bytes.Index($s, $_); $_ := $slicing[$i:]"}, + {Line: 509, Value: "$i := bytes.Index($s, $_); $_ = $slicing[$i:]"}, }, ReportTemplate: "Index() can return -1; maybe you wanted to do $s[$i+1:]", WhereExpr: ir.FilterExpr{ - Line: 504, + Line: 510, Op: ir.FilterEqOp, Src: "m[\"s\"].Text == m[\"slicing\"].Text", Args: []ir.FilterExpr{ - {Line: 504, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, - {Line: 504, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, + {Line: 510, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, + {Line: 510, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, }, }, LocationVar: "slicing", }, { - Line: 508, + Line: 514, SyntaxPatterns: []ir.PatternString{ - {Line: 509, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"}, - {Line: 510, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"}, - {Line: 511, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"}, - {Line: 512, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"}, + {Line: 515, Value: "$i := strings.Index($s, $_); $_ := $slicing[:$i]"}, + {Line: 516, Value: "$i := strings.Index($s, $_); $_ = $slicing[:$i]"}, + {Line: 517, Value: "$i := bytes.Index($s, $_); $_ := $slicing[:$i]"}, + {Line: 518, Value: "$i := bytes.Index($s, $_); $_ = $slicing[:$i]"}, }, ReportTemplate: "Index() can return -1; maybe you wanted to do $s[:$i+1]", WhereExpr: ir.FilterExpr{ - Line: 513, + Line: 519, Op: ir.FilterEqOp, Src: "m[\"s\"].Text == m[\"slicing\"].Text", Args: []ir.FilterExpr{ - {Line: 513, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, - {Line: 513, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, + {Line: 519, Op: ir.FilterVarTextOp, Src: "m[\"s\"].Text", Value: "s"}, + {Line: 519, Op: ir.FilterVarTextOp, Src: "m[\"slicing\"].Text", Value: "slicing"}, }, }, LocationVar: "slicing", }, { - Line: 517, + Line: 523, SyntaxPatterns: []ir.PatternString{ - {Line: 518, Value: "$s[strings.Index($s, $_):]"}, - {Line: 519, Value: "$s[:strings.Index($s, $_)]"}, - {Line: 520, Value: "$s[bytes.Index($s, $_):]"}, - {Line: 521, Value: "$s[:bytes.Index($s, $_)]"}, + {Line: 524, Value: "$s[strings.Index($s, $_):]"}, + {Line: 525, Value: "$s[:strings.Index($s, $_)]"}, + {Line: 526, Value: "$s[bytes.Index($s, $_):]"}, + {Line: 527, Value: "$s[:bytes.Index($s, $_)]"}, }, ReportTemplate: "Index() can return -1; maybe you wanted to do Index()+1", }, }, }, { - Line: 529, + Line: 535, Name: "unslice", MatcherName: "m", DocTags: []string{"style"}, @@ -1688,35 +1712,35 @@ var PrecompiledRules = &ir.File{ DocBefore: "copy(b[:], values...)", DocAfter: "copy(b, values...)", Rules: []ir.Rule{{ - Line: 530, - SyntaxPatterns: []ir.PatternString{{Line: 530, Value: "$s[:]"}}, + Line: 536, + SyntaxPatterns: []ir.PatternString{{Line: 536, Value: "$s[:]"}}, ReportTemplate: "could simplify $$ to $s", SuggestTemplate: "$s", WhereExpr: ir.FilterExpr{ - Line: 531, + Line: 537, Op: ir.FilterOrOp, Src: "m[\"s\"].Type.Is(`string`) || m[\"s\"].Type.Is(`[]$_`)", Args: []ir.FilterExpr{ { - Line: 531, + Line: 537, Op: ir.FilterVarTypeIsOp, Src: "m[\"s\"].Type.Is(`string`)", Value: "s", - Args: []ir.FilterExpr{{Line: 531, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, + Args: []ir.FilterExpr{{Line: 537, Op: ir.FilterStringOp, Src: "`string`", Value: "string"}}, }, { - Line: 531, + Line: 537, Op: ir.FilterVarTypeIsOp, Src: "m[\"s\"].Type.Is(`[]$_`)", Value: "s", - Args: []ir.FilterExpr{{Line: 531, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, + Args: []ir.FilterExpr{{Line: 537, Op: ir.FilterStringOp, Src: "`[]$_`", Value: "[]$_"}}, }, }, }, }}, }, { - Line: 540, + Line: 546, Name: "yodaStyleExpr", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -1725,105 +1749,105 @@ var PrecompiledRules = &ir.File{ DocAfter: "return ptr != nil", Rules: []ir.Rule{ { - Line: 541, - SyntaxPatterns: []ir.PatternString{{Line: 541, Value: "$constval != $x"}}, + Line: 547, + SyntaxPatterns: []ir.PatternString{{Line: 547, Value: "$constval != $x"}}, ReportTemplate: "consider to change order in expression to $x != $constval", WhereExpr: ir.FilterExpr{ - Line: 541, + Line: 547, Op: ir.FilterAndOp, Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)", Args: []ir.FilterExpr{ { - Line: 541, + Line: 547, Op: ir.FilterVarNodeIsOp, Src: "m[\"constval\"].Node.Is(`BasicLit`)", Value: "constval", - Args: []ir.FilterExpr{{Line: 541, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, + Args: []ir.FilterExpr{{Line: 547, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, }, { - Line: 541, + Line: 547, Op: ir.FilterNotOp, Src: "!m[\"x\"].Node.Is(`BasicLit`)", Args: []ir.FilterExpr{{ - Line: 541, + Line: 547, Op: ir.FilterVarNodeIsOp, Src: "m[\"x\"].Node.Is(`BasicLit`)", Value: "x", - Args: []ir.FilterExpr{{Line: 541, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, + Args: []ir.FilterExpr{{Line: 547, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, }}, }, }, }, }, { - Line: 543, - SyntaxPatterns: []ir.PatternString{{Line: 543, Value: "$constval == $x"}}, + Line: 549, + SyntaxPatterns: []ir.PatternString{{Line: 549, Value: "$constval == $x"}}, ReportTemplate: "consider to change order in expression to $x == $constval", WhereExpr: ir.FilterExpr{ - Line: 543, + Line: 549, Op: ir.FilterAndOp, Src: "m[\"constval\"].Node.Is(`BasicLit`) && !m[\"x\"].Node.Is(`BasicLit`)", Args: []ir.FilterExpr{ { - Line: 543, + Line: 549, Op: ir.FilterVarNodeIsOp, Src: "m[\"constval\"].Node.Is(`BasicLit`)", Value: "constval", - Args: []ir.FilterExpr{{Line: 543, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, + Args: []ir.FilterExpr{{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, }, { - Line: 543, + Line: 549, Op: ir.FilterNotOp, Src: "!m[\"x\"].Node.Is(`BasicLit`)", Args: []ir.FilterExpr{{ - Line: 543, + Line: 549, Op: ir.FilterVarNodeIsOp, Src: "m[\"x\"].Node.Is(`BasicLit`)", Value: "x", - Args: []ir.FilterExpr{{Line: 543, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, + Args: []ir.FilterExpr{{Line: 549, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, }}, }, }, }, }, { - Line: 546, - SyntaxPatterns: []ir.PatternString{{Line: 546, Value: "nil != $x"}}, + Line: 552, + SyntaxPatterns: []ir.PatternString{{Line: 552, Value: "nil != $x"}}, ReportTemplate: "consider to change order in expression to $x != nil", WhereExpr: ir.FilterExpr{ - Line: 546, + Line: 552, Op: ir.FilterNotOp, Src: "!m[\"x\"].Node.Is(`BasicLit`)", Args: []ir.FilterExpr{{ - Line: 546, + Line: 552, Op: ir.FilterVarNodeIsOp, Src: "m[\"x\"].Node.Is(`BasicLit`)", Value: "x", - Args: []ir.FilterExpr{{Line: 546, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, + Args: []ir.FilterExpr{{Line: 552, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, }}, }, }, { - Line: 548, - SyntaxPatterns: []ir.PatternString{{Line: 548, Value: "nil == $x"}}, + Line: 554, + SyntaxPatterns: []ir.PatternString{{Line: 554, Value: "nil == $x"}}, ReportTemplate: "consider to change order in expression to $x == nil", WhereExpr: ir.FilterExpr{ - Line: 548, + Line: 554, Op: ir.FilterNotOp, Src: "!m[\"x\"].Node.Is(`BasicLit`)", Args: []ir.FilterExpr{{ - Line: 548, + Line: 554, Op: ir.FilterVarNodeIsOp, Src: "m[\"x\"].Node.Is(`BasicLit`)", Value: "x", - Args: []ir.FilterExpr{{Line: 548, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, + Args: []ir.FilterExpr{{Line: 554, Op: ir.FilterStringOp, Src: "`BasicLit`", Value: "BasicLit"}}, }}, }, }, }, }, { - Line: 556, + Line: 562, Name: "equalFold", MatcherName: "m", DocTags: []string{"performance", "experimental"}, @@ -1832,114 +1856,114 @@ var PrecompiledRules = &ir.File{ DocAfter: "strings.EqualFold(x, y)", Rules: []ir.Rule{ { - Line: 565, + Line: 571, SyntaxPatterns: []ir.PatternString{ - {Line: 566, Value: "strings.ToLower($x) == $y"}, - {Line: 567, Value: "strings.ToLower($x) == strings.ToLower($y)"}, - {Line: 568, Value: "$x == strings.ToLower($y)"}, - {Line: 569, Value: "strings.ToUpper($x) == $y"}, - {Line: 570, Value: "strings.ToUpper($x) == strings.ToUpper($y)"}, - {Line: 571, Value: "$x == strings.ToUpper($y)"}, + {Line: 572, Value: "strings.ToLower($x) == $y"}, + {Line: 573, Value: "strings.ToLower($x) == strings.ToLower($y)"}, + {Line: 574, Value: "$x == strings.ToLower($y)"}, + {Line: 575, Value: "strings.ToUpper($x) == $y"}, + {Line: 576, Value: "strings.ToUpper($x) == strings.ToUpper($y)"}, + {Line: 577, Value: "$x == strings.ToUpper($y)"}, }, ReportTemplate: "consider replacing with strings.EqualFold($x, $y)", SuggestTemplate: "strings.EqualFold($x, $y)", WhereExpr: ir.FilterExpr{ - Line: 572, + Line: 578, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", Args: []ir.FilterExpr{ { - Line: 572, + Line: 578, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure", Args: []ir.FilterExpr{ - {Line: 572, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 572, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, + {Line: 578, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + {Line: 578, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, }, }, { - Line: 572, + Line: 578, Op: ir.FilterNeqOp, Src: "m[\"x\"].Text != m[\"y\"].Text", Args: []ir.FilterExpr{ - {Line: 572, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 572, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, + {Line: 578, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, + {Line: 578, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, }, }, }, }, }, { - Line: 577, + Line: 583, SyntaxPatterns: []ir.PatternString{ - {Line: 578, Value: "strings.ToLower($x) != $y"}, - {Line: 579, Value: "strings.ToLower($x) != strings.ToLower($y)"}, - {Line: 580, Value: "$x != strings.ToLower($y)"}, - {Line: 581, Value: "strings.ToUpper($x) != $y"}, - {Line: 582, Value: "strings.ToUpper($x) != strings.ToUpper($y)"}, - {Line: 583, Value: "$x != strings.ToUpper($y)"}, + {Line: 584, Value: "strings.ToLower($x) != $y"}, + {Line: 585, Value: "strings.ToLower($x) != strings.ToLower($y)"}, + {Line: 586, Value: "$x != strings.ToLower($y)"}, + {Line: 587, Value: "strings.ToUpper($x) != $y"}, + {Line: 588, Value: "strings.ToUpper($x) != strings.ToUpper($y)"}, + {Line: 589, Value: "$x != strings.ToUpper($y)"}, }, ReportTemplate: "consider replacing with !strings.EqualFold($x, $y)", SuggestTemplate: "!strings.EqualFold($x, $y)", WhereExpr: ir.FilterExpr{ - Line: 584, + Line: 590, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", Args: []ir.FilterExpr{ { - Line: 584, + Line: 590, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure", Args: []ir.FilterExpr{ - {Line: 584, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 584, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, + {Line: 590, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + {Line: 590, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, }, }, { - Line: 584, + Line: 590, Op: ir.FilterNeqOp, Src: "m[\"x\"].Text != m[\"y\"].Text", Args: []ir.FilterExpr{ - {Line: 584, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 584, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, + {Line: 590, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, + {Line: 590, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, }, }, }, }, }, { - Line: 589, + Line: 595, SyntaxPatterns: []ir.PatternString{ - {Line: 590, Value: "bytes.Equal(bytes.ToLower($x), $y)"}, - {Line: 591, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"}, - {Line: 592, Value: "bytes.Equal($x, bytes.ToLower($y))"}, - {Line: 593, Value: "bytes.Equal(bytes.ToUpper($x), $y)"}, - {Line: 594, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"}, - {Line: 595, Value: "bytes.Equal($x, bytes.ToUpper($y))"}, + {Line: 596, Value: "bytes.Equal(bytes.ToLower($x), $y)"}, + {Line: 597, Value: "bytes.Equal(bytes.ToLower($x), bytes.ToLower($y))"}, + {Line: 598, Value: "bytes.Equal($x, bytes.ToLower($y))"}, + {Line: 599, Value: "bytes.Equal(bytes.ToUpper($x), $y)"}, + {Line: 600, Value: "bytes.Equal(bytes.ToUpper($x), bytes.ToUpper($y))"}, + {Line: 601, Value: "bytes.Equal($x, bytes.ToUpper($y))"}, }, ReportTemplate: "consider replacing with bytes.EqualFold($x, $y)", SuggestTemplate: "bytes.EqualFold($x, $y)", WhereExpr: ir.FilterExpr{ - Line: 596, + Line: 602, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure && m[\"x\"].Text != m[\"y\"].Text", Args: []ir.FilterExpr{ { - Line: 596, + Line: 602, Op: ir.FilterAndOp, Src: "m[\"x\"].Pure && m[\"y\"].Pure", Args: []ir.FilterExpr{ - {Line: 596, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, - {Line: 596, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, + {Line: 602, Op: ir.FilterVarPureOp, Src: "m[\"x\"].Pure", Value: "x"}, + {Line: 602, Op: ir.FilterVarPureOp, Src: "m[\"y\"].Pure", Value: "y"}, }, }, { - Line: 596, + Line: 602, Op: ir.FilterNeqOp, Src: "m[\"x\"].Text != m[\"y\"].Text", Args: []ir.FilterExpr{ - {Line: 596, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, - {Line: 596, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, + {Line: 602, Op: ir.FilterVarTextOp, Src: "m[\"x\"].Text", Value: "x"}, + {Line: 602, Op: ir.FilterVarTextOp, Src: "m[\"y\"].Text", Value: "y"}, }, }, }, @@ -1948,7 +1972,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 605, + Line: 611, Name: "argOrder", MatcherName: "m", DocTags: []string{"diagnostic"}, @@ -1956,45 +1980,45 @@ var PrecompiledRules = &ir.File{ DocBefore: "strings.HasPrefix(\"#\", userpass)", DocAfter: "strings.HasPrefix(userpass, \"#\")", Rules: []ir.Rule{{ - Line: 606, + Line: 612, SyntaxPatterns: []ir.PatternString{ - {Line: 607, Value: "strings.HasPrefix($lit, $s)"}, - {Line: 608, Value: "bytes.HasPrefix($lit, $s)"}, - {Line: 609, Value: "strings.HasSuffix($lit, $s)"}, - {Line: 610, Value: "bytes.HasSuffix($lit, $s)"}, - {Line: 611, Value: "strings.Contains($lit, $s)"}, - {Line: 612, Value: "bytes.Contains($lit, $s)"}, - {Line: 613, Value: "strings.TrimPrefix($lit, $s)"}, - {Line: 614, Value: "bytes.TrimPrefix($lit, $s)"}, - {Line: 615, Value: "strings.TrimSuffix($lit, $s)"}, - {Line: 616, Value: "bytes.TrimSuffix($lit, $s)"}, - {Line: 617, Value: "strings.Split($lit, $s)"}, - {Line: 618, Value: "bytes.Split($lit, $s)"}, + {Line: 613, Value: "strings.HasPrefix($lit, $s)"}, + {Line: 614, Value: "bytes.HasPrefix($lit, $s)"}, + {Line: 615, Value: "strings.HasSuffix($lit, $s)"}, + {Line: 616, Value: "bytes.HasSuffix($lit, $s)"}, + {Line: 617, Value: "strings.Contains($lit, $s)"}, + {Line: 618, Value: "bytes.Contains($lit, $s)"}, + {Line: 619, Value: "strings.TrimPrefix($lit, $s)"}, + {Line: 620, Value: "bytes.TrimPrefix($lit, $s)"}, + {Line: 621, Value: "strings.TrimSuffix($lit, $s)"}, + {Line: 622, Value: "bytes.TrimSuffix($lit, $s)"}, + {Line: 623, Value: "strings.Split($lit, $s)"}, + {Line: 624, Value: "bytes.Split($lit, $s)"}, }, ReportTemplate: "$lit and $s arguments order looks reversed", WhereExpr: ir.FilterExpr{ - Line: 619, + Line: 625, Op: ir.FilterAndOp, Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice) &&\n\t!m[\"lit\"].Node.Is(`Ident`)", Args: []ir.FilterExpr{ { - Line: 619, + Line: 625, Op: ir.FilterAndOp, Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice) &&\n\t!(m[\"s\"].Const || m[\"s\"].ConstSlice)", Args: []ir.FilterExpr{ { - Line: 619, + Line: 625, Op: ir.FilterOrOp, Src: "(m[\"lit\"].Const || m[\"lit\"].ConstSlice)", Args: []ir.FilterExpr{ { - Line: 619, + Line: 625, Op: ir.FilterVarConstOp, Src: "m[\"lit\"].Const", Value: "lit", }, { - Line: 619, + Line: 625, Op: ir.FilterVarConstSliceOp, Src: "m[\"lit\"].ConstSlice", Value: "lit", @@ -2002,22 +2026,22 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 620, + Line: 626, Op: ir.FilterNotOp, Src: "!(m[\"s\"].Const || m[\"s\"].ConstSlice)", Args: []ir.FilterExpr{{ - Line: 620, + Line: 626, Op: ir.FilterOrOp, Src: "(m[\"s\"].Const || m[\"s\"].ConstSlice)", Args: []ir.FilterExpr{ { - Line: 620, + Line: 626, Op: ir.FilterVarConstOp, Src: "m[\"s\"].Const", Value: "s", }, { - Line: 620, + Line: 626, Op: ir.FilterVarConstSliceOp, Src: "m[\"s\"].ConstSlice", Value: "s", @@ -2028,15 +2052,15 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 621, + Line: 627, Op: ir.FilterNotOp, Src: "!m[\"lit\"].Node.Is(`Ident`)", Args: []ir.FilterExpr{{ - Line: 621, + Line: 627, Op: ir.FilterVarNodeIsOp, Src: "m[\"lit\"].Node.Is(`Ident`)", Value: "lit", - Args: []ir.FilterExpr{{Line: 621, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}}, + Args: []ir.FilterExpr{{Line: 627, Op: ir.FilterStringOp, Src: "`Ident`", Value: "Ident"}}, }}, }, }, @@ -2044,7 +2068,7 @@ var PrecompiledRules = &ir.File{ }}, }, { - Line: 629, + Line: 635, Name: "stringConcatSimplify", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -2053,27 +2077,27 @@ var PrecompiledRules = &ir.File{ DocAfter: "x + \"_\" + y", Rules: []ir.Rule{ { - Line: 630, - SyntaxPatterns: []ir.PatternString{{Line: 630, Value: "strings.Join([]string{$x, $y}, \"\")"}}, + Line: 636, + SyntaxPatterns: []ir.PatternString{{Line: 636, Value: "strings.Join([]string{$x, $y}, \"\")"}}, ReportTemplate: "suggestion: $x + $y", SuggestTemplate: "$x + $y", }, { - Line: 631, - SyntaxPatterns: []ir.PatternString{{Line: 631, Value: "strings.Join([]string{$x, $y, $z}, \"\")"}}, + Line: 637, + SyntaxPatterns: []ir.PatternString{{Line: 637, Value: "strings.Join([]string{$x, $y, $z}, \"\")"}}, ReportTemplate: "suggestion: $x + $y + $z", SuggestTemplate: "$x + $y + $z", }, { - Line: 632, - SyntaxPatterns: []ir.PatternString{{Line: 632, Value: "strings.Join([]string{$x, $y}, $glue)"}}, + Line: 638, + SyntaxPatterns: []ir.PatternString{{Line: 638, Value: "strings.Join([]string{$x, $y}, $glue)"}}, ReportTemplate: "suggestion: $x + $glue + $y", SuggestTemplate: "$x + $glue + $y", }, }, }, { - Line: 639, + Line: 645, Name: "timeExprSimplify", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -2082,39 +2106,39 @@ var PrecompiledRules = &ir.File{ DocAfter: "t.UnixMilli()", Rules: []ir.Rule{ { - Line: 644, - SyntaxPatterns: []ir.PatternString{{Line: 644, Value: "$t.Unix() / 1000"}}, + Line: 650, + SyntaxPatterns: []ir.PatternString{{Line: 650, Value: "$t.Unix() / 1000"}}, ReportTemplate: "use $t.UnixMilli() instead of $$", SuggestTemplate: "$t.UnixMilli()", WhereExpr: ir.FilterExpr{ - Line: 645, + Line: 651, Op: ir.FilterAndOp, Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])", Args: []ir.FilterExpr{ { - Line: 645, + Line: 651, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.17\")", Value: "1.17", }, { - Line: 645, + Line: 651, Op: ir.FilterOrOp, Src: "isTime(m[\"t\"])", Args: []ir.FilterExpr{ { - Line: 645, + Line: 651, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 641, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, + Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, }, { - Line: 645, + Line: 651, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`*time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 641, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, + Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, }, }, }, @@ -2122,39 +2146,39 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 649, - SyntaxPatterns: []ir.PatternString{{Line: 649, Value: "$t.UnixNano() * 1000"}}, + Line: 655, + SyntaxPatterns: []ir.PatternString{{Line: 655, Value: "$t.UnixNano() * 1000"}}, ReportTemplate: "use $t.UnixMicro() instead of $$", SuggestTemplate: "$t.UnixMicro()", WhereExpr: ir.FilterExpr{ - Line: 650, + Line: 656, Op: ir.FilterAndOp, Src: "m.GoVersion().GreaterEqThan(\"1.17\") && isTime(m[\"t\"])", Args: []ir.FilterExpr{ { - Line: 650, + Line: 656, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.17\")", Value: "1.17", }, { - Line: 650, + Line: 656, Op: ir.FilterOrOp, Src: "isTime(m[\"t\"])", Args: []ir.FilterExpr{ { - Line: 650, + Line: 656, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 641, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, + Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, }, { - Line: 650, + Line: 656, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`*time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 641, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, + Args: []ir.FilterExpr{{Line: 647, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, }, }, }, @@ -2164,7 +2188,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 659, + Line: 665, Name: "timeCmpSimplify", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -2173,55 +2197,55 @@ var PrecompiledRules = &ir.File{ DocAfter: "t.After(tt)", Rules: []ir.Rule{ { - Line: 664, - SyntaxPatterns: []ir.PatternString{{Line: 664, Value: "!$t.Before($tt)"}}, + Line: 670, + SyntaxPatterns: []ir.PatternString{{Line: 670, Value: "!$t.Before($tt)"}}, ReportTemplate: "suggestion: $t.After($tt)", SuggestTemplate: "$t.After($tt)", WhereExpr: ir.FilterExpr{ - Line: 665, + Line: 671, Op: ir.FilterOrOp, Src: "isTime(m[\"t\"])", Args: []ir.FilterExpr{ { - Line: 665, + Line: 671, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 661, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, + Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, }, { - Line: 665, + Line: 671, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`*time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 661, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, + Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, }, }, }, }, { - Line: 668, - SyntaxPatterns: []ir.PatternString{{Line: 668, Value: "!$t.After($tt)"}}, + Line: 674, + SyntaxPatterns: []ir.PatternString{{Line: 674, Value: "!$t.After($tt)"}}, ReportTemplate: "suggestion: $t.Before($tt)", SuggestTemplate: "$t.Before($tt)", WhereExpr: ir.FilterExpr{ - Line: 669, + Line: 675, Op: ir.FilterOrOp, Src: "isTime(m[\"t\"])", Args: []ir.FilterExpr{ { - Line: 669, + Line: 675, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 661, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, + Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`time.Time`", Value: "time.Time"}}, }, { - Line: 669, + Line: 675, Op: ir.FilterVarTypeIsOp, Src: "m[\"t\"].Type.Is(`*time.Time`)", Value: "t", - Args: []ir.FilterExpr{{Line: 661, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, + Args: []ir.FilterExpr{{Line: 667, Op: ir.FilterStringOp, Src: "`*time.Time`", Value: "*time.Time"}}, }, }, }, @@ -2229,7 +2253,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 677, + Line: 683, Name: "exposedSyncMutex", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -2238,57 +2262,57 @@ var PrecompiledRules = &ir.File{ DocAfter: "type Foo struct{ ...; mu sync.Mutex; ... }", Rules: []ir.Rule{ { - Line: 682, - SyntaxPatterns: []ir.PatternString{{Line: 682, Value: "type $x struct { $*_; sync.Mutex; $*_ }"}}, + Line: 688, + SyntaxPatterns: []ir.PatternString{{Line: 688, Value: "type $x struct { $*_; sync.Mutex; $*_ }"}}, ReportTemplate: "don't embed sync.Mutex", WhereExpr: ir.FilterExpr{ - Line: 683, + Line: 689, Op: ir.FilterVarTextMatchesOp, Src: "isExported(m[\"x\"])", Value: "x", - Args: []ir.FilterExpr{{Line: 679, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, + Args: []ir.FilterExpr{{Line: 685, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, }, }, { - Line: 686, - SyntaxPatterns: []ir.PatternString{{Line: 686, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"}}, + Line: 692, + SyntaxPatterns: []ir.PatternString{{Line: 692, Value: "type $x struct { $*_; *sync.Mutex; $*_ }"}}, ReportTemplate: "don't embed *sync.Mutex", WhereExpr: ir.FilterExpr{ - Line: 687, + Line: 693, Op: ir.FilterVarTextMatchesOp, Src: "isExported(m[\"x\"])", Value: "x", - Args: []ir.FilterExpr{{Line: 679, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, + Args: []ir.FilterExpr{{Line: 685, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, }, }, { - Line: 690, - SyntaxPatterns: []ir.PatternString{{Line: 690, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"}}, + Line: 696, + SyntaxPatterns: []ir.PatternString{{Line: 696, Value: "type $x struct { $*_; sync.RWMutex; $*_ }"}}, ReportTemplate: "don't embed sync.RWMutex", WhereExpr: ir.FilterExpr{ - Line: 691, + Line: 697, Op: ir.FilterVarTextMatchesOp, Src: "isExported(m[\"x\"])", Value: "x", - Args: []ir.FilterExpr{{Line: 679, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, + Args: []ir.FilterExpr{{Line: 685, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, }, }, { - Line: 694, - SyntaxPatterns: []ir.PatternString{{Line: 694, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"}}, + Line: 700, + SyntaxPatterns: []ir.PatternString{{Line: 700, Value: "type $x struct { $*_; *sync.RWMutex; $*_ }"}}, ReportTemplate: "don't embed *sync.RWMutex", WhereExpr: ir.FilterExpr{ - Line: 695, + Line: 701, Op: ir.FilterVarTextMatchesOp, Src: "isExported(m[\"x\"])", Value: "x", - Args: []ir.FilterExpr{{Line: 679, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, + Args: []ir.FilterExpr{{Line: 685, Op: ir.FilterStringOp, Src: "`^\\p{Lu}`", Value: "^\\p{Lu}"}}, }, }, }, }, { - Line: 703, + Line: 709, Name: "badSorting", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -2297,48 +2321,48 @@ var PrecompiledRules = &ir.File{ DocAfter: "sort.Strings(xs)", Rules: []ir.Rule{ { - Line: 704, - SyntaxPatterns: []ir.PatternString{{Line: 704, Value: "$x = sort.IntSlice($x)"}}, + Line: 710, + SyntaxPatterns: []ir.PatternString{{Line: 710, Value: "$x = sort.IntSlice($x)"}}, ReportTemplate: "suspicious sort.IntSlice usage, maybe sort.Ints was intended?", SuggestTemplate: "sort.Ints($x)", WhereExpr: ir.FilterExpr{ - Line: 705, + Line: 711, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`[]int`)", Value: "x", - Args: []ir.FilterExpr{{Line: 705, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"}}, + Args: []ir.FilterExpr{{Line: 711, Op: ir.FilterStringOp, Src: "`[]int`", Value: "[]int"}}, }, }, { - Line: 709, - SyntaxPatterns: []ir.PatternString{{Line: 709, Value: "$x = sort.Float64Slice($x)"}}, + Line: 715, + SyntaxPatterns: []ir.PatternString{{Line: 715, Value: "$x = sort.Float64Slice($x)"}}, ReportTemplate: "suspicious sort.Float64s usage, maybe sort.Float64s was intended?", SuggestTemplate: "sort.Float64s($x)", WhereExpr: ir.FilterExpr{ - Line: 710, + Line: 716, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`[]float64`)", Value: "x", - Args: []ir.FilterExpr{{Line: 710, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"}}, + Args: []ir.FilterExpr{{Line: 716, Op: ir.FilterStringOp, Src: "`[]float64`", Value: "[]float64"}}, }, }, { - Line: 714, - SyntaxPatterns: []ir.PatternString{{Line: 714, Value: "$x = sort.StringSlice($x)"}}, + Line: 720, + SyntaxPatterns: []ir.PatternString{{Line: 720, Value: "$x = sort.StringSlice($x)"}}, ReportTemplate: "suspicious sort.StringSlice usage, maybe sort.Strings was intended?", SuggestTemplate: "sort.Strings($x)", WhereExpr: ir.FilterExpr{ - Line: 715, + Line: 721, Op: ir.FilterVarTypeIsOp, Src: "m[\"x\"].Type.Is(`[]string`)", Value: "x", - Args: []ir.FilterExpr{{Line: 715, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"}}, + Args: []ir.FilterExpr{{Line: 721, Op: ir.FilterStringOp, Src: "`[]string`", Value: "[]string"}}, }, }, }, }, { - Line: 724, + Line: 730, Name: "externalErrorReassign", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -2346,34 +2370,34 @@ var PrecompiledRules = &ir.File{ DocBefore: "io.EOF = nil", DocAfter: "/* don't do it */", Rules: []ir.Rule{{ - Line: 725, - SyntaxPatterns: []ir.PatternString{{Line: 725, Value: "$pkg.$err = $x"}}, + Line: 731, + SyntaxPatterns: []ir.PatternString{{Line: 731, Value: "$pkg.$err = $x"}}, ReportTemplate: "suspicious reassignment of error from another package", WhereExpr: ir.FilterExpr{ - Line: 726, + Line: 732, Op: ir.FilterAndOp, Src: "m[\"err\"].Type.Is(`error`) && m[\"pkg\"].Object.Is(`PkgName`)", Args: []ir.FilterExpr{ { - Line: 726, + Line: 732, Op: ir.FilterVarTypeIsOp, Src: "m[\"err\"].Type.Is(`error`)", Value: "err", - Args: []ir.FilterExpr{{Line: 726, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}}, + Args: []ir.FilterExpr{{Line: 732, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}}, }, { - Line: 726, + Line: 732, Op: ir.FilterVarObjectIsOp, Src: "m[\"pkg\"].Object.Is(`PkgName`)", Value: "pkg", - Args: []ir.FilterExpr{{Line: 726, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}}, + Args: []ir.FilterExpr{{Line: 732, Op: ir.FilterStringOp, Src: "`PkgName`", Value: "PkgName"}}, }, }, }, }}, }, { - Line: 734, + Line: 740, Name: "emptyDecl", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -2382,24 +2406,24 @@ var PrecompiledRules = &ir.File{ DocAfter: "/* nothing */", Rules: []ir.Rule{ { - Line: 735, - SyntaxPatterns: []ir.PatternString{{Line: 735, Value: "var()"}}, + Line: 741, + SyntaxPatterns: []ir.PatternString{{Line: 741, Value: "var()"}}, ReportTemplate: "empty var() block", }, { - Line: 736, - SyntaxPatterns: []ir.PatternString{{Line: 736, Value: "const()"}}, + Line: 742, + SyntaxPatterns: []ir.PatternString{{Line: 742, Value: "const()"}}, ReportTemplate: "empty const() block", }, { - Line: 737, - SyntaxPatterns: []ir.PatternString{{Line: 737, Value: "type()"}}, + Line: 743, + SyntaxPatterns: []ir.PatternString{{Line: 743, Value: "type()"}}, ReportTemplate: "empty type() block", }, }, }, { - Line: 744, + Line: 750, Name: "dynamicFmtString", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -2408,16 +2432,16 @@ var PrecompiledRules = &ir.File{ DocAfter: "fmt.Errorf(\"%s\", msg)", Rules: []ir.Rule{ { - Line: 745, - SyntaxPatterns: []ir.PatternString{{Line: 745, Value: "fmt.Errorf($f)"}}, + Line: 751, + SyntaxPatterns: []ir.PatternString{{Line: 751, Value: "fmt.Errorf($f)"}}, ReportTemplate: "use errors.New($f) or fmt.Errorf(\"%s\", $f) instead", SuggestTemplate: "errors.New($f)", WhereExpr: ir.FilterExpr{ - Line: 746, + Line: 752, Op: ir.FilterNotOp, Src: "!m[\"f\"].Const", Args: []ir.FilterExpr{{ - Line: 746, + Line: 752, Op: ir.FilterVarConstOp, Src: "m[\"f\"].Const", Value: "f", @@ -2425,15 +2449,15 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 750, - SyntaxPatterns: []ir.PatternString{{Line: 750, Value: "fmt.Errorf($f($*args))"}}, + Line: 756, + SyntaxPatterns: []ir.PatternString{{Line: 756, Value: "fmt.Errorf($f($*args))"}}, ReportTemplate: "use errors.New($f($*args)) or fmt.Errorf(\"%s\", $f($*args)) instead", SuggestTemplate: "errors.New($f($*args))", }, }, }, { - Line: 759, + Line: 765, Name: "stringsCompare", MatcherName: "m", DocTags: []string{"style", "experimental"}, @@ -2442,25 +2466,25 @@ var PrecompiledRules = &ir.File{ DocAfter: "x < y", Rules: []ir.Rule{ { - Line: 760, - SyntaxPatterns: []ir.PatternString{{Line: 760, Value: "strings.Compare($s1, $s2) == 0"}}, + Line: 766, + SyntaxPatterns: []ir.PatternString{{Line: 766, Value: "strings.Compare($s1, $s2) == 0"}}, ReportTemplate: "suggestion: $s1 == $s2", SuggestTemplate: "$s1 == $s2", }, { - Line: 763, + Line: 769, SyntaxPatterns: []ir.PatternString{ - {Line: 763, Value: "strings.Compare($s1, $s2) == -1"}, - {Line: 764, Value: "strings.Compare($s1, $s2) < 0"}, + {Line: 769, Value: "strings.Compare($s1, $s2) == -1"}, + {Line: 770, Value: "strings.Compare($s1, $s2) < 0"}, }, ReportTemplate: "suggestion: $s1 < $s2", SuggestTemplate: "$s1 < $s2", }, { - Line: 767, + Line: 773, SyntaxPatterns: []ir.PatternString{ - {Line: 767, Value: "strings.Compare($s1, $s2) == 1"}, - {Line: 768, Value: "strings.Compare($s1, $s2) > 0"}, + {Line: 773, Value: "strings.Compare($s1, $s2) == 1"}, + {Line: 774, Value: "strings.Compare($s1, $s2) > 0"}, }, ReportTemplate: "suggestion: $s1 > $s2", SuggestTemplate: "$s1 > $s2", @@ -2468,7 +2492,7 @@ var PrecompiledRules = &ir.File{ }, }, { - Line: 776, + Line: 782, Name: "uncheckedInlineErr", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -2476,47 +2500,47 @@ var PrecompiledRules = &ir.File{ DocBefore: "if err := expr(); err2 != nil { /*...*/ }", DocAfter: "if err := expr(); err != nil { /*...*/ }", Rules: []ir.Rule{{ - Line: 777, + Line: 783, SyntaxPatterns: []ir.PatternString{ - {Line: 778, Value: "if $err := $_($*_); $err2 != nil { $*_ }"}, - {Line: 779, Value: "if $err = $_($*_); $err2 != nil { $*_ }"}, - {Line: 780, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"}, - {Line: 781, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"}, + {Line: 784, Value: "if $err := $_($*_); $err2 != nil { $*_ }"}, + {Line: 785, Value: "if $err = $_($*_); $err2 != nil { $*_ }"}, + {Line: 786, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"}, + {Line: 787, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"}, }, ReportTemplate: "$err error is unchecked, maybe intended to check it instead of $err2", WhereExpr: ir.FilterExpr{ - Line: 782, + Line: 788, Op: ir.FilterAndOp, Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\") &&\n\tm[\"err\"].Text != m[\"err2\"].Text", Args: []ir.FilterExpr{ { - Line: 782, + Line: 788, Op: ir.FilterAndOp, Src: "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\")", Args: []ir.FilterExpr{ { - Line: 782, + Line: 788, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"err\"].Type.Implements(\"error\")", Value: "err", - Args: []ir.FilterExpr{{Line: 782, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, + Args: []ir.FilterExpr{{Line: 788, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, }, { - Line: 782, + Line: 788, Op: ir.FilterVarTypeImplementsOp, Src: "m[\"err2\"].Type.Implements(\"error\")", Value: "err2", - Args: []ir.FilterExpr{{Line: 782, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, + Args: []ir.FilterExpr{{Line: 788, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}}, }, }, }, { - Line: 783, + Line: 789, Op: ir.FilterNeqOp, Src: "m[\"err\"].Text != m[\"err2\"].Text", Args: []ir.FilterExpr{ - {Line: 783, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"}, - {Line: 783, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"}, + {Line: 789, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"}, + {Line: 789, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"}, }, }, }, @@ -2525,7 +2549,7 @@ var PrecompiledRules = &ir.File{ }}, }, { - Line: 792, + Line: 798, Name: "badSyncOnceFunc", MatcherName: "m", DocTags: []string{"diagnostic", "experimental"}, @@ -2534,22 +2558,22 @@ var PrecompiledRules = &ir.File{ DocAfter: "fooOnce := sync.OnceFunc(foo); ...; fooOnce()", Rules: []ir.Rule{ { - Line: 793, - SyntaxPatterns: []ir.PatternString{{Line: 793, Value: "$*_; sync.OnceFunc($x); $*_;"}}, + Line: 799, + SyntaxPatterns: []ir.PatternString{{Line: 799, Value: "$*_; sync.OnceFunc($x); $*_;"}}, ReportTemplate: "possible sync.OnceFunc misuse, sync.OnceFunc($x) result is not used", WhereExpr: ir.FilterExpr{ - Line: 795, + Line: 801, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.21\")", Value: "1.21", }, }, { - Line: 797, - SyntaxPatterns: []ir.PatternString{{Line: 797, Value: "sync.OnceFunc($x)()"}}, + Line: 803, + SyntaxPatterns: []ir.PatternString{{Line: 803, Value: "sync.OnceFunc($x)()"}}, ReportTemplate: "possible sync.OnceFunc misuse, consider to assign sync.OnceFunc($x) to a variable", WhereExpr: ir.FilterExpr{ - Line: 799, + Line: 805, Op: ir.FilterGoVersionGreaterEqThanOp, Src: "m.GoVersion().GreaterEqThan(\"1.21\")", Value: "1.21", diff --git a/vendor/github.com/go-toolsmith/astequal/astequal.go b/vendor/github.com/go-toolsmith/astequal/astequal.go index 3d8db4af9..d1a04e942 100644 --- a/vendor/github.com/go-toolsmith/astequal/astequal.go +++ b/vendor/github.com/go-toolsmith/astequal/astequal.go @@ -4,8 +4,6 @@ package astequal import ( "go/ast" "go/token" - - "golang.org/x/exp/typeparams" ) // Node reports whether two AST nodes are structurally (deep) equal. @@ -109,8 +107,8 @@ func astExprEq(x, y ast.Expr) bool { y, ok := y.(*ast.IndexExpr) return ok && astIndexExprEq(x, y) - case *typeparams.IndexListExpr: - y, ok := y.(*typeparams.IndexListExpr) + case *ast.IndexListExpr: + y, ok := y.(*ast.IndexListExpr) return ok && astIndexListExprEq(x, y) case *ast.SliceExpr: @@ -323,7 +321,7 @@ func astFuncTypeEq(x, y *ast.FuncType) bool { } return astFieldListEq(x.Params, y.Params) && astFieldListEq(x.Results, y.Results) && - astFieldListEq(typeparams.ForFuncType(x), typeparams.ForFuncType(y)) + astFieldListEq(forFuncType(x), forFuncType(y)) } func astBasicLitEq(x, y *ast.BasicLit) bool { @@ -378,7 +376,7 @@ func astIndexExprEq(x, y *ast.IndexExpr) bool { return astExprEq(x.X, y.X) && astExprEq(x.Index, y.Index) } -func astIndexListExprEq(x, y *typeparams.IndexListExpr) bool { +func astIndexListExprEq(x, y *ast.IndexListExpr) bool { if x == nil || y == nil { return x == y } @@ -690,7 +688,7 @@ func astTypeSpecEq(x, y *ast.TypeSpec) bool { return x == y } return astIdentEq(x.Name, y.Name) && astExprEq(x.Type, y.Type) && - astFieldListEq(typeparams.ForTypeSpec(x), typeparams.ForTypeSpec(y)) + astFieldListEq(forTypeSpec(x), forTypeSpec(y)) } func astValueSpecEq(x, y *ast.ValueSpec) bool { @@ -755,3 +753,19 @@ func astExprSliceEq(xs, ys []ast.Expr) bool { } return true } + +// forTypeSpec returns n.TypeParams. +func forTypeSpec(n *ast.TypeSpec) *ast.FieldList { + if n == nil { + return nil + } + return n.TypeParams +} + +// forFuncType returns n.TypeParams. +func forFuncType(n *ast.FuncType) *ast.FieldList { + if n == nil { + return nil + } + return n.TypeParams +} diff --git a/vendor/github.com/go-toolsmith/astequal/diff.go b/vendor/github.com/go-toolsmith/astequal/diff.go new file mode 100644 index 000000000..cd69b4525 --- /dev/null +++ b/vendor/github.com/go-toolsmith/astequal/diff.go @@ -0,0 +1,23 @@ +package astequal + +import ( + "bytes" + "go/ast" + "go/format" + "go/token" + + "github.com/google/go-cmp/cmp" +) + +func Diff(x, y ast.Node) string { + var buf bytes.Buffer + format.Node(&buf, token.NewFileSet(), x) + s1 := buf.String() + + buf.Reset() + format.Node(&buf, token.NewFileSet(), y) + s2 := buf.String() + + // TODO(cristaloleg): replace with a more lightweight diff impl. + return cmp.Diff(s1, s2) +} diff --git a/vendor/github.com/matoous/godox/.golangci.yml b/vendor/github.com/matoous/godox/.golangci.yml index 3f0fcdb19..5fabb71fd 100644 --- a/vendor/github.com/matoous/godox/.golangci.yml +++ b/vendor/github.com/matoous/godox/.golangci.yml @@ -1,10 +1,4 @@ linters-settings: - depguard: - list-type: blacklist - include-go-root: true - packages: - # we are using "github.com/json-iterator/go" instead of json encoder from stdlib - - "encoding/json" dupl: threshold: 100 gocritic: @@ -38,27 +32,37 @@ linters-settings: linters: enable-all: true disable: + - depguard # prealloc is not recommended by `golangci-lint` developers. - prealloc - gochecknoglobals + # deprecated + - maligned + - exhaustivestruct + - nosnakecase + - scopelint + - structcheck + - ifshort + - varcheck + - deadcode + - golint + - interfacer + issues: exclude-rules: - path: _test\.go linters: + - exhaustruct - goconst - dupl - - path: fixtures - linters: - - gocritic - - varcheck - - deadcode - - unused - run: modules-download-mode: readonly + skip-dirs: + - "fixtures" + # output configuration options output: # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" diff --git a/vendor/github.com/matoous/godox/.revive.toml b/vendor/github.com/matoous/godox/.revive.toml index db0e4edb6..a4a30464d 100644 --- a/vendor/github.com/matoous/godox/.revive.toml +++ b/vendor/github.com/matoous/godox/.revive.toml @@ -1,5 +1,6 @@ ignoreGeneratedHeader = false severity = "warning" +exclude = ["./fixtures/..."] # confidence <= 0.2 generate a lot of errors from package-comments rule. It marks files that do not contain # package-level comments as a warning irrespective of existing package-level coment in one file. diff --git a/vendor/github.com/matoous/godox/Makefile b/vendor/github.com/matoous/godox/Makefile new file mode 100644 index 000000000..694aa21d6 --- /dev/null +++ b/vendor/github.com/matoous/godox/Makefile @@ -0,0 +1,20 @@ +## Help display. +## Pulls comments from beside commands and prints a nicely formatted +## display with the commands and their usage information. + +.DEFAULT_GOAL := help + +help: ## Prints this help + @grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: lint +lint: ## Lint the application + golangci-lint run --max-same-issues=0 --timeout=1m ./... + +.PHONY: test +test: ## Run unit tests + go test -race -shuffle=on ./... + +.PHONY: vet +vet: ## Run go vet + go vet ./... diff --git a/vendor/github.com/matoous/godox/godox.go b/vendor/github.com/matoous/godox/godox.go index 3903525c8..ed17059e0 100644 --- a/vendor/github.com/matoous/godox/godox.go +++ b/vendor/github.com/matoous/godox/godox.go @@ -1,3 +1,5 @@ +// Package godox is a linter that scans Go code for comments containing certain keywords +// (like TODO, BUG, FIXME) which typically indicate areas that require attention. package godox import ( diff --git a/vendor/github.com/mgechev/revive/config/config.go b/vendor/github.com/mgechev/revive/config/config.go index abd554a9f..c4ba0e7b4 100644 --- a/vendor/github.com/mgechev/revive/config/config.go +++ b/vendor/github.com/mgechev/revive/config/config.go @@ -1,3 +1,4 @@ +// Package config implements revive's configuration data structures and related methods package config import ( @@ -5,9 +6,9 @@ import ( "fmt" "os" - "github.com/mgechev/revive/formatter" - "github.com/BurntSushi/toml" + + "github.com/mgechev/revive/formatter" "github.com/mgechev/revive/lint" "github.com/mgechev/revive/rule" ) @@ -91,6 +92,7 @@ var allRules = append([]lint.Rule{ &rule.RedundantImportAlias{}, &rule.ImportAliasNamingRule{}, &rule.EnforceMapStyleRule{}, + &rule.EnforceSliceStyleRule{}, }, defaultRules...) var allFormatters = []lint.Formatter{ diff --git a/vendor/github.com/mgechev/revive/formatter/checkstyle.go b/vendor/github.com/mgechev/revive/formatter/checkstyle.go index 33a3b2ca1..f45b63c92 100644 --- a/vendor/github.com/mgechev/revive/formatter/checkstyle.go +++ b/vendor/github.com/mgechev/revive/formatter/checkstyle.go @@ -3,7 +3,7 @@ package formatter import ( "bytes" "encoding/xml" - plainTemplate "text/template" + plain "text/template" "github.com/mgechev/revive/lint" ) @@ -50,7 +50,7 @@ func (*Checkstyle) Format(failures <-chan lint.Failure, config lint.Config) (str issues[fn] = append(issues[fn], iss) } - t, err := plainTemplate.New("revive").Parse(checkstyleTemplate) + t, err := plain.New("revive").Parse(checkstyleTemplate) if err != nil { return "", err } diff --git a/vendor/github.com/mgechev/revive/formatter/default.go b/vendor/github.com/mgechev/revive/formatter/default.go index f76a7b29a..2d5a04434 100644 --- a/vendor/github.com/mgechev/revive/formatter/default.go +++ b/vendor/github.com/mgechev/revive/formatter/default.go @@ -1,6 +1,7 @@ package formatter import ( + "bytes" "fmt" "github.com/mgechev/revive/lint" @@ -19,8 +20,9 @@ func (*Default) Name() string { // Format formats the failures gotten from the lint. func (*Default) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) { + var buf bytes.Buffer for failure := range failures { - fmt.Printf("%v: %s\n", failure.Position.Start, failure.Failure) + fmt.Fprintf(&buf, "%v: %s\n", failure.Position.Start, failure.Failure) } - return "", nil + return buf.String(), nil } diff --git a/vendor/github.com/mgechev/revive/formatter/doc.go b/vendor/github.com/mgechev/revive/formatter/doc.go new file mode 100644 index 000000000..bb89f20ea --- /dev/null +++ b/vendor/github.com/mgechev/revive/formatter/doc.go @@ -0,0 +1,2 @@ +// Package formatter implements the linter output formatters. +package formatter diff --git a/vendor/github.com/mgechev/revive/formatter/friendly.go b/vendor/github.com/mgechev/revive/formatter/friendly.go index ced8fa46c..5ff329a23 100644 --- a/vendor/github.com/mgechev/revive/formatter/friendly.go +++ b/vendor/github.com/mgechev/revive/formatter/friendly.go @@ -3,6 +3,7 @@ package formatter import ( "bytes" "fmt" + "io" "sort" "github.com/fatih/color" @@ -31,13 +32,14 @@ func (*Friendly) Name() string { // Format formats the failures gotten from the lint. func (f *Friendly) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { + var buf bytes.Buffer errorMap := map[string]int{} warningMap := map[string]int{} totalErrors := 0 totalWarnings := 0 for failure := range failures { sev := severity(config, failure) - f.printFriendlyFailure(failure, sev) + f.printFriendlyFailure(&buf, failure, sev) if sev == lint.SeverityWarning { warningMap[failure.RuleName]++ totalWarnings++ @@ -47,29 +49,29 @@ func (f *Friendly) Format(failures <-chan lint.Failure, config lint.Config) (str totalErrors++ } } - f.printSummary(totalErrors, totalWarnings) - f.printStatistics(color.RedString("Errors:"), errorMap) - f.printStatistics(color.YellowString("Warnings:"), warningMap) - return "", nil + f.printSummary(&buf, totalErrors, totalWarnings) + f.printStatistics(&buf, color.RedString("Errors:"), errorMap) + f.printStatistics(&buf, color.YellowString("Warnings:"), warningMap) + return buf.String(), nil } -func (f *Friendly) printFriendlyFailure(failure lint.Failure, severity lint.Severity) { - f.printHeaderRow(failure, severity) - f.printFilePosition(failure) - fmt.Println() - fmt.Println() +func (f *Friendly) printFriendlyFailure(w io.Writer, failure lint.Failure, severity lint.Severity) { + f.printHeaderRow(w, failure, severity) + f.printFilePosition(w, failure) + fmt.Fprintln(w) + fmt.Fprintln(w) } -func (f *Friendly) printHeaderRow(failure lint.Failure, severity lint.Severity) { +func (f *Friendly) printHeaderRow(w io.Writer, failure lint.Failure, severity lint.Severity) { emoji := getWarningEmoji() if severity == lint.SeverityError { emoji = getErrorEmoji() } - fmt.Print(f.table([][]string{{emoji, "https://revive.run/r#" + failure.RuleName, color.GreenString(failure.Failure)}})) + fmt.Fprint(w, f.table([][]string{{emoji, "https://revive.run/r#" + failure.RuleName, color.GreenString(failure.Failure)}})) } -func (*Friendly) printFilePosition(failure lint.Failure) { - fmt.Printf(" %s:%d:%d", failure.GetFilename(), failure.Position.Start.Line, failure.Position.Start.Column) +func (*Friendly) printFilePosition(w io.Writer, failure lint.Failure) { + fmt.Fprintf(w, " %s:%d:%d", failure.GetFilename(), failure.Position.Start.Line, failure.Position.Start.Column) } type statEntry struct { @@ -77,7 +79,7 @@ type statEntry struct { failures int } -func (*Friendly) printSummary(errors, warnings int) { +func (*Friendly) printSummary(w io.Writer, errors, warnings int) { emoji := getWarningEmoji() if errors > 0 { emoji = getErrorEmoji() @@ -96,18 +98,18 @@ func (*Friendly) printSummary(errors, warnings int) { } str := fmt.Sprintf("%d %s (%d %s, %d %s)", errors+warnings, problemsLabel, errors, errorsLabel, warnings, warningsLabel) if errors > 0 { - fmt.Printf("%s %s\n", emoji, color.RedString(str)) - fmt.Println() + fmt.Fprintf(w, "%s %s\n", emoji, color.RedString(str)) + fmt.Fprintln(w) return } if warnings > 0 { - fmt.Printf("%s %s\n", emoji, color.YellowString(str)) - fmt.Println() + fmt.Fprintf(w, "%s %s\n", emoji, color.YellowString(str)) + fmt.Fprintln(w) return } } -func (f *Friendly) printStatistics(header string, stats map[string]int) { +func (f *Friendly) printStatistics(w io.Writer, header string, stats map[string]int) { if len(stats) == 0 { return } @@ -122,8 +124,8 @@ func (f *Friendly) printStatistics(header string, stats map[string]int) { for _, entry := range data { formatted = append(formatted, []string{color.GreenString(fmt.Sprintf("%d", entry.failures)), entry.name}) } - fmt.Println(header) - fmt.Println(f.table(formatted)) + fmt.Fprintln(w, header) + fmt.Fprintln(w, f.table(formatted)) } func (*Friendly) table(rows [][]string) string { diff --git a/vendor/github.com/mgechev/revive/formatter/ndjson.go b/vendor/github.com/mgechev/revive/formatter/ndjson.go index a02d9c80f..58b35dc44 100644 --- a/vendor/github.com/mgechev/revive/formatter/ndjson.go +++ b/vendor/github.com/mgechev/revive/formatter/ndjson.go @@ -1,8 +1,8 @@ package formatter import ( + "bytes" "encoding/json" - "os" "github.com/mgechev/revive/lint" ) @@ -20,7 +20,8 @@ func (*NDJSON) Name() string { // Format formats the failures gotten from the lint. func (*NDJSON) Format(failures <-chan lint.Failure, config lint.Config) (string, error) { - enc := json.NewEncoder(os.Stdout) + var buf bytes.Buffer + enc := json.NewEncoder(&buf) for failure := range failures { obj := jsonObject{} obj.Severity = severity(config, failure) @@ -30,5 +31,5 @@ func (*NDJSON) Format(failures <-chan lint.Failure, config lint.Config) (string, return "", err } } - return "", nil + return buf.String(), nil } diff --git a/vendor/github.com/mgechev/revive/formatter/plain.go b/vendor/github.com/mgechev/revive/formatter/plain.go index 6e083bcfd..09ebf6cdc 100644 --- a/vendor/github.com/mgechev/revive/formatter/plain.go +++ b/vendor/github.com/mgechev/revive/formatter/plain.go @@ -1,6 +1,7 @@ package formatter import ( + "bytes" "fmt" "github.com/mgechev/revive/lint" @@ -19,8 +20,9 @@ func (*Plain) Name() string { // Format formats the failures gotten from the lint. func (*Plain) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) { + var buf bytes.Buffer for failure := range failures { - fmt.Printf("%v: %s %s\n", failure.Position.Start, failure.Failure, "https://revive.run/r#"+failure.RuleName) + fmt.Fprintf(&buf, "%v: %s %s\n", failure.Position.Start, failure.Failure, "https://revive.run/r#"+failure.RuleName) } - return "", nil + return buf.String(), nil } diff --git a/vendor/github.com/mgechev/revive/formatter/unix.go b/vendor/github.com/mgechev/revive/formatter/unix.go index ef2f1613a..e46f3c275 100644 --- a/vendor/github.com/mgechev/revive/formatter/unix.go +++ b/vendor/github.com/mgechev/revive/formatter/unix.go @@ -1,6 +1,7 @@ package formatter import ( + "bytes" "fmt" "github.com/mgechev/revive/lint" @@ -8,7 +9,8 @@ import ( // Unix is an implementation of the Formatter interface // which formats the errors to a simple line based error format -// main.go:24:9: [errorf] should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) +// +// main.go:24:9: [errorf] should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...) type Unix struct { Metadata lint.FormatterMetadata } @@ -20,8 +22,9 @@ func (*Unix) Name() string { // Format formats the failures gotten from the lint. func (*Unix) Format(failures <-chan lint.Failure, _ lint.Config) (string, error) { + var buf bytes.Buffer for failure := range failures { - fmt.Printf("%v: [%s] %s\n", failure.Position.Start, failure.RuleName, failure.Failure) + fmt.Fprintf(&buf, "%v: [%s] %s\n", failure.Position.Start, failure.RuleName, failure.Failure) } - return "", nil + return buf.String(), nil } diff --git a/vendor/github.com/mgechev/revive/lint/config.go b/vendor/github.com/mgechev/revive/lint/config.go index 9b26d5841..7e51a93c2 100644 --- a/vendor/github.com/mgechev/revive/lint/config.go +++ b/vendor/github.com/mgechev/revive/lint/config.go @@ -3,6 +3,7 @@ package lint // Arguments is type used for the arguments of a rule. type Arguments = []interface{} +// FileFilters is type used for modeling file filters to apply to rules. type FileFilters = []*FileFilter // RuleConfig is type used for the rule configuration. @@ -32,8 +33,8 @@ func (rc *RuleConfig) Initialize() error { type RulesConfig = map[string]RuleConfig // MustExclude - checks if given filename `name` must be excluded -func (rcfg *RuleConfig) MustExclude(name string) bool { - for _, exclude := range rcfg.excludeFilters { +func (rc *RuleConfig) MustExclude(name string) bool { + for _, exclude := range rc.excludeFilters { if exclude.MatchFileName(name) { return true } diff --git a/vendor/github.com/mgechev/revive/lint/doc.go b/vendor/github.com/mgechev/revive/lint/doc.go new file mode 100644 index 000000000..7048adf4b --- /dev/null +++ b/vendor/github.com/mgechev/revive/lint/doc.go @@ -0,0 +1,2 @@ +// Package lint implements the linting machinery. +package lint diff --git a/vendor/github.com/mgechev/revive/rule/add-constant.go b/vendor/github.com/mgechev/revive/rule/add-constant.go index 36a7003da..f39f224b2 100644 --- a/vendor/github.com/mgechev/revive/rule/add-constant.go +++ b/vendor/github.com/mgechev/revive/rule/add-constant.go @@ -49,12 +49,13 @@ func (r *AddConstantRule) Apply(file *lint.File, arguments lint.Arguments) []lin failures = append(failures, failure) } - w := lintAddConstantRule{ + w := &lintAddConstantRule{ onFailure: onFailure, strLits: make(map[string]int), strLitLimit: r.strLitLimit, whiteLst: r.whiteList, ignoreFunctions: r.ignoreFunctions, + structTags: make(map[*ast.BasicLit]struct{}), } ast.Walk(w, file.AST) @@ -73,9 +74,14 @@ type lintAddConstantRule struct { strLitLimit int whiteLst whiteList ignoreFunctions []*regexp.Regexp + structTags map[*ast.BasicLit]struct{} } -func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor { +func (w *lintAddConstantRule) Visit(node ast.Node) ast.Visitor { + if node == nil { + return nil + } + switch n := node.(type) { case *ast.CallExpr: w.checkFunc(n) @@ -83,13 +89,23 @@ func (w lintAddConstantRule) Visit(node ast.Node) ast.Visitor { case *ast.GenDecl: return nil // skip declarations case *ast.BasicLit: - w.checkLit(n) + if !w.isStructTag(n) { + w.checkLit(n) + } + case *ast.StructType: + if n.Fields != nil { + for _, field := range n.Fields.List { + if field.Tag != nil { + w.structTags[field.Tag] = struct{}{} + } + } + } } return w } -func (w lintAddConstantRule) checkFunc(expr *ast.CallExpr) { +func (w *lintAddConstantRule) checkFunc(expr *ast.CallExpr) { fName := w.getFuncName(expr) for _, arg := range expr.Args { @@ -105,7 +121,7 @@ func (w lintAddConstantRule) checkFunc(expr *ast.CallExpr) { } } -func (w lintAddConstantRule) getFuncName(expr *ast.CallExpr) string { +func (*lintAddConstantRule) getFuncName(expr *ast.CallExpr) string { switch f := expr.Fun.(type) { case *ast.SelectorExpr: switch prefix := f.X.(type) { @@ -119,7 +135,7 @@ func (w lintAddConstantRule) getFuncName(expr *ast.CallExpr) string { return "" } -func (w lintAddConstantRule) checkLit(n *ast.BasicLit) { +func (w *lintAddConstantRule) checkLit(n *ast.BasicLit) { switch kind := n.Kind.String(); kind { case kindFLOAT, kindINT: w.checkNumLit(kind, n) @@ -128,7 +144,7 @@ func (w lintAddConstantRule) checkLit(n *ast.BasicLit) { } } -func (w lintAddConstantRule) isIgnoredFunc(fName string) bool { +func (w *lintAddConstantRule) isIgnoredFunc(fName string) bool { for _, pattern := range w.ignoreFunctions { if pattern.MatchString(fName) { return true @@ -138,7 +154,7 @@ func (w lintAddConstantRule) isIgnoredFunc(fName string) bool { return false } -func (w lintAddConstantRule) checkStrLit(n *ast.BasicLit) { +func (w *lintAddConstantRule) checkStrLit(n *ast.BasicLit) { if w.whiteLst[kindSTRING][n.Value] { return } @@ -158,7 +174,7 @@ func (w lintAddConstantRule) checkStrLit(n *ast.BasicLit) { } } -func (w lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) { +func (w *lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) { if w.whiteLst[kind][n.Value] { return } @@ -171,6 +187,11 @@ func (w lintAddConstantRule) checkNumLit(kind string, n *ast.BasicLit) { }) } +func (w *lintAddConstantRule) isStructTag(n *ast.BasicLit) bool { + _, ok := w.structTags[n] + return ok +} + func (r *AddConstantRule) configure(arguments lint.Arguments) { r.Lock() defer r.Unlock() @@ -179,7 +200,7 @@ func (r *AddConstantRule) configure(arguments lint.Arguments) { r.strLitLimit = defaultStrLitLimit r.whiteList = newWhiteList() if len(arguments) > 0 { - args, ok := arguments[0].(map[string]interface{}) + args, ok := arguments[0].(map[string]any) if !ok { panic(fmt.Sprintf("Invalid argument to the add-constant rule. Expecting a k,v map, got %T", arguments[0])) } diff --git a/vendor/github.com/mgechev/revive/rule/comment-spacings.go b/vendor/github.com/mgechev/revive/rule/comment-spacings.go index 0d75c55f3..2b8240ca5 100644 --- a/vendor/github.com/mgechev/revive/rule/comment-spacings.go +++ b/vendor/github.com/mgechev/revive/rule/comment-spacings.go @@ -8,7 +8,7 @@ import ( "github.com/mgechev/revive/lint" ) -// CommentSpacings Rule check the whether there is a space between +// CommentSpacingsRule check the whether there is a space between // the comment symbol( // ) and the start of the comment text type CommentSpacingsRule struct { allowList []string @@ -36,6 +36,7 @@ func (r *CommentSpacingsRule) configure(arguments lint.Arguments) { } } +// Apply the rule. func (r *CommentSpacingsRule) Apply(file *lint.File, args lint.Arguments) []lint.Failure { r.configure(args) @@ -74,6 +75,7 @@ func (r *CommentSpacingsRule) Apply(file *lint.File, args lint.Arguments) []lint return failures } +// Name yields this rule name. func (*CommentSpacingsRule) Name() string { return "comment-spacings" } diff --git a/vendor/github.com/mgechev/revive/rule/confusing-naming.go b/vendor/github.com/mgechev/revive/rule/confusing-naming.go index 8b1c3eac4..daaf51c81 100644 --- a/vendor/github.com/mgechev/revive/rule/confusing-naming.go +++ b/vendor/github.com/mgechev/revive/rule/confusing-naming.go @@ -71,7 +71,6 @@ func (*ConfusingNamingRule) Name() string { // checkMethodName checks if a given method/function name is similar (just case differences) to other method/function of the same struct/file. func checkMethodName(holder string, id *ast.Ident, w *lintConfusingNames) { - if id.Name == "init" && holder == defaultStructName { // ignore init functions return diff --git a/vendor/github.com/mgechev/revive/rule/constant-logical-expr.go b/vendor/github.com/mgechev/revive/rule/constant-logical-expr.go index 9abc95d67..36cd641f7 100644 --- a/vendor/github.com/mgechev/revive/rule/constant-logical-expr.go +++ b/vendor/github.com/mgechev/revive/rule/constant-logical-expr.go @@ -11,7 +11,7 @@ import ( type ConstantLogicalExprRule struct{} // Apply applies the rule to given file. -func (r *ConstantLogicalExprRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { +func (*ConstantLogicalExprRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { var failures []lint.Failure onFailure := func(failure lint.Failure) { @@ -63,7 +63,7 @@ func (w *lintConstantLogicalExpr) Visit(node ast.Node) ast.Visitor { return w } -func (w *lintConstantLogicalExpr) isOperatorWithLogicalResult(t token.Token) bool { +func (*lintConstantLogicalExpr) isOperatorWithLogicalResult(t token.Token) bool { switch t { case token.LAND, token.LOR, token.EQL, token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ: return true @@ -72,7 +72,7 @@ func (w *lintConstantLogicalExpr) isOperatorWithLogicalResult(t token.Token) boo return false } -func (w *lintConstantLogicalExpr) isEqualityOperator(t token.Token) bool { +func (*lintConstantLogicalExpr) isEqualityOperator(t token.Token) bool { switch t { case token.EQL, token.LEQ, token.GEQ: return true @@ -81,7 +81,7 @@ func (w *lintConstantLogicalExpr) isEqualityOperator(t token.Token) bool { return false } -func (w *lintConstantLogicalExpr) isInequalityOperator(t token.Token) bool { +func (*lintConstantLogicalExpr) isInequalityOperator(t token.Token) bool { switch t { case token.LSS, token.GTR, token.NEQ: return true diff --git a/vendor/github.com/mgechev/revive/rule/context-as-argument.go b/vendor/github.com/mgechev/revive/rule/context-as-argument.go index 3c400065e..e0c8cfa5e 100644 --- a/vendor/github.com/mgechev/revive/rule/context-as-argument.go +++ b/vendor/github.com/mgechev/revive/rule/context-as-argument.go @@ -82,7 +82,7 @@ func (w lintContextArguments) Visit(n ast.Node) ast.Visitor { func getAllowTypesFromArguments(args lint.Arguments) map[string]struct{} { allowTypesBefore := []string{} if len(args) >= 1 { - argKV, ok := args[0].(map[string]interface{}) + argKV, ok := args[0].(map[string]any) if !ok { panic(fmt.Sprintf("Invalid argument to the context-as-argument rule. Expecting a k,v map, got %T", args[0])) } diff --git a/vendor/github.com/mgechev/revive/rule/datarace.go b/vendor/github.com/mgechev/revive/rule/datarace.go index 26fcadcdc..39e96696a 100644 --- a/vendor/github.com/mgechev/revive/rule/datarace.go +++ b/vendor/github.com/mgechev/revive/rule/datarace.go @@ -53,7 +53,7 @@ func (w lintDataRaces) Visit(n ast.Node) ast.Visitor { return nil } -func (w lintDataRaces) ExtractReturnIDs(fields []*ast.Field) map[*ast.Object]struct{} { +func (lintDataRaces) ExtractReturnIDs(fields []*ast.Field) map[*ast.Object]struct{} { r := map[*ast.Object]struct{}{} for _, f := range fields { for _, id := range f.Names { @@ -111,7 +111,7 @@ func (w lintFunctionForDataRaces) Visit(node ast.Node) ast.Visitor { return ok } - ids := pick(funcLit.Body, selectIDs, nil) + ids := pick(funcLit.Body, selectIDs) for _, id := range ids { id := id.(*ast.Ident) _, isRangeID := w.rangeIDs[id.Obj] diff --git a/vendor/github.com/mgechev/revive/rule/defer.go b/vendor/github.com/mgechev/revive/rule/defer.go index f3ea17920..adc6478ae 100644 --- a/vendor/github.com/mgechev/revive/rule/defer.go +++ b/vendor/github.com/mgechev/revive/rule/defer.go @@ -56,7 +56,7 @@ func (*DeferRule) allowFromArgs(args lint.Arguments) map[string]bool { return allow } - aa, ok := args[0].([]interface{}) + aa, ok := args[0].([]any) if !ok { panic(fmt.Sprintf("Invalid argument '%v' for 'defer' rule. Expecting []string, got %T", args[0], args[0])) } @@ -144,8 +144,8 @@ func (w lintDeferRule) Visit(node ast.Node) ast.Visitor { w.newFailure("be careful when deferring calls to methods without pointer receiver", fn, 0.8, "bad practice", "method-call") } } - } + return nil } diff --git a/vendor/github.com/mgechev/revive/rule/doc.go b/vendor/github.com/mgechev/revive/rule/doc.go new file mode 100644 index 000000000..55bf6caa6 --- /dev/null +++ b/vendor/github.com/mgechev/revive/rule/doc.go @@ -0,0 +1,2 @@ +// Package rule implements revive's linting rules. +package rule diff --git a/vendor/github.com/mgechev/revive/rule/dot-imports.go b/vendor/github.com/mgechev/revive/rule/dot-imports.go index db78f1957..6b877677d 100644 --- a/vendor/github.com/mgechev/revive/rule/dot-imports.go +++ b/vendor/github.com/mgechev/revive/rule/dot-imports.go @@ -1,16 +1,23 @@ package rule import ( + "fmt" "go/ast" + "sync" "github.com/mgechev/revive/lint" ) // DotImportsRule lints given else constructs. -type DotImportsRule struct{} +type DotImportsRule struct { + sync.Mutex + allowedPackages allowPackages +} // Apply applies the rule to given file. -func (*DotImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { +func (r *DotImportsRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure { + r.configure(arguments) + var failures []lint.Failure fileAst := file.AST @@ -20,6 +27,7 @@ func (*DotImportsRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { onFailure: func(failure lint.Failure) { failures = append(failures, failure) }, + allowPackages: r.allowedPackages, } ast.Walk(walker, fileAst) @@ -32,15 +40,49 @@ func (*DotImportsRule) Name() string { return "dot-imports" } +func (r *DotImportsRule) configure(arguments lint.Arguments) { + r.Lock() + defer r.Unlock() + + if r.allowedPackages != nil { + return + } + + r.allowedPackages = make(allowPackages) + if len(arguments) == 0 { + return + } + + args, ok := arguments[0].(map[string]any) + if !ok { + panic(fmt.Sprintf("Invalid argument to the dot-imports rule. Expecting a k,v map, got %T", arguments[0])) + } + + if allowedPkgArg, ok := args["allowedPackages"]; ok { + if pkgs, ok := allowedPkgArg.([]any); ok { + for _, p := range pkgs { + if pkg, ok := p.(string); ok { + r.allowedPackages.add(pkg) + } else { + panic(fmt.Sprintf("Invalid argument to the dot-imports rule, string expected. Got '%v' (%T)", p, p)) + } + } + } else { + panic(fmt.Sprintf("Invalid argument to the dot-imports rule, []string expected. Got '%v' (%T)", allowedPkgArg, allowedPkgArg)) + } + } +} + type lintImports struct { - file *lint.File - fileAst *ast.File - onFailure func(lint.Failure) + file *lint.File + fileAst *ast.File + onFailure func(lint.Failure) + allowPackages allowPackages } func (w lintImports) Visit(_ ast.Node) ast.Visitor { for _, is := range w.fileAst.Imports { - if is.Name != nil && is.Name.Name == "." { + if is.Name != nil && is.Name.Name == "." && !w.allowPackages.isAllowedPackage(is.Path.Value) { w.onFailure(lint.Failure{ Confidence: 1, Failure: "should not use dot imports", @@ -51,3 +93,14 @@ func (w lintImports) Visit(_ ast.Node) ast.Visitor { } return nil } + +type allowPackages map[string]struct{} + +func (ap allowPackages) add(pkg string) { + ap[fmt.Sprintf(`"%s"`, pkg)] = struct{}{} // import path strings are with double quotes +} + +func (ap allowPackages) isAllowedPackage(pkg string) bool { + _, allowed := ap[pkg] + return allowed +} diff --git a/vendor/github.com/mgechev/revive/rule/early-return.go b/vendor/github.com/mgechev/revive/rule/early-return.go index 90a0acc55..9c04a1dbe 100644 --- a/vendor/github.com/mgechev/revive/rule/early-return.go +++ b/vendor/github.com/mgechev/revive/rule/early-return.go @@ -22,7 +22,7 @@ func (*EarlyReturnRule) Name() string { } // CheckIfElse evaluates the rule against an ifelse.Chain. -func (e *EarlyReturnRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) { +func (*EarlyReturnRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) { if !chain.Else.Deviates() { // this rule only applies if the else-block deviates control flow return diff --git a/vendor/github.com/mgechev/revive/rule/enforce-map-style.go b/vendor/github.com/mgechev/revive/rule/enforce-map-style.go index ae27b654f..36ac2374c 100644 --- a/vendor/github.com/mgechev/revive/rule/enforce-map-style.go +++ b/vendor/github.com/mgechev/revive/rule/enforce-map-style.go @@ -47,7 +47,7 @@ type EnforceMapStyleRule struct { func (r *EnforceMapStyleRule) configure(arguments lint.Arguments) { r.Lock() defer r.Unlock() - + if r.configured { return } @@ -58,7 +58,7 @@ func (r *EnforceMapStyleRule) configure(arguments lint.Arguments) { return } - enforceMapStyle, ok := arguments[0].(string) + enforceMapStyle, ok := arguments[0].(string) if !ok { panic(fmt.Sprintf("Invalid argument '%v' for 'enforce-map-style' rule. Expecting string, got %T", arguments[0], arguments[0])) } @@ -141,7 +141,7 @@ func (r *EnforceMapStyleRule) Apply(file *lint.File, arguments lint.Arguments) [ } // Name returns the rule name. -func (r *EnforceMapStyleRule) Name() string { +func (*EnforceMapStyleRule) Name() string { return "enforce-map-style" } diff --git a/vendor/github.com/mgechev/revive/rule/enforce-repeated-arg-type-style.go b/vendor/github.com/mgechev/revive/rule/enforce-repeated-arg-type-style.go new file mode 100644 index 000000000..067082b1b --- /dev/null +++ b/vendor/github.com/mgechev/revive/rule/enforce-repeated-arg-type-style.go @@ -0,0 +1,191 @@ +package rule + +import ( + "fmt" + "go/ast" + "go/types" + "sync" + + "github.com/mgechev/revive/lint" +) + +type enforceRepeatedArgTypeStyleType string + +const ( + enforceRepeatedArgTypeStyleTypeAny enforceRepeatedArgTypeStyleType = "any" + enforceRepeatedArgTypeStyleTypeShort enforceRepeatedArgTypeStyleType = "short" + enforceRepeatedArgTypeStyleTypeFull enforceRepeatedArgTypeStyleType = "full" +) + +func repeatedArgTypeStyleFromString(s string) enforceRepeatedArgTypeStyleType { + switch s { + case string(enforceRepeatedArgTypeStyleTypeAny), "": + return enforceRepeatedArgTypeStyleTypeAny + case string(enforceRepeatedArgTypeStyleTypeShort): + return enforceRepeatedArgTypeStyleTypeShort + case string(enforceRepeatedArgTypeStyleTypeFull): + return enforceRepeatedArgTypeStyleTypeFull + default: + err := fmt.Errorf( + "invalid repeated arg type style: %s (expecting one of %v)", + s, + []enforceRepeatedArgTypeStyleType{ + enforceRepeatedArgTypeStyleTypeAny, + enforceRepeatedArgTypeStyleTypeShort, + enforceRepeatedArgTypeStyleTypeFull, + }, + ) + + panic(fmt.Sprintf("Invalid argument to the enforce-repeated-arg-type-style rule: %v", err)) + } +} + +// EnforceRepeatedArgTypeStyleRule implements a rule to enforce repeated argument type style. +type EnforceRepeatedArgTypeStyleRule struct { + configured bool + funcArgStyle enforceRepeatedArgTypeStyleType + funcRetValStyle enforceRepeatedArgTypeStyleType + + sync.Mutex +} + +func (r *EnforceRepeatedArgTypeStyleRule) configure(arguments lint.Arguments) { + r.Lock() + defer r.Unlock() + + if r.configured { + return + } + r.configured = true + + r.funcArgStyle = enforceRepeatedArgTypeStyleTypeAny + r.funcRetValStyle = enforceRepeatedArgTypeStyleTypeAny + + if len(arguments) == 0 { + return + } + + switch funcArgStyle := arguments[0].(type) { + case string: + r.funcArgStyle = repeatedArgTypeStyleFromString(funcArgStyle) + r.funcRetValStyle = repeatedArgTypeStyleFromString(funcArgStyle) + case map[string]any: // expecting map[string]string + for k, v := range funcArgStyle { + switch k { + case "funcArgStyle": + val, ok := v.(string) + if !ok { + panic(fmt.Sprintf("Invalid map value type for 'enforce-repeated-arg-type-style' rule. Expecting string, got %T", v)) + } + r.funcArgStyle = repeatedArgTypeStyleFromString(val) + case "funcRetValStyle": + val, ok := v.(string) + if !ok { + panic(fmt.Sprintf("Invalid map value '%v' for 'enforce-repeated-arg-type-style' rule. Expecting string, got %T", v, v)) + } + r.funcRetValStyle = repeatedArgTypeStyleFromString(val) + default: + panic(fmt.Sprintf("Invalid map key for 'enforce-repeated-arg-type-style' rule. Expecting 'funcArgStyle' or 'funcRetValStyle', got %v", k)) + } + } + default: + panic(fmt.Sprintf("Invalid argument '%v' for 'import-alias-naming' rule. Expecting string or map[string]string, got %T", arguments[0], arguments[0])) + } +} + +// Apply applies the rule to a given file. +func (r *EnforceRepeatedArgTypeStyleRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure { + r.configure(arguments) + + if r.funcArgStyle == enforceRepeatedArgTypeStyleTypeAny && r.funcRetValStyle == enforceRepeatedArgTypeStyleTypeAny { + // This linter is not configured, return no failures. + return nil + } + + var failures []lint.Failure + + err := file.Pkg.TypeCheck() + if err != nil { + // the file has other issues + return nil + } + typesInfo := file.Pkg.TypesInfo() + + astFile := file.AST + ast.Inspect(astFile, func(n ast.Node) bool { + switch fn := n.(type) { + case *ast.FuncDecl: + if r.funcArgStyle == enforceRepeatedArgTypeStyleTypeFull { + if fn.Type.Params != nil { + for _, field := range fn.Type.Params.List { + if len(field.Names) > 1 { + failures = append(failures, lint.Failure{ + Confidence: 1, + Node: field, + Category: "style", + Failure: "argument types should not be omitted", + }) + } + } + } + } + + if r.funcArgStyle == enforceRepeatedArgTypeStyleTypeShort { + var prevType ast.Expr + if fn.Type.Params != nil { + for _, field := range fn.Type.Params.List { + if types.Identical(typesInfo.Types[field.Type].Type, typesInfo.Types[prevType].Type) { + failures = append(failures, lint.Failure{ + Confidence: 1, + Node: field, + Category: "style", + Failure: "repeated argument type can be omitted", + }) + } + prevType = field.Type + } + } + } + + if r.funcRetValStyle == enforceRepeatedArgTypeStyleTypeFull { + if fn.Type.Results != nil { + for _, field := range fn.Type.Results.List { + if len(field.Names) > 1 { + failures = append(failures, lint.Failure{ + Confidence: 1, + Node: field, + Category: "style", + Failure: "return types should not be omitted", + }) + } + } + } + } + + if r.funcRetValStyle == enforceRepeatedArgTypeStyleTypeShort { + var prevType ast.Expr + if fn.Type.Results != nil { + for _, field := range fn.Type.Results.List { + if field.Names != nil && types.Identical(typesInfo.Types[field.Type].Type, typesInfo.Types[prevType].Type) { + failures = append(failures, lint.Failure{ + Confidence: 1, + Node: field, + Category: "style", + Failure: "repeated return type can be omitted", + }) + } + prevType = field.Type + } + } + } + } + return true + }) + + return failures +} + +// Name returns the name of the linter rule. +func (*EnforceRepeatedArgTypeStyleRule) Name() string { + return "enforce-repeated-arg-type-style" +} diff --git a/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go b/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go new file mode 100644 index 000000000..abaf20be0 --- /dev/null +++ b/vendor/github.com/mgechev/revive/rule/enforce-slice-style.go @@ -0,0 +1,193 @@ +package rule + +import ( + "fmt" + "go/ast" + "sync" + + "github.com/mgechev/revive/lint" +) + +type enforceSliceStyleType string + +const ( + enforceSliceStyleTypeAny enforceSliceStyleType = "any" + enforceSliceStyleTypeMake enforceSliceStyleType = "make" + enforceSliceStyleTypeLiteral enforceSliceStyleType = "literal" +) + +func sliceStyleFromString(s string) (enforceSliceStyleType, error) { + switch s { + case string(enforceSliceStyleTypeAny), "": + return enforceSliceStyleTypeAny, nil + case string(enforceSliceStyleTypeMake): + return enforceSliceStyleTypeMake, nil + case string(enforceSliceStyleTypeLiteral): + return enforceSliceStyleTypeLiteral, nil + default: + return enforceSliceStyleTypeAny, fmt.Errorf( + "invalid slice style: %s (expecting one of %v)", + s, + []enforceSliceStyleType{ + enforceSliceStyleTypeAny, + enforceSliceStyleTypeMake, + enforceSliceStyleTypeLiteral, + }, + ) + } +} + +// EnforceSliceStyleRule implements a rule to enforce `make([]type)` over `[]type{}`. +type EnforceSliceStyleRule struct { + configured bool + enforceSliceStyle enforceSliceStyleType + sync.Mutex +} + +func (r *EnforceSliceStyleRule) configure(arguments lint.Arguments) { + r.Lock() + defer r.Unlock() + + if r.configured { + return + } + r.configured = true + + if len(arguments) < 1 { + r.enforceSliceStyle = enforceSliceStyleTypeAny + return + } + + enforceSliceStyle, ok := arguments[0].(string) + if !ok { + panic(fmt.Sprintf("Invalid argument '%v' for 'enforce-slice-style' rule. Expecting string, got %T", arguments[0], arguments[0])) + } + + var err error + r.enforceSliceStyle, err = sliceStyleFromString(enforceSliceStyle) + + if err != nil { + panic(fmt.Sprintf("Invalid argument to the enforce-slice-style rule: %v", err)) + } +} + +// Apply applies the rule to given file. +func (r *EnforceSliceStyleRule) Apply(file *lint.File, arguments lint.Arguments) []lint.Failure { + r.configure(arguments) + + if r.enforceSliceStyle == enforceSliceStyleTypeAny { + // this linter is not configured + return nil + } + + var failures []lint.Failure + + astFile := file.AST + ast.Inspect(astFile, func(n ast.Node) bool { + switch v := n.(type) { + case *ast.CompositeLit: + if r.enforceSliceStyle != enforceSliceStyleTypeMake { + return true + } + + if !r.isSliceType(v.Type) { + return true + } + + if len(v.Elts) > 0 { + // not an empty slice + return true + } + + failures = append(failures, lint.Failure{ + Confidence: 1, + Node: v, + Category: "style", + Failure: "use make([]type) instead of []type{} (or declare nil slice)", + }) + case *ast.CallExpr: + if r.enforceSliceStyle != enforceSliceStyleTypeLiteral { + // skip any function calls, even if it's make([]type) + // we don't want to report it if literals are not enforced + return true + } + + ident, ok := v.Fun.(*ast.Ident) + if !ok || ident.Name != "make" { + return true + } + + if len(v.Args) < 2 { + // skip invalid make declarations + return true + } + + if !r.isSliceType(v.Args[0]) { + // not a slice type + return true + } + + arg, ok := v.Args[1].(*ast.BasicLit) + if !ok { + // skip invalid make declarations + return true + } + + if arg.Value != "0" { + // skip slice with non-zero size + return true + } + + if len(v.Args) > 2 { + arg, ok := v.Args[2].(*ast.BasicLit) + if !ok { + // skip invalid make declarations + return true + } + + if arg.Value != "0" { + // skip non-zero capacity slice + return true + } + } + + failures = append(failures, lint.Failure{ + Confidence: 1, + Node: v.Args[0], + Category: "style", + Failure: "use []type{} instead of make([]type, 0) (or declare nil slice)", + }) + } + return true + }) + + return failures +} + +// Name returns the rule name. +func (*EnforceSliceStyleRule) Name() string { + return "enforce-slice-style" +} + +func (r *EnforceSliceStyleRule) isSliceType(v ast.Expr) bool { + switch t := v.(type) { + case *ast.ArrayType: + if t.Len != nil { + // array + return false + } + // slice + return true + case *ast.Ident: + if t.Obj == nil { + return false + } + typeSpec, ok := t.Obj.Decl.(*ast.TypeSpec) + if !ok { + return false + } + return r.isSliceType(typeSpec.Type) + default: + return false + } +} diff --git a/vendor/github.com/mgechev/revive/rule/flag-param.go b/vendor/github.com/mgechev/revive/rule/flag-param.go index 19a05f9fe..f9bfb712c 100644 --- a/vendor/github.com/mgechev/revive/rule/flag-param.go +++ b/vendor/github.com/mgechev/revive/rule/flag-param.go @@ -88,7 +88,7 @@ func (w conditionVisitor) Visit(node ast.Node) ast.Visitor { return false } - uses := pick(ifStmt.Cond, fselect, nil) + uses := pick(ifStmt.Cond, fselect) if len(uses) < 1 { return w diff --git a/vendor/github.com/mgechev/revive/rule/function-length.go b/vendor/github.com/mgechev/revive/rule/function-length.go index f7ab8b98e..fd65884e9 100644 --- a/vendor/github.com/mgechev/revive/rule/function-length.go +++ b/vendor/github.com/mgechev/revive/rule/function-length.go @@ -171,7 +171,7 @@ func (w lintFuncLength) countFuncLitStmts(stmt ast.Expr) int { return 0 } -func (w lintFuncLength) countBodyListStmts(t interface{}) int { +func (w lintFuncLength) countBodyListStmts(t any) int { i := reflect.ValueOf(t).Elem().FieldByName(`Body`).Elem().FieldByName(`List`).Interface() return w.countStmts(i.([]ast.Stmt)) } diff --git a/vendor/github.com/mgechev/revive/rule/import-alias-naming.go b/vendor/github.com/mgechev/revive/rule/import-alias-naming.go index 292392b5d..a6d096c8b 100644 --- a/vendor/github.com/mgechev/revive/rule/import-alias-naming.go +++ b/vendor/github.com/mgechev/revive/rule/import-alias-naming.go @@ -10,14 +10,15 @@ import ( // ImportAliasNamingRule lints import alias naming. type ImportAliasNamingRule struct { - configured bool - namingRuleRegexp *regexp.Regexp + configured bool + allowRegexp *regexp.Regexp + denyRegexp *regexp.Regexp sync.Mutex } -const defaultNamingRule = "^[a-z][a-z0-9]{0,}$" +const defaultImportAliasNamingAllowRule = "^[a-z][a-z0-9]{0,}$" -var defaultNamingRuleRegexp = regexp.MustCompile(defaultNamingRule) +var defaultImportAliasNamingAllowRegexp = regexp.MustCompile(defaultImportAliasNamingAllowRule) func (r *ImportAliasNamingRule) configure(arguments lint.Arguments) { r.Lock() @@ -26,20 +27,31 @@ func (r *ImportAliasNamingRule) configure(arguments lint.Arguments) { return } - if len(arguments) < 1 { - r.namingRuleRegexp = defaultNamingRuleRegexp + if len(arguments) == 0 { + r.allowRegexp = defaultImportAliasNamingAllowRegexp return } - namingRule, ok := arguments[0].(string) // Alt. non panicking version - if !ok { - panic(fmt.Sprintf("Invalid argument '%v' for 'import-alias-naming' rule. Expecting string, got %T", arguments[0], arguments[0])) + switch namingRule := arguments[0].(type) { + case string: + r.setAllowRule(namingRule) + case map[string]any: // expecting map[string]string + for k, v := range namingRule { + switch k { + case "allowRegex": + r.setAllowRule(v) + case "denyRegex": + r.setDenyRule(v) + default: + panic(fmt.Sprintf("Invalid map key for 'import-alias-naming' rule. Expecting 'allowRegex' or 'denyRegex', got %v", k)) + } + } + default: + panic(fmt.Sprintf("Invalid argument '%v' for 'import-alias-naming' rule. Expecting string or map[string]string, got %T", arguments[0], arguments[0])) } - var err error - r.namingRuleRegexp, err = regexp.Compile(namingRule) - if err != nil { - panic(fmt.Sprintf("Invalid argument to the import-alias-naming rule. Expecting %q to be a valid regular expression, got: %v", namingRule, err)) + if r.allowRegexp == nil && r.denyRegexp == nil { + r.allowRegexp = defaultImportAliasNamingAllowRegexp } } @@ -56,14 +68,23 @@ func (r *ImportAliasNamingRule) Apply(file *lint.File, arguments lint.Arguments) } alias := is.Name - if alias == nil || alias.Name == "_" { + if alias == nil || alias.Name == "_" || alias.Name == "." { // "_" and "." are special types of import aiases and should be processed by another linter rule continue } - if !r.namingRuleRegexp.MatchString(alias.Name) { + if r.allowRegexp != nil && !r.allowRegexp.MatchString(alias.Name) { + failures = append(failures, lint.Failure{ + Confidence: 1, + Failure: fmt.Sprintf("import name (%s) must match the regular expression: %s", alias.Name, r.allowRegexp.String()), + Node: alias, + Category: "imports", + }) + } + + if r.denyRegexp != nil && r.denyRegexp.MatchString(alias.Name) { failures = append(failures, lint.Failure{ Confidence: 1, - Failure: fmt.Sprintf("import name (%s) must match the regular expression: %s", alias.Name, r.namingRuleRegexp.String()), + Failure: fmt.Sprintf("import name (%s) must NOT match the regular expression: %s", alias.Name, r.denyRegexp.String()), Node: alias, Category: "imports", }) @@ -77,3 +98,29 @@ func (r *ImportAliasNamingRule) Apply(file *lint.File, arguments lint.Arguments) func (*ImportAliasNamingRule) Name() string { return "import-alias-naming" } + +func (r *ImportAliasNamingRule) setAllowRule(value any) { + namingRule, ok := value.(string) + if !ok { + panic(fmt.Sprintf("Invalid argument '%v' for import-alias-naming allowRegexp rule. Expecting string, got %T", value, value)) + } + + namingRuleRegexp, err := regexp.Compile(namingRule) + if err != nil { + panic(fmt.Sprintf("Invalid argument to the import-alias-naming allowRegexp rule. Expecting %q to be a valid regular expression, got: %v", namingRule, err)) + } + r.allowRegexp = namingRuleRegexp +} + +func (r *ImportAliasNamingRule) setDenyRule(value any) { + namingRule, ok := value.(string) + if !ok { + panic(fmt.Sprintf("Invalid argument '%v' for import-alias-naming denyRegexp rule. Expecting string, got %T", value, value)) + } + + namingRuleRegexp, err := regexp.Compile(namingRule) + if err != nil { + panic(fmt.Sprintf("Invalid argument to the import-alias-naming denyRegexp rule. Expecting %q to be a valid regular expression, got: %v", namingRule, err)) + } + r.denyRegexp = namingRuleRegexp +} diff --git a/vendor/github.com/mgechev/revive/rule/indent-error-flow.go b/vendor/github.com/mgechev/revive/rule/indent-error-flow.go index b80e6486c..294ceef84 100644 --- a/vendor/github.com/mgechev/revive/rule/indent-error-flow.go +++ b/vendor/github.com/mgechev/revive/rule/indent-error-flow.go @@ -19,7 +19,7 @@ func (*IndentErrorFlowRule) Name() string { } // CheckIfElse evaluates the rule against an ifelse.Chain. -func (e *IndentErrorFlowRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) { +func (*IndentErrorFlowRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) { if !chain.If.Deviates() { // this rule only applies if the if-block deviates control flow return diff --git a/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go b/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go index 34e651557..e9e64b9a6 100644 --- a/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go +++ b/vendor/github.com/mgechev/revive/rule/modifies-value-receiver.go @@ -78,11 +78,6 @@ func (w lintModifiesValRecRule) Visit(node ast.Node) ast.Visitor { if name == "" || name != receiverName { continue } - - if w.skipType(ast.Expr(e.Sel)) { - continue - } - case *ast.Ident: // receiver := ... if e.Name != receiverName { continue @@ -97,7 +92,7 @@ func (w lintModifiesValRecRule) Visit(node ast.Node) ast.Visitor { return false } - assignmentsToReceiver := pick(n.Body, fselect, nil) + assignmentsToReceiver := pick(n.Body, fselect) for _, assignment := range assignmentsToReceiver { w.onFailure(lint.Failure{ diff --git a/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go b/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go index 88928bb98..841bde56c 100644 --- a/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go +++ b/vendor/github.com/mgechev/revive/rule/optimize-operands-order.go @@ -54,13 +54,13 @@ func (w lintOptimizeOperandsOrderlExpr) Visit(node ast.Node) ast.Visitor { } // check if the left sub-expression contains a function call - nodes := pick(binExpr.X, isCaller, nil) + nodes := pick(binExpr.X, isCaller) if len(nodes) < 1 { return w } // check if the right sub-expression does not contain a function call - nodes = pick(binExpr.Y, isCaller, nil) + nodes = pick(binExpr.Y, isCaller) if len(nodes) > 0 { return w } diff --git a/vendor/github.com/mgechev/revive/rule/string-format.go b/vendor/github.com/mgechev/revive/rule/string-format.go index 3edd62477..70edf7387 100644 --- a/vendor/github.com/mgechev/revive/rule/string-format.go +++ b/vendor/github.com/mgechev/revive/rule/string-format.go @@ -38,7 +38,7 @@ func (*StringFormatRule) Name() string { // ParseArgumentsTest is a public wrapper around w.parseArguments used for testing. Returns the error message provided to panic, or nil if no error was encountered func (StringFormatRule) ParseArgumentsTest(arguments lint.Arguments) *string { w := lintStringFormatRule{} - c := make(chan interface{}) + c := make(chan any) // Parse the arguments in a goroutine, defer a recover() call, return the error encountered (or nil if there was no error) go func() { defer func() { @@ -101,8 +101,8 @@ func (w *lintStringFormatRule) parseArguments(arguments lint.Arguments) { } } -func (w lintStringFormatRule) parseArgument(argument interface{}, ruleNum int) (scope stringFormatSubruleScope, regex *regexp.Regexp, negated bool, errorMessage string) { - g, ok := argument.([]interface{}) // Cast to generic slice first +func (w lintStringFormatRule) parseArgument(argument any, ruleNum int) (scope stringFormatSubruleScope, regex *regexp.Regexp, negated bool, errorMessage string) { + g, ok := argument.([]any) // Cast to generic slice first if !ok { w.configError("argument is not a slice", ruleNum, 0) } diff --git a/vendor/github.com/mgechev/revive/rule/struct-tag.go b/vendor/github.com/mgechev/revive/rule/struct-tag.go index d1c8056aa..f6ee47a73 100644 --- a/vendor/github.com/mgechev/revive/rule/struct-tag.go +++ b/vendor/github.com/mgechev/revive/rule/struct-tag.go @@ -140,7 +140,7 @@ func (lintStructTagRule) getTagName(tag *structtag.Tag) string { return strings.TrimPrefix(option, "name=") } } - return "" //protobuf tag lacks 'name' option + return "" // protobuf tag lacks 'name' option default: return tag.Name } diff --git a/vendor/github.com/mgechev/revive/rule/superfluous-else.go b/vendor/github.com/mgechev/revive/rule/superfluous-else.go index 1ef67bf1a..2aa1b6b2c 100644 --- a/vendor/github.com/mgechev/revive/rule/superfluous-else.go +++ b/vendor/github.com/mgechev/revive/rule/superfluous-else.go @@ -20,7 +20,7 @@ func (*SuperfluousElseRule) Name() string { } // CheckIfElse evaluates the rule against an ifelse.Chain. -func (e *SuperfluousElseRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) { +func (*SuperfluousElseRule) CheckIfElse(chain ifelse.Chain, args ifelse.Args) (failMsg string) { if !chain.If.Deviates() { // this rule only applies if the if-block deviates control flow return diff --git a/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go b/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go index bad907533..9ac2648cd 100644 --- a/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go +++ b/vendor/github.com/mgechev/revive/rule/unconditional-recursion.go @@ -45,8 +45,9 @@ type funcStatus struct { } type lintUnconditionalRecursionRule struct { - onFailure func(lint.Failure) - currentFunc *funcStatus + onFailure func(lint.Failure) + currentFunc *funcStatus + inGoStatement bool } // Visit will traverse the file AST. @@ -68,9 +69,13 @@ func (w lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor { default: rec = n.Recv.List[0].Names[0] } - w.currentFunc = &funcStatus{&funcDesc{rec, n.Name}, false} case *ast.CallExpr: + // check if call arguments has a recursive call + for _, arg := range n.Args { + ast.Walk(w, arg) + } + var funcID *ast.Ident var selector *ast.Ident switch c := n.Fun.(type) { @@ -84,6 +89,9 @@ func (w lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor { return nil } funcID = c.Sel + case *ast.FuncLit: + ast.Walk(w, c.Body) // analyze the body of the function literal + return nil default: return w } @@ -93,11 +101,12 @@ func (w lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor { w.currentFunc.funcDesc.equal(&funcDesc{selector, funcID}) { w.onFailure(lint.Failure{ Category: "logic", - Confidence: 1, + Confidence: 0.8, Node: n, Failure: "unconditional recursive call", }) } + return nil case *ast.IfStmt: w.updateFuncStatus(n.Body) w.updateFuncStatus(n.Else) @@ -115,16 +124,21 @@ func (w lintUnconditionalRecursionRule) Visit(node ast.Node) ast.Visitor { w.updateFuncStatus(n.Body) return nil case *ast.GoStmt: - for _, a := range n.Call.Args { - ast.Walk(w, a) // check if arguments have a recursive call - } - return nil // recursive async call is not an issue + w.inGoStatement = true + ast.Walk(w, n.Call) + w.inGoStatement = false + return nil case *ast.ForStmt: if n.Cond != nil { return nil } // unconditional loop return w + case *ast.FuncLit: + if w.inGoStatement { + return w + } + return nil // literal call (closure) is not necessarily an issue } return w @@ -181,5 +195,5 @@ func (lintUnconditionalRecursionRule) hasControlExit(node ast.Node) bool { return false } - return len(pick(node, isExit, nil)) != 0 + return len(pick(node, isExit)) != 0 } diff --git a/vendor/github.com/mgechev/revive/rule/unused-param.go b/vendor/github.com/mgechev/revive/rule/unused-param.go index df6cd9af0..63eab3705 100644 --- a/vendor/github.com/mgechev/revive/rule/unused-param.go +++ b/vendor/github.com/mgechev/revive/rule/unused-param.go @@ -35,7 +35,7 @@ func (r *UnusedParamRule) configure(args lint.Arguments) { r.failureMsg = "parameter '%s' seems to be unused, consider removing or renaming it as _" } else { // Arguments = [{}] - options := args[0].(map[string]interface{}) + options := args[0].(map[string]any) // Arguments = [{allowedRegex="^_"}] if allowedRegexParam, ok := options["allowRegex"]; ok { @@ -113,7 +113,7 @@ func (w lintUnusedParamRule) Visit(node ast.Node) ast.Visitor { return false } - _ = pick(n.Body, fselect, nil) + _ = pick(n.Body, fselect) for _, p := range n.Type.Params.List { for _, n := range p.Names { diff --git a/vendor/github.com/mgechev/revive/rule/unused-receiver.go b/vendor/github.com/mgechev/revive/rule/unused-receiver.go index 488572b7b..715dba338 100644 --- a/vendor/github.com/mgechev/revive/rule/unused-receiver.go +++ b/vendor/github.com/mgechev/revive/rule/unused-receiver.go @@ -35,7 +35,7 @@ func (r *UnusedReceiverRule) configure(args lint.Arguments) { r.failureMsg = "method receiver '%s' is not referenced in method's body, consider removing or renaming it as _" } else { // Arguments = [{}] - options := args[0].(map[string]interface{}) + options := args[0].(map[string]any) // Arguments = [{allowedRegex="^_"}] if allowedRegexParam, ok := options["allowRegex"]; ok { @@ -113,7 +113,7 @@ func (w lintUnusedReceiverRule) Visit(node ast.Node) ast.Visitor { return isAnID && ident.Obj == recID.Obj } - refs2recID := pick(n.Body, fselect, nil) + refs2recID := pick(n.Body, fselect) if len(refs2recID) > 0 { return nil // the receiver is referenced in the func body diff --git a/vendor/github.com/mgechev/revive/rule/utils.go b/vendor/github.com/mgechev/revive/rule/utils.go index dca1674ca..5778e7696 100644 --- a/vendor/github.com/mgechev/revive/rule/utils.go +++ b/vendor/github.com/mgechev/revive/rule/utils.go @@ -93,21 +93,15 @@ func srcLine(src []byte, p token.Position) string { // pick yields a list of nodes by picking them from a sub-ast with root node n. // Nodes are selected by applying the fselect function -// f function is applied to each selected node before inserting it in the final result. -// If f==nil then it defaults to the identity function (ie it returns the node itself) -func pick(n ast.Node, fselect func(n ast.Node) bool, f func(n ast.Node) []ast.Node) []ast.Node { +func pick(n ast.Node, fselect func(n ast.Node) bool) []ast.Node { var result []ast.Node if n == nil { return result } - if f == nil { - f = func(n ast.Node) []ast.Node { return []ast.Node{n} } - } - onSelect := func(n ast.Node) { - result = append(result, f(n)...) + result = append(result, n) } p := picker{fselect: fselect, onSelect: onSelect} ast.Walk(p, n) @@ -158,7 +152,7 @@ func isExprABooleanLit(n ast.Node) (lexeme string, ok bool) { } // gofmt returns a string representation of an AST subtree. -func gofmt(x interface{}) string { +func gofmt(x any) string { buf := bytes.Buffer{} fs := token.NewFileSet() printer.Fprint(&buf, fs, x) diff --git a/vendor/github.com/mgechev/revive/rule/var-naming.go b/vendor/github.com/mgechev/revive/rule/var-naming.go index 286ff9d75..8dfba5b41 100644 --- a/vendor/github.com/mgechev/revive/rule/var-naming.go +++ b/vendor/github.com/mgechev/revive/rule/var-naming.go @@ -18,10 +18,11 @@ var upperCaseConstRE = regexp.MustCompile(`^_?[A-Z][A-Z\d]*(_[A-Z\d]+)*$`) // VarNamingRule lints given else constructs. type VarNamingRule struct { - configured bool - whitelist []string - blacklist []string - upperCaseConst bool // if true - allows to use UPPER_SOME_NAMES for constants + configured bool + whitelist []string + blacklist []string + upperCaseConst bool // if true - allows to use UPPER_SOME_NAMES for constants + skipPackageNameChecks bool sync.Mutex } @@ -44,19 +45,41 @@ func (r *VarNamingRule) configure(arguments lint.Arguments) { if len(arguments) >= 3 { // not pretty code because should keep compatibility with TOML (no mixed array types) and new map parameters thirdArgument := arguments[2] - asSlice, ok := thirdArgument.([]interface{}) + asSlice, ok := thirdArgument.([]any) if !ok { panic(fmt.Sprintf("Invalid third argument to the var-naming rule. Expecting a %s of type slice, got %T", "options", arguments[2])) } if len(asSlice) != 1 { panic(fmt.Sprintf("Invalid third argument to the var-naming rule. Expecting a %s of type slice, of len==1, but %d", "options", len(asSlice))) } - args, ok := asSlice[0].(map[string]interface{}) + args, ok := asSlice[0].(map[string]any) if !ok { panic(fmt.Sprintf("Invalid third argument to the var-naming rule. Expecting a %s of type slice, of len==1, with map, but %T", "options", asSlice[0])) } r.upperCaseConst = fmt.Sprint(args["upperCaseConst"]) == "true" + r.skipPackageNameChecks = fmt.Sprint(args["skipPackageNameChecks"]) == "true" + } +} + +func (r *VarNamingRule) applyPackageCheckRules(walker *lintNames) { + // Package names need slightly different handling than other names. + if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") { + walker.onFailure(lint.Failure{ + Failure: "don't use an underscore in package name", + Confidence: 1, + Node: walker.fileAst.Name, + Category: "naming", + }) + } + if anyCapsRE.MatchString(walker.fileAst.Name.Name) { + walker.onFailure(lint.Failure{ + Failure: fmt.Sprintf("don't use MixedCaps in package name; %s should be %s", walker.fileAst.Name.Name, strings.ToLower(walker.fileAst.Name.Name)), + Confidence: 1, + Node: walker.fileAst.Name, + Category: "naming", + }) } + } // Apply applies the rule to given file. @@ -78,22 +101,8 @@ func (r *VarNamingRule) Apply(file *lint.File, arguments lint.Arguments) []lint. upperCaseConst: r.upperCaseConst, } - // Package names need slightly different handling than other names. - if strings.Contains(walker.fileAst.Name.Name, "_") && !strings.HasSuffix(walker.fileAst.Name.Name, "_test") { - walker.onFailure(lint.Failure{ - Failure: "don't use an underscore in package name", - Confidence: 1, - Node: walker.fileAst.Name, - Category: "naming", - }) - } - if anyCapsRE.MatchString(walker.fileAst.Name.Name) { - walker.onFailure(lint.Failure{ - Failure: fmt.Sprintf("don't use MixedCaps in package name; %s should be %s", walker.fileAst.Name.Name, strings.ToLower(walker.fileAst.Name.Name)), - Confidence: 1, - Node: walker.fileAst.Name, - Category: "naming", - }) + if !r.skipPackageNameChecks { + r.applyPackageCheckRules(&walker) } ast.Walk(&walker, fileAst) @@ -127,7 +136,7 @@ func (w *lintNames) check(id *ast.Ident, thing string) { // #851 upperCaseConst support // if it's const - if thing == token.CONST.String() && w.upperCaseConst && upperCaseConstRE.Match([]byte(id.Name)) { + if thing == token.CONST.String() && w.upperCaseConst && upperCaseConstRE.MatchString(id.Name) { return } @@ -255,8 +264,8 @@ func (w *lintNames) Visit(n ast.Node) ast.Visitor { return w } -func getList(arg interface{}, argName string) []string { - temp, ok := arg.([]interface{}) +func getList(arg any, argName string) []string { + temp, ok := arg.([]any) if !ok { panic(fmt.Sprintf("Invalid argument to the var-naming rule. Expecting a %s of type slice with initialisms, got %T", argName, arg)) } diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index b18efb743..948a3ee63 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -4,6 +4,9 @@ // Package errgroup provides synchronization, error propagation, and Context // cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. package errgroup import ( diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 6202638ba..c6492020e 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -248,6 +248,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -283,10 +284,6 @@ struct ltchars { #include #endif -#ifndef MSG_FASTOPEN -#define MSG_FASTOPEN 0x20000000 -#endif - #ifndef PTRACE_GETREGS #define PTRACE_GETREGS 0xc #endif @@ -295,14 +292,6 @@ struct ltchars { #define PTRACE_SETREGS 0xd #endif -#ifndef SOL_NETLINK -#define SOL_NETLINK 270 -#endif - -#ifndef SOL_SMC -#define SOL_SMC 286 -#endif - #ifdef SOL_BLUETOOTH // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // but it is already in bluetooth_linux.go @@ -319,10 +308,23 @@ struct ltchars { #undef TIPC_WAIT_FOREVER #define TIPC_WAIT_FOREVER 0xffffffff -// Copied from linux/l2tp.h -// Including linux/l2tp.h here causes conflicts between linux/in.h -// and netinet/in.h included via net/route.h above. -#define IPPROTO_L2TP 115 +// Copied from linux/netfilter/nf_nat.h +// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h +// and netinet/in.h. +#define NF_NAT_RANGE_MAP_IPS (1 << 0) +#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1) +#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) +#define NF_NAT_RANGE_PERSISTENT (1 << 3) +#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4) +#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5) +#define NF_NAT_RANGE_NETMAP (1 << 6) +#define NF_NAT_RANGE_PROTO_RANDOM_ALL \ + (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY) +#define NF_NAT_RANGE_MASK \ + (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \ + NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \ + NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \ + NF_NAT_RANGE_NETMAP) // Copied from linux/hid.h. // Keep in sync with the size of the referenced fields. @@ -603,6 +605,9 @@ ccflags="$@" $2 ~ /^FSOPT_/ || $2 ~ /^WDIO[CFS]_/ || $2 ~ /^NFN/ || + $2 !~ /^NFT_META_IIFTYPE/ && + $2 ~ /^NFT_/ || + $2 ~ /^NF_NAT_/ || $2 ~ /^XDP_/ || $2 ~ /^RWF_/ || $2 ~ /^(HDIO|WIN|SMART)_/ || diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index c73cfe2f1..a5d3ff8df 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2127,6 +2127,60 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_CHAIN_FLAGS = 0x7 + NFT_CHAIN_MAXNAMELEN = 0x100 + NFT_CT_MAX = 0x17 + NFT_DATA_RESERVED_MASK = 0xffffff00 + NFT_DATA_VALUE_MAXLEN = 0x40 + NFT_EXTHDR_OP_MAX = 0x4 + NFT_FIB_RESULT_MAX = 0x3 + NFT_INNER_MASK = 0xf + NFT_LOGLEVEL_MAX = 0x8 + NFT_NAME_MAXLEN = 0x100 + NFT_NG_MAX = 0x1 + NFT_OBJECT_CONNLIMIT = 0x5 + NFT_OBJECT_COUNTER = 0x1 + NFT_OBJECT_CT_EXPECT = 0x9 + NFT_OBJECT_CT_HELPER = 0x3 + NFT_OBJECT_CT_TIMEOUT = 0x7 + NFT_OBJECT_LIMIT = 0x4 + NFT_OBJECT_MAX = 0xa + NFT_OBJECT_QUOTA = 0x2 + NFT_OBJECT_SECMARK = 0x8 + NFT_OBJECT_SYNPROXY = 0xa + NFT_OBJECT_TUNNEL = 0x6 + NFT_OBJECT_UNSPEC = 0x0 + NFT_OBJ_MAXNAMELEN = 0x100 + NFT_OSF_MAXGENRELEN = 0x10 + NFT_QUEUE_FLAG_BYPASS = 0x1 + NFT_QUEUE_FLAG_CPU_FANOUT = 0x2 + NFT_QUEUE_FLAG_MASK = 0x3 + NFT_REG32_COUNT = 0x10 + NFT_REG32_SIZE = 0x4 + NFT_REG_MAX = 0x4 + NFT_REG_SIZE = 0x10 + NFT_REJECT_ICMPX_MAX = 0x3 + NFT_RT_MAX = 0x4 + NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SET_MAXNAMELEN = 0x100 + NFT_SOCKET_MAX = 0x3 + NFT_TABLE_F_MASK = 0x3 + NFT_TABLE_MAXNAMELEN = 0x100 + NFT_TRACETYPE_MAX = 0x3 + NFT_TUNNEL_F_MASK = 0x7 + NFT_TUNNEL_MAX = 0x1 + NFT_TUNNEL_MODE_MAX = 0x2 + NFT_USERDATA_MAXLEN = 0x100 + NFT_XFRM_KEY_MAX = 0x6 + NF_NAT_RANGE_MAP_IPS = 0x1 + NF_NAT_RANGE_MASK = 0x7f + NF_NAT_RANGE_NETMAP = 0x40 + NF_NAT_RANGE_PERSISTENT = 0x8 + NF_NAT_RANGE_PROTO_OFFSET = 0x20 + NF_NAT_RANGE_PROTO_RANDOM = 0x4 + NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14 + NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10 + NF_NAT_RANGE_PROTO_SPECIFIED = 0x2 NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index a1d061597..9dc42410b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 5b2a74097..0d3a0751c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index f6eda1344..c39f7776d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 55df20ae9..57571d072 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 8c1155cbc..e62963e67 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 7cc80c58d..00831354c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 0688737f4..79029ed58 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 47dc57967..ffb8708cc 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -194,6 +194,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW //sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) //sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimePreciseAsFileTime(time *Filetime) //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 146a1f019..e8791c82c 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -342,6 +342,7 @@ var ( procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") procSetErrorMode = modkernel32.NewProc("SetErrorMode") procSetEvent = modkernel32.NewProc("SetEvent") @@ -2988,6 +2989,14 @@ func SetEndOfFile(handle Handle) (err error) { return } +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) if r1 == 0 { diff --git a/vendor/google.golang.org/api/iamcredentials/v1/iamcredentials-gen.go b/vendor/google.golang.org/api/iamcredentials/v1/iamcredentials-gen.go index 5dfff4cb2..386999cb5 100644 --- a/vendor/google.golang.org/api/iamcredentials/v1/iamcredentials-gen.go +++ b/vendor/google.golang.org/api/iamcredentials/v1/iamcredentials-gen.go @@ -1,4 +1,4 @@ -// Copyright 2023 Google LLC. +// Copyright 2024 Google LLC. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/google.golang.org/api/internal/settings.go b/vendor/google.golang.org/api/internal/settings.go index 3356fa97b..285e6e04d 100644 --- a/vendor/google.golang.org/api/internal/settings.go +++ b/vendor/google.golang.org/api/internal/settings.go @@ -27,6 +27,7 @@ const ( type DialSettings struct { Endpoint string DefaultEndpoint string + DefaultEndpointTemplate string DefaultMTLSEndpoint string Scopes []string DefaultScopes []string diff --git a/vendor/google.golang.org/api/internal/version.go b/vendor/google.golang.org/api/internal/version.go index 104a91132..b645b3eae 100644 --- a/vendor/google.golang.org/api/internal/version.go +++ b/vendor/google.golang.org/api/internal/version.go @@ -5,4 +5,4 @@ package internal // Version is the current tagged release of the library. -const Version = "0.154.0" +const Version = "0.155.0" diff --git a/vendor/google.golang.org/api/option/internaloption/internaloption.go b/vendor/google.golang.org/api/option/internaloption/internaloption.go index 3fdee095c..c15be9faa 100644 --- a/vendor/google.golang.org/api/option/internaloption/internaloption.go +++ b/vendor/google.golang.org/api/option/internaloption/internaloption.go @@ -22,10 +22,29 @@ func (o defaultEndpointOption) Apply(settings *internal.DialSettings) { // It should only be used internally by generated clients. // // This is similar to WithEndpoint, but allows us to determine whether the user has overridden the default endpoint. +// +// Deprecated: WithDefaultEndpoint does not support setting the universe domain. +// Use WithDefaultEndpointTemplate and WithDefaultUniverseDomain to compose the +// default endpoint instead. func WithDefaultEndpoint(url string) option.ClientOption { return defaultEndpointOption(url) } +type defaultEndpointTemplateOption string + +func (o defaultEndpointTemplateOption) Apply(settings *internal.DialSettings) { + settings.DefaultEndpointTemplate = string(o) +} + +// WithDefaultEndpointTemplate provides a template for creating the endpoint +// using a universe domain. See also WithDefaultUniverseDomain and +// option.WithUniverseDomain. +// +// It should only be used internally by generated clients. +func WithDefaultEndpointTemplate(url string) option.ClientOption { + return defaultEndpointTemplateOption(url) +} + type defaultMTLSEndpointOption string func (o defaultMTLSEndpointOption) Apply(settings *internal.DialSettings) { diff --git a/vendor/google.golang.org/api/storage/v1/storage-gen.go b/vendor/google.golang.org/api/storage/v1/storage-gen.go index c4331c04d..cbd777b15 100644 --- a/vendor/google.golang.org/api/storage/v1/storage-gen.go +++ b/vendor/google.golang.org/api/storage/v1/storage-gen.go @@ -1,4 +1,4 @@ -// Copyright 2023 Google LLC. +// Copyright 2024 Google LLC. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/vendor/google.golang.org/api/transport/grpc/dial.go b/vendor/google.golang.org/api/transport/grpc/dial.go index 34f9ba8bd..10830f016 100644 --- a/vendor/google.golang.org/api/transport/grpc/dial.go +++ b/vendor/google.golang.org/api/transport/grpc/dial.go @@ -14,6 +14,7 @@ import ( "net" "os" "strings" + "sync" "time" "cloud.google.com/go/compute/metadata" @@ -27,6 +28,7 @@ import ( grpcgoogle "google.golang.org/grpc/credentials/google" grpcinsecure "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/oauth" + "google.golang.org/grpc/stats" // Install grpclb, which is required for direct path. _ "google.golang.org/grpc/balancer/grpclb" @@ -47,6 +49,26 @@ var logRateLimiter = rate.Sometimes{Interval: 1 * time.Second} // Assign to var for unit test replacement var dialContext = grpc.DialContext +// otelStatsHandler is a singleton otelgrpc.clientHandler to be used across +// all dial connections to avoid the memory leak documented in +// https://github.com/open-telemetry/opentelemetry-go-contrib/issues/4226 +// +// TODO: If 4226 has been fixed in opentelemetry-go-contrib, replace this +// singleton with inline usage for simplicity. +var ( + initOtelStatsHandlerOnce sync.Once + otelStatsHandler stats.Handler +) + +// otelGRPCStatsHandler returns singleton otelStatsHandler for reuse across all +// dial connections. +func otelGRPCStatsHandler() stats.Handler { + initOtelStatsHandlerOnce.Do(func() { + otelStatsHandler = otelgrpc.NewClientHandler() + }) + return otelStatsHandler +} + // Dial returns a GRPC connection for use communicating with a Google cloud // service, configured with the given ClientOptions. func Dial(ctx context.Context, opts ...option.ClientOption) (*grpc.ClientConn, error) { @@ -146,52 +168,56 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C // when dialing an insecure connection? if !o.NoAuth && !insecure { if o.APIKey != "" { - log.Print("API keys are not supported for gRPC APIs. Remove the WithAPIKey option from your client-creating call.") - } - creds, err := internal.Creds(ctx, o) - if err != nil { - return nil, err - } - - grpcOpts = append(grpcOpts, - grpc.WithPerRPCCredentials(grpcTokenSource{ - TokenSource: oauth.TokenSource{creds.TokenSource}, - quotaProject: internal.GetQuotaProject(creds, o.QuotaProject), + grpcOpts = append(grpcOpts, grpc.WithPerRPCCredentials(grpcAPIKey{ + apiKey: o.APIKey, requestReason: o.RequestReason, - }), - ) - - // Attempt Direct Path: - logRateLimiter.Do(func() { - logDirectPathMisconfig(endpoint, creds.TokenSource, o) - }) - if isDirectPathEnabled(endpoint, o) && isTokenSourceDirectPathCompatible(creds.TokenSource, o) && metadata.OnGCE() { - // Overwrite all of the previously specific DialOptions, DirectPath uses its own set of credentials and certificates. - grpcOpts = []grpc.DialOption{ - grpc.WithCredentialsBundle(grpcgoogle.NewDefaultCredentialsWithOptions(grpcgoogle.DefaultCredentialsOptions{oauth.TokenSource{creds.TokenSource}}))} - if timeoutDialerOption != nil { - grpcOpts = append(grpcOpts, timeoutDialerOption) + })) + } else { + creds, err := internal.Creds(ctx, o) + if err != nil { + return nil, err } - // Check if google-c2p resolver is enabled for DirectPath - if isDirectPathXdsUsed(o) { - // google-c2p resolver target must not have a port number - if addr, _, err := net.SplitHostPort(endpoint); err == nil { - endpoint = "google-c2p:///" + addr - } else { - endpoint = "google-c2p:///" + endpoint + grpcOpts = append(grpcOpts, grpc.WithPerRPCCredentials(grpcTokenSource{ + TokenSource: oauth.TokenSource{TokenSource: creds.TokenSource}, + quotaProject: internal.GetQuotaProject(creds, o.QuotaProject), + requestReason: o.RequestReason, + })) + // Attempt Direct Path: + logRateLimiter.Do(func() { + logDirectPathMisconfig(endpoint, creds.TokenSource, o) + }) + if isDirectPathEnabled(endpoint, o) && isTokenSourceDirectPathCompatible(creds.TokenSource, o) && metadata.OnGCE() { + // Overwrite all of the previously specific DialOptions, DirectPath uses its own set of credentials and certificates. + grpcOpts = []grpc.DialOption{ + grpc.WithCredentialsBundle(grpcgoogle.NewDefaultCredentialsWithOptions( + grpcgoogle.DefaultCredentialsOptions{ + PerRPCCreds: oauth.TokenSource{TokenSource: creds.TokenSource}, + })), } - } else { - if !strings.HasPrefix(endpoint, "dns:///") { - endpoint = "dns:///" + endpoint + if timeoutDialerOption != nil { + grpcOpts = append(grpcOpts, timeoutDialerOption) + } + // Check if google-c2p resolver is enabled for DirectPath + if isDirectPathXdsUsed(o) { + // google-c2p resolver target must not have a port number + if addr, _, err := net.SplitHostPort(endpoint); err == nil { + endpoint = "google-c2p:///" + addr + } else { + endpoint = "google-c2p:///" + endpoint + } + } else { + if !strings.HasPrefix(endpoint, "dns:///") { + endpoint = "dns:///" + endpoint + } + grpcOpts = append(grpcOpts, + // For now all DirectPath go clients will be using the following lb config, but in future + // when different services need different configs, then we should change this to a + // per-service config. + grpc.WithDisableServiceConfig(), + grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"grpclb":{"childPolicy":[{"pick_first":{}}]}}]}`)) } - grpcOpts = append(grpcOpts, - // For now all DirectPath go clients will be using the following lb config, but in future - // when different services need different configs, then we should change this to a - // per-service config. - grpc.WithDisableServiceConfig(), - grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"grpclb":{"childPolicy":[{"pick_first":{}}]}}]}`)) + // TODO(cbro): add support for system parameters (quota project, request reason) via chained interceptor. } - // TODO(cbro): add support for system parameters (quota project, request reason) via chained interceptor. } } @@ -219,7 +245,7 @@ func addOpenTelemetryStatsHandler(opts []grpc.DialOption, settings *internal.Dia if settings.TelemetryDisabled { return opts } - return append(opts, grpc.WithStatsHandler(otelgrpc.NewClientHandler())) + return append(opts, grpc.WithStatsHandler(otelGRPCStatsHandler())) } // grpcTokenSource supplies PerRPCCredentials from an oauth.TokenSource. @@ -249,6 +275,31 @@ func (ts grpcTokenSource) GetRequestMetadata(ctx context.Context, uri ...string) return metadata, nil } +// grpcAPIKey supplies PerRPCCredentials from an API Key. +type grpcAPIKey struct { + apiKey string + + // Additional metadata attached as headers. + requestReason string +} + +// GetRequestMetadata gets the request metadata as a map from a grpcAPIKey. +func (ts grpcAPIKey) GetRequestMetadata(ctx context.Context, uri ...string) ( + map[string]string, error) { + metadata := map[string]string{ + "X-goog-api-key": ts.apiKey, + } + if ts.requestReason != "" { + metadata["X-goog-request-reason"] = ts.requestReason + } + return metadata, nil +} + +// RequireTransportSecurity indicates whether the credentials requires transport security. +func (ts grpcAPIKey) RequireTransportSecurity() bool { + return true +} + func isDirectPathEnabled(endpoint string, o *internal.DialSettings) bool { if !o.EnableDirectPath { return false diff --git a/vendor/modules.txt b/vendor/modules.txt index 3434b9b6d..2351e2dd0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -62,11 +62,12 @@ github.com/BurntSushi/toml/internal # github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 ## explicit; go 1.13 github.com/Djarvur/go-err113 -# github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 -## explicit; go 1.20 +# github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 +## explicit; go 1.21 github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer -github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields +github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern +github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure # github.com/Masterminds/semver v1.5.0 ## explicit github.com/Masterminds/semver @@ -95,7 +96,7 @@ github.com/ashanbrown/forbidigo/forbidigo # github.com/ashanbrown/makezero v1.1.1 ## explicit; go 1.12 github.com/ashanbrown/makezero/makezero -# github.com/aws/aws-sdk-go v1.49.13 +# github.com/aws/aws-sdk-go v1.49.16 ## explicit; go 1.19 github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws/arn @@ -217,7 +218,7 @@ github.com/cloudfoundry/bosh-agent/agentclient/applyspec github.com/cloudfoundry/bosh-agent/agentclient/fakes github.com/cloudfoundry/bosh-agent/agentclient/http github.com/cloudfoundry/bosh-agent/agentclient/http/mocks -# github.com/cloudfoundry/bosh-davcli v0.0.300 +# github.com/cloudfoundry/bosh-davcli v0.0.301 ## explicit; go 1.21 github.com/cloudfoundry/bosh-davcli/client github.com/cloudfoundry/bosh-davcli/client/fakes @@ -227,11 +228,11 @@ github.com/cloudfoundry/bosh-davcli/signer ## explicit; go 1.21 github.com/cloudfoundry/bosh-gcscli/client github.com/cloudfoundry/bosh-gcscli/config -# github.com/cloudfoundry/bosh-s3cli v0.0.247 +# github.com/cloudfoundry/bosh-s3cli v0.0.248 ## explicit; go 1.21 github.com/cloudfoundry/bosh-s3cli/client github.com/cloudfoundry/bosh-s3cli/config -# github.com/cloudfoundry/bosh-utils v0.0.419 +# github.com/cloudfoundry/bosh-utils v0.0.420 ## explicit; go 1.21 github.com/cloudfoundry/bosh-utils/blobstore github.com/cloudfoundry/bosh-utils/blobstore/fakes @@ -251,14 +252,14 @@ github.com/cloudfoundry/bosh-utils/system/fakes github.com/cloudfoundry/bosh-utils/uuid github.com/cloudfoundry/bosh-utils/uuid/fakes github.com/cloudfoundry/bosh-utils/work -# github.com/cloudfoundry/config-server v0.1.161 +# github.com/cloudfoundry/config-server v0.1.162 ## explicit; go 1.21 github.com/cloudfoundry/config-server/types github.com/cloudfoundry/config-server/types/typesfakes # github.com/cloudfoundry/go-socks5 v0.0.0-20180221174514-54f73bdb8a8e ## explicit github.com/cloudfoundry/go-socks5 -# github.com/cloudfoundry/socks5-proxy v0.2.106 +# github.com/cloudfoundry/socks5-proxy v0.2.107 ## explicit; go 1.21 github.com/cloudfoundry/socks5-proxy # github.com/cppforlife/go-patch v0.2.0 @@ -318,7 +319,7 @@ github.com/fzipp/gocyclo # github.com/ghostiam/protogetter v0.3.3 ## explicit; go 1.19 github.com/ghostiam/protogetter -# github.com/go-critic/go-critic v0.10.0 +# github.com/go-critic/go-critic v0.11.0 ## explicit; go 1.18 github.com/go-critic/go-critic/checkers github.com/go-critic/go-critic/checkers/internal/astwalk @@ -341,8 +342,8 @@ github.com/go-toolsmith/astcast # github.com/go-toolsmith/astcopy v1.1.0 ## explicit; go 1.16 github.com/go-toolsmith/astcopy -# github.com/go-toolsmith/astequal v1.1.0 -## explicit; go 1.16 +# github.com/go-toolsmith/astequal v1.2.0 +## explicit; go 1.18 github.com/go-toolsmith/astequal # github.com/go-toolsmith/astfmt v1.1.0 ## explicit; go 1.16 @@ -618,8 +619,8 @@ github.com/maratori/testableexamples/pkg/testableexamples # github.com/maratori/testpackage v1.1.1 ## explicit; go 1.20 github.com/maratori/testpackage/pkg/testpackage -# github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 -## explicit; go 1.13 +# github.com/matoous/godox v0.0.0-20240105082147-c5b5e0e7c0c0 +## explicit; go 1.18 github.com/matoous/godox # github.com/mattn/go-colorable v0.1.13 ## explicit; go 1.15 @@ -642,7 +643,7 @@ github.com/maxbrunsfeld/counterfeiter/v6/generator # github.com/mbilski/exhaustivestruct v1.2.0 ## explicit; go 1.15 github.com/mbilski/exhaustivestruct/pkg/analyzer -# github.com/mgechev/revive v1.3.4 +# github.com/mgechev/revive v1.3.5 ## explicit; go 1.20 github.com/mgechev/revive/config github.com/mgechev/revive/formatter @@ -1030,14 +1031,14 @@ golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf -# golang.org/x/exp v0.0.0-20231226003508-02704c960a9b +# golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc ## explicit; go 1.20 golang.org/x/exp/constraints golang.org/x/exp/slices golang.org/x/exp/slog golang.org/x/exp/slog/internal golang.org/x/exp/slog/internal/buffer -# golang.org/x/exp/typeparams v0.0.0-20231226003508-02704c960a9b +# golang.org/x/exp/typeparams v0.0.0-20240103183307-be819d1f06fc ## explicit; go 1.18 golang.org/x/exp/typeparams # golang.org/x/mod v0.14.0 @@ -1072,17 +1073,17 @@ golang.org/x/oauth2/google/internal/stsexchange golang.org/x/oauth2/internal golang.org/x/oauth2/jws golang.org/x/oauth2/jwt -# golang.org/x/sync v0.5.0 +# golang.org/x/sync v0.6.0 ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/semaphore -# golang.org/x/sys v0.15.0 +# golang.org/x/sys v0.16.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.15.0 +# golang.org/x/term v0.16.0 ## explicit; go 1.18 golang.org/x/term # golang.org/x/text v0.14.0 @@ -1193,7 +1194,7 @@ golang.org/x/tools/internal/tokeninternal golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal golang.org/x/tools/internal/versions -# google.golang.org/api v0.154.0 +# google.golang.org/api v0.155.0 ## explicit; go 1.19 google.golang.org/api/googleapi google.golang.org/api/googleapi/transport @@ -1223,16 +1224,16 @@ google.golang.org/appengine/internal/modules google.golang.org/appengine/internal/remote_api google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/urlfetch -# google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 +# google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 ## explicit; go 1.19 google.golang.org/genproto/googleapis/type/date google.golang.org/genproto/googleapis/type/expr google.golang.org/genproto/internal -# google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 +# google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 ## explicit; go 1.19 google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations -# google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 ## explicit; go 1.19 google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails @@ -1391,6 +1392,6 @@ mvdan.cc/interfacer/check # mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b ## explicit mvdan.cc/lint -# mvdan.cc/unparam v0.0.0-20231227222031-fe02aa31e4f6 +# mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 ## explicit; go 1.20 mvdan.cc/unparam/check diff --git a/vendor/mvdan.cc/unparam/check/check.go b/vendor/mvdan.cc/unparam/check/check.go index 8f9a3cb0a..39de800d9 100644 --- a/vendor/mvdan.cc/unparam/check/check.go +++ b/vendor/mvdan.cc/unparam/check/check.go @@ -916,7 +916,7 @@ func recvPrefix(recv *ast.FieldList) string { case *ast.IndexListExpr: return expr.X.(*ast.Ident).Name + "." default: - panic(fmt.Sprintf("unexepected receiver AST node: %T", expr)) + panic(fmt.Sprintf("unexpected receiver AST node: %T", expr)) } }