package edge
import (
"fmt"
"go/ast"
"reflect"
)
type Kind uint8
func (k Kind ) String () string {
if k == Invalid {
return "<invalid>"
}
info := fieldInfos [k ]
return fmt .Sprintf ("%v.%s" , info .nodeType .Elem ().Name (), info .name )
}
func (k Kind ) NodeType () reflect .Type { return fieldInfos [k ].nodeType }
func (k Kind ) FieldName () string { return fieldInfos [k ].name }
func (k Kind ) FieldType () reflect .Type { return fieldInfos [k ].fieldType }
func (k Kind ) Get (n ast .Node , idx int ) ast .Node {
if k .NodeType () != reflect .TypeOf (n ) {
panic (fmt .Sprintf ("%v.Get(%T): invalid node type" , k , n ))
}
v := reflect .ValueOf (n ).Elem ().Field (fieldInfos [k ].index )
if v .Kind () == reflect .Slice {
v = v .Index (idx )
} else if idx != -1 {
panic (fmt .Sprintf ("%v, Get(%T, %d): cannot index non-slice" , v , n , idx ))
}
out , _ := v .Interface ().(ast .Node )
return out
}
const (
Invalid Kind = iota
ArrayType_Elt
ArrayType_Len
AssignStmt_Lhs
AssignStmt_Rhs
BinaryExpr_X
BinaryExpr_Y
BlockStmt_List
BranchStmt_Label
CallExpr_Args
CallExpr_Fun
CaseClause_Body
CaseClause_List
ChanType_Value
CommClause_Body
CommClause_Comm
CommentGroup_List
CompositeLit_Elts
CompositeLit_Type
DeclStmt_Decl
DeferStmt_Call
Ellipsis_Elt
ExprStmt_X
FieldList_List
Field_Comment
Field_Doc
Field_Names
Field_Tag
Field_Type
File_Decls
File_Doc
File_Name
ForStmt_Body
ForStmt_Cond
ForStmt_Init
ForStmt_Post
FuncDecl_Body
FuncDecl_Doc
FuncDecl_Name
FuncDecl_Recv
FuncDecl_Type
FuncLit_Body
FuncLit_Type
FuncType_Params
FuncType_Results
FuncType_TypeParams
GenDecl_Doc
GenDecl_Specs
GoStmt_Call
IfStmt_Body
IfStmt_Cond
IfStmt_Else
IfStmt_Init
ImportSpec_Comment
ImportSpec_Doc
ImportSpec_Name
ImportSpec_Path
IncDecStmt_X
IndexExpr_Index
IndexExpr_X
IndexListExpr_Indices
IndexListExpr_X
InterfaceType_Methods
KeyValueExpr_Key
KeyValueExpr_Value
LabeledStmt_Label
LabeledStmt_Stmt
MapType_Key
MapType_Value
ParenExpr_X
RangeStmt_Body
RangeStmt_Key
RangeStmt_Value
RangeStmt_X
ReturnStmt_Results
SelectStmt_Body
SelectorExpr_Sel
SelectorExpr_X
SendStmt_Chan
SendStmt_Value
SliceExpr_High
SliceExpr_Low
SliceExpr_Max
SliceExpr_X
StarExpr_X
StructType_Fields
SwitchStmt_Body
SwitchStmt_Init
SwitchStmt_Tag
TypeAssertExpr_Type
TypeAssertExpr_X
TypeSpec_Comment
TypeSpec_Doc
TypeSpec_Name
TypeSpec_Type
TypeSpec_TypeParams
TypeSwitchStmt_Assign
TypeSwitchStmt_Body
TypeSwitchStmt_Init
UnaryExpr_X
ValueSpec_Comment
ValueSpec_Doc
ValueSpec_Names
ValueSpec_Type
ValueSpec_Values
maxKind
)
var _ = [1 << 7 ]struct {}{}[maxKind ]
type fieldInfo struct {
nodeType reflect .Type
name string
index int
fieldType reflect .Type
}
func info [N ast .Node ](fieldName string ) fieldInfo {
nodePtrType := reflect .TypeFor [N ]()
f , ok := nodePtrType .Elem ().FieldByName (fieldName )
if !ok {
panic (fieldName )
}
return fieldInfo {nodePtrType , fieldName , f .Index [0 ], f .Type }
}
var fieldInfos = [...]fieldInfo {
Invalid : {},
ArrayType_Elt : info [*ast .ArrayType ]("Elt" ),
ArrayType_Len : info [*ast .ArrayType ]("Len" ),
AssignStmt_Lhs : info [*ast .AssignStmt ]("Lhs" ),
AssignStmt_Rhs : info [*ast .AssignStmt ]("Rhs" ),
BinaryExpr_X : info [*ast .BinaryExpr ]("X" ),
BinaryExpr_Y : info [*ast .BinaryExpr ]("Y" ),
BlockStmt_List : info [*ast .BlockStmt ]("List" ),
BranchStmt_Label : info [*ast .BranchStmt ]("Label" ),
CallExpr_Args : info [*ast .CallExpr ]("Args" ),
CallExpr_Fun : info [*ast .CallExpr ]("Fun" ),
CaseClause_Body : info [*ast .CaseClause ]("Body" ),
CaseClause_List : info [*ast .CaseClause ]("List" ),
ChanType_Value : info [*ast .ChanType ]("Value" ),
CommClause_Body : info [*ast .CommClause ]("Body" ),
CommClause_Comm : info [*ast .CommClause ]("Comm" ),
CommentGroup_List : info [*ast .CommentGroup ]("List" ),
CompositeLit_Elts : info [*ast .CompositeLit ]("Elts" ),
CompositeLit_Type : info [*ast .CompositeLit ]("Type" ),
DeclStmt_Decl : info [*ast .DeclStmt ]("Decl" ),
DeferStmt_Call : info [*ast .DeferStmt ]("Call" ),
Ellipsis_Elt : info [*ast .Ellipsis ]("Elt" ),
ExprStmt_X : info [*ast .ExprStmt ]("X" ),
FieldList_List : info [*ast .FieldList ]("List" ),
Field_Comment : info [*ast .Field ]("Comment" ),
Field_Doc : info [*ast .Field ]("Doc" ),
Field_Names : info [*ast .Field ]("Names" ),
Field_Tag : info [*ast .Field ]("Tag" ),
Field_Type : info [*ast .Field ]("Type" ),
File_Decls : info [*ast .File ]("Decls" ),
File_Doc : info [*ast .File ]("Doc" ),
File_Name : info [*ast .File ]("Name" ),
ForStmt_Body : info [*ast .ForStmt ]("Body" ),
ForStmt_Cond : info [*ast .ForStmt ]("Cond" ),
ForStmt_Init : info [*ast .ForStmt ]("Init" ),
ForStmt_Post : info [*ast .ForStmt ]("Post" ),
FuncDecl_Body : info [*ast .FuncDecl ]("Body" ),
FuncDecl_Doc : info [*ast .FuncDecl ]("Doc" ),
FuncDecl_Name : info [*ast .FuncDecl ]("Name" ),
FuncDecl_Recv : info [*ast .FuncDecl ]("Recv" ),
FuncDecl_Type : info [*ast .FuncDecl ]("Type" ),
FuncLit_Body : info [*ast .FuncLit ]("Body" ),
FuncLit_Type : info [*ast .FuncLit ]("Type" ),
FuncType_Params : info [*ast .FuncType ]("Params" ),
FuncType_Results : info [*ast .FuncType ]("Results" ),
FuncType_TypeParams : info [*ast .FuncType ]("TypeParams" ),
GenDecl_Doc : info [*ast .GenDecl ]("Doc" ),
GenDecl_Specs : info [*ast .GenDecl ]("Specs" ),
GoStmt_Call : info [*ast .GoStmt ]("Call" ),
IfStmt_Body : info [*ast .IfStmt ]("Body" ),
IfStmt_Cond : info [*ast .IfStmt ]("Cond" ),
IfStmt_Else : info [*ast .IfStmt ]("Else" ),
IfStmt_Init : info [*ast .IfStmt ]("Init" ),
ImportSpec_Comment : info [*ast .ImportSpec ]("Comment" ),
ImportSpec_Doc : info [*ast .ImportSpec ]("Doc" ),
ImportSpec_Name : info [*ast .ImportSpec ]("Name" ),
ImportSpec_Path : info [*ast .ImportSpec ]("Path" ),
IncDecStmt_X : info [*ast .IncDecStmt ]("X" ),
IndexExpr_Index : info [*ast .IndexExpr ]("Index" ),
IndexExpr_X : info [*ast .IndexExpr ]("X" ),
IndexListExpr_Indices : info [*ast .IndexListExpr ]("Indices" ),
IndexListExpr_X : info [*ast .IndexListExpr ]("X" ),
InterfaceType_Methods : info [*ast .InterfaceType ]("Methods" ),
KeyValueExpr_Key : info [*ast .KeyValueExpr ]("Key" ),
KeyValueExpr_Value : info [*ast .KeyValueExpr ]("Value" ),
LabeledStmt_Label : info [*ast .LabeledStmt ]("Label" ),
LabeledStmt_Stmt : info [*ast .LabeledStmt ]("Stmt" ),
MapType_Key : info [*ast .MapType ]("Key" ),
MapType_Value : info [*ast .MapType ]("Value" ),
ParenExpr_X : info [*ast .ParenExpr ]("X" ),
RangeStmt_Body : info [*ast .RangeStmt ]("Body" ),
RangeStmt_Key : info [*ast .RangeStmt ]("Key" ),
RangeStmt_Value : info [*ast .RangeStmt ]("Value" ),
RangeStmt_X : info [*ast .RangeStmt ]("X" ),
ReturnStmt_Results : info [*ast .ReturnStmt ]("Results" ),
SelectStmt_Body : info [*ast .SelectStmt ]("Body" ),
SelectorExpr_Sel : info [*ast .SelectorExpr ]("Sel" ),
SelectorExpr_X : info [*ast .SelectorExpr ]("X" ),
SendStmt_Chan : info [*ast .SendStmt ]("Chan" ),
SendStmt_Value : info [*ast .SendStmt ]("Value" ),
SliceExpr_High : info [*ast .SliceExpr ]("High" ),
SliceExpr_Low : info [*ast .SliceExpr ]("Low" ),
SliceExpr_Max : info [*ast .SliceExpr ]("Max" ),
SliceExpr_X : info [*ast .SliceExpr ]("X" ),
StarExpr_X : info [*ast .StarExpr ]("X" ),
StructType_Fields : info [*ast .StructType ]("Fields" ),
SwitchStmt_Body : info [*ast .SwitchStmt ]("Body" ),
SwitchStmt_Init : info [*ast .SwitchStmt ]("Init" ),
SwitchStmt_Tag : info [*ast .SwitchStmt ]("Tag" ),
TypeAssertExpr_Type : info [*ast .TypeAssertExpr ]("Type" ),
TypeAssertExpr_X : info [*ast .TypeAssertExpr ]("X" ),
TypeSpec_Comment : info [*ast .TypeSpec ]("Comment" ),
TypeSpec_Doc : info [*ast .TypeSpec ]("Doc" ),
TypeSpec_Name : info [*ast .TypeSpec ]("Name" ),
TypeSpec_Type : info [*ast .TypeSpec ]("Type" ),
TypeSpec_TypeParams : info [*ast .TypeSpec ]("TypeParams" ),
TypeSwitchStmt_Assign : info [*ast .TypeSwitchStmt ]("Assign" ),
TypeSwitchStmt_Body : info [*ast .TypeSwitchStmt ]("Body" ),
TypeSwitchStmt_Init : info [*ast .TypeSwitchStmt ]("Init" ),
UnaryExpr_X : info [*ast .UnaryExpr ]("X" ),
ValueSpec_Comment : info [*ast .ValueSpec ]("Comment" ),
ValueSpec_Doc : info [*ast .ValueSpec ]("Doc" ),
ValueSpec_Names : info [*ast .ValueSpec ]("Names" ),
ValueSpec_Type : info [*ast .ValueSpec ]("Type" ),
ValueSpec_Values : info [*ast .ValueSpec ]("Values" ),
}