mirror of https://github.com/icsharpcode/ILSpy.git
				
				
			
			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.
		
		
		
		
		
			
		
			
				
					
					
						
							115 lines
						
					
					
						
							7.9 KiB
						
					
					
				
			
		
		
	
	
							115 lines
						
					
					
						
							7.9 KiB
						
					
					
				<html> | 
						|
<head><title>NRefactory Pattern Matching</title></head> | 
						|
<body> | 
						|
    The pattern matching API for the C# AST is similar to how regular | 
						|
    expressions work in .NET, except that it's working with AstNodes | 
						|
    instead of characters.<br> | 
						|
    First you declare a pattern, for example: "X a = new X(...);".<br> | 
						|
    <span style="color: #000080; ">var</span> pattern = <span | 
						|
      style="color: #008b8b; font-weight: bold; ">new</span> VariableDeclarationStatement <span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br> | 
						|
        Type = <span style="color: #008b8b; font-weight: bold; ">new</span> <span | 
						|
      style="color: #191970; font-weight: bold; ">AnyNode</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span | 
						|
      style="color: #0000ff; ">"type"</span><span style="color: #235100; | 
						|
      font-weight: normal; font-style: normal; ">),</span><br> | 
						|
        Variables = <span style="color: #235100; font-weight: normal; | 
						|
      font-style: normal; ">{</span><br> | 
						|
            <span style="color: #008b8b; font-weight: bold; ">new</span> VariableInitializer <span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br> | 
						|
                Name = Pattern<span style="color: #235100; font-weight: | 
						|
      normal; font-style: normal; ">.</span>AnyString<span style="color: | 
						|
      #235100; font-weight: normal; font-style: normal; ">,</span><br> | 
						|
                Initializer = <span style="color: #008b8b; font-weight: | 
						|
      bold; ">new</span> ObjectCreateExpression <span style="color: | 
						|
      #235100; font-weight: normal; font-style: normal; ">{</span><br> | 
						|
                    Type = <span style="color: #008b8b; font-weight: | 
						|
      bold; ">new</span> <span style="color: #191970; font-weight: bold; | 
						|
      ">Backreference</span><span style="color: #235100; font-weight: | 
						|
      normal; font-style: normal; ">(</span><span style="color: #0000ff; | 
						|
      ">"type"</span><span style="color: #235100; font-weight: normal; | 
						|
      font-style: normal; ">),</span><br> | 
						|
                    Arguments = <span style="color: #235100; | 
						|
      font-weight: normal; font-style: normal; ">{</span> <span | 
						|
      style="color: #008b8b; font-weight: bold; ">new</span> <span | 
						|
      style="color: #191970; font-weight: bold; ">Repeat</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span | 
						|
      style="color: #008b8b; font-weight: bold; ">new</span> <span | 
						|
      style="color: #191970; font-weight: bold; ">AnyNode</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">())</span> <span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">}</span><br> | 
						|
                    Initializer = <span style="color: #008b8b; | 
						|
      font-weight: bold; ">new</span> <span style="color: #191970; | 
						|
      font-weight: bold; ">OptionalNode</span><span style="color: | 
						|
      #235100; font-weight: normal; font-style: normal; ">(</span><span | 
						|
      style="color: #008b8b; font-weight: bold; ">new</span> <span | 
						|
      style="color: #191970; font-weight: bold; ">AnyNode</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">())</span><br> | 
						|
                <span style="color: #235100; font-weight: normal; | 
						|
      font-style: normal; ">}</span><br> | 
						|
            <span style="color: #235100; font-weight: normal; | 
						|
      font-style: normal; ">}</span><br> | 
						|
        <span style="color: #235100; font-weight: normal; font-style: | 
						|
      normal; ">}};</span><br> | 
						|
    <br> | 
						|
    This is a <b>pattern AST</b> - it is a C# AST using the normal C# | 
						|
    AST classes, but also contains special <b>pattern nodes</b> | 
						|
    (AnyNode, Repeat, OptionalNode, Backreference, NamedNode, Choice, | 
						|
    ...).<br> | 
						|
    If you call<br> | 
						|
     Match m = pattern<span style="color: #235100; font-weight: normal; | 
						|
      font-style: normal; ">.</span><span style="color: #191970; | 
						|
      font-weight: bold; ">Match</span><span style="color: #235100; | 
						|
      font-weight: normal; font-style: normal; ">(</span>someNode<span | 
						|
      style="color: rgb(35, 81, 0); font-weight: normal; font-style: | 
						|
      normal;">);<br> | 
						|
    </span>then m.Success will be true if someNode is a | 
						|
    VariableDeclarationStatement that declares a single variable, which | 
						|
    is initialized to a new object of the variable type.<br> | 
						|
    Basically, Match performs a comparison of the pattern AST with | 
						|
    someNode. If the pattern AST does not contain any pattern nodes, the | 
						|
    match will be successful if the ASTs are syntactically identical | 
						|
    (whitespace/comments are not compared).<br> | 
						|
      AnyNode will match any non-null node, and optionally store the | 
						|
    node it was matched against in a named <b>capture group</b>.<br> | 
						|
      Backreference will match any node that is syntactically identical | 
						|
    to the node that was previously stored in the named capture group.<br> | 
						|
      Repeat can be used only in AstNodeCollections and will try to | 
						|
    match its child pattern against any number of nodes - this is | 
						|
    equivalent to * (Kleene star) in regular expressions.<br> | 
						|
      OptionalNode will match null nodes, or will try to match its child | 
						|
    pattern against the node. OptionalNode can also be used in | 
						|
    AstNodeCollections, where it is equivalent to a Repeat with | 
						|
    MinCount=0 and MaxCount=1.<br> | 
						|
    <br> | 
						|
    The resulting match object can also be used to retrieve the nodes | 
						|
    stored in the capture groups:<br> | 
						|
    <span style="color: #0000ff; font-weight: bold; ">if</span> <span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">(</span>m<span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">.</span>Success<span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">)</span> <span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">{</span><br> | 
						|
        m<span style="color: #235100; font-weight: normal; font-style: | 
						|
      normal; ">.</span>Get<span style="color: #235100; font-weight: | 
						|
      normal; font-style: normal; "><</span>AstType<span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">>(</span><span | 
						|
      style="color: #0000ff; ">"type"</span><span style="color: #235100; | 
						|
      font-weight: normal; font-style: normal; ">).</span><span | 
						|
      style="color: #191970; font-weight: bold; ">Single</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">().</span><span | 
						|
      style="color: #191970; font-weight: bold; ">ReplaceWith</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span | 
						|
      style="color: #008b8b; font-weight: bold; ">new</span> <span | 
						|
      style="color: #191970; font-weight: bold; ">SimpleType</span><span | 
						|
      style="color: #235100; font-weight: normal; font-style: normal; ">(</span><span | 
						|
      style="color: #0000ff; ">"var"</span><span style="color: #235100; | 
						|
      font-weight: normal; font-style: normal; ">));</span><br> | 
						|
    <span style="color: #235100; font-weight: normal; font-style: | 
						|
      normal; ">}</span><br> | 
						|
    <br> | 
						|
    This feature was originally written for the decompiler in ILSpy, but | 
						|
    it is also very useful for refactorings. You can also implement | 
						|
    custom pattern nodes (derive from the Pattern base class) with | 
						|
    custom match logic - for example if you want to check the semantics | 
						|
    of a node.<br> | 
						|
</body></html> |