pattern.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. package pattern
  2. import (
  3. "fmt"
  4. "go/token"
  5. "reflect"
  6. "strings"
  7. )
  8. var (
  9. _ Node = Ellipsis{}
  10. _ Node = Binding{}
  11. _ Node = RangeStmt{}
  12. _ Node = AssignStmt{}
  13. _ Node = IndexExpr{}
  14. _ Node = IndexListExpr{}
  15. _ Node = Ident{}
  16. _ Node = Builtin{}
  17. _ Node = String("")
  18. _ Node = Any{}
  19. _ Node = ValueSpec{}
  20. _ Node = List{}
  21. _ Node = GenDecl{}
  22. _ Node = BinaryExpr{}
  23. _ Node = ForStmt{}
  24. _ Node = ArrayType{}
  25. _ Node = DeferStmt{}
  26. _ Node = MapType{}
  27. _ Node = ReturnStmt{}
  28. _ Node = SliceExpr{}
  29. _ Node = StarExpr{}
  30. _ Node = UnaryExpr{}
  31. _ Node = SendStmt{}
  32. _ Node = SelectStmt{}
  33. _ Node = ImportSpec{}
  34. _ Node = IfStmt{}
  35. _ Node = GoStmt{}
  36. _ Node = Field{}
  37. _ Node = SelectorExpr{}
  38. _ Node = StructType{}
  39. _ Node = KeyValueExpr{}
  40. _ Node = FuncType{}
  41. _ Node = FuncLit{}
  42. _ Node = FuncDecl{}
  43. _ Node = Token(0)
  44. _ Node = ChanType{}
  45. _ Node = CallExpr{}
  46. _ Node = CaseClause{}
  47. _ Node = CommClause{}
  48. _ Node = CompositeLit{}
  49. _ Node = EmptyStmt{}
  50. _ Node = SwitchStmt{}
  51. _ Node = TypeSwitchStmt{}
  52. _ Node = TypeAssertExpr{}
  53. _ Node = TypeSpec{}
  54. _ Node = InterfaceType{}
  55. _ Node = BranchStmt{}
  56. _ Node = IncDecStmt{}
  57. _ Node = BasicLit{}
  58. _ Node = Nil{}
  59. _ Node = Object{}
  60. _ Node = Function{}
  61. _ Node = Not{}
  62. _ Node = Or{}
  63. _ Node = IntegerLiteral{}
  64. _ Node = TrulyConstantExpression{}
  65. )
  66. type Function struct {
  67. Name Node
  68. }
  69. type Token token.Token
  70. type Nil struct {
  71. }
  72. type Ellipsis struct {
  73. Elt Node
  74. }
  75. type IncDecStmt struct {
  76. X Node
  77. Tok Node
  78. }
  79. type BranchStmt struct {
  80. Tok Node
  81. Label Node
  82. }
  83. type InterfaceType struct {
  84. Methods Node
  85. }
  86. type TypeSpec struct {
  87. Name Node
  88. Type Node
  89. }
  90. type TypeAssertExpr struct {
  91. X Node
  92. Type Node
  93. }
  94. type TypeSwitchStmt struct {
  95. Init Node
  96. Assign Node
  97. Body Node
  98. }
  99. type SwitchStmt struct {
  100. Init Node
  101. Tag Node
  102. Body Node
  103. }
  104. type EmptyStmt struct {
  105. }
  106. type CompositeLit struct {
  107. Type Node
  108. Elts Node
  109. }
  110. type CommClause struct {
  111. Comm Node
  112. Body Node
  113. }
  114. type CaseClause struct {
  115. List Node
  116. Body Node
  117. }
  118. type CallExpr struct {
  119. Fun Node
  120. Args Node
  121. // XXX handle ellipsis
  122. }
  123. // TODO(dh): add a ChanDir node, and a way of instantiating it.
  124. type ChanType struct {
  125. Dir Node
  126. Value Node
  127. }
  128. type FuncDecl struct {
  129. Recv Node
  130. Name Node
  131. Type Node
  132. Body Node
  133. }
  134. type FuncLit struct {
  135. Type Node
  136. Body Node
  137. }
  138. type FuncType struct {
  139. Params Node
  140. Results Node
  141. }
  142. type KeyValueExpr struct {
  143. Key Node
  144. Value Node
  145. }
  146. type StructType struct {
  147. Fields Node
  148. }
  149. type SelectorExpr struct {
  150. X Node
  151. Sel Node
  152. }
  153. type Field struct {
  154. Names Node
  155. Type Node
  156. Tag Node
  157. }
  158. type GoStmt struct {
  159. Call Node
  160. }
  161. type IfStmt struct {
  162. Init Node
  163. Cond Node
  164. Body Node
  165. Else Node
  166. }
  167. type ImportSpec struct {
  168. Name Node
  169. Path Node
  170. }
  171. type SelectStmt struct {
  172. Body Node
  173. }
  174. type ArrayType struct {
  175. Len Node
  176. Elt Node
  177. }
  178. type DeferStmt struct {
  179. Call Node
  180. }
  181. type MapType struct {
  182. Key Node
  183. Value Node
  184. }
  185. type ReturnStmt struct {
  186. Results Node
  187. }
  188. type SliceExpr struct {
  189. X Node
  190. Low Node
  191. High Node
  192. Max Node
  193. }
  194. type StarExpr struct {
  195. X Node
  196. }
  197. type UnaryExpr struct {
  198. Op Node
  199. X Node
  200. }
  201. type SendStmt struct {
  202. Chan Node
  203. Value Node
  204. }
  205. type Binding struct {
  206. Name string
  207. Node Node
  208. }
  209. type RangeStmt struct {
  210. Key Node
  211. Value Node
  212. Tok Node
  213. X Node
  214. Body Node
  215. }
  216. type AssignStmt struct {
  217. Lhs Node
  218. Tok Node
  219. Rhs Node
  220. }
  221. type IndexExpr struct {
  222. X Node
  223. Index Node
  224. }
  225. type IndexListExpr struct {
  226. X Node
  227. Indices Node
  228. }
  229. type Node interface {
  230. String() string
  231. isNode()
  232. }
  233. type Ident struct {
  234. Name Node
  235. }
  236. type Object struct {
  237. Name Node
  238. }
  239. type Builtin struct {
  240. Name Node
  241. }
  242. type String string
  243. type Any struct{}
  244. type ValueSpec struct {
  245. Names Node
  246. Type Node
  247. Values Node
  248. }
  249. type List struct {
  250. Head Node
  251. Tail Node
  252. }
  253. type GenDecl struct {
  254. Tok Node
  255. Specs Node
  256. }
  257. type BasicLit struct {
  258. Kind Node
  259. Value Node
  260. }
  261. // An IntegerLiteral is a constant expression made up of only integer basic literals and the "+" and "-" unary operators.
  262. // That is, 0, -4, -+42 are all integer literals, but 1 + 2 is not.
  263. type IntegerLiteral struct {
  264. Value Node
  265. }
  266. type BinaryExpr struct {
  267. X Node
  268. Op Node
  269. Y Node
  270. }
  271. type ForStmt struct {
  272. Init Node
  273. Cond Node
  274. Post Node
  275. Body Node
  276. }
  277. type Or struct {
  278. Nodes []Node
  279. }
  280. type Not struct {
  281. Node Node
  282. }
  283. // A TrulyConstantExpression is a constant expression that does not make use of any identifiers.
  284. // It is constant even under varying build tags.
  285. type TrulyConstantExpression struct {
  286. Value Node
  287. }
  288. func stringify(n Node) string {
  289. v := reflect.ValueOf(n)
  290. var parts []string
  291. parts = append(parts, v.Type().Name())
  292. for i := 0; i < v.NumField(); i++ {
  293. parts = append(parts, fmt.Sprintf("%s", v.Field(i)))
  294. }
  295. return "(" + strings.Join(parts, " ") + ")"
  296. }
  297. func (stmt AssignStmt) String() string { return stringify(stmt) }
  298. func (expr IndexExpr) String() string { return stringify(expr) }
  299. func (expr IndexListExpr) String() string { return stringify(expr) }
  300. func (id Ident) String() string { return stringify(id) }
  301. func (spec ValueSpec) String() string { return stringify(spec) }
  302. func (decl GenDecl) String() string { return stringify(decl) }
  303. func (lit BasicLit) String() string { return stringify(lit) }
  304. func (expr BinaryExpr) String() string { return stringify(expr) }
  305. func (stmt ForStmt) String() string { return stringify(stmt) }
  306. func (stmt RangeStmt) String() string { return stringify(stmt) }
  307. func (typ ArrayType) String() string { return stringify(typ) }
  308. func (stmt DeferStmt) String() string { return stringify(stmt) }
  309. func (typ MapType) String() string { return stringify(typ) }
  310. func (stmt ReturnStmt) String() string { return stringify(stmt) }
  311. func (expr SliceExpr) String() string { return stringify(expr) }
  312. func (expr StarExpr) String() string { return stringify(expr) }
  313. func (expr UnaryExpr) String() string { return stringify(expr) }
  314. func (stmt SendStmt) String() string { return stringify(stmt) }
  315. func (spec ImportSpec) String() string { return stringify(spec) }
  316. func (stmt SelectStmt) String() string { return stringify(stmt) }
  317. func (stmt IfStmt) String() string { return stringify(stmt) }
  318. func (stmt IncDecStmt) String() string { return stringify(stmt) }
  319. func (stmt GoStmt) String() string { return stringify(stmt) }
  320. func (field Field) String() string { return stringify(field) }
  321. func (expr SelectorExpr) String() string { return stringify(expr) }
  322. func (typ StructType) String() string { return stringify(typ) }
  323. func (expr KeyValueExpr) String() string { return stringify(expr) }
  324. func (typ FuncType) String() string { return stringify(typ) }
  325. func (lit FuncLit) String() string { return stringify(lit) }
  326. func (decl FuncDecl) String() string { return stringify(decl) }
  327. func (stmt BranchStmt) String() string { return stringify(stmt) }
  328. func (expr CallExpr) String() string { return stringify(expr) }
  329. func (clause CaseClause) String() string { return stringify(clause) }
  330. func (typ ChanType) String() string { return stringify(typ) }
  331. func (clause CommClause) String() string { return stringify(clause) }
  332. func (lit CompositeLit) String() string { return stringify(lit) }
  333. func (stmt EmptyStmt) String() string { return stringify(stmt) }
  334. func (typ InterfaceType) String() string { return stringify(typ) }
  335. func (stmt SwitchStmt) String() string { return stringify(stmt) }
  336. func (expr TypeAssertExpr) String() string { return stringify(expr) }
  337. func (spec TypeSpec) String() string { return stringify(spec) }
  338. func (stmt TypeSwitchStmt) String() string { return stringify(stmt) }
  339. func (nil Nil) String() string { return "nil" }
  340. func (builtin Builtin) String() string { return stringify(builtin) }
  341. func (obj Object) String() string { return stringify(obj) }
  342. func (fn Function) String() string { return stringify(fn) }
  343. func (el Ellipsis) String() string { return stringify(el) }
  344. func (not Not) String() string { return stringify(not) }
  345. func (lit IntegerLiteral) String() string { return stringify(lit) }
  346. func (expr TrulyConstantExpression) String() string { return stringify(expr) }
  347. func (or Or) String() string {
  348. s := "(Or"
  349. for _, node := range or.Nodes {
  350. s += " "
  351. s += node.String()
  352. }
  353. s += ")"
  354. return s
  355. }
  356. func isProperList(l List) bool {
  357. if l.Head == nil && l.Tail == nil {
  358. return true
  359. }
  360. switch tail := l.Tail.(type) {
  361. case nil:
  362. return false
  363. case List:
  364. return isProperList(tail)
  365. default:
  366. return false
  367. }
  368. }
  369. func (l List) String() string {
  370. if l.Head == nil && l.Tail == nil {
  371. return "[]"
  372. }
  373. if isProperList(l) {
  374. // pretty-print the list
  375. var objs []string
  376. for l.Head != nil {
  377. objs = append(objs, l.Head.String())
  378. l = l.Tail.(List)
  379. }
  380. return fmt.Sprintf("[%s]", strings.Join(objs, " "))
  381. }
  382. return fmt.Sprintf("%s:%s", l.Head, l.Tail)
  383. }
  384. func (bind Binding) String() string {
  385. if bind.Node == nil {
  386. return bind.Name
  387. }
  388. return fmt.Sprintf("%s@%s", bind.Name, bind.Node)
  389. }
  390. func (s String) String() string { return fmt.Sprintf("%q", string(s)) }
  391. func (tok Token) String() string {
  392. return fmt.Sprintf("%q", strings.ToUpper(token.Token(tok).String()))
  393. }
  394. func (Any) String() string { return "_" }
  395. func (AssignStmt) isNode() {}
  396. func (IndexExpr) isNode() {}
  397. func (IndexListExpr) isNode() {}
  398. func (Ident) isNode() {}
  399. func (ValueSpec) isNode() {}
  400. func (GenDecl) isNode() {}
  401. func (BasicLit) isNode() {}
  402. func (BinaryExpr) isNode() {}
  403. func (ForStmt) isNode() {}
  404. func (RangeStmt) isNode() {}
  405. func (ArrayType) isNode() {}
  406. func (DeferStmt) isNode() {}
  407. func (MapType) isNode() {}
  408. func (ReturnStmt) isNode() {}
  409. func (SliceExpr) isNode() {}
  410. func (StarExpr) isNode() {}
  411. func (UnaryExpr) isNode() {}
  412. func (SendStmt) isNode() {}
  413. func (ImportSpec) isNode() {}
  414. func (SelectStmt) isNode() {}
  415. func (IfStmt) isNode() {}
  416. func (IncDecStmt) isNode() {}
  417. func (GoStmt) isNode() {}
  418. func (Field) isNode() {}
  419. func (SelectorExpr) isNode() {}
  420. func (StructType) isNode() {}
  421. func (KeyValueExpr) isNode() {}
  422. func (FuncType) isNode() {}
  423. func (FuncLit) isNode() {}
  424. func (FuncDecl) isNode() {}
  425. func (BranchStmt) isNode() {}
  426. func (CallExpr) isNode() {}
  427. func (CaseClause) isNode() {}
  428. func (ChanType) isNode() {}
  429. func (CommClause) isNode() {}
  430. func (CompositeLit) isNode() {}
  431. func (EmptyStmt) isNode() {}
  432. func (InterfaceType) isNode() {}
  433. func (SwitchStmt) isNode() {}
  434. func (TypeAssertExpr) isNode() {}
  435. func (TypeSpec) isNode() {}
  436. func (TypeSwitchStmt) isNode() {}
  437. func (Nil) isNode() {}
  438. func (Builtin) isNode() {}
  439. func (Object) isNode() {}
  440. func (Function) isNode() {}
  441. func (Ellipsis) isNode() {}
  442. func (Or) isNode() {}
  443. func (List) isNode() {}
  444. func (String) isNode() {}
  445. func (Token) isNode() {}
  446. func (Any) isNode() {}
  447. func (Binding) isNode() {}
  448. func (Not) isNode() {}
  449. func (IntegerLiteral) isNode() {}
  450. func (TrulyConstantExpression) isNode() {}