From 0b092cc31ea2d9cd3dc1bf465b570f9fe7320114 Mon Sep 17 00:00:00 2001 From: Sasha Melentyev Date: Sun, 21 Aug 2022 14:15:09 +0300 Subject: [PATCH] feat: add more cases for switch stmt --- pkg/analyzer/analyzer.go | 87 +- .../internal/template/test-httpmethod.go.tmpl | 20 + .../template/test-httpstatuscode.go.tmpl | 21 +- pkg/analyzer/testdata/src/a/http/method.go | 144 +++ .../testdata/src/a/http/statuscode.go | 992 ++++++++++++++++++ 5 files changed, 1240 insertions(+), 24 deletions(-) diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 63c2f71..2a619aa 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -228,38 +228,79 @@ func run(pass *analysis.Pass) (interface{}, error) { case *ast.SwitchStmt: selectorExpr, ok := n.Tag.(*ast.SelectorExpr) - if !ok { - return - } + if ok { + var checkFunc func(pass *analysis.Pass, basicLit *ast.BasicLit) - var checkFunc func(pass *analysis.Pass, basicLit *ast.BasicLit) + switch selectorExpr.Sel.Name { + case "StatusCode": + if !lookupFlag(pass, HTTPStatusCodeFlag) { + return + } - switch selectorExpr.Sel.Name { - case "StatusCode": - if !lookupFlag(pass, HTTPStatusCodeFlag) { - return - } - checkFunc = checkHTTPStatusCode - case "Method": - if !lookupFlag(pass, HTTPMethodFlag) { + checkFunc = checkHTTPStatusCode + case "Method": + if !lookupFlag(pass, HTTPMethodFlag) { + return + } + + checkFunc = checkHTTPMethod + default: return } - checkFunc = checkHTTPMethod - default: - return - } - for _, stmt := range n.Body.List { - caseClause, ok := stmt.(*ast.CaseClause) - if !ok { - continue + for _, stmt := range n.Body.List { + caseClause, ok := stmt.(*ast.CaseClause) + if !ok { + continue + } + + for _, expr := range caseClause.List { + basicLit, ok := expr.(*ast.BasicLit) + if !ok { + continue + } + + checkFunc(pass, basicLit) + } } - for _, expr := range caseClause.List { - basicLit, ok := expr.(*ast.BasicLit) + } else { + for _, stmt := range n.Body.List { + caseClause, ok := stmt.(*ast.CaseClause) if !ok { continue } - checkFunc(pass, basicLit) + + for _, expr := range caseClause.List { + binaryExpr, ok := expr.(*ast.BinaryExpr) + if !ok { + continue + } + + selectorExpr, ok := binaryExpr.X.(*ast.SelectorExpr) + if !ok { + continue + } + + basicLit, ok := binaryExpr.Y.(*ast.BasicLit) + if !ok { + continue + } + + switch selectorExpr.Sel.Name { + case "StatusCode": + if !lookupFlag(pass, HTTPStatusCodeFlag) { + continue + } + + checkHTTPStatusCode(pass, basicLit) + case "Method": + if !lookupFlag(pass, HTTPMethodFlag) { + continue + } + + checkHTTPMethod(pass, basicLit) + } + } } } } diff --git a/pkg/analyzer/internal/template/test-httpmethod.go.tmpl b/pkg/analyzer/internal/template/test-httpmethod.go.tmpl index 1274943..cce6b13 100644 --- a/pkg/analyzer/internal/template/test-httpmethod.go.tmpl +++ b/pkg/analyzer/internal/template/test-httpmethod.go.tmpl @@ -83,3 +83,23 @@ func _() { } } {{ end -}} + +{{ range $key, $value := .Mapping }} +func _() { + var r http.Request + switch { + case r.Method == "{{ $key }}": // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}` + return + } +} +{{ end -}} + +{{ range $key, $value := .Mapping }} +func _() { + var r http.Request + switch { + case r.Method == {{ $value }}: + return + } +} +{{ end -}} diff --git a/pkg/analyzer/internal/template/test-httpstatuscode.go.tmpl b/pkg/analyzer/internal/template/test-httpstatuscode.go.tmpl index 2e02404..120a974 100644 --- a/pkg/analyzer/internal/template/test-httpstatuscode.go.tmpl +++ b/pkg/analyzer/internal/template/test-httpstatuscode.go.tmpl @@ -127,7 +127,6 @@ func _() { } {{ end -}} - {{ range $key, $value := .Mapping }} func _() { var resp http.Response @@ -147,3 +146,23 @@ func _() { } } {{ end -}} + +{{ range $key, $value := .Mapping }} +func _() { + var resp http.Response + switch { + case resp.StatusCode == {{ $key }}: // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}` + return + } +} +{{ end -}} + +{{ range $key, $value := .Mapping }} +func _() { + var resp http.Response + switch { + case resp.StatusCode == {{ $value }}: + return + } +} +{{ end -}} diff --git a/pkg/analyzer/testdata/src/a/http/method.go b/pkg/analyzer/testdata/src/a/http/method.go index 42fca51..5b21984 100755 --- a/pkg/analyzer/testdata/src/a/http/method.go +++ b/pkg/analyzer/testdata/src/a/http/method.go @@ -441,3 +441,147 @@ func _() { return } } + +func _() { + var r http.Request + switch { + case r.Method == "CONNECT": // want `"CONNECT" can be replaced by http\.MethodConnect` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "DELETE": // want `"DELETE" can be replaced by http\.MethodDelete` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "GET": // want `"GET" can be replaced by http\.MethodGet` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "HEAD": // want `"HEAD" can be replaced by http\.MethodHead` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "OPTIONS": // want `"OPTIONS" can be replaced by http\.MethodOptions` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "PATCH": // want `"PATCH" can be replaced by http\.MethodPatch` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "POST": // want `"POST" can be replaced by http\.MethodPost` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "PUT": // want `"PUT" can be replaced by http\.MethodPut` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == "TRACE": // want `"TRACE" can be replaced by http\.MethodTrace` + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodConnect: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodDelete: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodGet: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodHead: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodOptions: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodPatch: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodPost: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodPut: + return + } +} + +func _() { + var r http.Request + switch { + case r.Method == http.MethodTrace: + return + } +} diff --git a/pkg/analyzer/testdata/src/a/http/statuscode.go b/pkg/analyzer/testdata/src/a/http/statuscode.go index 85535e2..c2165ed 100755 --- a/pkg/analyzer/testdata/src/a/http/statuscode.go +++ b/pkg/analyzer/testdata/src/a/http/statuscode.go @@ -6333,3 +6333,995 @@ func _() { return } } + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 100: // want `"100" can be replaced by http\.StatusContinue` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 101: // want `"101" can be replaced by http\.StatusSwitchingProtocols` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 102: // want `"102" can be replaced by http\.StatusProcessing` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 103: // want `"103" can be replaced by http\.StatusEarlyHints` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 200: // want `"200" can be replaced by http\.StatusOK` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 201: // want `"201" can be replaced by http\.StatusCreated` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 202: // want `"202" can be replaced by http\.StatusAccepted` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 203: // want `"203" can be replaced by http\.StatusNonAuthoritativeInfo` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 204: // want `"204" can be replaced by http\.StatusNoContent` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 205: // want `"205" can be replaced by http\.StatusResetContent` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 206: // want `"206" can be replaced by http\.StatusPartialContent` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 207: // want `"207" can be replaced by http\.StatusMultiStatus` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 208: // want `"208" can be replaced by http\.StatusAlreadyReported` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 226: // want `"226" can be replaced by http\.StatusIMUsed` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 300: // want `"300" can be replaced by http\.StatusMultipleChoices` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 301: // want `"301" can be replaced by http\.StatusMovedPermanently` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 302: // want `"302" can be replaced by http\.StatusFound` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 303: // want `"303" can be replaced by http\.StatusSeeOther` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 304: // want `"304" can be replaced by http\.StatusNotModified` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 305: // want `"305" can be replaced by http\.StatusUseProxy` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 307: // want `"307" can be replaced by http\.StatusTemporaryRedirect` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 308: // want `"308" can be replaced by http\.StatusPermanentRedirect` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 400: // want `"400" can be replaced by http\.StatusBadRequest` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 401: // want `"401" can be replaced by http\.StatusUnauthorized` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 402: // want `"402" can be replaced by http\.StatusPaymentRequired` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 403: // want `"403" can be replaced by http\.StatusForbidden` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 404: // want `"404" can be replaced by http\.StatusNotFound` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 405: // want `"405" can be replaced by http\.StatusMethodNotAllowed` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 406: // want `"406" can be replaced by http\.StatusNotAcceptable` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 407: // want `"407" can be replaced by http\.StatusProxyAuthRequired` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 408: // want `"408" can be replaced by http\.StatusRequestTimeout` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 409: // want `"409" can be replaced by http\.StatusConflict` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 410: // want `"410" can be replaced by http\.StatusGone` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 411: // want `"411" can be replaced by http\.StatusLengthRequired` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 412: // want `"412" can be replaced by http\.StatusPreconditionFailed` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 413: // want `"413" can be replaced by http\.StatusRequestEntityTooLarge` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 414: // want `"414" can be replaced by http\.StatusRequestURITooLong` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 415: // want `"415" can be replaced by http\.StatusUnsupportedMediaType` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 416: // want `"416" can be replaced by http\.StatusRequestedRangeNotSatisfiable` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 417: // want `"417" can be replaced by http\.StatusExpectationFailed` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 418: // want `"418" can be replaced by http\.StatusTeapot` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 421: // want `"421" can be replaced by http\.StatusMisdirectedRequest` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 422: // want `"422" can be replaced by http\.StatusUnprocessableEntity` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 423: // want `"423" can be replaced by http\.StatusLocked` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 424: // want `"424" can be replaced by http\.StatusFailedDependency` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 425: // want `"425" can be replaced by http\.StatusTooEarly` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 426: // want `"426" can be replaced by http\.StatusUpgradeRequired` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 428: // want `"428" can be replaced by http\.StatusPreconditionRequired` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 429: // want `"429" can be replaced by http\.StatusTooManyRequests` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 431: // want `"431" can be replaced by http\.StatusRequestHeaderFieldsTooLarge` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 451: // want `"451" can be replaced by http\.StatusUnavailableForLegalReasons` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 500: // want `"500" can be replaced by http\.StatusInternalServerError` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 501: // want `"501" can be replaced by http\.StatusNotImplemented` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 502: // want `"502" can be replaced by http\.StatusBadGateway` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 503: // want `"503" can be replaced by http\.StatusServiceUnavailable` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 504: // want `"504" can be replaced by http\.StatusGatewayTimeout` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 505: // want `"505" can be replaced by http\.StatusHTTPVersionNotSupported` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 506: // want `"506" can be replaced by http\.StatusVariantAlsoNegotiates` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 507: // want `"507" can be replaced by http\.StatusInsufficientStorage` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 508: // want `"508" can be replaced by http\.StatusLoopDetected` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 510: // want `"510" can be replaced by http\.StatusNotExtended` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == 511: // want `"511" can be replaced by http\.StatusNetworkAuthenticationRequired` + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusContinue: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusSwitchingProtocols: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusProcessing: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusEarlyHints: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusOK: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusCreated: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusAccepted: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNonAuthoritativeInfo: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNoContent: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusResetContent: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusPartialContent: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusMultiStatus: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusAlreadyReported: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusIMUsed: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusMultipleChoices: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusMovedPermanently: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusFound: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusSeeOther: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNotModified: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusUseProxy: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusTemporaryRedirect: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusPermanentRedirect: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusBadRequest: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusUnauthorized: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusPaymentRequired: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusForbidden: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNotFound: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusMethodNotAllowed: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNotAcceptable: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusProxyAuthRequired: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusRequestTimeout: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusConflict: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusGone: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusLengthRequired: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusPreconditionFailed: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusRequestEntityTooLarge: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusRequestURITooLong: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusUnsupportedMediaType: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusRequestedRangeNotSatisfiable: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusExpectationFailed: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusTeapot: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusMisdirectedRequest: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusUnprocessableEntity: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusLocked: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusFailedDependency: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusTooEarly: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusUpgradeRequired: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusPreconditionRequired: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusTooManyRequests: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusRequestHeaderFieldsTooLarge: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusUnavailableForLegalReasons: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusInternalServerError: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNotImplemented: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusBadGateway: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusServiceUnavailable: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusGatewayTimeout: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusHTTPVersionNotSupported: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusVariantAlsoNegotiates: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusInsufficientStorage: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusLoopDetected: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNotExtended: + return + } +} + +func _() { + var resp http.Response + switch { + case resp.StatusCode == http.StatusNetworkAuthenticationRequired: + return + } +}