Я использовал go/parser для анализа файла golang и изучения его AST. У меня есть определенная проблема, для которой я хочу использовать go/parser, но я попал в блокпост.Использование go/parser через пакеты
Учтите, что следующие файлы присутствуют в GOPATH/SRC
$GOPATH/src/
example.go
example_package/
example_package.go
Ниже приведены содержимое файлов выше
example.go
package main
import (
"example_package"
)
type MyObject struct {
base *example_package.BaseObject
}
func DoMyThing(arg *example_package.FirstArg) {
arg.Write(10)
}
func DoMyAnotherThing() {
}
func main() {
example_package.GetItStarted(&MyObject{})
}
example_package. go
package example_package
func GetItStarted(obj interface{}) {
}
type FirstArg interface {
Read() int
Write(x int)
}
type BaseObject struct {
}
func (p *BaseObject) DoSomething(arg *FirstArg, a int) {
arg.Write(arg.Read() + a)
}
Мое намерение состоит в том, чтобы написать программу идти под названием gen_structure
, который используется как этот
$ gen_structure example.go
Выходной сигнал будет
> MyObject
- DoMyThing(arg)
- base
- DoSomething(arg, a)
Что gen_structure делать?
Он анализирует example.go и
- экстрактов "MyObject" из линии
example_package.GetItStarted(&MyObject{})
из внутри основной функции(). - Ищет методы на
MyObject
, которые имеют по крайней мере один аргумент, первый из которых имеет тип*package_example.FirstArg
. Он находитDoMyThing
(и игнорируетсяDoMyAnotherThing
). - Идентифицирует элемент
base
и заглядывает внутрь (открывexample_package
). - Применяет тот же процесс для поиска методов, как указано выше, и находит
DoSomething
- Используя собранную информацию, он печатает требуемый результат.
Я понимаю, что могу разобрать один файл или кучу файлов в том же каталоге, используя функциональность в пределах go/parser
. Однако я не могу понять, как разрешать символы через пакеты (в этом случае example_package
).
Как это сделать?
спасибо. Я попытаюсь выполнить реализацию на основе вышеизложенного. –
Могу ли я использовать это для импортера - http://godoc.org/go/importer По умолчанию()? –
Они разные импортеры. 'Ast.Importer' прост: вызовите функцию импорта go/build, чтобы получить' * build.Package' и вернуть '& ast.Object {вид: ast.Pkg, Name: p.Name}' где 'p' '* build.Package'. Я бы использовал go/types вместо go/ast. Проблема, описанная в вопросе, находится на пределе того, что можно сделать с пакетом go/ast. Вероятно, код будет короче, если вы используете go/types вместо go/ast напрямую. –