Repository: go-critic/go-critic
Pull request #1321 (2023-02-22 16:46:08)

all: get rid of framework package
- moved `framework/linttest` -> `checkers/internal/linttest`
- moved all `framework/linter` declarations to `linter`
- added aliases in `framework/linter` for backward compatibility
- also we small adjustments


Patch:
diff --git a/checkers/analyzer/analyzer.go b/checkers/analyzer/analyzer.go
index f0f3600..2c92a93 100644
--- a/checkers/analyzer/analyzer.go
+++ b/checkers/analyzer/analyzer.go
@@ -2,7 +2,8 @@
 package analyzer
 
 import (
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"golang.org/x/tools/go/analysis"
 )
 
diff --git a/checkers/analyzer/run.go b/checkers/analyzer/run.go
index be23336..bb76d68 100644
--- a/checkers/analyzer/run.go
+++ b/checkers/analyzer/run.go
@@ -7,10 +7,10 @@ import (
 	"strings"
 	"sync"
 
-	"golang.org/x/tools/go/analysis"
-
 	_ "github.com/go-critic/go-critic/checkers" // Register go-critic checkers
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
+	"golang.org/x/tools/go/analysis"
 )
 
 type gocritic struct {
diff --git a/checkers/appendAssign_checker.go b/checkers/appendAssign_checker.go
index a9324dd..a0727f4 100644
--- a/checkers/appendAssign_checker.go
+++ b/checkers/appendAssign_checker.go
@@ -6,7 +6,8 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/astp"
 	"golang.org/x/tools/go/ast/astutil"
diff --git a/checkers/appendCombine_checker.go b/checkers/appendCombine_checker.go
index 3c81449..cce1a8f 100644
--- a/checkers/appendCombine_checker.go
+++ b/checkers/appendCombine_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astequal"
 )
diff --git a/checkers/badCond_checker.go b/checkers/badCond_checker.go
index d3d139a..b0834ff 100644
--- a/checkers/badCond_checker.go
+++ b/checkers/badCond_checker.go
@@ -7,7 +7,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astcopy"
 	"github.com/go-toolsmith/astequal"
diff --git a/checkers/badRegexp_checker.go b/checkers/badRegexp_checker.go
index 8a35900..4b957f0 100644
--- a/checkers/badRegexp_checker.go
+++ b/checkers/badRegexp_checker.go
@@ -9,7 +9,8 @@ import (
 	"unicode/utf8"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/quasilyte/regex/syntax"
 )
 
diff --git a/checkers/boolExprSimplify_checker.go b/checkers/boolExprSimplify_checker.go
index b4000a8..9c7897f 100644
--- a/checkers/boolExprSimplify_checker.go
+++ b/checkers/boolExprSimplify_checker.go
@@ -5,16 +5,16 @@ import (
 	"go/token"
 	"strconv"
 
+	"github.com/go-critic/go-critic/checkers/internal/astwalk"
+	"github.com/go-critic/go-critic/checkers/internal/lintutil"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astcopy"
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/astp"
 	"github.com/go-toolsmith/typep"
 	"golang.org/x/tools/go/ast/astutil"
-
-	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
 )
 
 func init() {
diff --git a/checkers/builtinShadowDecl_checker.go b/checkers/builtinShadowDecl_checker.go
index 94d51a9..0eaf9b8 100644
--- a/checkers/builtinShadowDecl_checker.go
+++ b/checkers/builtinShadowDecl_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/builtinShadow_checker.go b/checkers/builtinShadow_checker.go
index 1e1661d..b910462 100644
--- a/checkers/builtinShadow_checker.go
+++ b/checkers/builtinShadow_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/captLocal_checker.go b/checkers/captLocal_checker.go
index d9b4b7e..dd3a415 100644
--- a/checkers/captLocal_checker.go
+++ b/checkers/captLocal_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/caseOrder_checker.go b/checkers/caseOrder_checker.go
index 047ea4f..e403476 100644
--- a/checkers/caseOrder_checker.go
+++ b/checkers/caseOrder_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/checkers.go b/checkers/checkers.go
index 0c2ebc0..5797daf 100644
--- a/checkers/checkers.go
+++ b/checkers/checkers.go
@@ -4,7 +4,7 @@ package checkers
 import (
 	"os"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 var collection = &linter.CheckerCollection{
diff --git a/checkers/codegenComment_checker.go b/checkers/codegenComment_checker.go
index 52a72d2..eebe55b 100644
--- a/checkers/codegenComment_checker.go
+++ b/checkers/codegenComment_checker.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/commentFormatting_checker.go b/checkers/commentFormatting_checker.go
index f330b72..40c8296 100644
--- a/checkers/commentFormatting_checker.go
+++ b/checkers/commentFormatting_checker.go
@@ -8,7 +8,7 @@ import (
 	"unicode/utf8"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/commentedOutCode_checker.go b/checkers/commentedOutCode_checker.go
index 554e062..dcad296 100644
--- a/checkers/commentedOutCode_checker.go
+++ b/checkers/commentedOutCode_checker.go
@@ -8,7 +8,8 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/strparse"
 )
 
diff --git a/checkers/commentedOutImport_checker.go b/checkers/commentedOutImport_checker.go
index 3c08656..2f33973 100644
--- a/checkers/commentedOutImport_checker.go
+++ b/checkers/commentedOutImport_checker.go
@@ -6,7 +6,7 @@ import (
 	"regexp"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/defaultCaseOrder_checker.go b/checkers/defaultCaseOrder_checker.go
index e06944d..ef3a4c1 100644
--- a/checkers/defaultCaseOrder_checker.go
+++ b/checkers/defaultCaseOrder_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/deferInLoop_checker.go b/checkers/deferInLoop_checker.go
index da90fe6..5b9266e 100644
--- a/checkers/deferInLoop_checker.go
+++ b/checkers/deferInLoop_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/deprecatedComment_checker.go b/checkers/deprecatedComment_checker.go
index 0eb5072..dc4df5d 100644
--- a/checkers/deprecatedComment_checker.go
+++ b/checkers/deprecatedComment_checker.go
@@ -5,7 +5,7 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/docStub_checker.go b/checkers/docStub_checker.go
index d8aaaf7..738544f 100644
--- a/checkers/docStub_checker.go
+++ b/checkers/docStub_checker.go
@@ -7,7 +7,7 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/dupBranchBody_checker.go b/checkers/dupBranchBody_checker.go
index ad16e3b..734e894 100644
--- a/checkers/dupBranchBody_checker.go
+++ b/checkers/dupBranchBody_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astequal"
 )
 
diff --git a/checkers/dupCase_checker.go b/checkers/dupCase_checker.go
index a565007..9e36d99 100644
--- a/checkers/dupCase_checker.go
+++ b/checkers/dupCase_checker.go
@@ -5,7 +5,7 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/dupImports_checker.go b/checkers/dupImports_checker.go
index 54658eb..8f55d0b 100644
--- a/checkers/dupImports_checker.go
+++ b/checkers/dupImports_checker.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"go/ast"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/dupSubExpr_checker.go b/checkers/dupSubExpr_checker.go
index 00f8fd0..3516091 100644
--- a/checkers/dupSubExpr_checker.go
+++ b/checkers/dupSubExpr_checker.go
@@ -6,7 +6,8 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/typep"
 )
diff --git a/checkers/elseif_checker.go b/checkers/elseif_checker.go
index dcc9648..5cd9a3e 100644
--- a/checkers/elseif_checker.go
+++ b/checkers/elseif_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astp"
 )
 
diff --git a/checkers/embedded_rules.go b/checkers/embedded_rules.go
index b17178e..7be115f 100644
--- a/checkers/embedded_rules.go
+++ b/checkers/embedded_rules.go
@@ -7,10 +7,10 @@ import (
 	"go/token"
 	"os"
 
-	"github.com/quasilyte/go-ruleguard/ruleguard"
-
 	"github.com/go-critic/go-critic/checkers/rulesdata"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
+	"github.com/quasilyte/go-ruleguard/ruleguard"
 )
 
 //go:generate go run ./rules/precompile.go -rules ./rules/rules.go -o ./rulesdata/rulesdata.go
diff --git a/checkers/emptyFallthrough_checker.go b/checkers/emptyFallthrough_checker.go
index ebb8dad..1b2f58c 100644
--- a/checkers/emptyFallthrough_checker.go
+++ b/checkers/emptyFallthrough_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/evalOrder_checker.go b/checkers/evalOrder_checker.go
index 6ba07fe..7365970 100644
--- a/checkers/evalOrder_checker.go
+++ b/checkers/evalOrder_checker.go
@@ -7,7 +7,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/typep"
diff --git a/checkers/exitAfterDefer_checker.go b/checkers/exitAfterDefer_checker.go
index 63e0049..2781dc2 100644
--- a/checkers/exitAfterDefer_checker.go
+++ b/checkers/exitAfterDefer_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astfmt"
 	"github.com/go-toolsmith/astp"
 	"golang.org/x/tools/go/ast/astutil"
diff --git a/checkers/filepathJoin_checker.go b/checkers/filepathJoin_checker.go
index 698f536..6d62ef2 100644
--- a/checkers/filepathJoin_checker.go
+++ b/checkers/filepathJoin_checker.go
@@ -5,7 +5,8 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 )
 
