Re: [go-nuts] navigating through interface calls
IntelliJ has “show implementations” which will do what you want. > On Dec 7, 2018, at 11:13 AM, Burak Serdar wrote: > > On Fri, Dec 7, 2018 at 9:53 AM David Wahlstedt > wrote: >> >> Hi, >> I am still quite inexperienced in go programming, and I find it quite >> frustrating, sometimes, to find what will actually be executed by a call to >> an interface method found in some arbitrary code. >> Here I have traced the process of finding the definition of "conn.Close()" >> an instance of an interface method call. This is what I would like to have >> automatized by godef, for instance. >> Is there anything like that out there that does it with one command / key >> stroke, etc, automagically ? > > That is not possible in general. This is not unique to go either. > Consider a function like: > > type Shape interface { > Draw() > } > > func draw(shapes []Shape) { > for _,x:=range shapes { > x.Draw() > } > } > > > Each element of 'shapes' can be a different type, with a different > Draw() implementation. > > What I do in these situations is to either backtrack calls as you did, > or simply use grep, and find a list of candidate implementations, and > work from there. > > This is somewhat easier with languages like Java because you can look > for classes implementing that interface, but then you still have to > work with a list of candidates. > > > > >> Godef and go-guru does not, as far as I know. >> >> BR, >> David >> >> Here follows some anonymized code: >> (please forgive me if I've made some errors, I hope you get the idea anyway) >> >> In the file file1.go:1234 in the library lib1, I found a call: >> : _ = conn.Close() >> How do i figure out what happens when this line is executed? >> Here is a list of steps to find it "mechanically", so to say: >> 1. file1.go:1234 >> : func returnConn(conn lib2.Conn) { >> : _ = conn.Close() >> : } >> >> Using godef-jump on the Close() will just give me the interface >> declaration. I can use go-guru-implements, and get a list of >> possible implementations of Close, but how do I know which one will >> actually be used? So, let's figure out the actual type of conn. >> I use go-guru-referrers on returnConn, and choose one of the hits, >> which is file1.go:206 >> >> 2. file1.go:206 >> : func (r *Record) Release(foo bar.T1) error { >> : ... >> : var conn lib2.Conn >> : if conn, err = r.foo.getConn(baz); err != nil { >> : return err >> : } >> : defer returnConn(conn) >> conn gets its value from getConn, so I end up in file1.go:1074 >> >> 3. file1.go:1074 >> : func (foo *FOO) getConn(mu T2) (lib2.Conn, error) { >> : ... >> : conn := foo.connBax.Get() >> : ... >> : return conn, nil >> conn gets its value from Get(), so I go to file3.go:178 >> >> 4. file3.go:178 >> : func (p *Bax) Get() Conn { >> : ... >> : return &xooConn{x: p, xc: xc} >> I find the return value and go to its definition in file3.go:371 >> >> 5. file3.go:371 >> : type xooConn struct { >> : x *Bax >> : xc*baxConn >> : s T3 >> : } >> Aaah! This is the type of conn at file1.go:1234! >> >> 6. file1.go:1234 >> : _ = conn.Close() >> Now I can follow the "definition" of Close() using godef-jump, and >> end up in file1.go:30: >> >> 7. file1.go:30 >> : type Conn interface { >> : Close() error >> >> I use go-guru-implements to see a list of possible implementations: >> : PATH1/lib2/dir1/file1.go:30.2-30.6: abstract method func >> (ConnWithTimeout).Close() error >> : PATH1/lib2/dir1/file3.go:394.23-394.27: is implemented by method >> (*xooConn).Close >> : PATH1/lib2/dir1/conn.go:304.16-304.20: is implemented by method >> (*conn).Close >> : PATH1/lib2/dir1/boo.go:12.3-45.6: is implemented by method >> (*booingConn).Close >> : PATH1/lib2/dir1/file3.go:510.21-510.25: is implemented by method >> (errorConn).Close >> : PATH1/lib2/dir1/file1.go:30.2-30.6: implements method (Conn).Close >> : PATH2/bah.go:78.9-101.2: implements method (bah.Closer).Close >> Now, since I know the type is *xooConn, I can jump to the right hit, >> and go to file3.go:394. >> 8. file3.go:394 >> : func (ac *xooConn) Close() error { >> : pc := ac.pc >> : ... >> : return nil >> Yes, here it is, at step 8 >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group.
Re: [go-nuts] navigating through interface calls
On Fri, Dec 7, 2018 at 9:53 AM David Wahlstedt wrote: > > Hi, > I am still quite inexperienced in go programming, and I find it quite > frustrating, sometimes, to find what will actually be executed by a call to > an interface method found in some arbitrary code. > Here I have traced the process of finding the definition of "conn.Close()" an > instance of an interface method call. This is what I would like to have > automatized by godef, for instance. > Is there anything like that out there that does it with one command / key > stroke, etc, automagically ? That is not possible in general. This is not unique to go either. Consider a function like: type Shape interface { Draw() } func draw(shapes []Shape) { for _,x:=range shapes { x.Draw() } } Each element of 'shapes' can be a different type, with a different Draw() implementation. What I do in these situations is to either backtrack calls as you did, or simply use grep, and find a list of candidate implementations, and work from there. This is somewhat easier with languages like Java because you can look for classes implementing that interface, but then you still have to work with a list of candidates. > Godef and go-guru does not, as far as I know. > > BR, > David > > Here follows some anonymized code: > (please forgive me if I've made some errors, I hope you get the idea anyway) > > In the file file1.go:1234 in the library lib1, I found a call: > : _ = conn.Close() > How do i figure out what happens when this line is executed? > Here is a list of steps to find it "mechanically", so to say: > 1. file1.go:1234 >: func returnConn(conn lib2.Conn) { >: _ = conn.Close() >: } > >Using godef-jump on the Close() will just give me the interface >declaration. I can use go-guru-implements, and get a list of >possible implementations of Close, but how do I know which one will >actually be used? So, let's figure out the actual type of conn. >I use go-guru-referrers on returnConn, and choose one of the hits, >which is file1.go:206 > > 2. file1.go:206 >: func (r *Record) Release(foo bar.T1) error { >: ... >: var conn lib2.Conn >: if conn, err = r.foo.getConn(baz); err != nil { >: return err >: } >: defer returnConn(conn) >conn gets its value from getConn, so I end up in file1.go:1074 > > 3. file1.go:1074 >: func (foo *FOO) getConn(mu T2) (lib2.Conn, error) { >: ... >: conn := foo.connBax.Get() >: ... >: return conn, nil >conn gets its value from Get(), so I go to file3.go:178 > > 4. file3.go:178 >: func (p *Bax) Get() Conn { >: ... >: return &xooConn{x: p, xc: xc} >I find the return value and go to its definition in file3.go:371 > > 5. file3.go:371 >: type xooConn struct { >: x *Bax >: xc*baxConn >: s T3 >: } >Aaah! This is the type of conn at file1.go:1234! > > 6. file1.go:1234 >: _ = conn.Close() >Now I can follow the "definition" of Close() using godef-jump, and >end up in file1.go:30: > > 7. file1.go:30 >: type Conn interface { >: Close() error > >I use go-guru-implements to see a list of possible implementations: >: PATH1/lib2/dir1/file1.go:30.2-30.6: abstract method func > (ConnWithTimeout).Close() error >: PATH1/lib2/dir1/file3.go:394.23-394.27: is implemented by method > (*xooConn).Close >: PATH1/lib2/dir1/conn.go:304.16-304.20: is implemented by method > (*conn).Close >: PATH1/lib2/dir1/boo.go:12.3-45.6: is implemented by method > (*booingConn).Close >: PATH1/lib2/dir1/file3.go:510.21-510.25: is implemented by method > (errorConn).Close >: PATH1/lib2/dir1/file1.go:30.2-30.6: implements method (Conn).Close >: PATH2/bah.go:78.9-101.2: implements method (bah.Closer).Close >Now, since I know the type is *xooConn, I can jump to the right hit, >and go to file3.go:394. > 8. file3.go:394 >: func (ac *xooConn) Close() error { >: pc := ac.pc >: ... >: return nil >Yes, here it is, at step 8 > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] navigating through interface calls
Hi, I am still quite inexperienced in go programming, and I find it quite frustrating, sometimes, to find what will actually be executed by a call to an interface method found in some arbitrary code. Here I have traced the process of finding the definition of "conn.Close()" an instance of an interface method call. This is what I would like to have automatized by godef, for instance. Is there anything like that out there that does it with one command / key stroke, etc, automagically ? Godef and go-guru does not, as far as I know. BR, David Here follows some anonymized code: (please forgive me if I've made some errors, I hope you get the idea anyway) In the file file1.go:1234 in the library lib1, I found a call: : _ = conn.Close() How do i figure out what happens when this line is executed? Here is a list of steps to find it "mechanically", so to say: 1. file1.go:1234 : func returnConn(conn lib2.Conn) { : _ = conn.Close() : } Using godef-jump on the Close() will just give me the interface declaration. I can use go-guru-implements, and get a list of possible implementations of Close, but how do I know which one will actually be used? So, let's figure out the actual type of conn. I use go-guru-referrers on returnConn, and choose one of the hits, which is file1.go:206 2. file1.go:206 : func (r *Record) Release(foo bar.T1) error { : ... : var conn lib2.Conn : if conn, err = r.foo.getConn(baz); err != nil { : return err : } : defer returnConn(conn) conn gets its value from getConn, so I end up in file1.go:1074 3. file1.go:1074 : func (foo *FOO) getConn(mu T2) (lib2.Conn, error) { : ... : conn := foo.connBax.Get() : ... : return conn, nil conn gets its value from Get(), so I go to file3.go:178 4. file3.go:178 : func (p *Bax) Get() Conn { : ... : return &xooConn{x: p, xc: xc} I find the return value and go to its definition in file3.go:371 5. file3.go:371 : type xooConn struct { : x *Bax : xc*baxConn : s T3 : } Aaah! This is the type of conn at file1.go:1234! 6. file1.go:1234 : _ = conn.Close() Now I can follow the "definition" of Close() using godef-jump, and end up in file1.go:30: 7. file1.go:30 : type Conn interface { : Close() error I use go-guru-implements to see a list of possible implementations: : PATH1/lib2/dir1/file1.go:30.2-30.6: abstract method func (ConnWithTimeout).Close() error : PATH1/lib2/dir1/file3.go:394.23-394.27: is implemented by method (*xooConn).Close : PATH1/lib2/dir1/conn.go:304.16-304.20: is implemented by method (*conn).Close : PATH1/lib2/dir1/boo.go:12.3-45.6: is implemented by method (*booingConn).Close : PATH1/lib2/dir1/file3.go:510.21-510.25: is implemented by method (errorConn).Close : PATH1/lib2/dir1/file1.go:30.2-30.6: implements method (Conn).Close : PATH2/bah.go:78.9-101.2: implements method (bah.Closer).Close Now, since I know the type is *xooConn, I can jump to the right hit, and go to file3.go:394. 8. file3.go:394 : func (ac *xooConn) Close() error { : pc := ac.pc : ... : return nil Yes, here it is, at step 8 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.