コード例 #1
0
        public void GetBranchPoints_ExceptionFilter()
        {
            // arrange
            var type   = _module.Types.Single(x => x.FullName == typeof(ExceptionFilter).FullName);
            var method = type.Methods.Single(x => x.FullName.Contains($"::{nameof(ExceptionFilter.Test)}"));
            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            Assert.Empty(points);
        }
コード例 #2
0
        public void GetBranchPoints_GeneratedBranches_DueToCachedAnonymousMethodDelegate_Ignored()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSimpleTaskWithLambda)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            Assert.Empty(points);
        }
コード例 #3
0
        public void GetBranchPoints_Using_Where_GeneratedBranchesIgnored()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSimpleUsingStatement)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            Assert.Equal(2, points.Count());
        }
コード例 #4
0
        public void GetBranchPoints_IgnoresBranchesIn_AsyncAwaitStateMachine()
        {
            // arrange
            var nestedName = typeof(AsyncAwaitStateMachine).GetNestedTypes(BindingFlags.NonPublic).First().Name;
            var type       = _module.Types.FirstOrDefault(x => x.FullName == typeof(AsyncAwaitStateMachine).FullName);
            var nestedType = type.NestedTypes.FirstOrDefault(x => x.FullName.EndsWith(nestedName));
            var method     = nestedType.Methods.First(x => x.FullName.EndsWith("::MoveNext()"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.Empty(points);
        }
コード例 #5
0
        public void GetBranchPoints_CompleteIf()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasCompleteIf)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(2, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(34, points[0].StartLine);
            Assert.Equal(34, points[1].StartLine);
        }
コード例 #6
0
        public void GetBranchPoints_TwoBranch()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains("::HasTwoDecisions"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(4, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(points[2].Offset, points[3].Offset);
            Assert.Equal(27, points[0].StartLine);
            Assert.Equal(28, points[2].StartLine);
        }
コード例 #7
0
        public void GetBranchPoints_OneBranch()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSingleDecision)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(2, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(0, points[0].Path);
            Assert.Equal(1, points[1].Path);
            Assert.Equal(21, points[0].StartLine);
            Assert.Equal(21, points[1].StartLine);
            Assert.NotNull(points[1].Document);
            Assert.Equal(points[0].Document, points[1].Document);
        }
コード例 #8
0
        public void GetBranchPoints_UsingWithException_Issue243_IgnoresBranchInFinallyBlock()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.UsingWithException_Issue243)}"));

            // check that the method is laid out the way we discovered it to be during the defect
            // @see https://github.com/OpenCover/opencover/issues/243
            Assert.Single(method.Body.ExceptionHandlers);
            Assert.NotNull(method.Body.ExceptionHandlers[0].HandlerStart);
            Assert.Null(method.Body.ExceptionHandlers[0].HandlerEnd);
            Assert.Equal(1, method.Body.Instructions.Count(i => i.OpCode.FlowControl == FlowControl.Cond_Branch));
            Assert.True(method.Body.Instructions.First(i => i.OpCode.FlowControl == FlowControl.Cond_Branch).Offset > method.Body.ExceptionHandlers[0].HandlerStart.Offset);

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.Empty(points);
        }
コード例 #9
0
        public void GetBranchPoints_AssignsNegativeLineNumberToBranchesInMethodsThatHaveNoInstrumentablePoints()
        {
            /*
             * Yes these actually exist - the compiler is very inventive
             * in this case for an anonymous class the compiler will dynamically create an Equals 'utility' method.
             */
            // arrange
            var type   = _module.Types.First(x => x.FullName.Contains("f__AnonymousType"));
            var method = type.Methods.First(x => x.FullName.Contains("::Equals"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            foreach (var branchPoint in points)
            {
                Assert.Equal(-1, branchPoint.StartLine);
            }
        }
コード例 #10
0
        public void GetBranchPoints_SwitchWithBreaks()
        {
            // arrange
            var type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            var method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSwitchWithBreaks)}"));

            // act
            var points = CecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(4, points.Count());
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(points[0].Offset, points[2].Offset);
            Assert.Equal(3, points[3].Path);

            Assert.Equal(76, points[0].StartLine);
            Assert.Equal(76, points[1].StartLine);
            Assert.Equal(76, points[2].StartLine);
            Assert.Equal(76, points[3].StartLine);
        }
コード例 #11
0
        private void InstrumentIL(MethodDefinition method)
        {
            method.Body.SimplifyMacros();
            ILProcessor processor = method.Body.GetILProcessor();

            var index = 0;
            var count = processor.Body.Instructions.Count;

            var branchPoints = CecilSymbolHelper.GetBranchPoints(method);

            for (int n = 0; n < count; n++)
            {
                var instruction          = processor.Body.Instructions[index];
                var sequencePoint        = method.DebugInformation.GetSequencePoint(instruction);
                var targetedBranchPoints = branchPoints.Where(p => p.EndOffset == instruction.Offset);

                if (sequencePoint != null && !sequencePoint.IsHidden)
                {
                    var target = AddInstrumentationCode(method, processor, instruction, sequencePoint);
                    foreach (var _instruction in processor.Body.Instructions)
                    {
                        ReplaceInstructionTarget(_instruction, instruction, target);
                    }

                    foreach (ExceptionHandler handler in processor.Body.ExceptionHandlers)
                    {
                        ReplaceExceptionHandlerBoundary(handler, instruction, target);
                    }

                    index += 2;
                }

                foreach (var _branchTarget in targetedBranchPoints)
                {
                    /*
                     * Skip branches with no sequence point reference for now.
                     * In this case for an anonymous class the compiler will dynamically create an Equals 'utility' method.
                     * The CecilSymbolHelper will create branch points with a start line of -1 and no document, which
                     * I am currently not sure how to handle.
                     */
                    if (_branchTarget.StartLine == -1 || _branchTarget.Document == null)
                    {
                        continue;
                    }

                    var target = AddInstrumentationCode(method, processor, instruction, _branchTarget);
                    foreach (var _instruction in processor.Body.Instructions)
                    {
                        ReplaceInstructionTarget(_instruction, instruction, target);
                    }

                    foreach (ExceptionHandler handler in processor.Body.ExceptionHandlers)
                    {
                        ReplaceExceptionHandlerBoundary(handler, instruction, target);
                    }

                    index += 2;
                }

                index++;
            }

            method.Body.OptimizeMacros();
        }
コード例 #12
0
        public void GetBranchPoints_OneBranch()
        {
            // arrange
            TypeDefinition   type   = _module.Types.First(x => x.FullName == typeof(DeclaredConstructorClass).FullName);
            MethodDefinition method = type.Methods.First(x => x.FullName.Contains($"::{nameof(DeclaredConstructorClass.HasSingleDecision)}"));

            // act
            System.Collections.Generic.IReadOnlyList <BranchPoint> points = _cecilSymbolHelper.GetBranchPoints(method);

            // assert
            Assert.NotNull(points);
            Assert.Equal(2, points.Count);
            Assert.Equal(points[0].Offset, points[1].Offset);
            Assert.Equal(0, points[0].Path);
            Assert.Equal(1, points[1].Path);
            Assert.Equal(22, points[0].StartLine);
            Assert.Equal(22, points[1].StartLine);
            Assert.NotNull(points[1].Document);
            Assert.Equal(points[0].Document, points[1].Document);
        }