diff --git a/checkers/flagName_checker.go b/checkers/flagName_checker.go
index 7f6ce3c..e704010 100644
--- a/checkers/flagName_checker.go
+++ b/checkers/flagName_checker.go
@@ -7,7 +7,8 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 )
 
diff --git a/checkers/hexLiteral_checker.go b/checkers/hexLiteral_checker.go
index ae61a11..fead716 100644
--- a/checkers/hexLiteral_checker.go
+++ b/checkers/hexLiteral_checker.go
@@ -6,7 +6,8 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 )
 
diff --git a/checkers/hugeParam_checker.go b/checkers/hugeParam_checker.go
index 742652a..07a1a22 100644
--- a/checkers/hugeParam_checker.go
+++ b/checkers/hugeParam_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/ifElseChain_checker.go b/checkers/ifElseChain_checker.go
index c3d127c..b36f1f1 100644
--- a/checkers/ifElseChain_checker.go
+++ b/checkers/ifElseChain_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/importShadow_checker.go b/checkers/importShadow_checker.go
index 5ac711f..76a11e3 100644
--- a/checkers/importShadow_checker.go
+++ b/checkers/importShadow_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/initClause_checker.go b/checkers/initClause_checker.go
index a1b6b2a..8a3182f 100644
--- a/checkers/initClause_checker.go
+++ b/checkers/initClause_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astp"
 )
 
