mirror of https://github.com/icsharpcode/ILSpy.git
5 changed files with 116 additions and 248 deletions
@ -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 @@ |
|||||||
|
// 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