2
<head><title>NRefactory Pattern Matching</title></head>
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> pattern = <span
9
style="color: #008b8b; font-weight: bold; ">new</span> VariableDeclarationStatement <span
10
style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br>
11
Type = <span style="color: #008b8b; font-weight: bold; ">new</span> <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
Variables = <span style="color: #235100; font-weight: normal;
17
font-style: normal; ">{</span><br>
18
<span style="color: #008b8b; font-weight: bold; ">new</span> VariableInitializer <span
19
style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br>
20
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
Initializer = <span style="color: #008b8b; font-weight:
24
bold; ">new</span> ObjectCreateExpression <span style="color:
25
#235100; font-weight: normal; font-style: normal; ">{</span><br>
26
Type = <span style="color: #008b8b; font-weight:
27
bold; ">new</span> <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
Arguments = <span style="color: #235100;
33
font-weight: normal; font-style: normal; ">{</span> <span
34
style="color: #008b8b; font-weight: bold; ">new</span> <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> <span
38
style="color: #191970; font-weight: bold; ">AnyNode</span><span
39
style="color: #235100; font-weight: normal; font-style: normal; ">())</span> <span
40
style="color: #235100; font-weight: normal; font-style: normal; ">}</span><br>
41
Initializer = <span style="color: #008b8b;
42
font-weight: bold; ">new</span> <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> <span
46
style="color: #191970; font-weight: bold; ">AnyNode</span><span
47
style="color: #235100; font-weight: normal; font-style: normal; ">())</span><br>
48
<span style="color: #235100; font-weight: normal;
49
font-style: normal; ">}</span><br>
50
<span style="color: #235100; font-weight: normal;
51
font-style: normal; ">}</span><br>
52
<span style="color: #235100; font-weight: normal; font-style:
53
normal; ">}};</span><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,
60
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:
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
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
Backreference will match any node that is syntactically identical
76
to the node that was previously stored in the named capture group.<br>
77
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
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>
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> <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> <span
91
style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br>
92
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; "><</span>AstType<span
95
style="color: #235100; font-weight: normal; font-style: normal; ">>(</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> <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>
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
b'\\ No newline at end of file'