diff --git a/checkers/internal/astwalk/walker.go b/checkers/internal/astwalk/walker.go
index cd5e1c9..f838a64 100644
--- a/checkers/internal/astwalk/walker.go
+++ b/checkers/internal/astwalk/walker.go
@@ -3,7 +3,7 @@ package astwalk
 import (
 	"go/types"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 // WalkerForFuncDecl returns file walker implementation for FuncDeclVisitor.
diff --git a/framework/linttest/testdata/sanity/tests.go b/checkers/internal/linttest/testdata/sanity/tests.go
similarity index 100%
rename from framework/linttest/testdata/sanity/tests.go
rename to checkers/internal/linttest/testdata/sanity/tests.go
diff --git a/checkers/mapKey_checker.go b/checkers/mapKey_checker.go
index 64c2821..596ff87 100644
--- a/checkers/mapKey_checker.go
+++ b/checkers/mapKey_checker.go
@@ -7,7 +7,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astp"
 	"github.com/go-toolsmith/typep"
diff --git a/checkers/methodExprCall_checker.go b/checkers/methodExprCall_checker.go
index 2553def..4206d4e 100644
--- a/checkers/methodExprCall_checker.go
+++ b/checkers/methodExprCall_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astcopy"
 	"github.com/go-toolsmith/typep"
diff --git a/checkers/nestingReduce_checker.go b/checkers/nestingReduce_checker.go
index a68acec..86b8696 100644
--- a/checkers/nestingReduce_checker.go
+++ b/checkers/nestingReduce_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/newDeref_checker.go b/checkers/newDeref_checker.go
index 04a3474..fb50283 100644
--- a/checkers/newDeref_checker.go
+++ b/checkers/newDeref_checker.go
@@ -2,12 +2,13 @@ package checkers
 
 import (
 	"go/ast"
+	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
-	"golang.org/x/exp/typeparams"
 	"golang.org/x/tools/go/ast/astutil"
 )
 
@@ -35,7 +36,7 @@ func (c *newDerefChecker) VisitExpr(expr ast.Expr) {
 	if astcast.ToIdent(call.Fun).Name == "new" {
 		typ := c.ctx.TypeOf(call.Args[0])
 		// allow *new(T) if T is a type parameter, see #1272 for details
-		if typeparams.IsTypeParam(typ) {
+		if _, ok := typ.(*types.TypeParam); ok {
 			return
 		}
 		zv := lintutil.ZeroValueOf(astutil.Unparen(call.Args[0]), typ)
diff --git a/checkers/nilValReturn_checker.go b/checkers/nilValReturn_checker.go
index 0a8e793..c3539cb 100644
--- a/checkers/nilValReturn_checker.go
+++ b/checkers/nilValReturn_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/typep"
 )
diff --git a/checkers/octalLiteral_checker.go b/checkers/octalLiteral_checker.go
index bed227a..b2c2519 100644
--- a/checkers/octalLiteral_checker.go
+++ b/checkers/octalLiteral_checker.go
@@ -7,7 +7,8 @@ import (
 	"unicode"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 )
 
diff --git a/checkers/paramTypeCombine_checker.go b/checkers/paramTypeCombine_checker.go
index c80e6f8..1f76ab6 100644
--- a/checkers/paramTypeCombine_checker.go
+++ b/checkers/paramTypeCombine_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcopy"
 	"github.com/go-toolsmith/astequal"
 )
diff --git a/checkers/ptrToRefParam_checker.go b/checkers/ptrToRefParam_checker.go
index 88c8f4c..6b86933 100644
--- a/checkers/ptrToRefParam_checker.go
+++ b/checkers/ptrToRefParam_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/rangeExprCopy_checker.go b/checkers/rangeExprCopy_checker.go
index 813fff3..8adc16b 100644
--- a/checkers/rangeExprCopy_checker.go
+++ b/checkers/rangeExprCopy_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/rangeValCopy_checker.go b/checkers/rangeValCopy_checker.go
index 37f4696..e1f76fd 100644
--- a/checkers/rangeValCopy_checker.go
+++ b/checkers/rangeValCopy_checker.go
@@ -4,7 +4,7 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/regexpPattern_checker.go b/checkers/regexpPattern_checker.go
index 31dc4aa..5d57c84 100644
--- a/checkers/regexpPattern_checker.go
+++ b/checkers/regexpPattern_checker.go
@@ -7,7 +7,7 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/regexpSimplify_checker.go b/checkers/regexpSimplify_checker.go
index 5b15e05..5c5e54a 100644
--- a/checkers/regexpSimplify_checker.go
+++ b/checkers/regexpSimplify_checker.go
@@ -8,10 +8,10 @@ import (
 	"strings"
 	"unicode/utf8"
 
-	"github.com/quasilyte/regex/syntax"
-
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
+	"github.com/quasilyte/regex/syntax"
 )
 
 func init() {
diff --git a/checkers/ruleguard_checker.go b/checkers/ruleguard_checker.go
index 000007a..769ebad 100644
--- a/checkers/ruleguard_checker.go
+++ b/checkers/ruleguard_checker.go
@@ -12,9 +12,9 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/quasilyte/go-ruleguard/ruleguard"
+	"github.com/go-critic/go-critic/linter"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/quasilyte/go-ruleguard/ruleguard"
 )
 
 func init() {
diff --git a/checkers/singleCaseSwitch_checker.go b/checkers/singleCaseSwitch_checker.go
index b369a43..4de5d19 100644
--- a/checkers/singleCaseSwitch_checker.go
+++ b/checkers/singleCaseSwitch_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"golang.org/x/tools/go/ast/astutil"
 )
 
diff --git a/checkers/sloppyReassign_checker.go b/checkers/sloppyReassign_checker.go
index 2f9ac62..c80a171 100644
--- a/checkers/sloppyReassign_checker.go
+++ b/checkers/sloppyReassign_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astcopy"
 	"github.com/go-toolsmith/astequal"
diff --git a/checkers/sloppyTypeAssert_checker.go b/checkers/sloppyTypeAssert_checker.go
index 5541977..c3bc159 100644
--- a/checkers/sloppyTypeAssert_checker.go
+++ b/checkers/sloppyTypeAssert_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 )
 
diff --git a/checkers/sortSlice_checker.go b/checkers/sortSlice_checker.go
index 29550da..4394f20 100644
--- a/checkers/sortSlice_checker.go
+++ b/checkers/sortSlice_checker.go
@@ -6,7 +6,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/typep"
diff --git a/checkers/sqlQuery_checker.go b/checkers/sqlQuery_checker.go
index eb3b49d..c1cf6bb 100644
--- a/checkers/sqlQuery_checker.go
+++ b/checkers/sqlQuery_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 )
 
diff --git a/checkers/todoCommentWithoutDetail_checker.go b/checkers/todoCommentWithoutDetail_checker.go
index 5ec2881..ca2b6d2 100644
--- a/checkers/todoCommentWithoutDetail_checker.go
+++ b/checkers/todoCommentWithoutDetail_checker.go
@@ -5,7 +5,7 @@ import (
 	"regexp"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/tooManyResults_checker.go b/checkers/tooManyResults_checker.go
index 4d4dcc2..9527c57 100644
--- a/checkers/tooManyResults_checker.go
+++ b/checkers/tooManyResults_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/truncateCmp_checker.go b/checkers/truncateCmp_checker.go
index 9d40c2b..34946d1 100644
--- a/checkers/truncateCmp_checker.go
+++ b/checkers/truncateCmp_checker.go
@@ -6,7 +6,8 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astp"
 )
diff --git a/checkers/typeAssertChain_checker.go b/checkers/typeAssertChain_checker.go
index d87657c..48757bc 100644
--- a/checkers/typeAssertChain_checker.go
+++ b/checkers/typeAssertChain_checker.go
@@ -6,7 +6,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/astp"
diff --git a/checkers/typeDefFirst_checker.go b/checkers/typeDefFirst_checker.go
index bc59eef..2177001 100644
--- a/checkers/typeDefFirst_checker.go
+++ b/checkers/typeDefFirst_checker.go
@@ -5,8 +5,7 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
-	"golang.org/x/exp/typeparams"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
@@ -81,7 +80,7 @@ func (c *typeDefFirstChecker) receiverType(e ast.Expr) string {
 		return e.Name
 	case *ast.IndexExpr:
 		return c.receiverType(e.X)
-	case *typeparams.IndexListExpr:
+	case *ast.IndexListExpr:
 		return c.receiverType(e.X)
 	default:
 		panic("unreachable")
diff --git a/checkers/typeSwitchVar_checker.go b/checkers/typeSwitchVar_checker.go
index 1e11e49..b4339de 100644
--- a/checkers/typeSwitchVar_checker.go
+++ b/checkers/typeSwitchVar_checker.go
@@ -5,7 +5,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/astp"
 )
diff --git a/checkers/typeUnparen_checker.go b/checkers/typeUnparen_checker.go
index cd8e043..8c6491c 100644
--- a/checkers/typeUnparen_checker.go
+++ b/checkers/typeUnparen_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcopy"
 	"github.com/go-toolsmith/astequal"
 )
diff --git a/checkers/underef_checker.go b/checkers/underef_checker.go
index d0426a9..e9d7cc6 100644
--- a/checkers/underef_checker.go
+++ b/checkers/underef_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astp"
 )
diff --git a/checkers/unlabelStmt_checker.go b/checkers/unlabelStmt_checker.go
index bcca24d..38e689c 100644
--- a/checkers/unlabelStmt_checker.go
+++ b/checkers/unlabelStmt_checker.go
@@ -6,7 +6,7 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/unlambda_checker.go b/checkers/unlambda_checker.go
index cce995d..6e5ed59 100644
--- a/checkers/unlambda_checker.go
+++ b/checkers/unlambda_checker.go
@@ -7,7 +7,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/typep"
diff --git a/checkers/unnamedResult_checker.go b/checkers/unnamedResult_checker.go
index 3149d9e..5f1afbd 100644
--- a/checkers/unnamedResult_checker.go
+++ b/checkers/unnamedResult_checker.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/checkers/unnecessaryBlock_checker.go b/checkers/unnecessaryBlock_checker.go
index 6cbdfdf..b1d1728 100644
--- a/checkers/unnecessaryBlock_checker.go
+++ b/checkers/unnecessaryBlock_checker.go
@@ -5,7 +5,8 @@ import (
 	"go/token"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astp"
 )
 
