protected virtual Expression InstrumentCore(Expression expression, InstrumentationKind kind) { var exit = default(Expression); if (TryGetEnterExpression(expression, out var enter) || TryGetExitExpression(expression, out exit)) { switch (kind) { case InstrumentationKind.Block: { if (expression.Type != typeof(void)) { var t = Expression.Parameter(expression.Type, "__t"); return(Expression.Block(expression.Type, new[] { t }, enter, Expression.Assign(t, expression), exit, t)); } else { return(Expression.Block(typeof(void), enter, expression, exit)); } } case InstrumentationKind.TryFinally: { return(Expression.Block(expression.Type, enter, Expression.TryFinally(expression, exit))); } case InstrumentationKind.TryCatchFinally: { if (TryGetCatchBlocks(expression, out var handlers) && handlers.Length > 0) { // NB: We require the handlers to be of the same type as the try block; but the derived class can inspect the node to figure it out. return(Expression.Block(expression.Type, enter, Expression.TryCatchFinally(expression, exit, handlers))); } else { return(Expression.Block(expression.Type, enter, Expression.TryFinally(expression, exit))); } } default: throw new NotSupportedException(); } } return(expression); }
internal static bool IsValid(this InstrumentationKind value) { return(value >= InstrumentationKind.None && value <= InstrumentationKind.TestCoverage); }
protected virtual bool ShouldInstrument(Expression expression, out InstrumentationKind kind) { kind = InstrumentationKind.Block; return(true); }
protected override bool ShouldInstrument(Expression expression, out InstrumentationKind kind) { kind = InstrumentationKind.TryCatchFinally; return(true); }