@@ -21,9 +21,8 @@ import (
2121 fmtparser "golang.org/x/text/internal/format"
2222 "golang.org/x/tools/go/callgraph"
2323 "golang.org/x/tools/go/callgraph/cha"
24- "golang.org/x/tools/go/loader "
24+ "golang.org/x/tools/go/packages "
2525 "golang.org/x/tools/go/ssa"
26- "golang.org/x/tools/go/ssa/ssautil"
2726)
2827
2928const debug = false
@@ -49,8 +48,7 @@ func Extract(c *Config) (*State, error) {
4948 x .extractMessages ()
5049
5150 return & State {
52- Config : * c ,
53- program : x .iprog ,
51+ Config : * c ,
5452 Extracted : Messages {
5553 Language : c .SourceLanguage ,
5654 Messages : x .messages ,
@@ -59,8 +57,8 @@ func Extract(c *Config) (*State, error) {
5957}
6058
6159type extracter struct {
62- conf loader .Config
63- iprog * loader. Program
60+ conf packages .Config
61+ pkgs [] * packages. Package
6462 prog * ssa.Program
6563 callGraph * callgraph.Graph
6664
@@ -72,17 +70,20 @@ type extracter struct {
7270
7371func newExtracter (c * Config ) (x * extracter , err error ) {
7472 x = & extracter {
75- conf : loader.Config {},
73+ conf : packages.Config {
74+ Fset : token .NewFileSet (),
75+ },
7676 globals : map [token.Pos ]* constData {},
7777 funcs : map [token.Pos ]* callData {},
7878 }
7979
80- x . iprog , err = loadPackages (& x .conf , c .Packages )
80+ prog , pkgs , err : = loadPackages (& x .conf , c .Packages )
8181 if err != nil {
8282 return nil , wrap (err , "" )
8383 }
84+ x .prog = prog
85+ x .pkgs = pkgs
8486
85- x .prog = ssautil .CreateProgram (x .iprog , ssa .GlobalDebug | ssa .BareInits )
8687 x .prog .Build ()
8788
8889 x .callGraph = cha .CallGraph (x .prog )
@@ -100,26 +101,46 @@ func (x *extracter) globalData(pos token.Pos) *constData {
100101}
101102
102103func (x * extracter ) seedEndpoints () error {
103- pkgInfo := x .iprog .Package ("golang.org/x/text/message" )
104- if pkgInfo == nil {
105- return errors .New ("pipeline: golang.org/x/text/message is not imported" )
104+ var pkg * packages.Package
105+ imports := ""
106+ for _ , p := range x .pkgs {
107+ for k := range p .Imports {
108+ imports = imports + k + "\n "
109+ }
110+ if p2 , ok := p .Imports ["golang.org/x/text/message" ]; ok {
111+ pkg = p2
112+ break
113+ }
114+ }
115+ if pkg == nil {
116+ return errors .New ("pipeline: golang.org/x/text/message is not imported.\n " + imports )
117+ }
118+
119+ var typ * types.Pointer
120+ for _ , typeAndVal := range pkg .TypesInfo .Types {
121+ if typeAndVal .Type .String () == "golang.org/x/text/message.Printer" {
122+ typ = types .NewPointer (typeAndVal .Type )
123+ break
124+ }
125+ }
126+
127+ if typ == nil {
128+ return errors .New ("pipeline: golang.org/x/text/message.Printer was not found" )
106129 }
107- pkg := x .prog .Package (pkgInfo .Pkg )
108- typ := types .NewPointer (pkg .Type ("Printer" ).Type ())
109130
110131 x .processGlobalVars ()
111132
112- x .handleFunc (x .prog .LookupMethod (typ , pkg .Pkg , "Printf" ), & callData {
133+ x .handleFunc (x .prog .LookupMethod (typ , pkg .Types , "Printf" ), & callData {
113134 formatPos : 1 ,
114135 argPos : 2 ,
115136 isMethod : true ,
116137 })
117- x .handleFunc (x .prog .LookupMethod (typ , pkg .Pkg , "Sprintf" ), & callData {
138+ x .handleFunc (x .prog .LookupMethod (typ , pkg .Types , "Sprintf" ), & callData {
118139 formatPos : 1 ,
119140 argPos : 2 ,
120141 isMethod : true ,
121142 })
122- x .handleFunc (x .prog .LookupMethod (typ , pkg .Pkg , "Fprintf" ), & callData {
143+ x .handleFunc (x .prog .LookupMethod (typ , pkg .Types , "Fprintf" ), & callData {
123144 formatPos : 2 ,
124145 argPos : 3 ,
125146 isMethod : true ,
@@ -488,14 +509,14 @@ func (x *extracter) visitArgs(fd *callData, v ssa.Value) {
488509// print returns Go syntax for the specified node.
489510func (x * extracter ) print (n ast.Node ) string {
490511 var buf bytes.Buffer
491- format .Node (& buf , x .conf .Fset , n )
512+ _ = format .Node (& buf , x .conf .Fset , n )
492513 return buf .String ()
493514}
494515
495516type packageExtracter struct {
496517 f * ast.File
497518 x * extracter
498- info * loader. PackageInfo
519+ pkg * packages. Package
499520 cmap ast.CommentMap
500521}
501522
@@ -508,14 +529,13 @@ func (px packageExtracter) getComment(n ast.Node) string {
508529}
509530
510531func (x * extracter ) extractMessages () {
511- prog := x .iprog
512532 files := []packageExtracter {}
513- for _ , info := range x .iprog . AllPackages {
514- for _ , f := range info . Files {
533+ for _ , pkg := range x .pkgs {
534+ for _ , f := range pkg . Syntax {
515535 // Associate comments with nodes.
516536 px := packageExtracter {
517- f , x , info ,
518- ast .NewCommentMap (prog .Fset , f , f .Comments ),
537+ f , x , pkg ,
538+ ast .NewCommentMap (pkg .Fset , f , f .Comments ),
519539 }
520540 files = append (files , px )
521541 }
@@ -609,13 +629,13 @@ func (px packageExtracter) handleCall(call *ast.CallExpr) bool {
609629func (px packageExtracter ) getArguments (data * callData ) []argument {
610630 arguments := []argument {}
611631 x := px .x
612- info := px .info
632+ pkg := px .pkg
613633 if data .callArgsStart () >= 0 {
614634 args := data .expr .Args [data .callArgsStart ():]
615635 for i , arg := range args {
616636 expr := x .print (arg )
617637 val := ""
618- if v := info .Types [arg ].Value ; v != nil {
638+ if v := pkg . TypesInfo .Types [arg ].Value ; v != nil {
619639 val = v .ExactString ()
620640 switch arg .(type ) {
621641 case * ast.BinaryExpr , * ast.UnaryExpr :
@@ -624,12 +644,12 @@ func (px packageExtracter) getArguments(data *callData) []argument {
624644 }
625645 arguments = append (arguments , argument {
626646 ArgNum : i + 1 ,
627- Type : info .Types [arg ].Type .String (),
628- UnderlyingType : info .Types [arg ].Type .Underlying ().String (),
647+ Type : pkg . TypesInfo .Types [arg ].Type .String (),
648+ UnderlyingType : pkg . TypesInfo .Types [arg ].Type .Underlying ().String (),
629649 Expr : expr ,
630650 Value : val ,
631651 Comment : px .getComment (arg ),
632- Position : posString (& x .conf , info . Pkg , arg .Pos ()),
652+ Position : posString (& x .conf , pkg . Types , arg .Pos ()),
633653 // TODO report whether it implements
634654 // interfaces plural.Interface,
635655 // gender.Interface.
@@ -675,7 +695,7 @@ func (px packageExtracter) addMessage(
675695 case fmtparser .StatusBadArgNum , fmtparser .StatusMissingArg :
676696 arg = & argument {
677697 ArgNum : p .ArgNum ,
678- Position : posString (& x .conf , px .info . Pkg , pos ),
698+ Position : posString (& x .conf , px .pkg . Types , pos ),
679699 }
680700 name , arg .UnderlyingType = verbToPlaceholder (p .Text (), p .ArgNum )
681701 }
@@ -704,11 +724,11 @@ func (px packageExtracter) addMessage(
704724 // TODO(fix): this doesn't get the before comment.
705725 Comment : comment ,
706726 Placeholders : ph .slice ,
707- Position : posString (& x .conf , px .info . Pkg , pos ),
727+ Position : posString (& x .conf , px .pkg . Types , pos ),
708728 })
709729}
710730
711- func posString (conf * loader .Config , pkg * types.Package , pos token.Pos ) string {
731+ func posString (conf * packages .Config , pkg * types.Package , pos token.Pos ) string {
712732 p := conf .Fset .Position (pos )
713733 file := fmt .Sprintf ("%s:%d:%d" , filepath .Base (p .Filename ), p .Line , p .Column )
714734 return filepath .Join (pkg .Path (), file )
0 commit comments