Использование go / parser в пакетах

Прашант Эллина:

Я использовал go / parser для анализа файла golang и изучения его AST. У меня есть конкретная проблема, для которой я хочу использовать 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)
}

Я намерен написать программу go, gen_structureкоторая будет использоваться вот так

$ gen_structure example.go

Результат будет

> MyObject
- DoMyThing(arg)
- base
    - DoSomething(arg, a)

Что сделала gen_structure?

Он анализирует example.go и

  1. Извлекает "MyObject" из строки example_package.GetItStarted(&MyObject{})внутри функции main ().
  2. Ищет методы, MyObjectкоторые имеют хотя бы один аргумент, первый из которых имеет тип *package_example.FirstArg. Находит DoMyThing(и игнорирует DoMyAnotherThing).
  3. Определяет член baseи заглядывает внутрь (открывая example_package).
  4. Применяет тот же процесс для поиска методов, что и выше, и находит DoSomething
  5. Используя собранную информацию, он распечатывает требуемый вывод.

Я понимаю, что могу проанализировать один файл или несколько файлов в одном каталоге, используя внутренние функции go/parser. Однако я не могу понять, как разрешать символы в пакетах (в данном случае example_package).

Как мне это сделать?

Верхушка кекса :

Вызов ast.NewPackage для разрешения имен пакетов. Вам нужно будет предоставить импортер, который возвращает * ast.Object для заданного пути импорта. Если все, что вы хотите сделать, это преобразовать имя в путь, импортер может просто вернуть * ast.Object с Kind, установленным на ast.Pkg, и Name, установленным на имя пакета. Большую часть тяжелой работы в импортере можно выполнить с помощью go / build.пакет. Если вы хотите решить, выполните AST для целевого пакета, вам нужно будет проанализировать пакет и вернуть ast.Object для пакета. Чтобы предотвратить загрузку одного и того же пакета несколько раз, используйте аргумент map для импортера в качестве кеша ранее загруженных пакетов.

Вот некоторый непроверенный код для поиска разрешенного пути к пакету из *ast.SelectorExpr se:

    if x, _ := se.X.(*ast.Ident); x != nil {
        if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
            if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
                if path, err := strconv.Unquote(spec.Path.Value); err == nil {
                    // path is resolved path for selector expression se.
                }
            }
         }
     }

Пакет go / types также можно использовать для получения этой и другой информации. Я рекомендую использовать go / types вместо прямого использования go / ast.

Эта статья взята из Интернета, укажите источник при перепечатке.

Если есть какие-либо нарушения, пожалуйста, свяжитесь с[email protected] Удалить.

Отредактировано в
0

я говорю два предложения

0обзор
Войти в системуУчаствуйте в комментариях

Статьи по теме

проверьте, является ли выражение пользовательским типом, используя "go / parser"

Is there an open source lexer (parser) for the go language?

go time.Parser error with a date DMYYYY

Что не так с типами моего класса Parser?

Описание моего типа Parser как серии преобразователей монад

Что делают узлы Body Parser и cookie parser? И мне их использовать?

Безопасен ли Perl Parser для анализа произвольного кода?

Модуль импорта C ++ Parser

C Parser необычно повторяет выходные данные

stanford parser не может читать немецкие умляуты

Lark Parser: не определен терминал для ':' (кажущееся предубеждение против символа двоеточия ":")

dateutil parser для формата месяц / год: вернуть начало месяца

ImportError: невозможно импортировать имя 'Parser'

Stanford Parser: Как включить знаки препинания?

Сказать SAX Parser игнорировать недопустимые символы?

поиск существительного и глагола в stanford parser

Scrapy Parser - не выводит данные

Переполнение стека двумя функциями, вызывающими друг друга в Applicative parser

Используя SAX Parser, получите значение атрибута

Представление приоритета специального оператора в Scala Parser

Невозможно преобразовать xmlReader в Parser

Как добавить библиотеки JSON Parser?

Может ли Stanford Parser игнорировать регистр?

проблема с анализатором заимствования nom parser

Использование PowerShell Parser для консольного приложения

Как получить доступ к отдельным узлам в дереве зависимостей и дереве группы интересов, возвращаемом Stanford Parser?

JSQL Parser - Информация о функциях парсинга

Superpower Parser: иметь дело с частичным совпадением суб-парсера в комбинаторе?

JSQL Parser - Информация о функциях парсинга

TOP список

  1. 1

    Распределение Рэлея Curve_fit на Python

  2. 2

    TypeError: store.getState não é uma função. (Em 'store.getState ()', 'store.getState' é indefinido, como posso resolver esse problema?

  3. 3

    How to set windows.form's start position to bottom?

  4. 4

    Does addListener in JavaFX get garbage collected when the ChangeListener is typed as a lambda?

  5. 5

    В типе Observable <unknown> отсутствуют следующие свойства из типа Promise <any>.

  6. 6

    How to click an array of links in puppeteer?

  7. 7

    Перебирайте несколько столбцов в фрейме данных Panda и находите уникальные значения подсчета

  8. 8

    FormsAuthentication.SignOut () не работает после изменения CookieDomain

  9. 9

    PayPal REST API возвращает INVALID_CURRENCY_AMOUNT_FORMAT

  10. 10

    ContentDialog.showAsync в универсальном оконном приложении Win 10

  11. 11

    Как добавить Swagger в веб-API с поддержкой OData, работающий на ASP.NET Core 3.1

  12. 12

    Définition de la valeur par défaut dans le dictionnaire Python si la clé est manquante

  13. 13

    Набор данных Spark Streaming Cassandra Connection UnsupportedOperationChecker

  14. 14

    Merging legends in plotly subplot

  15. 15

    Проверьте, если коммит произошло на странице GitHub

  16. 16

    Преобразование символа в числовое значение ASCII в Java

  17. 17

    Есть ли у этого комбинатора Functor имя?

  18. 18

    Сохранить регистр в ConfigParser?

  19. 19

    Разделить набор на несколько наборов Scala

  20. 20

    Convert Array to Observable, perform transformations and return again as Array?

  21. 21

    MySQL - запрос не возвращает правильные результаты

популярныйтег

файл