ast.Inspect不走* ast.UnaryExpr

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

我需要知道函数/方法内部如何使用通道。

我将其作为示例代码进行检查:

package main

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

    }
}

这是功能B的AST:

 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的{​​{1}}节点。那就是我要捕捉的节点。

我尝试使用此代码来误导用户并仅捕获该节点。

range

但这似乎无效。

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

mefie 回答:ast.Inspect不走* ast.UnaryExpr

作为@mkopriva,*ast.Ident个节点被视为叶子。因此,我们需要手动从RangeStmt移至AssignStmt(如果有),然后再次使用检查以到达UnaryExpr

本文链接:https://www.f2er.com/3121058.html

大家都在问