Skip to content

Commit 76c4521

Browse files
authored
add 'predeclared' linter (#1606)
1 parent 5c9e386 commit 76c4521

File tree

9 files changed

+118
-6
lines changed

9 files changed

+118
-6
lines changed

.golangci.example.yml

+10-5
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ linters-settings:
152152
# Settings passed to gocritic.
153153
# The settings key is the name of a supported gocritic checker.
154154
# The list of supported checkers can be find in https://go-critic.github.io/overview.
155-
settings:
155+
settings:
156156
captLocal: # must be valid enabled check name
157157
# whether to restrict checker to params only (default true)
158-
paramsOnly: true
158+
paramsOnly: true
159159
elseif:
160160
# whether to skip balanced if-else pairs (default true)
161161
skipBalanced: true
@@ -219,13 +219,13 @@ linters-settings:
219219
#
220220
# {{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
221221
# SPDX-License-Identifier: Apache-2.0
222-
222+
223223
# Licensed under the Apache License, Version 2.0 (the "License");
224224
# you may not use this file except in compliance with the License.
225225
# You may obtain a copy of the License at:
226-
226+
227227
# http://www.apache.org/licenses/LICENSE-2.0
228-
228+
229229
# Unless required by applicable law or agreed to in writing, software
230230
# distributed under the License is distributed on an "AS IS" BASIS,
231231
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -321,6 +321,11 @@ linters-settings:
321321
simple: true
322322
range-loops: true # Report preallocation suggestions on range loops, true by default
323323
for-loops: false # Report preallocation suggestions on for loops, false by default
324+
predeclared:
325+
# comma-separated list of predeclared identifiers to not report on
326+
ignore: ""
327+
# include method names and field names (i.e., qualified names) in checks
328+
q: false
324329
nolintlint:
325330
# Enable to ensure that nolint directives are all used. Default is true.
326331
allow-unused: false

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ require (
4343
github.com/moricho/tparallel v0.2.1
4444
github.com/nakabonne/nestif v0.3.0
4545
github.com/nishanths/exhaustive v0.1.0
46+
github.com/nishanths/predeclared v0.2.1
4647
github.com/pkg/errors v0.9.1
4748
github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f
4849
github.com/ryancurrah/gomodguard v1.2.0
@@ -69,7 +70,7 @@ require (
6970
github.com/valyala/quicktemplate v1.6.3
7071
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 // indirect
7172
golang.org/x/text v0.3.4 // indirect
72-
golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb
73+
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c
7374
gopkg.in/yaml.v2 v2.4.0
7475
honnef.co/go/tools v0.0.1-2020.1.6
7576
mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475

go.sum

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/config/config.go

+10
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ type LintersSettings struct {
270270
Makezero MakezeroSettings
271271
Thelper ThelperSettings
272272
Forbidigo ForbidigoSettings
273+
Predeclared PredeclaredSettings
273274

274275
Custom map[string]CustomLinterSettings
275276
}
@@ -411,6 +412,11 @@ type ForbidigoSettings struct {
411412
Forbid []string `mapstructure:"forbid"`
412413
}
413414

415+
type PredeclaredSettings struct {
416+
Ignore string `mapstructure:"ignore"`
417+
Qualified bool `mapstructure:"q"`
418+
}
419+
414420
var defaultLintersSettings = LintersSettings{
415421
Lll: LllSettings{
416422
LineLength: 120,
@@ -471,6 +477,10 @@ var defaultLintersSettings = LintersSettings{
471477
ErrorLint: ErrorLintSettings{
472478
Errorf: true,
473479
},
480+
Predeclared: PredeclaredSettings{
481+
Ignore: "",
482+
Qualified: false,
483+
},
474484
}
475485

476486
type CustomLinterSettings struct {

pkg/golinters/predeclared.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package golinters
2+
3+
import (
4+
"github.com/nishanths/predeclared/passes/predeclared"
5+
"golang.org/x/tools/go/analysis"
6+
7+
"github.com/golangci/golangci-lint/pkg/config"
8+
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
9+
)
10+
11+
func NewPredeclared(settings *config.PredeclaredSettings) *goanalysis.Linter {
12+
a := predeclared.Analyzer
13+
14+
var cfg map[string]map[string]interface{}
15+
if settings != nil {
16+
cfg = map[string]map[string]interface{}{
17+
a.Name: {
18+
predeclared.IgnoreFlag: settings.Ignore,
19+
predeclared.QualifiedFlag: settings.Qualified,
20+
},
21+
}
22+
}
23+
24+
return goanalysis.NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, cfg).
25+
WithLoadMode(goanalysis.LoadModeSyntax)
26+
}

pkg/lint/lintersdb/manager.go

+5
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,14 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
9494
var exhaustiveCfg *config.ExhaustiveSettings
9595
var errorlintCfg *config.ErrorLintSettings
9696
var thelperCfg *config.ThelperSettings
97+
var predeclaredCfg *config.PredeclaredSettings
9798
if m.cfg != nil {
9899
govetCfg = &m.cfg.LintersSettings.Govet
99100
testpackageCfg = &m.cfg.LintersSettings.Testpackage
100101
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
101102
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
102103
thelperCfg = &m.cfg.LintersSettings.Thelper
104+
predeclaredCfg = &m.cfg.LintersSettings.Predeclared
103105
}
104106
const megacheckName = "megacheck"
105107
lcs := []*linter.Config{
@@ -342,6 +344,9 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
342344
linter.NewConfig(golinters.NewForbidigo()).
343345
WithPresets(linter.PresetStyle).
344346
WithURL("https://github.com/ashanbrown/forbidigo"),
347+
linter.NewConfig(golinters.NewPredeclared(predeclaredCfg)).
348+
WithPresets(linter.PresetStyle).
349+
WithURL("https://github.com/nishanths/predeclared"),
345350

346351
// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
347352
linter.NewConfig(golinters.NewNoLintLint()).

test/testdata/configs/predeclared.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
linters-settings:
2+
predeclared:
3+
ignore: "real,recover"
4+
q: true

test/testdata/predeclared.go

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//args: -Epredeclared
2+
package testdata
3+
4+
func hello() {
5+
var real int // ERROR "variable real has same name as predeclared identifier"
6+
a := A{}
7+
copy := Clone(a) // ERROR "variable copy has same name as predeclared identifier"
8+
9+
// suppress any "declared but not used" errors
10+
_ = real
11+
_ = a
12+
_ = copy
13+
}
14+
15+
type A struct {
16+
true bool
17+
foo int
18+
}
19+
20+
func Clone(a A) A {
21+
return A{
22+
true: a.true,
23+
foo: a.foo,
24+
}
25+
}
26+
27+
func recover() {} // ERROR "function recover has same name as predeclared identifier"

test/testdata/predeclared_custom.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//args: -Epredeclared
2+
//config_path: testdata/configs/predeclared.yml
3+
package testdata
4+
5+
func hello() {
6+
var real int
7+
a := A{}
8+
copy := Clone(a) // ERROR "variable copy has same name as predeclared identifier"
9+
10+
// suppress any "declared but not used" errors
11+
_ = real
12+
_ = a
13+
_ = copy
14+
}
15+
16+
type A struct {
17+
true bool // ERROR "field true has same name as predeclared identifier"
18+
foo int
19+
}
20+
21+
func Clone(a A) A {
22+
return A{
23+
true: a.true,
24+
foo: a.foo,
25+
}
26+
}
27+
28+
func recover() {}

0 commit comments

Comments
 (0)