diff --git a/checkers/unnecessaryDefer_checker.go b/checkers/unnecessaryDefer_checker.go
index ef72142..a3863e6 100644
--- a/checkers/unnecessaryDefer_checker.go
+++ b/checkers/unnecessaryDefer_checker.go
@@ -4,7 +4,8 @@ import (
 	"go/ast"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astfmt"
 )
 
diff --git a/checkers/utils.go b/checkers/utils.go
index b71f24d..e912335 100644
--- a/checkers/utils.go
+++ b/checkers/utils.go
@@ -5,7 +5,7 @@ import (
 	"go/types"
 	"strings"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 // goStdlib contains `go list std` command output list.
diff --git a/checkers/weakCond_checker.go b/checkers/weakCond_checker.go
index 831857c..42f63e2 100644
--- a/checkers/weakCond_checker.go
+++ b/checkers/weakCond_checker.go
@@ -6,7 +6,8 @@ import (
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
 	"github.com/go-critic/go-critic/checkers/internal/lintutil"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/astcast"
 	"github.com/go-toolsmith/astequal"
 	"github.com/go-toolsmith/typep"
diff --git a/checkers/whyNoLint_checker.go b/checkers/whyNoLint_checker.go
index 6829433..4840018 100644
--- a/checkers/whyNoLint_checker.go
+++ b/checkers/whyNoLint_checker.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 
 	"github.com/go-critic/go-critic/checkers/internal/astwalk"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 func init() {
diff --git a/cmd/gocritic/check.go b/cmd/gocritic/check.go
index a45e84a..2bd93eb 100644
--- a/cmd/gocritic/check.go
+++ b/cmd/gocritic/check.go
@@ -19,10 +19,10 @@ import (
 	"strings"
 	"sync"
 
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/pkgload"
 	"golang.org/x/tools/go/packages"
-
-	"github.com/go-critic/go-critic/framework/linter"
 )
 
 // Main implements sub-command entry point.
diff --git a/cmd/gocritic/doc.go b/cmd/gocritic/doc.go
index 4f4ccfd..81acdbc 100644
--- a/cmd/gocritic/doc.go
+++ b/cmd/gocritic/doc.go
@@ -9,7 +9,7 @@ import (
 	"reflect"
 	"text/template"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 // Main implements sub-command entry point.
diff --git a/cmd/makedocs/main.go b/cmd/makedocs/main.go
index dcd81ba..3336316 100644
--- a/cmd/makedocs/main.go
+++ b/cmd/makedocs/main.go
@@ -8,7 +8,7 @@ import (
 	"text/template"
 
 	_ "github.com/go-critic/go-critic/checkers"
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 const (
diff --git a/framework/linter/context.go b/framework/linter/context.go
deleted file mode 100644
index 6e108ab..0000000
--- a/framework/linter/context.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package linter
-
-import (
-	"go/ast"
-	"go/types"
-	"strconv"
-)
-
-func resolvePkgObjects(ctx *Context, f *ast.File) {
-	ctx.PkgObjects = make(map[*types.PkgName]string, len(f.Imports))
-
-	for _, spec := range f.Imports {
-		if spec.Name != nil {
-			obj := ctx.TypesInfo.ObjectOf(spec.Name)
-			ctx.PkgObjects[obj.(*types.PkgName)] = spec.Name.Name
-		} else {
-			obj := ctx.TypesInfo.Implicits[spec]
-			ctx.PkgObjects[obj.(*types.PkgName)] = obj.Name()
-		}
-	}
-}
-
-func resolvePkgRenames(ctx *Context, f *ast.File) {
-	ctx.PkgRenames = make(map[string]string)
-
-	for _, spec := range f.Imports {
-		if spec.Name != nil {
-			path, err := strconv.Unquote(spec.Path.Value)
-			if err != nil {
-				panic(err)
-			}
-			ctx.PkgRenames[path] = spec.Name.Name
-		}
-	}
-}
diff --git a/framework/linter/linter.go b/framework/linter/linter.go
index 8573ace..c2a7a07 100644
--- a/framework/linter/linter.go
+++ b/framework/linter/linter.go
@@ -1,344 +1,95 @@
 package linter
 
 import (
-	"go/ast"
 	"go/token"
 	"go/types"
 
-	"github.com/go-toolsmith/astfmt"
+	"github.com/go-critic/go-critic/linter"
 )
 
-// CheckerCollection provides additional information for a group of checkers.
-type CheckerCollection struct {
-	// URL is a link for a main source of information on the collection.
-	URL string
-}
+// UnknownType is a special sentinel value that is returned from the CheckerContext.TypeOf
+// method instead of the nil type.
+// Deprecated: use linter.UnknownType.
+var UnknownType = linter.UnknownType
 
-// AddChecker registers a new checker into a checkers pool.
-// Constructor is used to create a new checker instance.
-// Checker name (defined in CheckerInfo.Name) must be unique.
-//
-// CheckerInfo.Collection is automatically set to the coll (the receiver).
-//
-// If checker is never needed, for example if it is disabled,
-// constructor will not be called.
-func (coll *CheckerCollection) AddChecker(info *CheckerInfo, constructor func(*CheckerContext) (FileWalker, error)) {
-	if coll == nil {
-		panic("adding checker to a nil collection")
-	}
-	info.Collection = coll
-	addChecker(info, constructor)
-}
+// Deprecated: use linter.GoVersion.
+type GoVersion = linter.GoVersion
 
-// CheckerParam describes a single checker customizable parameter.
-type CheckerParam struct {
-	// Value holds parameter bound value.
-	// It might be overwritten by the integrating linter.
-	//
-	// Permitted types include:
-	//	- int
-	//	- bool
-	//	- string
-	Value interface{}
+// CheckerCollection provides additional information for a group of checkers.
+// Deprecated: use linter.CheckerCollection.
+type CheckerCollection = linter.CheckerCollection
 
-	// Usage gives an overview about what parameter does.
-	Usage string
-}
+// CheckerParam describes a single checker customizable parameter.
+// Deprecated: use linter.CheckerParam.
+type CheckerParam = linter.CheckerParam
 
 // CheckerParams holds all checker-specific parameters.
 //
 // Provides convenient access to the loosely typed underlying map.
-type CheckerParams map[string]*CheckerParam
-
-// Int lookups pname key in underlying map and type-asserts it to int.
-func (params CheckerParams) Int(pname string) int { return params[pname].Value.(int) }
-
-// Bool lookups pname key in underlying map and type-asserts it to bool.
-func (params CheckerParams) Bool(pname string) bool { return params[pname].Value.(bool) }
-
-// String lookups pname key in underlying map and type-asserts it to string.
-func (params CheckerParams) String(pname string) string { return params[pname].Value.(string) }
+// Deprecated: use linter.CheckerParams.
+type CheckerParams = linter.CheckerParams
 
 // CheckerInfo holds checker metadata and structured documentation.
-type CheckerInfo struct {
-	// Name is a checker name.
-	Name string
-
-	// Tags is a list of labels that can be used to enable or disable checker.
-	// Common tags are "experimental" and "performance".
-	Tags []string
-
-	// Params declares checker-specific parameters. Optional.
-	Params CheckerParams
-
-	// Summary is a short one sentence description.
-	// Should not end with a period.
-	Summary string
-
-	// Details extends summary with additional info. Optional.
-	Details string
-
-	// Before is a code snippet of code that will violate rule.
-	Before string
-
-	// After is a code snippet of fixed code that complies to the rule.
-	After string
-
-	// Note is an optional caution message or advice.
-	Note string
-
-	// EmbeddedRuleguard tells whether this checker is auto-generated
-	// from the embedded ruleguard rules.
-	EmbeddedRuleguard bool
-
-	// Collection establishes a checker-to-collection relationship.
-	Collection *CheckerCollection
-}
-
-// GetCheckersInfo returns a checkers info list for all registered checkers.
-// The slice is sorted by a checker name.
-//
-// Info objects can be used to instantiate checkers with NewChecker function.
-func GetCheckersInfo() []*CheckerInfo {
-	return getCheckersInfo()
-}
-
-// HasTag reports whether checker described by the info has specified tag.
-func (info *CheckerInfo) HasTag(tag string) bool {
-	for i := range info.Tags {
-		if info.Tags[i] == tag {
-			return true
-		}
-	}
-	return false
-}
+// Deprecated: use linter.CheckerInfo.
+type CheckerInfo = linter.CheckerInfo
 
 // Checker is an implementation of a check that is described by the associated info.
-type Checker struct {
-	// Info is an info object that was used to instantiate this checker.
-	Info *CheckerInfo
-
-	ctx CheckerContext
-
-	fileWalker FileWalker
-}
-
-// Check runs rule checker over file f.
-func (c *Checker) Check(f *ast.File) []Warning {
-	c.ctx.warnings = c.ctx.warnings[:0]
-	c.fileWalker.WalkFile(f)
-	return c.ctx.warnings
-}
+// Deprecated: use linter.Checker.
+type Checker = linter.Checker
 
 // QuickFix is our analysis.TextEdit; we're using it here to avoid
 // direct analysis package dependency for now.
-type QuickFix struct {
-	From        token.Pos
-	To          token.Pos
-	Replacement []byte
-}
+// Deprecated: use linter.QuickFix.
+type QuickFix = linter.QuickFix
 
 // Warning represents issue that is found by checker.
-type Warning struct {
-	Pos token.Pos
+// Deprecated: use linter.Warning.
+type Warning = linter.Warning
 
-	// Text is warning message without source location info.
-	Text string
+// Context is a readonly state shared among every checker.
+// Deprecated: use linter.Context.
+type Context = linter.Context
 
-	// Suggestion is a quick fix for a given problem.
-	// QuickFix is analysis.TextEdit and can be used to
-	// construct an analysis.SuggestedFix object.
-	//
-	// For convenience, there is Warning.HasQuickFix() method
-	// that reports whether Suggestion has something meaningful.
-	Suggestion QuickFix
-}
+// CheckerContext is checker-local context copy.
+// Fields that are not from Context itself are writeable.
+// Deprecated: use linter.CheckerContext.
+type CheckerContext = linter.CheckerContext
+
+// FileWalker is an interface every checker should implement.
+//
+// The WalkFile method is executed for every Go file inside the
+// package that is being checked.
+// Deprecated: use linter.FileWalker.
+type FileWalker = linter.FileWalker
 
-// HasQuickFix reports whether this warning has a suggested fix.
-func (warn Warning) HasQuickFix() bool {
-	return warn.Suggestion.Replacement != nil
+// Deprecated: use linter.ParseGoVersion.
+func ParseGoVersion(version string) (GoVersion, error) {
+	return linter.ParseGoVersion(version)
 }
 
 // NewChecker returns initialized checker identified by an info.
 // info must be non-nil.
 // Returns an error if info describes a checker that was not properly registered,
 // or if checker fails to initialize.
+// Deprecated: use linter.NewChecker.
 func NewChecker(ctx *Context, info *CheckerInfo) (*Checker, error) {
-	return newChecker(ctx, info)
-}
-
-// Context is a readonly state shared among every checker.
-type Context struct {
-	// TypesInfo carries parsed packages types information.
-	TypesInfo *types.Info
-
-	// SizesInfo carries alignment and type size information.
-	// Arch-dependent.
-	SizesInfo types.Sizes
-
-	// GoVersion is a target Go version.
-	GoVersion GoVersion
-
-	// FileSet is a file set that was used during the program loading.
-	FileSet *token.FileSet
-
-	// Pkg describes package that is being checked.
-	Pkg *types.Package
-
-	// Filename is a currently checked file name.
-	Filename string
-
-	// Require records what optional resources are required
-	// by the checkers set that use this context.
-	//
-	// Every require fields makes associated context field
-	// to be properly initialized.
-	// For example, Context.require.PkgObjects => Context.PkgObjects.
-	Require struct {
-		PkgObjects bool
-		PkgRenames bool
-	}
-
-	// PkgObjects stores all imported packages and their local names.
-	PkgObjects map[*types.PkgName]string
-
-	// PkgRenames maps package path to its local renaming.
-	// Contains no entries for packages that were imported without
-	// explicit local names.
-	PkgRenames map[string]string
+	return linter.NewChecker(ctx, info)
 }
 
 // NewContext returns new shared context to be used by every checker.
 //
 // All data carried by the context is readonly for checkers,
 // but can be modified by the integrating application.
+// Deprecated: use linter.NewContext.
 func NewContext(fset *token.FileSet, sizes types.Sizes) *Context {
-	return &Context{
-		FileSet:   fset,
-		SizesInfo: sizes,
-		TypesInfo: &types.Info{},
-	}
-}
-
-// SetGoVersion adjust the target Go language version.
-//
-// The format is like "1.5", "1.8", etc.
-// It's permitted to have "go" prefix (e.g. "go1.5").
-//
-// Empty string (the default) means that we make no
-// Go version assumptions and (like gocritic does) behave
-// like all features are available. To make gocritic
-// more conservative, the upper Go version level should be adjusted.
-func (c *Context) SetGoVersion(version string) {
-	v, err := ParseGoVersion(version)
-	if err != nil {
-		panic(err)
-	}
-	c.GoVersion = v
-}
-
-// SetPackageInfo sets package-related metadata.
-//
-// Must be called for every package being checked.
-func (c *Context) SetPackageInfo(info *types.Info, pkg *types.Package) {
-	if info != nil {
-		// We do this kind of assignment to avoid
-		// changing c.typesInfo field address after
-		// every re-assignment.
-		*c.TypesInfo = *info
-	}
-	c.Pkg = pkg
-}
-
-// SetFileInfo sets file-related metadata.
-//
-// Must be called for every source code file being checked.
-func (c *Context) SetFileInfo(name string, f *ast.File) {
-	c.Filename = name
-	if c.Require.PkgObjects {
-		resolvePkgObjects(c, f)
-	}
-	if c.Require.PkgRenames {
-		resolvePkgRenames(c, f)
-	}
-}
-
-// CheckerContext is checker-local context copy.
-// Fields that are not from Context itself are writeable.
-type CheckerContext struct {
-	*Context
-
-	// printer used to format warning text.
-	printer *astfmt.Printer
-
-	warnings []Warning
+	return linter.NewContext(fset, sizes)
 }
 
-// Warn adds a Warning to checker output.
-func (ctx *CheckerContext) Warn(node ast.Node, format string, args ...interface{}) {
-	ctx.WarnWithPos(node.Pos(), format, args...)
-}
-
-// WarnFixable emits a warning with a fix suggestion provided by the caller.
-func (ctx *CheckerContext) WarnFixable(node ast.Node, fix QuickFix, format string, args ...interface{}) {
-	ctx.WarnFixableWithPos(node.Pos(), fix, format, args...)
-}
-
-// WarnWithPos adds a Warning to checker output. Useful for ruleguard's Report func.
-func (ctx *CheckerContext) WarnWithPos(pos token.Pos, format string, args ...interface{}) {
-	ctx.warnings = append(ctx.warnings, Warning{
-		Text: ctx.printer.Sprintf(format, args...),
-		Pos:  pos,
-	})
-}
-
-// WarnFixableWithPos adds a Warning to checker output. Useful for ruleguard's Report func.
-func (ctx *CheckerContext) WarnFixableWithPos(pos token.Pos, fix QuickFix, format string, args ...interface{}) {
-	ctx.warnings = append(ctx.warnings, Warning{
-		Text:       ctx.printer.Sprintf(format, args...),
-		Pos:        pos,
-		Suggestion: fix,
-	})
-}
-
-// UnknownType is a special sentinel value that is returned from the CheckerContext.TypeOf
-// method instead of the nil type.
-var UnknownType types.Type = types.Typ[types.Invalid]
-
-// TypeOf returns the type of expression x.
-//
-// Unlike TypesInfo.TypeOf, it never returns nil.
-// Instead, it returns the Invalid type as a sentinel UnknownType value.
-func (ctx *CheckerContext) TypeOf(x ast.Expr) types.Type {
-	typ := ctx.TypesInfo.TypeOf(x)
-	if typ != nil {
-		return typ
-	}
-	// Usually it means that some incorrect type info was loaded
-	// or the analyzed package was only partially (?) correct.
-	// To avoid nil pointer panics we can return a sentinel value
-	// that will fail most type assertions as well as kind checks
-	// (if the call side expects a *types.Basic).
-	return UnknownType
-}
-
-// SizeOf returns the size of the typ in bytes.
-//
-// Unlike SizesInfo.SizeOf, it will not panic on generic types.
-func (ctx *CheckerContext) SizeOf(typ types.Type) (int64, bool) {
-	if _, ok := typ.(*types.TypeParam); ok {
-		return 0, false
-	}
-	if named, ok := typ.(*types.Named); ok && named.TypeParams() != nil {
-		return 0, false
-	}
-	return ctx.SizesInfo.Sizeof(typ), true
-}
-
-// FileWalker is an interface every checker should implement.
+// GetCheckersInfo returns a checkers info list for all registered checkers.
+// The slice is sorted by a checker name.
 //
-// The WalkFile method is executed for every Go file inside the
-// package that is being checked.
-type FileWalker interface {
-	WalkFile(*ast.File)
+// Info objects can be used to instantiate checkers with NewChecker function.
+// Deprecated: use linter.GetCheckersInfo.
+func GetCheckersInfo() []*CheckerInfo {
+	return linter.GetCheckersInfo()
 }
diff --git a/framework/linter/go_version.go b/linter/go_version.go
similarity index 100%
rename from framework/linter/go_version.go
rename to linter/go_version.go
diff --git a/framework/linter/go_version_test.go b/linter/go_version_test.go
similarity index 100%
rename from framework/linter/go_version_test.go
rename to linter/go_version_test.go
diff --git a/framework/linter/checkers_db.go b/linter/helpers.go
similarity index 100%
rename from framework/linter/checkers_db.go
rename to linter/helpers.go
diff --git a/linter/linter.go b/linter/linter.go
new file mode 100644
index 0000000..12f0a1c
--- /dev/null
+++ b/linter/linter.go
@@ -0,0 +1,373 @@
+package linter
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+	"strconv"
+
+	"github.com/go-toolsmith/astfmt"
+)
+
+// UnknownType is a special sentinel value that is returned from the CheckerContext.TypeOf
+// method instead of the nil type.
+var UnknownType types.Type = types.Typ[types.Invalid]
+
+// FileWalker is an interface every checker should implement.
+//
+// The WalkFile method is executed for every Go file inside the
+// package that is being checked.
+type FileWalker interface {
+	WalkFile(*ast.File)
+}
+
+// CheckerCollection provides additional information for a group of checkers.
+type CheckerCollection struct {
+	// URL is a link for a main source of information on the collection.
+	URL string
+}
+
+// AddChecker registers a new checker into a checkers pool.
+// Constructor is used to create a new checker instance.
+// Checker name (defined in CheckerInfo.Name) must be unique.
+//
+// CheckerInfo.Collection is automatically set to the coll (the receiver).
+//
+// If checker is never needed, for example if it is disabled,
+// constructor will not be called.
+func (coll *CheckerCollection) AddChecker(info *CheckerInfo, constructor func(*CheckerContext) (FileWalker, error)) {
+	if coll == nil {
+		panic("adding checker to a nil collection")
+	}
+	info.Collection = coll
+	addChecker(info, constructor)
+}
+
+// CheckerParam describes a single checker customizable parameter.
+type CheckerParam struct {
+	// Value holds parameter bound value.
+	// It might be overwritten by the integrating linter.
+	//
+	// Permitted types include:
+	//	- int
+	//	- bool
+	//	- string
+	Value interface{}
+
+	// Usage gives an overview about what parameter does.
+	Usage string
+}
+
+// CheckerParams holds all checker-specific parameters.
+//
+// Provides convenient access to the loosely typed underlying map.
+type CheckerParams map[string]*CheckerParam
+
+// Int lookups pname key in underlying map and type-asserts it to int.
+func (params CheckerParams) Int(pname string) int { return params[pname].Value.(int) }
+
+// Bool lookups pname key in underlying map and type-asserts it to bool.
+func (params CheckerParams) Bool(pname string) bool { return params[pname].Value.(bool) }
+
+// String lookups pname key in underlying map and type-asserts it to string.
+func (params CheckerParams) String(pname string) string { return params[pname].Value.(string) }
+
+// CheckerInfo holds checker metadata and structured documentation.
+type CheckerInfo struct {
+	// Name is a checker name.
+	Name string
+
+	// Tags is a list of labels that can be used to enable or disable checker.
+	// Common tags are "experimental" and "performance".
+	Tags []string
+
+	// Params declares checker-specific parameters. Optional.
+	Params CheckerParams
+
+	// Summary is a short one sentence description.
+	// Should not end with a period.
+	Summary string
+
+	// Details extends summary with additional info. Optional.
+	Details string
+
+	// Before is a code snippet of code that will violate rule.
+	Before string
+
+	// After is a code snippet of fixed code that complies to the rule.
+	After string
+
+	// Note is an optional caution message or advice.
+	Note string
+
+	// EmbeddedRuleguard tells whether this checker is auto-generated
+	// from the embedded ruleguard rules.
+	EmbeddedRuleguard bool
+
+	// Collection establishes a checker-to-collection relationship.
+	Collection *CheckerCollection
+}
+
+// GetCheckersInfo returns a checkers info list for all registered checkers.
+// The slice is sorted by a checker name.
+//
+// Info objects can be used to instantiate checkers with NewChecker function.
+func GetCheckersInfo() []*CheckerInfo {
+	return getCheckersInfo()
+}
+
+// HasTag reports whether checker described by the info has specified tag.
+func (info *CheckerInfo) HasTag(tag string) bool {
+	for i := range info.Tags {
+		if info.Tags[i] == tag {
+			return true
+		}
+	}
+	return false
+}
+
+// Checker is an implementation of a check that is described by the associated info.
+type Checker struct {
+	// Info is an info object that was used to instantiate this checker.
+	Info *CheckerInfo
+
+	ctx CheckerContext
+
+	fileWalker FileWalker
+}
+
+// NewChecker returns initialized checker identified by an info.
+// info must be non-nil.
+// Returns an error if info describes a checker that was not properly registered,
+// or if checker fails to initialize.
+func NewChecker(ctx *Context, info *CheckerInfo) (*Checker, error) {
+	return newChecker(ctx, info)
+}
+
+// Check runs rule checker over file f.
+func (c *Checker) Check(f *ast.File) []Warning {
+	c.ctx.warnings = c.ctx.warnings[:0]
+	c.fileWalker.WalkFile(f)
+	return c.ctx.warnings
+}
+
+// QuickFix is our analysis.TextEdit; we're using it here to avoid
+// direct analysis package dependency for now.
+type QuickFix struct {
+	From        token.Pos
+	To          token.Pos
+	Replacement []byte
+}
+
+// Warning represents issue that is found by checker.
+type Warning struct {
+	Pos token.Pos
+
+	// Text is warning message without source location info.
+	Text string
+
+	// Suggestion is a quick fix for a given problem.
+	// QuickFix is analysis.TextEdit and can be used to
+	// construct an analysis.SuggestedFix object.
+	//
+	// For convenience, there is Warning.HasQuickFix() method
+	// that reports whether Suggestion has something meaningful.
+	Suggestion QuickFix
+}
+
+// HasQuickFix reports whether this warning has a suggested fix.
+func (warn Warning) HasQuickFix() bool {
+	return warn.Suggestion.Replacement != nil
+}
+
+// Context is a readonly state shared among every checker.
+type Context struct {
+	// TypesInfo carries parsed packages types information.
+	TypesInfo *types.Info
+
+	// SizesInfo carries alignment and type size information.
+	// Arch-dependent.
+	SizesInfo types.Sizes
+
+	// GoVersion is a target Go version.
+	GoVersion GoVersion
+
+	// FileSet is a file set that was used during the program loading.
+	FileSet *token.FileSet
+
+	// Pkg describes package that is being checked.
+	Pkg *types.Package
+
+	// Filename is a currently checked file name.
+	Filename string
+
+	// Require records what optional resources are required
+	// by the checkers set that use this context.
+	//
+	// Every require fields makes associated context field
+	// to be properly initialized.
+	// For example, Context.require.PkgObjects => Context.PkgObjects.
+	Require struct {
+		PkgObjects bool
+		PkgRenames bool
+	}
+
+	// PkgObjects stores all imported packages and their local names.
+	PkgObjects map[*types.PkgName]string
+
+	// PkgRenames maps package path to its local renaming.
+	// Contains no entries for packages that were imported without
+	// explicit local names.
+	PkgRenames map[string]string
+}
+
+// NewContext returns new shared context to be used by every checker.
+//
+// All data carried by the context is readonly for checkers,
+// but can be modified by the integrating application.
+func NewContext(fset *token.FileSet, sizes types.Sizes) *Context {
+	return &Context{
+		FileSet:   fset,
+		SizesInfo: sizes,
+		TypesInfo: &types.Info{},
+	}
+}
+
+// SetGoVersion adjust the target Go language version.
+//
+// The format is like "1.5", "1.8", etc.
+// It's permitted to have "go" prefix (e.g. "go1.5").
+//
+// Empty string (the default) means that we make no
+// Go version assumptions and (like gocritic does) behave
+// like all features are available. To make gocritic
+// more conservative, the upper Go version level should be adjusted.
+func (c *Context) SetGoVersion(version string) {
+	v, err := ParseGoVersion(version)
+	if err != nil {
+		panic(err)
+	}
+	c.GoVersion = v
+}
+
+// SetPackageInfo sets package-related metadata.
+//
+// Must be called for every package being checked.
+func (c *Context) SetPackageInfo(info *types.Info, pkg *types.Package) {
+	if info != nil {
+		// We do this kind of assignment to avoid
+		// changing c.typesInfo field address after
+		// every re-assignment.
+		*c.TypesInfo = *info
+	}
+	c.Pkg = pkg
+}
+
+// SetFileInfo sets file-related metadata.
+//
+// Must be called for every source code file being checked.
+func (c *Context) SetFileInfo(name string, f *ast.File) {
+	c.Filename = name
+	if c.Require.PkgObjects {
+		resolvePkgObjects(c, f)
+	}
+	if c.Require.PkgRenames {
+		resolvePkgRenames(c, f)
+	}
+}
+
+// CheckerContext is checker-local context copy.
+// Fields that are not from Context itself are writeable.
+type CheckerContext struct {
+	*Context
+
+	// printer used to format warning text.
+	printer *astfmt.Printer
+
+	warnings []Warning
+}
+
+// Warn adds a Warning to checker output.
+func (ctx *CheckerContext) Warn(node ast.Node, format string, args ...interface{}) {
+	ctx.WarnWithPos(node.Pos(), format, args...)
+}
+
+// WarnFixable emits a warning with a fix suggestion provided by the caller.
+func (ctx *CheckerContext) WarnFixable(node ast.Node, fix QuickFix, format string, args ...interface{}) {
+	ctx.WarnFixableWithPos(node.Pos(), fix, format, args...)
+}
+
+// WarnWithPos adds a Warning to checker output. Useful for ruleguard's Report func.
+func (ctx *CheckerContext) WarnWithPos(pos token.Pos, format string, args ...interface{}) {
+	ctx.warnings = append(ctx.warnings, Warning{
+		Text: ctx.printer.Sprintf(format, args...),
+		Pos:  pos,
+	})
+}
+
+// WarnFixableWithPos adds a Warning to checker output. Useful for ruleguard's Report func.
+func (ctx *CheckerContext) WarnFixableWithPos(pos token.Pos, fix QuickFix, format string, args ...interface{}) {
+	ctx.warnings = append(ctx.warnings, Warning{
+		Text:       ctx.printer.Sprintf(format, args...),
+		Pos:        pos,
+		Suggestion: fix,
+	})
+}
+
+// TypeOf returns the type of expression x.
+//
+// Unlike TypesInfo.TypeOf, it never returns nil.
+// Instead, it returns the Invalid type as a sentinel UnknownType value.
+func (ctx *CheckerContext) TypeOf(x ast.Expr) types.Type {
+	typ := ctx.TypesInfo.TypeOf(x)
+	if typ != nil {
+		return typ
+	}
+	// Usually it means that some incorrect type info was loaded
+	// or the analyzed package was only partially (?) correct.
+	// To avoid nil pointer panics we can return a sentinel value
+	// that will fail most type assertions as well as kind checks
+	// (if the call side expects a *types.Basic).
+	return UnknownType
+}
+
+// SizeOf returns the size of the typ in bytes.
+//
+// Unlike SizesInfo.SizeOf, it will not panic on generic types.
+func (ctx *CheckerContext) SizeOf(typ types.Type) (int64, bool) {
+	if _, ok := typ.(*types.TypeParam); ok {
+		return 0, false
+	}
+	if named, ok := typ.(*types.Named); ok && named.TypeParams() != nil {
+		return 0, false
+	}
+	return ctx.SizesInfo.Sizeof(typ), true
+}
+
+func resolvePkgObjects(ctx *Context, f *ast.File) {
+	ctx.PkgObjects = make(map[*types.PkgName]string, len(f.Imports))
+
+	for _, spec := range f.Imports {
+		if spec.Name != nil {
+			obj := ctx.TypesInfo.ObjectOf(spec.Name)
+			ctx.PkgObjects[obj.(*types.PkgName)] = spec.Name.Name
+		} else {
+			obj := ctx.TypesInfo.Implicits[spec]
+			ctx.PkgObjects[obj.(*types.PkgName)] = obj.Name()
+		}
+	}
+}
+
+func resolvePkgRenames(ctx *Context, f *ast.File) {
+	ctx.PkgRenames = make(map[string]string)
+
+	for _, spec := range f.Imports {
+		if spec.Name != nil {
+			path, err := strconv.Unquote(spec.Path.Value)
+			if err != nil {
+				panic(err)
+			}
+			ctx.PkgRenames[path] = spec.Name.Name
+		}
+	}
+}


Test patch:
diff --git a/checkers/checkers_test.go b/checkers/checkers_test.go
index 75731c8..ead511f 100644
--- a/checkers/checkers_test.go
+++ b/checkers/checkers_test.go
@@ -7,8 +7,9 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/go-critic/go-critic/framework/linter"
-	"github.com/go-critic/go-critic/framework/linttest"
+	"github.com/go-critic/go-critic/checkers/internal/linttest"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/google/go-cmp/cmp"
 )
 
diff --git a/framework/linttest/end2end.go b/checkers/internal/linttest/end2end.go
similarity index 100%
rename from framework/linttest/end2end.go
rename to checkers/internal/linttest/end2end.go
diff --git a/framework/linttest/integration.go b/checkers/internal/linttest/integration.go
similarity index 100%
rename from framework/linttest/integration.go
rename to checkers/internal/linttest/integration.go
diff --git a/framework/linttest/linttest.go b/checkers/internal/linttest/linttest.go
similarity index 99%
rename from framework/linttest/linttest.go
rename to checkers/internal/linttest/linttest.go
index 11a1041..4670d7d 100644
--- a/framework/linttest/linttest.go
+++ b/checkers/internal/linttest/linttest.go
@@ -11,7 +11,8 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
+
 	"github.com/go-toolsmith/pkgload"
 	"golang.org/x/tools/go/packages"
 )
diff --git a/checkers/testdata/importShadow/negative_tests.go b/checkers/testdata/importShadow/negative_tests.go
index b7dc827..c2d1c34 100644
--- a/checkers/testdata/importShadow/negative_tests.go
+++ b/checkers/testdata/importShadow/negative_tests.go
@@ -4,9 +4,9 @@ import (
 	"fmt"
 	"math"
 
-	_ "github.com/go-toolsmith/astfmt" // To reproduce #665
+	"github.com/go-critic/go-critic/linter"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	_ "github.com/go-toolsmith/astfmt" // To reproduce #665
 )
 
 func noWarnings() {
diff --git a/checkers/testdata/importShadow/positive_tests.go b/checkers/testdata/importShadow/positive_tests.go
index 94d9e65..b302ee9 100644
--- a/checkers/testdata/importShadow/positive_tests.go
+++ b/checkers/testdata/importShadow/positive_tests.go
@@ -7,7 +7,7 @@ import (
 	mymath1 "math"
 	mymath2 "math"
 
-	"github.com/go-critic/go-critic/framework/linter"
+	"github.com/go-critic/go-critic/linter"
 )
 
 var _ = mymath1.E
@@ -18,7 +18,7 @@ func shadowImportedPackages() {
 
 	/*! shadow of imported package 'math' */
 	math := "some math"
-	/*! shadow of imported from 'github.com/go-critic/go-critic/framework/linter' package 'linter' */
+	/*! shadow of imported from 'github.com/go-critic/go-critic/linter' package 'linter' */
 	linter := "some lint"
 
 	fmt.Printf("Hello math=%v, lint=%v", math, linter)
@@ -30,7 +30,7 @@ func genDeclShadow() {
 	var (
 		/*! shadow of imported package 'fmt' */
 		fmt = 2
-		/*! shadow of imported from 'github.com/go-critic/go-critic/framework/linter' package 'linter' */
+		/*! shadow of imported from 'github.com/go-critic/go-critic/linter' package 'linter' */
 		linter = 3
 	)
 	_, _ = fmt, linter