File: Lowering\Instrumentation\CompoundInstrumenter.cs
Web Access
Project: src\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.Shared.Collections;
 
namespace Microsoft.CodeAnalysis.CSharp
{
    /// <summary>
    /// Utility class, provides a convenient way of combining various <see cref="Instrumenter"/>s in a chain,
    /// allowing each of them to apply specific instrumentations in particular order.
    /// 
    /// Default implementation of all APIs delegates to the "previous" <see cref="Instrumenter"/> passed as a parameter
    /// to the constructor of this class. Usually, derived types are going to let the base (this class) to do its work first
    /// and then operate on the result they get back.
    /// </summary>
    internal abstract class CompoundInstrumenter : Instrumenter
    {
        public CompoundInstrumenter(Instrumenter previous)
        {
            Debug.Assert(previous != null);
            Previous = previous;
        }
 
        public Instrumenter Previous { get; }
 
        /// <summary>
        /// Returns <see cref="CompoundInstrumenter"/> with <see cref="Previous"/> instrumenter set to <paramref name="previous"/>.
        /// </summary>
        public CompoundInstrumenter WithPrevious(Instrumenter previous)
            => ReferenceEquals(previous, Previous) ? this : WithPreviousImpl(previous);
 
        protected abstract CompoundInstrumenter WithPreviousImpl(Instrumenter previous);
 
