跨包使用 go/parser

2024-01-03

我用过去/解析器 https://golang.org/pkg/go/parser/解析 golang 文件并检查它的 AST。我有一个特定的问题,我想使用 go/parser,但遇到了障碍。

考虑 GOPATH/src 中存在以下文件

$GOPATH/src/
    example.go
    example_package/
        example_package.go

以下是上面文件的内容

示例.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{})
}

示例_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_struct 做了什么?

它解析 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).

我该怎么做呢?


Call 新建包 http://godoc.org/go/ast#NewPackage解析包名称。您需要提供一个importer http://godoc.org/go/ast#Importer返回一个*ast.对象 http://godoc.org/go/ast#Object对于给定的导入路径。如果您只想将名称解析为路径,导入器只需返回一个*ast.对象 http://godoc.org/go/ast#ObjectKind http://godoc.org/go/ast#Object.Kind set to ast.Pkg http://godoc.org/go/ast#PkgName http://godoc.org/go/ast#Object.Name设置为包的名称。进口商的大部分繁重工作都可以通过go/build http://godoc.org/go/build包裹。如果想要解析目标包的 AST,则需要解析包并返回包的 ast.Object。为了防止多次加载相同的包,请使用导入器的映射参数作为先前加载的包的缓存。

这是一些未经测试的代码,用于从*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.
                }
            }
         }
     }

The go/types http://godoc.org/go/types包也可用于获取此信息及更多信息。我建议使用 go/types 而不是直接使用 go/ast。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

跨包使用 go/parser 的相关文章

随机推荐

  • 如何直接从 R 控制台打开工作目录?

    我怎样才能打开我的getwd 直接从 R 控制台获取文件夹 如果我想查看我最近刚刚导出到那里的东西 这很有用 谷歌搜索没有透露任何信息 我没有能力构建一个函数 如果您确实想要一个文件浏览器 您可以创建一个函数来打开目录 根据您使用的操作系统
  • 导入错误:使用 Azure SDK 时无法导入名称会话

    我正在使用 Azure SDK 运行代码 首先 我通过下载sdkpip install azure 然后我编写运行以下 python 代码 import requests import os make sure you configure
  • Rails Basecamp 风格子域最佳实践

    我的目标是为每个子域拥有单独的用户帐户 在任何情况下 我都不想在子域之间进行异花授粉 我看过了罗比 拉塞尔 http www robbyonrails com articles 2009 01 11 subdomain accounts w
  • 从 url mysql 或 python 中提取模式编号

    我有一堆 url 其中有一个字符串 hotel 4 digit number hotel1234 or slash 4digit html 1234 html 是否有正则表达式可以使用 python 或 mysql 提取 4 位数字 例如
  • 在 AWS Lambda 上使用来自 Python 的 NodeJS 4 脚本

    问题 我有一个在 AWS Lambda 上运行的 Python 脚本 该脚本正在使用subprocess执行 NodeJS 4 脚本 我尝试过什么 subprocess check output my script js 得到非零结果 得到
  • 更改外部变量的值

    我们在 File1 c 中有 int arr 10 在 File2 c 中 extern int arr int main arr 0 10 return 0 这样做可能会出现哪些问题以及为什么 数组不是指针 内存访问将会出错 In Fil
  • 从头开始实现 cv2.warpPerspective()

    我正在使用 OpenCV 函数进行一些实验cv2 warpPerspective当我决定从头开始编码以更好地理解它的管道时 尽管我 希望 遵循了每一个理论步骤 但似乎我仍然遗漏了一些东西 并且我正在努力理解什么 请你帮助我好吗 SRC 图像
  • 谷歌应用引擎支持环境变量吗?

    我注意到开发人员控制台似乎没有公开任何可以配置静态环境变量的地方 GAE 是否期望我将这些变量捆绑为构建服务器部署的一部分 如果是这样 GAE Google Cloud 上是否有任何文档介绍了原因或详细说明了其原理 几年过去了 仍然没有 我
  • Ruby 枚举器如何终止迭代?

    朋友们 我需要帮助解释一下 在下面的 Ruby 代码中 什么条件白蚁循环会做什么 它应该是一个无限循环 但是 它如何终止呢 Ruby code fib Enumerator new do y a b 1 loop do y lt lt a
  • 跟踪代码数据类型和操作

    跟踪代码允许企业 例如我们 在 Box 上的用户数据中存储一些本地 ID 我意识到需要在企业上启用该功能 我们的联系人正在处理 第一个问题 文档说它是一个 数组 其他答案表明它是一个 名称 值对 的数组 在数据类型中 Box API 到底将
  • 在 kubernetes 上持续部署有状态 apache flink 应用程序

    我想在 kubernetes 上运行 apache flink 1 11 1 流应用程序 文件系统状态后端保存到 s3 s3 的检查点正在运行 args standalone job s s3 BUCKET NAME 34619f2862c
  • copyInputStreamToOutputStream(in, System.out) [重复]

    这个问题在这里已经有答案了 我已通读HTTPS 和 SSL 的安全性 https developer android com training articles security ssl java来自 Android 的文档 我看到它一直在
  • 仅使用composer.lock安装Composer

    我新安装了一个带有composer lock 文件的PHP 应用程序 运行composer install时 命令行工具仍然要求composer json 我没有 在composer文档中 据说安装命令首先查找composer lock 然
  • 错误:android.app.SuperNotCalledException

    我是 android 的新用户 我已经建立了一个 android 数据库连接并创建表应用程序 但在运行时它会生成一个错误 听到错误 07 15 16 25 55 404 ERROR AndroidRuntime 3308 Uncaught
  • nameof 运算符有什么方法可以访问方法参数(在同一方法之外)?

    采用以下类和方法 public class Foo public Foo Create string bar return new Foo bar 所以得到 创建 是显而易见的 nameof Foo Create 除了在运行时使用反射读取参
  • Angular2 - 动态添加 HTML 属性和类

    您能帮我找到如何在 Angular 2 中动态添加属性 类到 HTML 模板中的答案吗 Eg div class some class class 8 div 上例中的 8 应来自配置属性 但如果未定义特定属性 则col and class
  • typedef 类型检查?

    如何让 g 对 typedef 进行类型检查 是否可以 IE typedef int T1 typedef int T2 T1 x 5 Ok with me T2 y x Any way to get an error or a warni
  • VisualSVN Server 通常被视为值得信赖的 SVN 服务器吗?

    is 视觉SVN服务器 http en wikipedia org wiki VisualSVN Server通常被视为值得信赖的 SVN 服务器 我公司一直在用 据我所知 它只是 SVN Apache 的自定义发行版 并集成到安装程序中
  • 查找字符串数组的公共前缀

    我有一个像这样的数组 sports array Softball Counties Softball Eastern Softball North Harbour Softball South Softball Western 我想找到字符
  • 跨包使用 go/parser

    我用过去 解析器 https golang org pkg go parser 解析 golang 文件并检查它的 AST 我有一个特定的问题 我想使用 go parser 但遇到了障碍 考虑 GOPATH src 中存在以下文件 GOPA