首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ast.Inspect not walking *ast.UnaryExpr

ast.Inspect not walking *ast.UnaryExpr
EN

Stack Overflow用户
提问于 2019-11-12 06:03:05
回答 1查看 140关注 0票数 1

我正在尝试检查Go的源代码,以便制作一个工具。为此,我使用了ast.Inspect函数。

我需要知道通道是如何在函数/方法中使用的。

我有一个示例代码来检查:

代码语言:javascript
复制
package main

func B(ch chan int) {
    for x := range ch {

    }
}

这是函数B的AST:

代码语言:javascript
复制
 0  *ast.FuncDecl {
     1  .  Name: *ast.Ident {
     2  .  .  NamePos: -:4:6
     3  .  .  Name: "B"
     4  .  .  Obj: *ast.Object {
     5  .  .  .  Kind: func
     6  .  .  .  Name: "B"
     7  .  .  .  Decl: *(obj @ 0)
     8  .  .  }
     9  .  }
    10  .  Type: *ast.FuncType {
    11  .  .  Func: -:4:1
    12  .  .  Params: *ast.FieldList {
    13  .  .  .  Opening: -:4:7
    14  .  .  .  List: []*ast.Field (len = 1) {
    15  .  .  .  .  0: *ast.Field {
    16  .  .  .  .  .  Names: []*ast.Ident (len = 1) {
    17  .  .  .  .  .  .  0: *ast.Ident {
    18  .  .  .  .  .  .  .  NamePos: -:4:8
    19  .  .  .  .  .  .  .  Name: "ch"
    20  .  .  .  .  .  .  .  Obj: *ast.Object {
    21  .  .  .  .  .  .  .  .  Kind: var
    22  .  .  .  .  .  .  .  .  Name: "ch"
    23  .  .  .  .  .  .  .  .  Decl: *(obj @ 15)
    24  .  .  .  .  .  .  .  }
    25  .  .  .  .  .  .  }
    26  .  .  .  .  .  }
    27  .  .  .  .  .  Type: *ast.ChanType {
    28  .  .  .  .  .  .  Begin: -:4:11
    29  .  .  .  .  .  .  Arrow: -
    30  .  .  .  .  .  .  Dir: 3
    31  .  .  .  .  .  .  Value: *ast.Ident {
    32  .  .  .  .  .  .  .  NamePos: -:4:16
    33  .  .  .  .  .  .  .  Name: "int"
    34  .  .  .  .  .  .  }
    35  .  .  .  .  .  }
    36  .  .  .  .  }
    37  .  .  .  }
    38  .  .  .  Closing: -:4:19
    39  .  .  }
    40  .  }
    41  .  Body: *ast.BlockStmt {
    42  .  .  Lbrace: -:4:21
    43  .  .  List: []ast.Stmt (len = 1) {
    44  .  .  .  0: *ast.RangeStmt {
    45  .  .  .  .  For: -:5:2
    46  .  .  .  .  Key: *ast.Ident {
    47  .  .  .  .  .  NamePos: -:5:6
    48  .  .  .  .  .  Name: "x"
    49  .  .  .  .  .  Obj: *ast.Object {
    50  .  .  .  .  .  .  Kind: var
    51  .  .  .  .  .  .  Name: "x"
    52  .  .  .  .  .  .  Decl: *ast.AssignStmt {
    53  .  .  .  .  .  .  .  Lhs: []ast.Expr (len = 1) {
    54  .  .  .  .  .  .  .  .  0: *(obj @ 46)
    55  .  .  .  .  .  .  .  }
    56  .  .  .  .  .  .  .  TokPos: -:5:8
    57  .  .  .  .  .  .  .  Tok: :=
    58  .  .  .  .  .  .  .  Rhs: []ast.Expr (len = 1) {
    59  .  .  .  .  .  .  .  .  0: *ast.UnaryExpr {
    60  .  .  .  .  .  .  .  .  .  OpPos: -:5:11
    61  .  .  .  .  .  .  .  .  .  Op: range
    62  .  .  .  .  .  .  .  .  .  X: *ast.Ident {
    63  .  .  .  .  .  .  .  .  .  .  NamePos: -:5:17
    64  .  .  .  .  .  .  .  .  .  .  Name: "ch"
    65  .  .  .  .  .  .  .  .  .  .  Obj: *(obj @ 20)
    66  .  .  .  .  .  .  .  .  .  }
    67  .  .  .  .  .  .  .  .  }
    68  .  .  .  .  .  .  .  }
    69  .  .  .  .  .  .  }
    70  .  .  .  .  .  }
    71  .  .  .  .  }
    72  .  .  .  .  TokPos: -:5:8
    73  .  .  .  .  Tok: :=
    74  .  .  .  .  X: *(obj @ 62)
    75  .  .  .  .  Body: *ast.BlockStmt {
    76  .  .  .  .  .  Lbrace: -:5:20
    77  .  .  .  .  .  Rbrace: -:7:2
    78  .  .  .  .  }
    79  .  .  .  }
    80  .  .  }
    81  .  .  Rbrace: -:8:1
    82  .

正如您在59行中看到的,我们可以看到有一个UnaryExpr节点,其Op设置为range。这就是我想要捕获的节点。

我尝试使用这段代码遍历最后一个节点,并且只捕获那个节点。

代码语言:javascript
复制
exampleFunc := `
package main

func B(ch chan int) {
    for x := range ch {

    }
}
`
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "-", exampleFunc, parser.ParseComments)
ast.Inspect(file, func(node ast.Node) bool {
    fn, ok := node.(*ast.UnaryExpr) // try to cast
    if !ok {
        return true
    }
        ast.Print(fset, fn)
    return true
})

但它似乎不起作用。

知道为什么,打印整个FuncDecl的AST时,我可以看到有一个UnaryExpr节点,但在尝试获取该节点时什么也没有出现?

EN

回答 1

Stack Overflow用户

发布于 2019-11-12 08:07:45

作为@mkopriva,*ast.Ident节点被视为叶节点。因此,我们需要手动从RangeStmt移动到AssignStmt (如果有),然后再次使用inspect来访问UnaryExpr

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58809296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档