You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
7.9 KiB

  1. <html>
  2. <head><title>NRefactory Pattern Matching</title></head>
  3. <body>
  4. The pattern matching API for the C# AST is similar to how regular
  5. expressions work in .NET, except that it's working with AstNodes
  6. instead of characters.<br>
  7. First you declare a pattern, for example: "X a = new X(...);".<br>
  8. <span style="color: #000080; ">var</span>&nbsp;pattern =&nbsp;<span
  9. style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;VariableDeclarationStatement&nbsp;<span
  10. style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br>
  11. &nbsp;&nbsp;&nbsp;&nbsp;Type =&nbsp;<span style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;<span
  12. style="color: #191970; font-weight: bold; ">AnyNode</span><span
  13. style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span
  14. style="color: #0000ff; ">"type"</span><span style="color: #235100;
  15. font-weight: normal; font-style: normal; ">),</span><br>
  16. &nbsp;&nbsp;&nbsp;&nbsp;Variables =&nbsp;<span style="color: #235100; font-weight: normal;
  17. font-style: normal; ">{</span><br>
  18. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;VariableInitializer&nbsp;<span
  19. style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br>
  20. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name = Pattern<span style="color: #235100; font-weight:
  21. normal; font-style: normal; ">.</span>AnyString<span style="color:
  22. #235100; font-weight: normal; font-style: normal; ">,</span><br>
  23. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializer =&nbsp;<span style="color: #008b8b; font-weight:
  24. bold; ">new</span>&nbsp;ObjectCreateExpression&nbsp;<span style="color:
  25. #235100; font-weight: normal; font-style: normal; ">{</span><br>
  26. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type =&nbsp;<span style="color: #008b8b; font-weight:
  27. bold; ">new</span>&nbsp;<span style="color: #191970; font-weight: bold;
  28. ">Backreference</span><span style="color: #235100; font-weight:
  29. normal; font-style: normal; ">(</span><span style="color: #0000ff;
  30. ">"type"</span><span style="color: #235100; font-weight: normal;
  31. font-style: normal; ">),</span><br>
  32. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Arguments =&nbsp;<span style="color: #235100;
  33. font-weight: normal; font-style: normal; ">{</span>&nbsp;<span
  34. style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;<span
  35. style="color: #191970; font-weight: bold; ">Repeat</span><span
  36. style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span
  37. style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;<span
  38. style="color: #191970; font-weight: bold; ">AnyNode</span><span
  39. style="color: #235100; font-weight: normal; font-style: normal; ">())</span>&nbsp;<span
  40. style="color: #235100; font-weight: normal; font-style: normal; ">}</span><br>
  41. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializer =&nbsp;<span style="color: #008b8b;
  42. font-weight: bold; ">new</span>&nbsp;<span style="color: #191970;
  43. font-weight: bold; ">OptionalNode</span><span style="color:
  44. #235100; font-weight: normal; font-style: normal; ">(</span><span
  45. style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;<span
  46. style="color: #191970; font-weight: bold; ">AnyNode</span><span
  47. style="color: #235100; font-weight: normal; font-style: normal; ">())</span><br>
  48. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #235100; font-weight: normal;
  49. font-style: normal; ">}</span><br>
  50. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #235100; font-weight: normal;
  51. font-style: normal; ">}</span><br>
  52. &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #235100; font-weight: normal; font-style:
  53. normal; ">}};</span><br>
  54. <br>
  55. This is a <b>pattern AST</b> - it is a C# AST using the normal C#
  56. AST classes, but also contains special <b>pattern nodes</b>
  57. (AnyNode, Repeat, OptionalNode, Backreference, NamedNode, Choice,
  58. ...).<br>
  59. If you call<br>
  60. &nbsp;Match m = pattern<span style="color: #235100; font-weight: normal;
  61. font-style: normal; ">.</span><span style="color: #191970;
  62. font-weight: bold; ">Match</span><span style="color: #235100;
  63. font-weight: normal; font-style: normal; ">(</span>someNode<span
  64. style="color: rgb(35, 81, 0); font-weight: normal; font-style:
  65. normal;">);<br>
  66. </span>then m.Success will be true if someNode is a
  67. VariableDeclarationStatement that declares a single variable, which
  68. is initialized to a new object of the variable type.<br>
  69. Basically, Match performs a comparison of the pattern AST with
  70. someNode. If the pattern AST does not contain any pattern nodes, the
  71. match will be successful if the ASTs are syntactically identical
  72. (whitespace/comments are not compared).<br>
  73. &nbsp; AnyNode will match any non-null node, and optionally store the
  74. node it was matched against in a named <b>capture group</b>.<br>
  75. &nbsp; Backreference will match any node that is syntactically identical
  76. to the node that was previously stored in the named capture group.<br>
  77. &nbsp; Repeat can be used only in AstNodeCollections and will try to
  78. match its child pattern against any number of nodes - this is
  79. equivalent to * (Kleene star) in regular expressions.<br>
  80. &nbsp; OptionalNode will match null nodes, or will try to match its child
  81. pattern against the node. OptionalNode can also be used in
  82. AstNodeCollections, where it is equivalent to a Repeat with
  83. MinCount=0 and MaxCount=1.<br>
  84. <br>
  85. The resulting match object can also be used to retrieve the nodes
  86. stored in the capture groups:<br>
  87. <span style="color: #0000ff; font-weight: bold; ">if</span>&nbsp;<span
  88. style="color: #235100; font-weight: normal; font-style: normal; ">(</span>m<span
  89. style="color: #235100; font-weight: normal; font-style: normal; ">.</span>Success<span
  90. style="color: #235100; font-weight: normal; font-style: normal; ">)</span>&nbsp;<span
  91. style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br>
  92. &nbsp;&nbsp;&nbsp;&nbsp;m<span style="color: #235100; font-weight: normal; font-style:
  93. normal; ">.</span>Get<span style="color: #235100; font-weight:
  94. normal; font-style: normal; ">&lt;</span>AstType<span
  95. style="color: #235100; font-weight: normal; font-style: normal; ">&gt;(</span><span
  96. style="color: #0000ff; ">"type"</span><span style="color: #235100;
  97. font-weight: normal; font-style: normal; ">).</span><span
  98. style="color: #191970; font-weight: bold; ">Single</span><span
  99. style="color: #235100; font-weight: normal; font-style: normal; ">().</span><span
  100. style="color: #191970; font-weight: bold; ">ReplaceWith</span><span
  101. style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span
  102. style="color: #008b8b; font-weight: bold; ">new</span>&nbsp;<span
  103. style="color: #191970; font-weight: bold; ">SimpleType</span><span
  104. style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span
  105. style="color: #0000ff; ">"var"</span><span style="color: #235100;
  106. font-weight: normal; font-style: normal; ">));</span><br>
  107. <span style="color: #235100; font-weight: normal; font-style:
  108. normal; ">}</span><br>
  109. <br>
  110. This feature was originally written for the decompiler in ILSpy, but
  111. it is also very useful for refactorings. You can also implement
  112. custom pattern nodes (derive from the Pattern base class) with
  113. custom match logic - for example if you want to check the semantics
  114. of a node.<br>
  115. </body></html>