        public override BoundStatement InstrumentNoOpStatement(BoundNoOpStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentNoOpStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentYieldBreakStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentYieldReturnStatement(BoundYieldReturnStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentYieldReturnStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentThrowStatement(BoundThrowStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentThrowStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentContinueStatement(BoundContinueStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentContinueStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentGotoStatement(BoundGotoStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentGotoStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentExpressionStatement(BoundExpressionStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentExpressionStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentFieldOrPropertyInitializer(BoundStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentFieldOrPropertyInitializer(original, rewritten);
        }
 
        public override BoundStatement InstrumentBreakStatement(BoundBreakStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentBreakStatement(original, rewritten);
        }
 
        public override void PreInstrumentBlock(BoundBlock original, LocalRewriter rewriter)
        {
            Previous.PreInstrumentBlock(original, rewriter);
        }
 
        public override void InstrumentBlock(BoundBlock original, LocalRewriter rewriter, ref TemporaryArray<LocalSymbol> additionalLocals, out BoundStatement? prologue, out BoundStatement? epilogue, out BoundBlockInstrumentation? instrumentation)
        {
            Previous.InstrumentBlock(original, rewriter, ref additionalLocals, out prologue, out epilogue, out instrumentation);
        }
 
        public override BoundExpression InstrumentDoStatementCondition(BoundDoStatement original, BoundExpression rewrittenCondition, SyntheticBoundNodeFactory factory)
        {
            return Previous.InstrumentDoStatementCondition(original, rewrittenCondition, factory);
        }
 
        public override BoundStatement InstrumentDoStatementConditionalGotoStart(BoundDoStatement original, BoundStatement ifConditionGotoStart)
        {
            return Previous.InstrumentDoStatementConditionalGotoStart(original, ifConditionGotoStart);
        }
 
        public override BoundStatement? InstrumentForEachStatementCollectionVarDeclaration(BoundForEachStatement original, BoundStatement? collectionVarDecl)
        {
            return Previous.InstrumentForEachStatementCollectionVarDeclaration(original, collectionVarDecl);
        }
 
        public override BoundStatement InstrumentForEachStatement(BoundForEachStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentForEachStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentForEachStatementIterationVarDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)
        {
            return Previous.InstrumentForEachStatementIterationVarDeclaration(original, iterationVarDecl);
        }
 
        public override BoundStatement InstrumentForStatementConditionalGotoStartOrBreak(BoundForStatement original, BoundStatement branchBack)
        {
            return Previous.InstrumentForStatementConditionalGotoStartOrBreak(original, branchBack);
        }
 
        public override BoundStatement InstrumentForEachStatementConditionalGotoStart(BoundForEachStatement original, BoundStatement branchBack)
        {
            return Previous.InstrumentForEachStatementConditionalGotoStart(original, branchBack);
        }
 
        public override BoundExpression InstrumentForStatementCondition(BoundForStatement original, BoundExpression rewrittenCondition, SyntheticBoundNodeFactory factory)
        {
            return Previous.InstrumentForStatementCondition(original, rewrittenCondition, factory);
        }
 
        public override BoundStatement InstrumentIfStatementConditionalGoto(BoundIfStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentIfStatementConditionalGoto(original, rewritten);
        }
 
        public override BoundExpression InstrumentIfStatementCondition(BoundIfStatement original, BoundExpression rewrittenCondition, SyntheticBoundNodeFactory factory)
        {
            return Previous.InstrumentIfStatementCondition(original, rewrittenCondition, factory);
        }
 
        public override BoundStatement InstrumentLabelStatement(BoundLabeledStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentLabelStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentUserDefinedLocalInitialization(BoundLocalDeclaration original, BoundStatement rewritten)
        {
            return Previous.InstrumentUserDefinedLocalInitialization(original, rewritten);
        }
 
        public override BoundExpression InstrumentUserDefinedLocalAssignment(BoundAssignmentOperator original)
        {
            return Previous.InstrumentUserDefinedLocalAssignment(original);
        }
 
        public override BoundExpression InstrumentCall(BoundCall original, BoundExpression rewritten)
        {
            return Previous.InstrumentCall(original, rewritten);
        }
 
        public override void InterceptCallAndAdjustArguments(
            ref MethodSymbol method,
            ref BoundExpression? receiver,
            ref ImmutableArray<BoundExpression> arguments,
            ref ImmutableArray<RefKind> argumentRefKindsOpt)
        {
            Previous.InterceptCallAndAdjustArguments(ref method, ref receiver, ref arguments, ref argumentRefKindsOpt);
        }
 
        public override BoundExpression InstrumentObjectCreationExpression(BoundObjectCreationExpression original, BoundExpression rewritten)
        {
            return Previous.InstrumentObjectCreationExpression(original, rewritten);
        }
 
        public override BoundExpression InstrumentFunctionPointerInvocation(BoundFunctionPointerInvocation original, BoundExpression rewritten)
        {
            return Previous.InstrumentFunctionPointerInvocation(original, rewritten);
        }
 
        public override BoundStatement InstrumentLockTargetCapture(BoundLockStatement original, BoundStatement lockTargetCapture)
        {
            return Previous.InstrumentLockTargetCapture(original, lockTargetCapture);
        }
 
        public override BoundStatement InstrumentReturnStatement(BoundReturnStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentReturnStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentSwitchStatement(BoundSwitchStatement original, BoundStatement rewritten)
        {
            return Previous.InstrumentSwitchStatement(original, rewritten);
        }
 
        public override BoundStatement InstrumentSwitchWhenClauseConditionalGotoBody(BoundExpression original, BoundStatement ifConditionGotoBody)
        {
            return Previous.InstrumentSwitchWhenClauseConditionalGotoBody(original, ifConditionGotoBody);
        }
 
        public override BoundStatement InstrumentUsingTargetCapture(BoundUsingStatement original, BoundStatement usingTargetCapture)
        {
            return Previous.InstrumentUsingTargetCapture(original, usingTargetCapture);
        }
 
        public override BoundExpression InstrumentWhileStatementCondition(BoundWhileStatement original, BoundExpression rewrittenCondition, SyntheticBoundNodeFactory factory)
        {
            return Previous.InstrumentWhileStatementCondition(original, rewrittenCondition, factory);
        }
 
        public override BoundStatement InstrumentWhileStatementConditionalGotoStartOrBreak(BoundWhileStatement original, BoundStatement ifConditionGotoStart)
        {
            return Previous.InstrumentWhileStatementConditionalGotoStartOrBreak(original, ifConditionGotoStart);
        }
 
        public override void InstrumentCatchBlock(
            BoundCatchBlock original,
            ref BoundExpression? rewrittenSource,
            ref BoundStatementList? rewrittenFilterPrologue,
            ref BoundExpression? rewrittenFilter,
            ref BoundBlock rewrittenBody,
            ref TypeSymbol? rewrittenType,
            SyntheticBoundNodeFactory factory)
        {
            Previous.InstrumentCatchBlock(
                original,
                ref rewrittenSource,
                ref rewrittenFilterPrologue,
                ref rewrittenFilter,
                ref rewrittenBody,
                ref rewrittenType,
                factory);
        }
 
        public override BoundExpression InstrumentSwitchStatementExpression(BoundStatement original, BoundExpression rewrittenExpression, SyntheticBoundNodeFactory factory)
        {
            return Previous.InstrumentSwitchStatementExpression(original, rewrittenExpression, factory);
        }
 
        public override BoundExpression InstrumentSwitchExpressionArmExpression(BoundExpression original, BoundExpression rewrittenExpression, SyntheticBoundNodeFactory factory)
        {
            return Previous.InstrumentSwitchExpressionArmExpression(original, rewrittenExpression, factory);
        }
 
        public override BoundStatement InstrumentSwitchBindCasePatternVariables(BoundStatement bindings)
        {
            return Previous.InstrumentSwitchBindCasePatternVariables(bindings);
        }
 
        public override BoundStatement InstrumentForEachStatementDeconstructionVariablesDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)
        {
            return Previous.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl);
        }
    }
}