Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7922cc4

Browse files
committed
message/pipeline: hoist CallExpr handling
Change-Id: I01ed5f06814dc71268407e302bebeefd7b608b8f Reviewed-on: https://go-review.googlesource.com/105015 Run-TryBot: Marcel van Lohuizen <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ross Light <[email protected]>
1 parent 367d765 commit 7922cc4

File tree

1 file changed

+136
-119
lines changed

1 file changed

+136
-119
lines changed

message/pipeline/extract.go

Lines changed: 136 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -348,143 +348,160 @@ func (x *extracter) visitArgs(fd *callData, v ssa.Value) {
348348
}
349349
}
350350

351-
func (x *extracter) extractMessages() {
352-
// print returns Go syntax for the specified node.
353-
print := func(n ast.Node) string {
354-
var buf bytes.Buffer
355-
format.Node(&buf, x.conf.Fset, n)
356-
return buf.String()
351+
// print returns Go syntax for the specified node.
352+
func (x *extracter) print(n ast.Node) string {
353+
var buf bytes.Buffer
354+
format.Node(&buf, x.conf.Fset, n)
355+
return buf.String()
356+
}
357+
358+
type packageExtracter struct {
359+
x *extracter
360+
info *loader.PackageInfo
361+
cmap ast.CommentMap
362+
}
363+
364+
func (px packageExtracter) getComment(n ast.Node) string {
365+
cs := px.cmap.Filter(n).Comments()
366+
if len(cs) > 0 {
367+
return strings.TrimSpace(cs[0].Text())
357368
}
369+
return ""
370+
}
371+
372+
func (x *extracter) extractMessages() {
358373
prog := x.iprog
359374
for _, info := range x.iprog.AllPackages {
360375
for _, f := range info.Files {
361376
// Associate comments with nodes.
362-
cmap := ast.NewCommentMap(prog.Fset, f, f.Comments)
363-
getComment := func(n ast.Node) string {
364-
cs := cmap.Filter(n).Comments()
365-
if len(cs) > 0 {
366-
return strings.TrimSpace(cs[0].Text())
367-
}
368-
return ""
377+
px := packageExtracter{
378+
x, info,
379+
ast.NewCommentMap(prog.Fset, f, f.Comments),
369380
}
370381

371382
// Find function calls.
372383
ast.Inspect(f, func(n ast.Node) bool {
373-
call, ok := n.(*ast.CallExpr)
374-
if !ok {
375-
return true
376-
}
377-
data := x.funcs[call.Lparen]
378-
if data == nil || len(data.formats) == 0 {
379-
return true
384+
switch v := n.(type) {
385+
case *ast.CallExpr:
386+
return px.handleCall(v)
380387
}
381-
x.debug(data.call, "INSERT", data.formats)
388+
return true
389+
})
390+
}
391+
}
392+
}
382393

383-
argn := data.callFormatPos()
384-
if argn >= len(call.Args) {
385-
return true
386-
}
387-
format := call.Args[argn]
388-
389-
comment := ""
390-
key := []string{}
391-
if ident, ok := format.(*ast.Ident); ok {
392-
key = append(key, ident.Name)
393-
if v, ok := ident.Obj.Decl.(*ast.ValueSpec); ok && v.Comment != nil {
394-
// TODO: get comment above ValueSpec as well
395-
comment = v.Comment.Text()
396-
}
397-
}
394+
func (px packageExtracter) handleCall(call *ast.CallExpr) bool {
395+
x := px.x
396+
info := px.info
397+
data := x.funcs[call.Lparen]
398+
if data == nil || len(data.formats) == 0 {
399+
return true
400+
}
401+
x.debug(data.call, "INSERT", data.formats)
398402

399-
arguments := []argument{}
400-
simArgs := []interface{}{}
401-
if data.callArgsStart() >= 0 {
402-
args := call.Args[data.callArgsStart():]
403-
simArgs = make([]interface{}, len(args))
404-
for i, arg := range args {
405-
expr := print(arg)
406-
val := ""
407-
if v := info.Types[arg].Value; v != nil {
408-
val = v.ExactString()
409-
simArgs[i] = val
410-
switch arg.(type) {
411-
case *ast.BinaryExpr, *ast.UnaryExpr:
412-
expr = val
413-
}
414-
}
415-
arguments = append(arguments, argument{
416-
ArgNum: i + 1,
417-
Type: info.Types[arg].Type.String(),
418-
UnderlyingType: info.Types[arg].Type.Underlying().String(),
419-
Expr: expr,
420-
Value: val,
421-
Comment: getComment(arg),
422-
Position: posString(&x.conf, info.Pkg, arg.Pos()),
423-
// TODO report whether it implements
424-
// interfaces plural.Interface,
425-
// gender.Interface.
426-
})
427-
}
403+
argn := data.callFormatPos()
404+
if argn >= len(call.Args) {
405+
return true
406+
}
407+
format := call.Args[argn]
408+
409+
comment := ""
410+
key := []string{}
411+
if ident, ok := format.(*ast.Ident); ok {
412+
key = append(key, ident.Name)
413+
if v, ok := ident.Obj.Decl.(*ast.ValueSpec); ok && v.Comment != nil {
414+
// TODO: get comment above ValueSpec as well
415+
comment = v.Comment.Text()
416+
}
417+
}
418+
419+
arguments := []argument{}
420+
simArgs := []interface{}{}
421+
if data.callArgsStart() >= 0 {
422+
args := call.Args[data.callArgsStart():]
423+
simArgs = make([]interface{}, len(args))
424+
for i, arg := range args {
425+
expr := x.print(arg)
426+
val := ""
427+
if v := info.Types[arg].Value; v != nil {
428+
val = v.ExactString()
429+
simArgs[i] = val
430+
switch arg.(type) {
431+
case *ast.BinaryExpr, *ast.UnaryExpr:
432+
expr = val
428433
}
434+
}
435+
arguments = append(arguments, argument{
436+
ArgNum: i + 1,
437+
Type: info.Types[arg].Type.String(),
438+
UnderlyingType: info.Types[arg].Type.Underlying().String(),
439+
Expr: expr,
440+
Value: val,
441+
Comment: px.getComment(arg),
442+
Position: posString(&x.conf, info.Pkg, arg.Pos()),
443+
// TODO report whether it implements
444+
// interfaces plural.Interface,
445+
// gender.Interface.
446+
})
447+
}
448+
}
429449

430-
formats := data.formats
431-
for _, c := range formats {
432-
key := append([]string{}, key...)
433-
fmtMsg := constant.StringVal(c)
434-
msg := ""
435-
436-
ph := placeholders{index: map[string]string{}}
437-
438-
trimmed, _, _ := trimWS(fmtMsg)
439-
440-
p := fmtparser.Parser{}
441-
p.Reset(simArgs)
442-
for p.SetFormat(trimmed); p.Scan(); {
443-
switch p.Status {
444-
case fmtparser.StatusText:
445-
msg += p.Text()
446-
case fmtparser.StatusSubstitution,
447-
fmtparser.StatusBadWidthSubstitution,
448-
fmtparser.StatusBadPrecSubstitution:
449-
arguments[p.ArgNum-1].used = true
450-
arg := arguments[p.ArgNum-1]
451-
sub := p.Text()
452-
if !p.HasIndex {
453-
r, sz := utf8.DecodeLastRuneInString(sub)
454-
sub = fmt.Sprintf("%s[%d]%c", sub[:len(sub)-sz], p.ArgNum, r)
455-
}
456-
msg += fmt.Sprintf("{%s}", ph.addArg(&arg, sub))
457-
}
458-
}
459-
key = append(key, msg)
460-
461-
// Add additional Placeholders that can be used in translations
462-
// that are not present in the string.
463-
for _, arg := range arguments {
464-
if arg.used {
465-
continue
466-
}
467-
ph.addArg(&arg, fmt.Sprintf("%%[%d]v", arg.ArgNum))
468-
}
450+
formats := data.formats
451+
for _, c := range formats {
452+
key := append([]string{}, key...)
453+
fmtMsg := constant.StringVal(c)
454+
msg := ""
455+
456+
ph := placeholders{index: map[string]string{}}
457+
458+
trimmed, _, _ := trimWS(fmtMsg)
459+
460+
p := fmtparser.Parser{}
461+
p.Reset(simArgs)
462+
for p.SetFormat(trimmed); p.Scan(); {
463+
switch p.Status {
464+
case fmtparser.StatusText:
465+
msg += p.Text()
466+
case fmtparser.StatusSubstitution,
467+
fmtparser.StatusBadWidthSubstitution,
468+
fmtparser.StatusBadPrecSubstitution:
469+
arguments[p.ArgNum-1].used = true
470+
arg := arguments[p.ArgNum-1]
471+
sub := p.Text()
472+
if !p.HasIndex {
473+
r, sz := utf8.DecodeLastRuneInString(sub)
474+
sub = fmt.Sprintf("%s[%d]%c", sub[:len(sub)-sz], p.ArgNum, r)
475+
}
476+
msg += fmt.Sprintf("{%s}", ph.addArg(&arg, sub))
477+
}
478+
}
479+
key = append(key, msg)
469480

470-
if c := getComment(call.Args[0]); c != "" {
471-
comment = c
472-
}
481+
// Add additional Placeholders that can be used in translations
482+
// that are not present in the string.
483+
for _, arg := range arguments {
484+
if arg.used {
485+
continue
486+
}
487+
ph.addArg(&arg, fmt.Sprintf("%%[%d]v", arg.ArgNum))
488+
}
473489

474-
x.messages = append(x.messages, Message{
475-
ID: key,
476-
Key: fmtMsg,
477-
Message: Text{Msg: msg},
478-
// TODO(fix): this doesn't get the before comment.
479-
Comment: comment,
480-
Placeholders: ph.slice,
481-
Position: posString(&x.conf, info.Pkg, call.Lparen),
482-
})
483-
}
484-
return true
485-
})
490+
if c := px.getComment(call.Args[0]); c != "" {
491+
comment = c
486492
}
493+
494+
x.messages = append(x.messages, Message{
495+
ID: key,
496+
Key: fmtMsg,
497+
Message: Text{Msg: msg},
498+
// TODO(fix): this doesn't get the before comment.
499+
Comment: comment,
500+
Placeholders: ph.slice,
501+
Position: posString(&x.conf, info.Pkg, call.Lparen),
502+
})
487503
}
504+
return true
488505
}
489506

490507
func posString(conf *loader.Config, pkg *types.Package, pos token.Pos) string {

0 commit comments

Comments
 (0)