| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- package pattern
- import (
- "fmt"
- "go/token"
- "reflect"
- "strings"
- )
- var (
- _ Node = Ellipsis{}
- _ Node = Binding{}
- _ Node = RangeStmt{}
- _ Node = AssignStmt{}
- _ Node = IndexExpr{}
- _ Node = IndexListExpr{}
- _ Node = Ident{}
- _ Node = Builtin{}
- _ Node = String("")
- _ Node = Any{}
- _ Node = ValueSpec{}
- _ Node = List{}
- _ Node = GenDecl{}
- _ Node = BinaryExpr{}
- _ Node = ForStmt{}
- _ Node = ArrayType{}
- _ Node = DeferStmt{}
- _ Node = MapType{}
- _ Node = ReturnStmt{}
- _ Node = SliceExpr{}
- _ Node = StarExpr{}
- _ Node = UnaryExpr{}
- _ Node = SendStmt{}
- _ Node = SelectStmt{}
- _ Node = ImportSpec{}
- _ Node = IfStmt{}
- _ Node = GoStmt{}
- _ Node = Field{}
- _ Node = SelectorExpr{}
- _ Node = StructType{}
- _ Node = KeyValueExpr{}
- _ Node = FuncType{}
- _ Node = FuncLit{}
- _ Node = FuncDecl{}
- _ Node = Token(0)
- _ Node = ChanType{}
- _ Node = CallExpr{}
- _ Node = CaseClause{}
- _ Node = CommClause{}
- _ Node = CompositeLit{}
- _ Node = EmptyStmt{}
- _ Node = SwitchStmt{}
- _ Node = TypeSwitchStmt{}
- _ Node = TypeAssertExpr{}
- _ Node = TypeSpec{}
- _ Node = InterfaceType{}
- _ Node = BranchStmt{}
- _ Node = IncDecStmt{}
- _ Node = BasicLit{}
- _ Node = Nil{}
- _ Node = Object{}
- _ Node = Function{}
- _ Node = Not{}
- _ Node = Or{}
- _ Node = IntegerLiteral{}
- _ Node = TrulyConstantExpression{}
- )
- type Function struct {
- Name Node
- }
- type Token token.Token
- type Nil struct {
- }
- type Ellipsis struct {
- Elt Node
- }
- type IncDecStmt struct {
- X Node
- Tok Node
- }
- type BranchStmt struct {
- Tok Node
- Label Node
- }
- type InterfaceType struct {
- Methods Node
- }
- type TypeSpec struct {
- Name Node
- Type Node
- }
- type TypeAssertExpr struct {
- X Node
- Type Node
- }
- type TypeSwitchStmt struct {
- Init Node
- Assign Node
- Body Node
- }
- type SwitchStmt struct {
- Init Node
- Tag Node
- Body Node
- }
- type EmptyStmt struct {
- }
- type CompositeLit struct {
- Type Node
- Elts Node
- }
- type CommClause struct {
- Comm Node
- Body Node
- }
- type CaseClause struct {
- List Node
- Body Node
- }
- type CallExpr struct {
- Fun Node
- Args Node
- // XXX handle ellipsis
- }
- // TODO(dh): add a ChanDir node, and a way of instantiating it.
- type ChanType struct {
- Dir Node
- Value Node
- }
- type FuncDecl struct {
- Recv Node
- Name Node
- Type Node
- Body Node
- }
- type FuncLit struct {
- Type Node
- Body Node
- }
- type FuncType struct {
- Params Node
- Results Node
- }
- type KeyValueExpr struct {
- Key Node
- Value Node
- }
- type StructType struct {
- Fields Node
- }
- type SelectorExpr struct {
- X Node
- Sel Node
- }
- type Field struct {
- Names Node
- Type Node
- Tag Node
- }
- type GoStmt struct {
- Call Node
- }
- type IfStmt struct {
- Init Node
- Cond Node
- Body Node
- Else Node
- }
- type ImportSpec struct {
- Name Node
- Path Node
- }
- type SelectStmt struct {
- Body Node
- }
- type ArrayType struct {
- Len Node
- Elt Node
- }
- type DeferStmt struct {
- Call Node
- }
- type MapType struct {
- Key Node
- Value Node
- }
- type ReturnStmt struct {
- Results Node
- }
- type SliceExpr struct {
- X Node
- Low Node
- High Node
- Max Node
- }
- type StarExpr struct {
- X Node
- }
- type UnaryExpr struct {
- Op Node
- X Node
- }
- type SendStmt struct {
- Chan Node
- Value Node
- }
- type Binding struct {
- Name string
- Node Node
- }
- type RangeStmt struct {
- Key Node
- Value Node
- Tok Node
- X Node
- Body Node
- }
- type AssignStmt struct {
- Lhs Node
- Tok Node
- Rhs Node
- }
- type IndexExpr struct {
- X Node
- Index Node
- }
- type IndexListExpr struct {
- X Node
- Indices Node
- }
- type Node interface {
- String() string
- isNode()
- }
- type Ident struct {
- Name Node
- }
- type Object struct {
- Name Node
- }
- type Builtin struct {
- Name Node
- }
- type String string
- type Any struct{}
- type ValueSpec struct {
- Names Node
- Type Node
- Values Node
- }
- type List struct {
- Head Node
- Tail Node
- }
- type GenDecl struct {
- Tok Node
- Specs Node
- }
- type BasicLit struct {
- Kind Node
- Value Node
- }
- // An IntegerLiteral is a constant expression made up of only integer basic literals and the "+" and "-" unary operators.
- // That is, 0, -4, -+42 are all integer literals, but 1 + 2 is not.
- type IntegerLiteral struct {
- Value Node
- }
- type BinaryExpr struct {
- X Node
- Op Node
- Y Node
- }
- type ForStmt struct {
- Init Node
- Cond Node
- Post Node
- Body Node
- }
- type Or struct {
- Nodes []Node
- }
- type Not struct {
- Node Node
- }
- // A TrulyConstantExpression is a constant expression that does not make use of any identifiers.
- // It is constant even under varying build tags.
- type TrulyConstantExpression struct {
- Value Node
- }
- func stringify(n Node) string {
- v := reflect.ValueOf(n)
- var parts []string
- parts = append(parts, v.Type().Name())
- for i := 0; i < v.NumField(); i++ {
- parts = append(parts, fmt.Sprintf("%s", v.Field(i)))
- }
- return "(" + strings.Join(parts, " ") + ")"
- }
- func (stmt AssignStmt) String() string { return stringify(stmt) }
- func (expr IndexExpr) String() string { return stringify(expr) }
- func (expr IndexListExpr) String() string { return stringify(expr) }
- func (id Ident) String() string { return stringify(id) }
- func (spec ValueSpec) String() string { return stringify(spec) }
- func (decl GenDecl) String() string { return stringify(decl) }
- func (lit BasicLit) String() string { return stringify(lit) }
- func (expr BinaryExpr) String() string { return stringify(expr) }
- func (stmt ForStmt) String() string { return stringify(stmt) }
- func (stmt RangeStmt) String() string { return stringify(stmt) }
- func (typ ArrayType) String() string { return stringify(typ) }
- func (stmt DeferStmt) String() string { return stringify(stmt) }
- func (typ MapType) String() string { return stringify(typ) }
- func (stmt ReturnStmt) String() string { return stringify(stmt) }
- func (expr SliceExpr) String() string { return stringify(expr) }
- func (expr StarExpr) String() string { return stringify(expr) }
- func (expr UnaryExpr) String() string { return stringify(expr) }
- func (stmt SendStmt) String() string { return stringify(stmt) }
- func (spec ImportSpec) String() string { return stringify(spec) }
- func (stmt SelectStmt) String() string { return stringify(stmt) }
- func (stmt IfStmt) String() string { return stringify(stmt) }
- func (stmt IncDecStmt) String() string { return stringify(stmt) }
- func (stmt GoStmt) String() string { return stringify(stmt) }
- func (field Field) String() string { return stringify(field) }
- func (expr SelectorExpr) String() string { return stringify(expr) }
- func (typ StructType) String() string { return stringify(typ) }
- func (expr KeyValueExpr) String() string { return stringify(expr) }
- func (typ FuncType) String() string { return stringify(typ) }
- func (lit FuncLit) String() string { return stringify(lit) }
- func (decl FuncDecl) String() string { return stringify(decl) }
- func (stmt BranchStmt) String() string { return stringify(stmt) }
- func (expr CallExpr) String() string { return stringify(expr) }
- func (clause CaseClause) String() string { return stringify(clause) }
- func (typ ChanType) String() string { return stringify(typ) }
- func (clause CommClause) String() string { return stringify(clause) }
- func (lit CompositeLit) String() string { return stringify(lit) }
- func (stmt EmptyStmt) String() string { return stringify(stmt) }
- func (typ InterfaceType) String() string { return stringify(typ) }
- func (stmt SwitchStmt) String() string { return stringify(stmt) }
- func (expr TypeAssertExpr) String() string { return stringify(expr) }
- func (spec TypeSpec) String() string { return stringify(spec) }
- func (stmt TypeSwitchStmt) String() string { return stringify(stmt) }
- func (nil Nil) String() string { return "nil" }
- func (builtin Builtin) String() string { return stringify(builtin) }
- func (obj Object) String() string { return stringify(obj) }
- func (fn Function) String() string { return stringify(fn) }
- func (el Ellipsis) String() string { return stringify(el) }
- func (not Not) String() string { return stringify(not) }
- func (lit IntegerLiteral) String() string { return stringify(lit) }
- func (expr TrulyConstantExpression) String() string { return stringify(expr) }
- func (or Or) String() string {
- s := "(Or"
- for _, node := range or.Nodes {
- s += " "
- s += node.String()
- }
- s += ")"
- return s
- }
- func isProperList(l List) bool {
- if l.Head == nil && l.Tail == nil {
- return true
- }
- switch tail := l.Tail.(type) {
- case nil:
- return false
- case List:
- return isProperList(tail)
- default:
- return false
- }
- }
- func (l List) String() string {
- if l.Head == nil && l.Tail == nil {
- return "[]"
- }
- if isProperList(l) {
- // pretty-print the list
- var objs []string
- for l.Head != nil {
- objs = append(objs, l.Head.String())
- l = l.Tail.(List)
- }
- return fmt.Sprintf("[%s]", strings.Join(objs, " "))
- }
- return fmt.Sprintf("%s:%s", l.Head, l.Tail)
- }
- func (bind Binding) String() string {
- if bind.Node == nil {
- return bind.Name
- }
- return fmt.Sprintf("%s@%s", bind.Name, bind.Node)
- }
- func (s String) String() string { return fmt.Sprintf("%q", string(s)) }
- func (tok Token) String() string {
- return fmt.Sprintf("%q", strings.ToUpper(token.Token(tok).String()))
- }
- func (Any) String() string { return "_" }
- func (AssignStmt) isNode() {}
- func (IndexExpr) isNode() {}
- func (IndexListExpr) isNode() {}
- func (Ident) isNode() {}
- func (ValueSpec) isNode() {}
- func (GenDecl) isNode() {}
- func (BasicLit) isNode() {}
- func (BinaryExpr) isNode() {}
- func (ForStmt) isNode() {}
- func (RangeStmt) isNode() {}
- func (ArrayType) isNode() {}
- func (DeferStmt) isNode() {}
- func (MapType) isNode() {}
- func (ReturnStmt) isNode() {}
- func (SliceExpr) isNode() {}
- func (StarExpr) isNode() {}
- func (UnaryExpr) isNode() {}
- func (SendStmt) isNode() {}
- func (ImportSpec) isNode() {}
- func (SelectStmt) isNode() {}
- func (IfStmt) isNode() {}
- func (IncDecStmt) isNode() {}
- func (GoStmt) isNode() {}
- func (Field) isNode() {}
- func (SelectorExpr) isNode() {}
- func (StructType) isNode() {}
- func (KeyValueExpr) isNode() {}
- func (FuncType) isNode() {}
- func (FuncLit) isNode() {}
- func (FuncDecl) isNode() {}
- func (BranchStmt) isNode() {}
- func (CallExpr) isNode() {}
- func (CaseClause) isNode() {}
- func (ChanType) isNode() {}
- func (CommClause) isNode() {}
- func (CompositeLit) isNode() {}
- func (EmptyStmt) isNode() {}
- func (InterfaceType) isNode() {}
- func (SwitchStmt) isNode() {}
- func (TypeAssertExpr) isNode() {}
- func (TypeSpec) isNode() {}
- func (TypeSwitchStmt) isNode() {}
- func (Nil) isNode() {}
- func (Builtin) isNode() {}
- func (Object) isNode() {}
- func (Function) isNode() {}
- func (Ellipsis) isNode() {}
- func (Or) isNode() {}
- func (List) isNode() {}
- func (String) isNode() {}
- func (Token) isNode() {}
- func (Any) isNode() {}
- func (Binding) isNode() {}
- func (Not) isNode() {}
- func (IntegerLiteral) isNode() {}
- func (TrulyConstantExpression) isNode() {}
|