// 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(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 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 args; if (node.Match(code, out args) && args.Count == 1) { arg = args[0]; return true; } arg = null; return false; } public static bool Match(this ILNode node, ILCode code, out T operand, out List 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(this ILNode node, ILCode code, out T operand, out ILExpression arg) { List 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(this ILNode node, ILCode code, out T operand, out ILExpression arg1, out ILExpression arg2) { List 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(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; } } }