I've been working with go/ast to parse go source code and copy it into another file as part of a vendoring exercise. I've got most things handled - functions, types etc - but I'm struggling with const declarations which use iota. I'm iterating through the items in ast.File.Scope.Objects and copying over the source for objects with Scope.Outer == nil and their Decl == ast.ValueSpec, basically implying top level variables and constants.
In a block of type:
const (
a = iota
b
c
d
)
...each one of them registers as a separate object, which is fair enough. However, I'm struggling to assign them with values because the objects can also be out of order when I'm iterating through them. I'm able to see the value as ast.Object.Data for these, but it also seems off when it's set to 1 << iota and so on. Does anyone have any thoughts on how I can get a grouped const declaration with the correct iota values assigned?
Thank you!
On the
*ast.File
type:Scope.Objects
tells you the names and values of the const declarations, but does not have them in the correct order, so you can't use it to infer the type.Decls
gives you the declarations in order, so you can use it to infer the typeYou can iterate on both list. First on the
Scope.Objects
to get the const values, then onDecls
to infer the type.Samplecode on the playground: https://go.dev/play/p/yEz6G1Kqoe3
I'll provide a sample code below. To make it more concrete, there are two assumptions:
We have a
file *ast.File
which we got from the parser package (for example, by callingparser.ParseDir(..)
We have a list of enum type name we want to get the consts for.
and we have a
enumTypesMap map[string]*EnumInfo
that maps a type name to the EnumInfo object.The purpose of the following snippet is to populate the
Consts
list of theEnumInfo
struct. We assume we have the name and base typename via other means (e.g. reflection).Modify to suit your own purposes