Alternatively, if you are walking an AST and only interested in the
exported names then you can use
https://golang.org/pkg/go/ast/#PackageExports . It will filter your tree to
only elements that are exported before you begin traversal.

As to your specific case of determining if a type used in a method
signature is exported, I'd ask: Does it matter if the source package is the
same one where the method is defined or is it any non-builtin, exported
types used in the signature?

I believe the case of "exported name used in a method within the same
package" can be determined by iterating of the 'Params.List' attribute of
the ast.FuncType and looking for elements of the slice that are of type
'*ast.Ident' and checking the corresponding 'IsExported' method call
results. For complete coverage, you'd also need to check for
*ast.ArrayType, *ast.ChanType, *ast.MapType, *ast.Ellipsis (for uses of the
type as a variadic), *ast.FuncType (and its corresponding arguments and
return types), and *ast.StarExpr (for uses of the type as a pointer).

The case of "any non-builtin, exported type from any package" would use the
previous logic but also add in checking for elements of 'Params.List' that
are of type '*ast.SelectorExpr'. While I'm sure there is a case where this
is not true, the elements of type *ast.SelectorExpr in the parameter list
of an *ast.FuncType are usually references to a type exported by another
package (think "http.Handler"). The 'X' attribute can be converted to
*ast.Ident for the source package name and the 'Sel' attribute contains the
name of the referenced type. Note that the package name might actually be a
local alias when the file imports with ' import myname "net/http" '.

https://play.golang.org/p/yNKAQe_YSV

PS the implementation of 'IsExported' used by everything checks the
capitalisation of the first letter to make its choice:
https://golang.org/src/go/ast/ast.go?s=16357:16390#L516

On Mon, Apr 24, 2017 at 2:49 AM Tejas Manohar <m...@tejas.io> wrote:

> Agreed! I ended up casting to types.NamedType (or pointer then elem())...
> I'll try your method too!
> On Sun, Apr 23, 2017 at 11:11 PM Axel Wagner <
> axel.wagner...@googlemail.com> wrote:
>
>> I'd say, probably type-asserting to a *types.TypeName
>> <https://golang.org/pkg/go/types/#TypeName> and then use Exported()
>> <https://golang.org/pkg/go/types/#TypeName.Exported> (the code of which
>> also leads to ast.IsExported <https://golang.org/pkg/go/ast/#IsExported>
>> ).
>>
>> Side-note: You probably shouldn't rely on parsing the output of String()
>> of any value, just as you shouldn't rely on parsing the output of
>> error.Error().
>>
>> On Mon, Apr 24, 2017 at 7:06 AM, <m...@tejas.io> wrote:
>>
>>> https://golang.org/pkg/go/types/#Type
>>>
>>> Is there a helper function to determine whether a *types.Type* is
>>> exported? It seems like I can do some string parsing like
>>>
>>> t := something.Type()
>>> parts := strings.Split(t.String(), ".") // go/ast.Node => ["go/ast",
>>> "Node"]
>>> ident := parts[len(parts)-1] // "Node"
>>> exported := strings.IsUpper(ident[0])
>>>
>>> but I imagine there's a simpler, more robust way. The end goal is to
>>> find out whether a type of a method argument is exported-- e.g.
>>> namedType := obj.Type().(*types.Named)
>>> method := namedType.Method(0)
>>> signature := method.Type().(*types.Signature)
>>> signature.Params().At(0).Type() // is this exported?
>>>
>>> And, for some context, all of this is from walking go/ast
>>>
>>> --
>>> 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.
>>>
>>
>> --
>
> Best regards,
>
> Tejas Manohar
>
> --
> 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.

Reply via email to