Skip to content

Instantly share code, notes, and snippets.

@ssoroka
Last active August 8, 2019 04:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssoroka/d1872f86701ac1b4a9171ac33aabfb56 to your computer and use it in GitHub Desktop.
Save ssoroka/d1872f86701ac1b4a9171ac33aabfb56 to your computer and use it in GitHub Desktop.
golang.org/x/text go modules WIP
diff --git a/cmd/gotext/common.go b/cmd/gotext/common.go
index 51322db..03e85db 100644
--- a/cmd/gotext/common.go
+++ b/cmd/gotext/common.go
@@ -6,16 +6,6 @@ package main
import (
"fmt"
- "go/build"
- "go/parser"
-
- "golang.org/x/tools/go/loader"
-)
-
-const (
- extractFile = "extracted.gotext.json"
- outFile = "out.gotext.json"
- gotextSuffix = ".gotext.json"
)
// NOTE: The command line tool already prefixes with "gotext:".
@@ -28,22 +18,3 @@ var (
}
errorf = fmt.Errorf
)
-
-// TODO: still used. Remove when possible.
-func loadPackages(conf *loader.Config, args []string) (*loader.Program, error) {
- if len(args) == 0 {
- args = []string{"."}
- }
-
- conf.Build = &build.Default
- conf.ParserMode = parser.ParseComments
-
- // Use the initial packages from the command line.
- args, err := conf.FromArgs(args, false)
- if err != nil {
- return nil, wrap(err, "loading packages failed")
- }
-
- // Load, parse and type-check the whole program.
- return conf.Load()
-}
diff --git a/go.mod b/go.mod
index 5eb1e8b..13ff5eb 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
module golang.org/x/text
-require golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e
+require golang.org/x/tools v0.0.0-20190807223507-b346f7fd45de
diff --git a/go.sum b/go.sum
index 6a308d7..5910ca4 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,10 @@
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190807223507-b346f7fd45de h1:VNumCimp/Bwk6fRqgPHkjiUPZ/vzlpi23/kQTuQ4gBA=
+golang.org/x/tools v0.0.0-20190807223507-b346f7fd45de/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/message/pipeline/extract.go b/message/pipeline/extract.go
index 39b3dd5..37d484e 100644
--- a/message/pipeline/extract.go
+++ b/message/pipeline/extract.go
@@ -21,9 +21,8 @@ import (
fmtparser "golang.org/x/text/internal/format"
"golang.org/x/tools/go/callgraph"
"golang.org/x/tools/go/callgraph/cha"
- "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/packages"
"golang.org/x/tools/go/ssa"
- "golang.org/x/tools/go/ssa/ssautil"
)
const debug = false
@@ -49,8 +48,8 @@ func Extract(c *Config) (*State, error) {
x.extractMessages()
return &State{
- Config: *c,
- program: x.iprog,
+ Config: *c,
+ // program: x.pkg,
Extracted: Messages{
Language: c.SourceLanguage,
Messages: x.messages,
@@ -59,8 +58,9 @@ func Extract(c *Config) (*State, error) {
}
type extracter struct {
- conf loader.Config
- iprog *loader.Program
+ conf packages.Config
+ // pkg *packages.Package
+ pkgs []*packages.Package
prog *ssa.Program
callGraph *callgraph.Graph
@@ -72,17 +72,18 @@ type extracter struct {
func newExtracter(c *Config) (x *extracter, err error) {
x = &extracter{
- conf: loader.Config{},
+ conf: packages.Config{},
globals: map[token.Pos]*constData{},
funcs: map[token.Pos]*callData{},
}
- x.iprog, err = loadPackages(&x.conf, c.Packages)
+ prog, pkgs, err := loadPackages(&x.conf, c.Packages)
if err != nil {
return nil, wrap(err, "")
}
+ x.prog = prog
+ x.pkgs = pkgs
- x.prog = ssautil.CreateProgram(x.iprog, ssa.GlobalDebug|ssa.BareInits)
x.prog.Build()
x.callGraph = cha.CallGraph(x.prog)
@@ -100,26 +101,42 @@ func (x *extracter) globalData(pos token.Pos) *constData {
}
func (x *extracter) seedEndpoints() error {
- pkgInfo := x.iprog.Package("golang.org/x/text/message")
- if pkgInfo == nil {
+ var pkg *packages.Package
+ for _, p := range x.pkgs {
+ if p2, ok := p.Imports["golang.org/x/text/message"]; ok {
+ pkg = p2
+ break
+ }
+ }
+ if pkg == nil {
return errors.New("pipeline: golang.org/x/text/message is not imported")
}
- pkg := x.prog.Package(pkgInfo.Pkg)
- typ := types.NewPointer(pkg.Type("Printer").Type())
+
+ var typ *types.Pointer
+ for _, typeAndVal := range pkg.TypesInfo.Types {
+ if typeAndVal.Type.String() == "golang.org/x/text/message.Printer" {
+ typ = types.NewPointer(typeAndVal.Type)
+ break
+ }
+ }
+
+ if typ == nil {
+ return errors.New("pipeline: golang.org/x/text/message.Printer was not found")
+ }
x.processGlobalVars()
- x.handleFunc(x.prog.LookupMethod(typ, pkg.Pkg, "Printf"), &callData{
+ x.handleFunc(x.prog.LookupMethod(typ, pkg.Types, "Printf"), &callData{
formatPos: 1,
argPos: 2,
isMethod: true,
})
- x.handleFunc(x.prog.LookupMethod(typ, pkg.Pkg, "Sprintf"), &callData{
+ x.handleFunc(x.prog.LookupMethod(typ, pkg.Types, "Sprintf"), &callData{
formatPos: 1,
argPos: 2,
isMethod: true,
})
- x.handleFunc(x.prog.LookupMethod(typ, pkg.Pkg, "Fprintf"), &callData{
+ x.handleFunc(x.prog.LookupMethod(typ, pkg.Types, "Fprintf"), &callData{
formatPos: 2,
argPos: 3,
isMethod: true,
@@ -488,14 +505,14 @@ func (x *extracter) visitArgs(fd *callData, v ssa.Value) {
// print returns Go syntax for the specified node.
func (x *extracter) print(n ast.Node) string {
var buf bytes.Buffer
- format.Node(&buf, x.conf.Fset, n)
+ _ = format.Node(&buf, x.conf.Fset, n)
return buf.String()
}
type packageExtracter struct {
f *ast.File
x *extracter
- info *loader.PackageInfo
+ pkg *packages.Package
cmap ast.CommentMap
}
@@ -508,14 +525,13 @@ func (px packageExtracter) getComment(n ast.Node) string {
}
func (x *extracter) extractMessages() {
- prog := x.iprog
files := []packageExtracter{}
- for _, info := range x.iprog.AllPackages {
- for _, f := range info.Files {
+ for _, pkg := range x.pkgs {
+ for _, f := range pkg.Syntax {
// Associate comments with nodes.
px := packageExtracter{
- f, x, info,
- ast.NewCommentMap(prog.Fset, f, f.Comments),
+ f, x, pkg,
+ ast.NewCommentMap(pkg.Fset, f, f.Comments),
}
files = append(files, px)
}
@@ -609,13 +625,13 @@ func (px packageExtracter) handleCall(call *ast.CallExpr) bool {
func (px packageExtracter) getArguments(data *callData) []argument {
arguments := []argument{}
x := px.x
- info := px.info
+ pkg := px.pkg
if data.callArgsStart() >= 0 {
args := data.expr.Args[data.callArgsStart():]
for i, arg := range args {
expr := x.print(arg)
val := ""
- if v := info.Types[arg].Value; v != nil {
+ if v := pkg.TypesInfo.Types[arg].Value; v != nil {
val = v.ExactString()
switch arg.(type) {
case *ast.BinaryExpr, *ast.UnaryExpr:
@@ -624,12 +640,12 @@ func (px packageExtracter) getArguments(data *callData) []argument {
}
arguments = append(arguments, argument{
ArgNum: i + 1,
- Type: info.Types[arg].Type.String(),
- UnderlyingType: info.Types[arg].Type.Underlying().String(),
+ Type: pkg.TypesInfo.Types[arg].Type.String(),
+ UnderlyingType: pkg.TypesInfo.Types[arg].Type.Underlying().String(),
Expr: expr,
Value: val,
Comment: px.getComment(arg),
- Position: posString(&x.conf, info.Pkg, arg.Pos()),
+ Position: posString(&x.conf, pkg.Types, arg.Pos()),
// TODO report whether it implements
// interfaces plural.Interface,
// gender.Interface.
@@ -675,7 +691,7 @@ func (px packageExtracter) addMessage(
case fmtparser.StatusBadArgNum, fmtparser.StatusMissingArg:
arg = &argument{
ArgNum: p.ArgNum,
- Position: posString(&x.conf, px.info.Pkg, pos),
+ Position: posString(&x.conf, px.pkg.Types, pos),
}
name, arg.UnderlyingType = verbToPlaceholder(p.Text(), p.ArgNum)
}
@@ -704,11 +720,11 @@ func (px packageExtracter) addMessage(
// TODO(fix): this doesn't get the before comment.
Comment: comment,
Placeholders: ph.slice,
- Position: posString(&x.conf, px.info.Pkg, pos),
+ Position: posString(&x.conf, px.pkg.Types, pos),
})
}
-func posString(conf *loader.Config, pkg *types.Package, pos token.Pos) string {
+func posString(conf *packages.Config, pkg *types.Package, pos token.Pos) string {
p := conf.Fset.Position(pos)
file := fmt.Sprintf("%s:%d:%d", filepath.Base(p.Filename), p.Line, p.Column)
return filepath.Join(pkg.Path(), file)
diff --git a/message/pipeline/generate.go b/message/pipeline/generate.go
index 5d329b2..7c58e64 100644
--- a/message/pipeline/generate.go
+++ b/message/pipeline/generate.go
@@ -20,7 +20,7 @@ import (
"golang.org/x/text/internal/catmsg"
"golang.org/x/text/internal/gen"
"golang.org/x/text/language"
- "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/packages"
)
var transRe = regexp.MustCompile(`messages\.(.*)\.json`)
@@ -34,15 +34,13 @@ func (s *State) Generate() error {
path = "."
}
isDir := path[0] == '.'
- prog, err := loadPackages(&loader.Config{}, []string{path})
+ _, pkgs, err := loadPackages(&packages.Config{}, []string{path})
if err != nil {
return wrap(err, "could not load package")
}
- pkgs := prog.InitialPackages()
if len(pkgs) != 1 {
return errorf("more than one package selected: %v", pkgs)
}
- pkg := pkgs[0].Pkg.Name()
cw, err := s.generate()
if err != nil {
@@ -50,10 +48,10 @@ func (s *State) Generate() error {
}
if !isDir {
gopath := build.Default.GOPATH
- path = filepath.Join(gopath, filepath.FromSlash(pkgs[0].Pkg.Path()))
+ path = filepath.Join(gopath, filepath.FromSlash(pkgs[0].PkgPath))
}
path = filepath.Join(path, s.Config.GenFile)
- cw.WriteGoFile(path, pkg) // TODO: WriteGoFile should return error.
+ cw.WriteGoFile(path, pkgs[0].Name) // TODO: WriteGoFile should return error.
return err
}
diff --git a/message/pipeline/pipeline.go b/message/pipeline/pipeline.go
index cafd6f2..c4d7926 100644
--- a/message/pipeline/pipeline.go
+++ b/message/pipeline/pipeline.go
@@ -11,8 +11,6 @@ import (
"bytes"
"encoding/json"
"fmt"
- "go/build"
- "go/parser"
"io/ioutil"
"log"
"os"
@@ -25,7 +23,9 @@ import (
"golang.org/x/text/internal"
"golang.org/x/text/language"
"golang.org/x/text/runes"
- "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/packages"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
)
const (
@@ -125,7 +125,7 @@ type State struct {
Config Config
Package string
- program *loader.Program
+ // program *packages.Package
Extracted Messages `json:"messages"`
@@ -403,20 +403,19 @@ func warnf(format string, args ...interface{}) {
log.Printf(format, args...)
}
-func loadPackages(conf *loader.Config, args []string) (*loader.Program, error) {
+func loadPackages(conf *packages.Config, args []string) (*ssa.Program, []*packages.Package, error) {
if len(args) == 0 {
args = []string{"."}
}
- conf.Build = &build.Default
- conf.ParserMode = parser.ParseComments
-
- // Use the initial packages from the command line.
- args, err := conf.FromArgs(args, false)
+ conf.Mode = packages.LoadAllSyntax
+ pkgs, err := packages.Load(conf, args...)
if err != nil {
- return nil, wrap(err, "loading packages failed")
+ packages.PrintErrors(pkgs)
+ return nil, nil, err
}
- // Load, parse and type-check the whole program.
- return conf.Load()
+ prog, _ := ssautil.Packages(pkgs, 0)
+
+ return prog, pkgs, nil
}
diff --git a/message/pipeline/rewrite.go b/message/pipeline/rewrite.go
index cf1511f..acbb60d 100644
--- a/message/pipeline/rewrite.go
+++ b/message/pipeline/rewrite.go
@@ -15,7 +15,7 @@ import (
"os"
"strings"
- "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/packages"
)
const printerType = "golang.org/x/text/message.Printer"
@@ -25,22 +25,21 @@ const printerType = "golang.org/x/text/message.Printer"
// If w is not nil the generated files are written to it, each files with a
// "--- <filename>" header. Otherwise the files are overwritten.
func Rewrite(w io.Writer, args ...string) error {
- conf := &loader.Config{
- AllowErrors: true, // Allow unused instances of message.Printer.
- }
- prog, err := loadPackages(conf, args)
+ conf := &packages.Config{}
+ _, pkgs, err := loadPackages(conf, args)
if err != nil {
return wrap(err, "")
}
- for _, info := range prog.InitialPackages() {
- for _, f := range info.Files {
+ for _, pkg := range pkgs {
+ for _, f := range pkg.Syntax {
// Associate comments with nodes.
// Pick up initialized Printers at the package level.
- r := rewriter{info: info, conf: conf}
- for _, n := range info.InitOrder {
- if t := r.info.Types[n.Rhs].Type.String(); strings.HasSuffix(t, printerType) {
+ r := rewriter{pkg: pkg, conf: conf}
+
+ for _, n := range pkg.TypesInfo.InitOrder {
+ if t := r.pkg.TypesInfo.Types[n.Rhs].Type.String(); strings.HasSuffix(t, printerType) {
r.printerVar = n.Lhs[0].Name()
}
}
@@ -67,8 +66,8 @@ func Rewrite(w io.Writer, args ...string) error {
}
type rewriter struct {
- info *loader.PackageInfo
- conf *loader.Config
+ pkg *packages.Package
+ conf *packages.Config
printerVar string
}
@@ -94,7 +93,7 @@ func (r *rewriter) Visit(n ast.Node) ast.Visitor {
}
}
for i, v := range stmt.Rhs {
- if t := r.info.Types[v].Type.String(); strings.HasSuffix(t, printerType) {
+ if t := r.pkg.TypesInfo.Types[v].Type.String(); strings.HasSuffix(t, printerType) {
r.printerVar = r.print(stmt.Lhs[i])
return r
}
@@ -109,7 +108,7 @@ func (r *rewriter) Visit(n ast.Node) ast.Visitor {
}
}
for i, v := range spec.Values {
- if t := r.info.Types[v].Type.String(); strings.HasSuffix(t, printerType) {
+ if t := r.pkg.TypesInfo.Types[v].Type.String(); strings.HasSuffix(t, printerType) {
r.printerVar = r.print(spec.Names[i])
return r
}
@@ -128,7 +127,7 @@ func (r *rewriter) Visit(n ast.Node) ast.Visitor {
if !ok {
return r
}
- meth := r.info.Selections[sel]
+ meth := r.pkg.TypesInfo.Selections[sel]
source := r.print(sel.X)
fun := r.print(sel.Sel)
@@ -163,7 +162,7 @@ func (r *rewriter) Visit(n ast.Node) ast.Visitor {
}
hasConst := false
for _, a := range call.Args[argn:] {
- if v := r.info.Types[a].Value; v != nil && v.Kind() == constant.String {
+ if v := r.pkg.TypesInfo.Types[a].Value; v != nil && v.Kind() == constant.String {
hasConst = true
break
}
@@ -176,7 +175,7 @@ func (r *rewriter) Visit(n ast.Node) ast.Visitor {
// We are done if there is only a single string that does not need to be
// escaped.
if len(call.Args) == 1 {
- s, ok := constStr(r.info, call.Args[0])
+ s, ok := constStr(r.pkg, call.Args[0])
if ok && !strings.Contains(s, "%") && !rewriteType.newLine {
return r
}
@@ -190,7 +189,7 @@ func (r *rewriter) Visit(n ast.Node) ast.Visitor {
newArgs := append(call.Args[:argn:argn], expr)
newStr := []string{}
for i, a := range call.Args[argn:] {
- if s, ok := constStr(r.info, a); ok {
+ if s, ok := constStr(r.pkg, a); ok {
newStr = append(newStr, strings.Replace(s, "%", "%%", -1))
} else {
newStr = append(newStr, "%v")
@@ -259,8 +258,8 @@ var rewriteFuncs = map[string]map[string]rewriteType{
},
}
-func constStr(info *loader.PackageInfo, e ast.Expr) (s string, ok bool) {
- v := info.Types[e].Value
+func constStr(pkg *packages.Package, e ast.Expr) (s string, ok bool) {
+ v := pkg.TypesInfo.Types[e].Value
if v == nil || v.Kind() != constant.String {
return "", false
}
Running tool: /usr/local/bin/go test -timeout 30s golang.org/x/text/message/pipeline -run ^(TestFullCycle)$
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x114667c]
goroutine 35 [running]:
testing.tRunner.func1(0xc000150200)
/usr/local/go/src/testing/testing.go:830 +0x392
panic(0x1577760, 0x1be54e0)
/usr/local/go/src/runtime/panic.go:522 +0x1b5
sync.(*RWMutex).RLock(...)
/usr/local/go/src/sync/rwmutex.go:48
go/token.(*FileSet).file(0x0, 0x3351e9, 0xc0013965f0)
/usr/local/go/src/go/token/position.go:452 +0x2c
go/token.(*FileSet).PositionFor(0x0, 0x3351e9, 0x1045300, 0x0, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/go/token/position.go:492 +0x61
go/printer.(*printer).posFor(...)
/usr/local/go/src/go/printer/printer.go:195
go/printer.(*printer).print(0xc0005a4db0, 0xc0005a4b40, 0x1, 0x1)
/usr/local/go/src/go/printer/printer.go:964 +0x6bf
go/printer.(*printer).expr1(0xc0005a4db0, 0x16e2020, 0xc0074f3980, 0x0, 0x1)
/usr/local/go/src/go/printer/nodes.go:741 +0xb1
go/printer.(*printer).expr(0xc00317adb0, 0x16e2020, 0xc0074f3980)
/usr/local/go/src/go/printer/nodes.go:1001 +0x51
go/printer.(*printer).printNode(0xc00317adb0, 0x1583820, 0xc0074f3980, 0xc0071638b0, 0x0)
/usr/local/go/src/go/printer/printer.go:1128 +0x3cd
go/printer.(*Config).fprint(0x1a72eb0, 0x16d8220, 0xc001395d70, 0x0, 0x1583820, 0xc0074f3980, 0xc001395da0, 0x1d266d0, 0x0)
/usr/local/go/src/go/printer/printer.go:1293 +0x172
go/printer.(*Config).Fprint(...)
/usr/local/go/src/go/printer/printer.go:1351
go/format.Node(0x16d8220, 0xc001395d70, 0x0, 0x1583820, 0xc0074f3980, 0x1583820, 0xc000012000)
/usr/local/go/src/go/format/format.go:79 +0x114
golang.org/x/text/message/pipeline.(*extracter).print(0xc000188750, 0x16dbda0, 0xc0074f3980, 0x16dbda0, 0xc0074f3980)
~/go/src/golang.org/x/text/message/pipeline/extract.go:508 +0x76
golang.org/x/text/message/pipeline.packageExtracter.getArguments(0xc006aa1b80, 0xc000188750, 0xc000350b40, 0xc001395d10, 0xc0001302a0, 0xc00317b1f0, 0x11554ba, 0x0)
~/go/src/golang.org/x/text/message/pipeline/extract.go:633 +0x15c
golang.org/x/text/message/pipeline.packageExtracter.handleCall(0xc006aa1b80, 0xc000188750, 0xc000350b40, 0xc001395d10, 0xc0074e9cc0, 0x0)
~/go/src/golang.org/x/text/message/pipeline/extract.go:604 +0x17a
golang.org/x/text/message/pipeline.(*extracter).extractMessages.func2(0x16dbea0, 0xc0074e9cc0, 0x16dc301)
~/go/src/golang.org/x/text/message/pipeline/extract.go:555 +0xa7
go/ast.inspector.Visit(0xc001396630, 0x16dbea0, 0xc0074e9cc0, 0x16d90e0, 0xc001396600)
/usr/local/go/src/go/ast/walk.go:373 +0x3a
go/ast.Walk(0x16d90e0, 0xc001396630, 0x16dbea0, 0xc0074e9cc0)
/usr/local/go/src/go/ast/walk.go:52 +0x66
go/ast.Walk(0x16d90e0, 0xc001396630, 0x16dc160, 0xc0074e55c0)
/usr/local/go/src/go/ast/walk.go:196 +0x1b12
go/ast.walkStmtList(0x16d90e0, 0xc001396630, 0xc006aa1880, 0x8, 0x8)
/usr/local/go/src/go/ast/walk.go:32 +0x9e
go/ast.Walk(0x16d90e0, 0xc001396630, 0x16dbe20, 0xc0074ed560)
/usr/local/go/src/go/ast/walk.go:224 +0x1b67
go/ast.Walk(0x16d90e0, 0xc001396630, 0x16dc2a0, 0xc0074ed590)
/usr/local/go/src/go/ast/walk.go:344 +0xd73
go/ast.walkDeclList(0x16d90e0, 0xc001396630, 0xc006a4d400, 0x1f, 0x20)
/usr/local/go/src/go/ast/walk.go:38 +0x9e
go/ast.Walk(0x16d90e0, 0xc001396630, 0x16dc220, 0xc006aa1b80)
/usr/local/go/src/go/ast/walk.go:353 +0x2659
go/ast.Inspect(...)
/usr/local/go/src/go/ast/walk.go:385
golang.org/x/text/message/pipeline.(*extracter).extractMessages(0xc000188750)
~/go/src/golang.org/x/text/message/pipeline/extract.go:552 +0x4ab
golang.org/x/text/message/pipeline.Extract(0xc0005a5ec8, 0xc0001ae130, 0x2, 0xc000132420)
~/go/src/golang.org/x/text/message/pipeline/extract.go:48 +0x76
golang.org/x/text/message/pipeline.TestFullCycle.func1(0xc000150200)
~/go/src/golang.org/x/text/message/pipeline/pipeline_test.go:56 +0x2ed
testing.tRunner(0xc000150200, 0xc0001ae0f0)
/usr/local/go/src/testing/testing.go:865 +0xc0
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:916 +0x35a
FAIL golang.org/x/text/message/pipeline 1.014s
Error: Tests failed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment