mirror of https://github.com/icsharpcode/ILSpy.git
5 changed files with 116 additions and 248 deletions
@ -1,120 +0,0 @@
@@ -1,120 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using Mono.Cecil; |
||||
|
||||
namespace ICSharpCode.Decompiler.ILAst |
||||
{ |
||||
public interface IVariablePattern |
||||
{ |
||||
bool MatchVariable(ILVariable v); |
||||
} |
||||
|
||||
public class StoreToVariable : ILExpression, IVariablePattern |
||||
{ |
||||
public bool MustBeGenerated; |
||||
public ILExpression LastMatch; |
||||
|
||||
public ILVariable LastVariable { |
||||
get { |
||||
return LastMatch != null ? LastMatch.Operand as ILVariable : null; |
||||
} |
||||
} |
||||
|
||||
public StoreToVariable(ILExpression arg) : base(ILCode.Pattern, null, arg) |
||||
{ |
||||
} |
||||
|
||||
public override bool Match(ILNode other) |
||||
{ |
||||
ILExpression expr = other as ILExpression; |
||||
if (expr != null && expr.Code == ILCode.Stloc && (!MustBeGenerated || ((ILVariable)expr.Operand).IsGenerated) && Match(this.Arguments, expr.Arguments)) { |
||||
this.LastMatch = expr; |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
bool IVariablePattern.MatchVariable(ILVariable v) |
||||
{ |
||||
return v == LastMatch.Operand; |
||||
} |
||||
} |
||||
|
||||
public class LoadFromVariable : ILExpression |
||||
{ |
||||
readonly IVariablePattern v; |
||||
|
||||
public LoadFromVariable(IVariablePattern v) : base(ILCode.Pattern, null) |
||||
{ |
||||
this.v = v; |
||||
} |
||||
|
||||
public override bool Match(ILNode other) |
||||
{ |
||||
ILExpression expr = other as ILExpression; |
||||
return expr != null && expr.Code == ILCode.Ldloc && v.MatchVariable(expr.Operand as ILVariable); |
||||
} |
||||
} |
||||
|
||||
public class LoadFromArgument : ILExpression |
||||
{ |
||||
int index; |
||||
public static readonly LoadFromArgument This = new LoadFromArgument(-1); |
||||
|
||||
public LoadFromArgument(int index) : base(ILCode.Pattern, null) |
||||
{ |
||||
this.index = index; |
||||
} |
||||
|
||||
public override bool Match(ILNode other) |
||||
{ |
||||
ILExpression expr = other as ILExpression; |
||||
return expr != null && expr.Code == ILCode.Ldarg && ((ParameterDefinition)expr.Operand).Index == index; |
||||
} |
||||
} |
||||
|
||||
public class AnyILExpression : ILExpression |
||||
{ |
||||
public ILExpression LastMatch; |
||||
|
||||
public AnyILExpression() : base(ILCode.Pattern, null) |
||||
{ |
||||
} |
||||
|
||||
public override bool Match(ILNode other) |
||||
{ |
||||
if (other is ILExpression) { |
||||
LastMatch = (ILExpression)other; |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class ILCall : ILExpression |
||||
{ |
||||
string fullClassName; |
||||
string methodName; |
||||
|
||||
public ILCall(string fullClassName, string methodName, params ILExpression[] args) : base(ILCode.Pattern, null, args) |
||||
{ |
||||
this.fullClassName = fullClassName; |
||||
this.methodName = methodName; |
||||
} |
||||
|
||||
public override bool Match(ILNode other) |
||||
{ |
||||
ILExpression expr = other as ILExpression; |
||||
if (expr != null && expr.Code == ILCode.Call) { |
||||
MethodReference r = (MethodReference)expr.Operand; |
||||
if (r.Name == methodName && r.DeclaringType.FullName == fullClassName) |
||||
return Match(this.Arguments, expr.Arguments); |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,112 @@
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
|
||||
using Mono.Cecil; |
||||
|
||||
namespace ICSharpCode.Decompiler.ILAst |
||||
{ |
||||
public static class PatternMatching |
||||
{ |
||||
public static bool Match(this ILNode node, ILCode code) |
||||
{ |
||||
ILExpression expr = node as ILExpression; |
||||
return expr != null && expr.Prefixes == null && expr.Code == code; |
||||
} |
||||
|
||||
public static bool Match<T>(this ILNode node, ILCode code, out T operand) |
||||
{ |
||||
ILExpression expr = node as ILExpression; |
||||
if (expr != null && expr.Prefixes == null && expr.Code == code) { |
||||
operand = (T)expr.Operand; |
||||
Debug.Assert(expr.Arguments.Count == 0); |
||||
return true; |
||||
} |
||||
operand = default(T); |
||||
return false; |
||||
} |
||||
|
||||
public static bool Match(this ILNode node, ILCode code, out List<ILExpression> args) |
||||
{ |
||||
ILExpression expr = node as ILExpression; |
||||
if (expr != null && expr.Prefixes == null && expr.Code == code) { |
||||
Debug.Assert(expr.Operand == null); |
||||
args = expr.Arguments; |
||||
return true; |
||||
} |
||||
args = null; |
||||
return false; |
||||
} |
||||
|
||||
public static bool Match(this ILNode node, ILCode code, out ILExpression arg) |
||||
{ |
||||
List<ILExpression> args; |
||||
if (node.Match(code, out args) && args.Count == 1) { |
||||
arg = args[0]; |
||||
return true; |
||||
} |
||||
arg = null; |
||||
return false; |
||||
} |
||||
|
||||
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out List<ILExpression> args) |
||||
{ |
||||
ILExpression expr = node as ILExpression; |
||||
if (expr != null && expr.Prefixes == null && expr.Code == code) { |
||||
operand = (T)expr.Operand; |
||||
args = expr.Arguments; |
||||
return true; |
||||
} |
||||
operand = default(T); |
||||
args = null; |
||||
return false; |
||||
} |
||||
|
||||
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out ILExpression arg) |
||||
{ |
||||
List<ILExpression> args; |
||||
if (node.Match(code, out operand, out args) && args.Count == 1) { |
||||
arg = args[0]; |
||||
return true; |
||||
} |
||||
arg = null; |
||||
return false; |
||||
} |
||||
|
||||
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out ILExpression arg1, out ILExpression arg2) |
||||
{ |
||||
List<ILExpression> args; |
||||
if (node.Match(code, out operand, out args) && args.Count == 2) { |
||||
arg1 = args[0]; |
||||
arg2 = args[1]; |
||||
return true; |
||||
} |
||||
arg1 = null; |
||||
arg2 = null; |
||||
return false; |
||||
} |
||||
|
||||
public static bool Match<T>(this ILBasicBlock bb, ILCode code, out T operand, out ILExpression arg, out ILLabel fallLabel) |
||||
{ |
||||
if (bb.Body.Count == 1) { |
||||
if (bb.Body[0].Match(code, out operand, out arg)) { |
||||
fallLabel = bb.FallthoughGoto != null ? (ILLabel)bb.FallthoughGoto.Operand : null; |
||||
return true; |
||||
} |
||||
} |
||||
operand = default(T); |
||||
arg = null; |
||||
fallLabel = null; |
||||
return false; |
||||
} |
||||
|
||||
public static bool MatchThis(this ILNode node) |
||||
{ |
||||
ParameterDefinition parDef; |
||||
return node.Match(ILCode.Ldarg, out parDef) && parDef.Index == -1; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue