예제 #1
0
        private LocalRewriter(
            CSharpCompilation compilation,
            MethodSymbol containingMethod,
            int containingMethodOrdinal,
            BoundStatement rootStatement,
            NamedTypeSymbol containingType,
            SyntheticBoundNodeFactory factory,
            SynthesizedSubmissionFields previousSubmissionFields,
            bool allowOmissionOfConditionalCalls,
            DiagnosticBag diagnostics,
            Instrumenter instrumenter)
        {
            _compilation             = compilation;
            _factory                 = factory;
            _factory.CurrentFunction = containingMethod;
            Debug.Assert(TypeSymbol.Equals(factory.CurrentType, (containingType ?? containingMethod.ContainingType), TypeCompareKind.ConsiderEverything2));
            _dynamicFactory                  = new LoweredDynamicOperationFactory(factory, containingMethodOrdinal);
            _previousSubmissionFields        = previousSubmissionFields;
            _allowOmissionOfConditionalCalls = allowOmissionOfConditionalCalls;
            _diagnostics = diagnostics;

            Debug.Assert(instrumenter != null);
            _instrumenter  = instrumenter;
            _rootStatement = rootStatement;
        }
        public static DynamicAnalysisInjector TryCreate(
            MethodSymbol method,
            BoundStatement methodBody,
            SyntheticBoundNodeFactory methodBodyFactory,
            DiagnosticBag diagnostics,
            DebugDocumentProvider debugDocumentProvider,
            Instrumenter previous)
        {
            // Do not instrument implicitly-declared methods, except for constructors.
            // Instrument implicit constructors in order to instrument member initializers.
            if (method.IsImplicitlyDeclared && !method.IsImplicitConstructor)
            {
                return(null);
            }

            // Do not instrument methods marked with or in scope of ExcludeFromCodeCoverageAttribute.
            if (IsExcludedFromCodeCoverage(method))
            {
                return(null);
            }

            MethodSymbol createPayloadForMethodsSpanningSingleFile = GetCreatePayloadOverload(
                methodBodyFactory.Compilation,
                WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningSingleFile,
                methodBody.Syntax,
                diagnostics);

            MethodSymbol createPayloadForMethodsSpanningMultipleFiles = GetCreatePayloadOverload(
                methodBodyFactory.Compilation,
                WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningMultipleFiles,
                methodBody.Syntax,
                diagnostics);

            // Do not instrument any methods if CreatePayload is not present.
            if ((object)createPayloadForMethodsSpanningSingleFile == null || (object)createPayloadForMethodsSpanningMultipleFiles == null)
            {
                return(null);
            }

            // Do not instrument CreatePayload if it is part of the current compilation (which occurs only during testing).
            // CreatePayload will fail at run time with an infinite recursion if it is instrumented.
            if (method.Equals(createPayloadForMethodsSpanningSingleFile) || method.Equals(createPayloadForMethodsSpanningMultipleFiles))
            {
                return(null);
            }

            return(new DynamicAnalysisInjector(
                       method,
                       methodBody,
                       methodBodyFactory,
                       createPayloadForMethodsSpanningSingleFile,
                       createPayloadForMethodsSpanningMultipleFiles,
                       diagnostics,
                       debugDocumentProvider,
                       previous));
        }
        private DynamicAnalysisInjector(
            MethodSymbol method,
            BoundStatement methodBody,
            SyntheticBoundNodeFactory methodBodyFactory,
            MethodSymbol createPayloadForMethodsSpanningSingleFile,
            MethodSymbol createPayloadForMethodsSpanningMultipleFiles,
            DiagnosticBag diagnostics,
            DebugDocumentProvider debugDocumentProvider,
            Instrumenter previous) : base(previous)
        {
            _createPayloadForMethodsSpanningSingleFile    = createPayloadForMethodsSpanningSingleFile;
            _createPayloadForMethodsSpanningMultipleFiles = createPayloadForMethodsSpanningMultipleFiles;
            _method       = method;
            _methodBody   = methodBody;
            _spansBuilder = ArrayBuilder <SourceSpan> .GetInstance();

            TypeSymbol payloadElementType = methodBodyFactory.SpecialType(SpecialType.System_Boolean);

            _payloadType           = ArrayTypeSymbol.CreateCSharpArray(methodBodyFactory.Compilation.Assembly, TypeSymbolWithAnnotations.Create(payloadElementType));
            _diagnostics           = diagnostics;
            _debugDocumentProvider = debugDocumentProvider;
            _methodBodyFactory     = methodBodyFactory;

            // Set the factory context to generate nodes for the current method
            var oldMethod = methodBodyFactory.CurrentFunction;

            methodBodyFactory.CurrentFunction = method;

            _methodPayload = methodBodyFactory.SynthesizedLocal(_payloadType, kind: SynthesizedLocalKind.InstrumentationPayload, syntax: methodBody.Syntax);
            // The first point indicates entry into the method and has the span of the method definition.
            SyntaxNode syntax = MethodDeclarationIfAvailable(methodBody.Syntax);

            if (!method.IsImplicitlyDeclared)
            {
                _methodEntryInstrumentation = AddAnalysisPoint(syntax, SkipAttributes(syntax), methodBodyFactory);
            }

            // Restore context
            methodBodyFactory.CurrentFunction = oldMethod;
        }
예제 #4
0
 public DebugInfoInjector(Instrumenter previous)
     : base(previous)
 {
 }
예제 #5
0
 public CompoundInstrumenter(Instrumenter previous)
 {
     Debug.Assert(previous != null);
     Previous = previous;
 }