Skip to content

Commit b6dbcdb

Browse files
committed
highlight
1 parent 83d37da commit b6dbcdb

File tree

4 files changed

+114
-294
lines changed

4 files changed

+114
-294
lines changed

go/analysis/passes/printf/printf.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -486,25 +486,25 @@ func checkPrintf(pass *analysis.Pass, kind Kind, call *ast.CallExpr, name string
486486
}
487487
return
488488
}
489-
// Check formats against args.
490-
states, err := fmtstr.ParsePrintf(pass.TypesInfo, call)
489+
directives, err := fmtstr.ParsePrintf(pass.TypesInfo, call)
491490
if err != nil {
492491
pass.ReportRangef(call.Fun, "%s %s", name, err.Error())
493492
return
494493
}
495494

496495
maxArgNum := firstArg
497496
anyIndex := false
498-
for _, state := range states {
499-
if (state.Prec != nil && state.Prec.Index != -1) ||
500-
(state.Width != nil && state.Width.Index != -1) ||
501-
(state.Verb != nil && state.Verb.Index != -1) {
497+
// Check formats against args.
498+
for _, directive := range directives {
499+
if (directive.Prec != nil && directive.Prec.Index != -1) ||
500+
(directive.Width != nil && directive.Width.Index != -1) ||
501+
(directive.Verb != nil && directive.Verb.Index != -1) {
502502
anyIndex = true
503503
}
504-
if !okPrintfArg(pass, call, &maxArgNum, name, state) { // One error per format is enough.
504+
if !okPrintfArg(pass, call, &maxArgNum, name, directive) { // One error per format is enough.
505505
return
506506
}
507-
if state.Verb.Verb == 'w' {
507+
if directive.Verb.Verb == 'w' {
508508
switch kind {
509509
case KindNone, KindPrint, KindPrintf:
510510
pass.Reportf(call.Pos(), "%s does not support error-wrapping directive %%w", name)
@@ -591,8 +591,8 @@ var printVerbs = []printVerb{
591591
// okPrintfArg compares the FormatDirective to the arguments actually present,
592592
// reporting any discrepancies it can discern. If the final argument is ellipsissed,
593593
// there's little it can do for that.
594-
func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgNum *int, name string, state *fmtstr.FormatDirective) (ok bool) {
595-
verb := state.Verb.Verb
594+
func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgNum *int, name string, directive *fmtstr.FormatDirective) (ok bool) {
595+
verb := directive.Verb.Verb
596596
var v printVerb
597597
found := false
598598
// Linear scan is fast enough for a small list.
@@ -606,42 +606,42 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgNum *int, name s
606606
// Could verb's arg implement fmt.Formatter?
607607
// Skip check for the %w verb, which requires an error.
608608
formatter := false
609-
if v.typ != argError && state.Verb.ArgNum < len(call.Args) {
610-
if tv, ok := pass.TypesInfo.Types[call.Args[state.Verb.ArgNum]]; ok {
609+
if v.typ != argError && directive.Verb.ArgNum < len(call.Args) {
610+
if tv, ok := pass.TypesInfo.Types[call.Args[directive.Verb.ArgNum]]; ok {
611611
formatter = isFormatter(tv.Type)
612612
}
613613
}
614614

615615
if !formatter {
616616
if !found {
617-
pass.ReportRangef(call, "%s format %s has unknown verb %c", name, state.Format, verb)
617+
pass.ReportRangef(call, "%s format %s has unknown verb %c", name, directive.Format, verb)
618618
return false
619619
}
620-
for _, flag := range state.Flags {
620+
for _, flag := range directive.Flags {
621621
// TODO: Disable complaint about '0' for Go 1.10. To be fixed properly in 1.11.
622622
// See issues 23598 and 23605.
623623
if flag == '0' {
624624
continue
625625
}
626626
if !strings.ContainsRune(v.flags, rune(flag)) {
627-
pass.ReportRangef(call, "%s format %s has unrecognized flag %c", name, state.Format, flag)
627+
pass.ReportRangef(call, "%s format %s has unrecognized flag %c", name, directive.Format, flag)
628628
return false
629629
}
630630
}
631631
}
632632
var argNums []int
633-
if state.Width != nil && state.Width.ArgNum != -1 {
634-
argNums = append(argNums, state.Width.ArgNum)
633+
if directive.Width != nil && directive.Width.ArgNum != -1 {
634+
argNums = append(argNums, directive.Width.ArgNum)
635635
}
636-
if state.Prec != nil && state.Prec.ArgNum != -1 {
637-
argNums = append(argNums, state.Prec.ArgNum)
636+
if directive.Prec != nil && directive.Prec.ArgNum != -1 {
637+
argNums = append(argNums, directive.Prec.ArgNum)
638638
}
639639

640640
// Verb is good. If len(argNums)>0, we have something like %.*s and all
641641
// args in argNums must be an integer.
642642
for i := 0; i < len(argNums); i++ {
643643
argNum := argNums[i]
644-
if !argCanBeChecked(pass, call, argNums[i], state, name) {
644+
if !argCanBeChecked(pass, call, argNums[i], directive, name) {
645645
return
646646
}
647647
arg := call.Args[argNum]
@@ -650,14 +650,14 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgNum *int, name s
650650
if reason != "" {
651651
details = " (" + reason + ")"
652652
}
653-
pass.ReportRangef(call, "%s format %s uses non-int %s%s as argument of *", name, state.Format, analysisutil.Format(pass.Fset, arg), details)
653+
pass.ReportRangef(call, "%s format %s uses non-int %s%s as argument of *", name, directive.Format, analysisutil.Format(pass.Fset, arg), details)
654654
return false
655655
}
656656
}
657657

658-
// Collect to conveniently update maxArgNum.
659-
if state.Verb != nil && state.Verb.ArgNum != -1 && verb != '%' {
660-
argNums = append(argNums, state.Verb.ArgNum)
658+
// Collect to update maxArgNum in one loop.
659+
if directive.Verb != nil && directive.Verb.ArgNum != -1 && verb != '%' {
660+
argNums = append(argNums, directive.Verb.ArgNum)
661661
}
662662
for _, n := range argNums {
663663
if n >= *maxArgNum {
@@ -671,12 +671,12 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgNum *int, name s
671671

672672
// Now check verb's type.
673673
argNum := argNums[len(argNums)-1]
674-
if !argCanBeChecked(pass, call, argNums[len(argNums)-1], state, name) {
674+
if !argCanBeChecked(pass, call, argNums[len(argNums)-1], directive, name) {
675675
return false
676676
}
677677
arg := call.Args[argNum]
678678
if isFunctionValue(pass, arg) && verb != 'p' && verb != 'T' {
679-
pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", name, state.Format, analysisutil.Format(pass.Fset, arg))
679+
pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", name, directive.Format, analysisutil.Format(pass.Fset, arg))
680680
return false
681681
}
682682
if reason, ok := matchArgType(pass, v.typ, arg); !ok {
@@ -688,12 +688,12 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, maxArgNum *int, name s
688688
if reason != "" {
689689
details = " (" + reason + ")"
690690
}
691-
pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s%s", name, state.Format, analysisutil.Format(pass.Fset, arg), typeString, details)
691+
pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s%s", name, directive.Format, analysisutil.Format(pass.Fset, arg), typeString, details)
692692
return false
693693
}
694-
if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.Flags, []byte{'#'}) {
694+
if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(directive.Flags, []byte{'#'}) {
695695
if methodName, ok := recursiveStringer(pass, arg); ok {
696-
pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", name, state.Format, analysisutil.Format(pass.Fset, arg), methodName)
696+
pass.ReportRangef(call, "%s format %s with arg %s causes recursive %s method call", name, directive.Format, analysisutil.Format(pass.Fset, arg), methodName)
697697
return false
698698
}
699699
}
@@ -777,7 +777,7 @@ func isFunctionValue(pass *analysis.Pass, e ast.Expr) bool {
777777
// argCanBeChecked reports whether the specified argument is statically present;
778778
// it may be beyond the list of arguments or in a terminal slice... argument, which
779779
// means we can't see it.
780-
func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, argNum int, state *fmtstr.FormatDirective, name string) bool {
780+
func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, argNum int, directive *fmtstr.FormatDirective, name string) bool {
781781
if argNum <= 0 {
782782
// Shouldn't happen, so catch it with prejudice.
783783
panic("negative arg num")
@@ -793,8 +793,8 @@ func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, argNum int, state
793793
}
794794
// There are bad indexes in the format or there are fewer arguments than the format needs.
795795
// This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi".
796-
arg := argNum - state.FirstArg + 1 // People think of arguments as 1-indexed.
797-
pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", name, state.Format, arg, count(len(call.Args)-state.FirstArg, "arg"))
796+
arg := argNum - directive.FirstArg + 1 // People think of arguments as 1-indexed.
797+
pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", name, directive.Format, arg, count(len(call.Args)-directive.FirstArg, "arg"))
798798
return false
799799
}
800800

0 commit comments

Comments
 (0)