Skip to content

Commit

Permalink
feat: add http.NoBody (#34)
Browse files Browse the repository at this point in the history
feat: add http.NoBody
  • Loading branch information
sashamelentyev committed Aug 7, 2022
1 parent 738e06f commit bc6bdf8
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 48 deletions.
52 changes: 44 additions & 8 deletions pkg/analyzer/analyzer.go
Expand Up @@ -20,6 +20,7 @@ const (
CryptoHashFlag = "crypto-hash"
HTTPMethodFlag = "http-method"
HTTPStatusCodeFlag = "http-status-code"
HTTPNoBodyFlag = "http-no-body"
DefaultRPCPathFlag = "default-rpc-path"
)

Expand All @@ -38,6 +39,7 @@ func flags() flag.FlagSet {
flags := flag.NewFlagSet("", flag.ExitOnError)
flags.Bool(HTTPMethodFlag, true, "suggest the use of http.MethodXX")
flags.Bool(HTTPStatusCodeFlag, true, "suggest the use of http.StatusXX")
flags.Bool(HTTPNoBodyFlag, false, "suggest the use of http.NoBody")
flags.Bool(TimeWeekdayFlag, false, "suggest the use of time.Weekday")
flags.Bool(TimeMonthFlag, false, "suggest the use of time.Month")
flags.Bool(TimeLayoutFlag, false, "suggest the use of time.Layout")
Expand Down Expand Up @@ -74,21 +76,29 @@ func run(pass *analysis.Pass) (interface{}, error) {
}

case "NewRequest":
if !lookupFlag(pass, HTTPMethodFlag) {
return
if lookupFlag(pass, HTTPMethodFlag) {
if basicLit := getBasicLitFromArgs(n.Args, 3, 0, token.STRING); basicLit != nil {
checkHTTPMethod(pass, basicLit)
}
}

if basicLit := getBasicLitFromArgs(n.Args, 3, 0, token.STRING); basicLit != nil {
checkHTTPMethod(pass, basicLit)
if lookupFlag(pass, HTTPNoBodyFlag) {
if ident := getIdentFromArgs(n.Args, 3, 2); ident != nil {
checkHTTPNoBody(pass, ident)
}
}

case "NewRequestWithContext":
if !lookupFlag(pass, HTTPMethodFlag) {
return
if lookupFlag(pass, HTTPMethodFlag) {
if basicLit := getBasicLitFromArgs(n.Args, 4, 1, token.STRING); basicLit != nil {
checkHTTPMethod(pass, basicLit)
}
}

if basicLit := getBasicLitFromArgs(n.Args, 4, 1, token.STRING); basicLit != nil {
checkHTTPMethod(pass, basicLit)
if lookupFlag(pass, HTTPNoBodyFlag) {
if ident := getIdentFromArgs(n.Args, 4, 3); ident != nil {
checkHTTPNoBody(pass, ident)
}
}
}

Expand Down Expand Up @@ -173,6 +183,14 @@ func checkHTTPStatusCode(pass *analysis.Pass, basicLit *ast.BasicLit) {
}
}

func checkHTTPNoBody(pass *analysis.Pass, ident *ast.Ident) {
currentVal := ident.Name

if newVal, ok := mapping.HTTPNoBody[currentVal]; ok {
report(pass, ident.Pos(), currentVal, newVal)
}
}

func checkTimeWeekday(pass *analysis.Pass, pos token.Pos, currentVal string) {
if newVal, ok := mapping.TimeWeekday[currentVal]; ok {
report(pass, pos, currentVal, newVal)
Expand Down Expand Up @@ -226,6 +244,24 @@ func getBasicLitFromArgs(args []ast.Expr, count, idx int, typ token.Token) *ast.
return basicLit
}

// getIdentFromArgs gets the *ast.Ident of a function argument.
//
// Arguments:
// - count - expected number of argument in function
// - idx - index of the argument to get the *ast.Ident
func getIdentFromArgs(args []ast.Expr, count, idx int) *ast.Ident {
if len(args) != count {
return nil
}

ident, ok := args[idx].(*ast.Ident)
if !ok {
return nil
}

return ident
}

// getBasicLitFromElts gets the *ast.BasicLit of a struct elements.
//
// Arguments:
Expand Down
3 changes: 3 additions & 0 deletions pkg/analyzer/analyzer_test.go
Expand Up @@ -33,6 +33,9 @@ func TestUseStdlibVars(t *testing.T) {
if err := a.Flags.Set(analyzer.DefaultRPCPathFlag, "true"); err != nil {
t.Error(err)
}
if err := a.Flags.Set(analyzer.HTTPNoBodyFlag, "true"); err != nil {
t.Error(err)
}

analysistest.Run(t, analysistest.TestData(), a, pkgs...)
}
6 changes: 6 additions & 0 deletions pkg/analyzer/internal/gen.go
Expand Up @@ -83,6 +83,12 @@ func main() {
templateName: "test-issue32.go.tmpl",
fileName: "pkg/analyzer/testdata/src/a/http/issue32.go",
},
{
mapping: mapping.HTTPNoBody,
packageName: "http_test",
templateName: "test-httpnobody.go.tmpl",
fileName: "pkg/analyzer/testdata/src/a/http/nobody.go",
},
}

for _, operation := range operations {
Expand Down
4 changes: 4 additions & 0 deletions pkg/analyzer/internal/mapping/mapping.go
Expand Up @@ -159,3 +159,7 @@ var TimeLayout = map[string]string{
time.StampMicro: "time.StampMicro",
time.StampNano: "time.StampNano",
}

var HTTPNoBody = map[string]string{
"nil": "http.NoBody",
}
4 changes: 2 additions & 2 deletions pkg/analyzer/internal/template/test-httpmethod.go.tmpl
Expand Up @@ -18,13 +18,13 @@ const (

func _() {
{{- range $key, $value := .Mapping }}
_, _ = http.NewRequest("{{ $key }}", "", nil) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
_, _ = http.NewRequest("{{ $key }}", "", http.NoBody) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
{{- end }}
}

func _() {
{{- range $key, $value := .Mapping }}
_, _ = http.NewRequestWithContext(nil, "{{ $key }}", "", nil) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
_, _ = http.NewRequestWithContext(nil, "{{ $key }}", "", http.NoBody) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
{{- end }}
}

Expand Down
17 changes: 17 additions & 0 deletions pkg/analyzer/internal/template/test-httpnobody.go.tmpl
@@ -0,0 +1,17 @@
// Code generated by usestdlibvars, DO NOT EDIT.

package {{ .PackageName }}

import "net/http"

func _() {
{{- range $key, $value := .Mapping }}
_, _ = http.NewRequest(http.MethodGet, "", {{ $key }}) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
{{- end }}
}

func _() {
{{- range $key, $value := .Mapping }}
_, _ = http.NewRequestWithContext(nil, http.MethodGet, "", {{ $key }}) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
{{- end }}
}
4 changes: 2 additions & 2 deletions pkg/analyzer/internal/template/test-issue32.go.tmpl
Expand Up @@ -18,13 +18,13 @@ const (

func _() {
{{- range $key, $value := .Mapping }}
_, _ = http.NewRequest("{{ lower $key }}", "", nil) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
_, _ = http.NewRequest("{{ lower $key }}", "", http.NoBody) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
{{- end }}
}

func _() {
{{- range $key, $value := .Mapping }}
_, _ = http.NewRequestWithContext(nil, "{{ lower $key }}", "", nil) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
_, _ = http.NewRequestWithContext(nil, "{{ lower $key }}", "", http.NoBody) // want `"{{ quoteMeta $key }}" can be replaced by {{ quoteMeta $value }}`
{{- end }}
}

Expand Down
36 changes: 18 additions & 18 deletions pkg/analyzer/testdata/src/a/http/issue32.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 18 additions & 18 deletions pkg/analyzer/testdata/src/a/http/method.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions pkg/analyzer/testdata/src/a/http/nobody.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bc6bdf8

Please sign in to comment.