Proposal: loader should expose ast.Package

375 views
Skip to first unread message

m...@tejas.io

unread,
Apr 17, 2017, 11:06:44 AM4/17/17
to golang-dev
https://github.com/golang/tools/blob/master/go/loader/loader.go

I think it'd be nice to expose ast.Package so it's ast.Walk-able, as (I think) that would mean you could assume things like `*ast.Ident.Obj` were not nil for valid Go code while traversing method declarations and whatnot rather than having to ast.Walk on a per-file basis when the linked declaration could be in another file.

I'm pretty new to this part of Go so correct me if I'm missing something :)

Daniel Martí

unread,
Apr 17, 2017, 11:11:43 AM4/17/17
to m...@tejas.io, golang-dev
On Sun, Apr 16, 2017 at 23:50:06 -0700, m...@tejas.io wrote:
> https://github.com/golang/tools/blob/master/go/loader/loader.go

Looking at that file, where is the ast.Package you want to expose? Seems
like it's simply not existent. I don't know if that's on purpose or just
missing.

I have found the same issue that you describe, but I've simply opted for
looping over the files and walking each one as you describe. Perhaps
Alan or other x/tools/go/loader architects can answer.

--
Daniel Martí - mv...@mvdan.cc - https://mvdan.cc/

Robert Griesemer

unread,
Apr 17, 2017, 11:35:46 AM4/17/17
to Daniel Martí, m...@tejas.io, golang-dev, Alan Donovan
cc: Alan Donovan.


--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matthew Dempsky

unread,
Apr 17, 2017, 2:10:40 PM4/17/17
to m...@tejas.io, golang-dev
When using go/types (including via go/loader), you want to use https://golang.org/pkg/go/types/#Info.ObjectOf instead of `*ast.Ident.Obj`.

--

Alan Donovan

unread,
Apr 17, 2017, 2:43:19 PM4/17/17
to golang-dev, m...@tejas.io
On Monday, 17 April 2017 14:10:40 UTC-4, Matthew Dempsky wrote:
When using go/types (including via go/loader), you want to use https://golang.org/pkg/go/types/#Info.ObjectOf instead of `*ast.Ident.Obj`.

On Sun, Apr 16, 2017 at 11:50 PM, <m...@tejas.io> wrote:
https://github.com/golang/tools/blob/master/go/loader/loader.go

I think it'd be nice to expose ast.Package so it's ast.Walk-able, as (I think) that would mean you could assume things like `*ast.Ident.Obj` were not nil for valid Go code while traversing method declarations and whatnot rather than having to ast.Walk on a per-file basis when the linked declaration could be in another file.


You can use ast.Walk or ast.Inspect to traverse the ast.Files, which you can find in the Files field of the loader.Package.

Use go/ast only for its syntactic data types, not for "semantic" ones like ast.Package or ast.Object.  The go/types package provides complete information about the members of each package, the type of each expression, the value of each constant, and the reference of each name.  By contrast, the go/ast versions of these facts are necessarily incomplete and in some cases incorrect, so we use them only in special circumstances such as when quickly inspecting a single file without its siblings from the same package.  See the go/types tutorial for more details.

Tejas Manohar

unread,
Apr 17, 2017, 11:11:28 PM4/17/17
to Alan Donovan, golang-dev
But this won't work if the object is declared in a different file if AST is parsed on a per file basis right? If we were using an ast.Package I'd assume everything was available in the scope of the package
--

Best regards,

Tejas Manohar

Matthew Dempsky

unread,
Apr 18, 2017, 1:13:57 PM4/18/17
to Tejas Manohar, Alan Donovan, golang-dev
On Mon, Apr 17, 2017 at 8:11 PM, Tejas Manohar <m...@tejas.io> wrote:
But this won't work if the object is declared in a different file if AST is parsed on a per file basis right?

Sorry, I don't understand your question. go/types and x/tools/go/loader both understand how Go packages work. For example, see types.Package and loader.PackageInfo.

If we were using an ast.Package I'd assume everything was available in the scope of the package

Everything declared at package scope is available in the types.Package's Scope (though depending on your use case, types.Info may be more convenient).

Reiterating what Alan said, I encourage you to read golang.org/s/types-tutorial.

m...@tejas.io

unread,
Apr 19, 2017, 12:52:16 AM4/19/17
to golang-dev, m...@tejas.io, adon...@google.com
Got it. That tutorial is great. One thing that I could not find-- by any chance, is it possible to derive go/types.Named from AST? I am able to match on `*ast.TypeSpec` and get a StructType from here, but it does not have support for extracting things like receiver methods (even though reflection and Named allow for this).

Alan Donovan

unread,
Apr 19, 2017, 10:27:50 AM4/19/17
to m...@tejas.io, golang-dev
On 19 April 2017 at 00:52, <m...@tejas.io> wrote:
is it possible to derive go/types.Named from AST? I am able to match on `*ast.TypeSpec` and get a StructType from here, but it does not have support for extracting things like receiver methods (even though reflection and Named allow for this).

The type checker creates a Named type (now called a "defined type" by the Go 1.9 spec) for every non-alias type declaration such as 

   type T struct { ... }

To find it, find the identifier T in the syntax tree, then look in Info.Defs for the TypeName object to which it refers. Alternatively, if this declaration is at package level, look up the TypeName for "T" in the package's Scope.  Once you have the TypeName, call its Type method to get its Named type.  (Don't use Underlying--that would return the struct type.)
Reply all
Reply to author
Forward
0 new messages