An entity that can be instrumented
Example #1
0
        public void MethodIsGenerated()
        {
            // arrange
            var method = new Method
            {
                FullName = "System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32)"
            };

            // act
            var result = method.IsGenerated;

            // assert
            Assert.True (result);
        }
Example #2
0
        public void MethodIsNotGenerated()
        {
            // arrange
            var method = new Method
            {
                FullName = "System.Void DD.Collections.BitSetArray::_SetItems(System.Collections.Generic.IEnumerable`1<System.Int32>)"
            };

            // act
            var result = method.IsGenerated;

            // assert
            Assert.False (result);
        }
Example #3
0
        public void MethodIsNotGeneratedFullNameIsNull()
        {
            // arrange
            var method = new Method
            {
                FullName = null
            };

            // act
            var result = method.IsGenerated;

            // assert
            Assert.False (result);
        }
Example #4
0
        private string AsPropertyName(Method method)
        {
            if (!(method.IsGetter || method.IsSetter))
            {
                return method.Name;
            }

            try
            {
                var methodName = method.Name;
                if (methodName.Contains("set_"))
                {
                    var name = methodName.Split(new[] { "set_" }, System.StringSplitOptions.None)[1];
                    return name;
                }
                else if (methodName.Contains("get_"))
                {
                    var type = methodName.Split(new[] { ' ' })[0];
                    var getWithEmptyParentheses = methodName.Split(new[] { "get_" }, System.StringSplitOptions.None)[1];

                    var firstParenthesis = getWithEmptyParentheses.IndexOf('(');
                    var getWithoutEmptyParentheses = (firstParenthesis != -1)
                        ? getWithEmptyParentheses.Substring(0, firstParenthesis)
                        : getWithEmptyParentheses;

                    var name = string.Format("{0}({1})", getWithoutEmptyParentheses, type);
                    return name;
                }

                return methodName;
            }
            catch
            {
                return method.Name;
            }
        }
Example #5
0
        private static void TransformSequences_RemoveFalsePositiveUnvisited (Method method, CodeCoverageStringTextSource source, ICollection<Tuple<Method, SequencePoint>> toRemoveMethodSequencePoint)
        {
            // Select false unvisited right-curly-braces at generated "MoveNext" method
            // (Curly braces moved to generated "MoveNext" method and left unvisited)
            // Source is required here to identify curly braces
            if (method.CallName == "MoveNext" && source.FileFound && source.FileType == FileType.CSharp) {

                int countDown = 2; // remove up to two last right-curly-braces
                foreach (var sp in method.SequencePoints.Reverse()) {
                    if (sp.FileId == method.FileRefUniqueId
                        && sp.IsSingleCharSequencePoint
                        && sp.VisitCount == 0) { // unvisited only

                        if (countDown > 0) {
                            if (source.GetText(sp) == "}") {
                                toRemoveMethodSequencePoint.Add (new Tuple<Method, SequencePoint>(method, sp));
                                countDown -= 1;
                            }
                        }
                        else {
                            break;
                        }
                    }
                }
            }
        }
Example #6
0
        public void MethodCallNameWhenFullNameIsInvalid()
        {
            // arrange
            var method = new Method
            {
                FullName = "a::c"
            };

            // act
            var result = method.CallName; // now covers all branches

            // assert
            Assert.True (result == "");
        }
Example #7
0
        private static void CalculateCrapScore(Method method, Class @class)
        {
            method.CrapScore = Math.Round((decimal) Math.Pow(method.CyclomaticComplexity, 2) *
                                          (decimal) Math.Pow(1.0 - (double) (method.SequenceCoverage / (decimal) 100.0), 3.0) +
                                          method.CyclomaticComplexity,
                                          2);

            // TODO: is 0 a possible crap score?
            method.Summary.MinCrapScore = Math.Max(0, method.CrapScore);
            method.Summary.MaxCrapScore = method.Summary.MinCrapScore;

            if (@class.Summary.MinCrapScore == 0)
            {
                @class.Summary.MinCrapScore = method.Summary.MinCrapScore;
            }

            @class.Summary.MinCrapScore = Math.Min(@class.Summary.MinCrapScore, method.CrapScore);
            @class.Summary.MaxCrapScore = Math.Max(@class.Summary.MaxCrapScore, method.CrapScore);
        }
Example #8
0
        public void MethodCallNameWhenFullNameIsEmpty()
        {
            // arrange
            var method = new Method
            {
                FullName = string.Empty
            };

            // act
            var result = method.CallName;

            // assert
            Assert.True (result == "");
        }
Example #9
0
 public Class()
 {
     Methods = new Method[0];
 }
        private Method BuildMethod(IEnumerable<Model.File> files, MethodDefinition methodDefinition)
        {
            var method = new Method
            {
                Name = methodDefinition.FullName,
                IsConstructor = methodDefinition.IsConstructor,
                IsStatic = methodDefinition.IsStatic,
                IsGetter = methodDefinition.IsGetter,
                IsSetter = methodDefinition.IsSetter,
                MetadataToken = methodDefinition.MetadataToken.ToInt32()
            };

            if (methodDefinition.SafeGetMethodBody() == null)
            {
                if (methodDefinition.IsNative)
                    method.MarkAsSkipped(SkippedMethod.NativeCode);
                else
                    method.MarkAsSkipped(SkippedMethod.Unknown);
                return method;
            }

            if (_filter.ExcludeByAttribute(methodDefinition))
                method.MarkAsSkipped(SkippedMethod.Attribute);

            var definition = methodDefinition;
            method.FileRef = files.Where(x => x.FullPath == ModulePath + "::" + methodDefinition.Module.Name)
                .Select(x => new FileRef { UniqueId = x.UniqueId }).FirstOrDefault();
            return method;
        }
Example #11
0
        public void MethodCallNameWhenFullNameIsNull()
        {
            // arrange
            var method = new Method
            {
                FullName = null
            };

            // act
            var result = method.CallName;

            // assert
            Assert.True (result == "");
        }
Example #12
0
		public Class()
		{
			Methods = new Method[0];
			Summary = new Summary();
		}
        private static Method BuildMethod(IEnumerable<File> files, IFilter filter, MethodDefinition methodDefinition, bool alreadySkippedDueToAttr, ICommandLine commandLine)
        {
            var method = new Method();
            method.Name = methodDefinition.FullName;
            method.IsConstructor = methodDefinition.IsConstructor;
            method.IsStatic = methodDefinition.IsStatic;
            method.IsGetter = methodDefinition.IsGetter;
            method.IsSetter = methodDefinition.IsSetter;
            method.MetadataToken = methodDefinition.MetadataToken.ToInt32();

            if (alreadySkippedDueToAttr || filter.ExcludeByAttribute(methodDefinition))
                method.MarkAsSkipped(SkippedMethod.Attribute);
            else if (filter.ExcludeByFile(GetFirstFile(methodDefinition)))
                method.MarkAsSkipped(SkippedMethod.File);
            else if (commandLine.SkipAutoImplementedProperties && filter.IsAutoImplementedProperty(methodDefinition))
                method.MarkAsSkipped(SkippedMethod.AutoImplementedProperty);

            var definition = methodDefinition;
            method.FileRef = files.Where(x => x.FullPath == GetFirstFile(definition))
                .Select(x => new FileRef() {UniqueId = x.UniqueId}).FirstOrDefault();
            return method;
        }
Example #14
0
        private static bool TransformSequences_RemoveCompilerGeneratedBranches (Method method, CodeCoverageStringTextSource source, long startOffset, long finalOffset) {

            // foreach sequence point
            foreach (var sp in method.SequencePoints
                     .Where (sp => sp.FileId == method.FileRefUniqueId 
                             && sp.BranchPoints.Count != 0)) {

                if (sp.Offset <= startOffset || sp.Offset >= finalOffset) {
                    // doRemoveBranches where .Offset <= startOffset"{" or finalOffset"}" <= .Offset
                    // this will exclude "{" and "}" compiler generated branches and majority of ccrewrite Code-Contract's
                    sp.BranchPoints = new List<BranchPoint>();

                } else { // branches not removed
                    // check for other options by reading SequencePoint source
                    var text = source.GetText(sp); // text is never null
                    if (text.Length == 0) {
                        ("Empty sequence-point at line: " + sp.StartLine + " column: " + sp.StartColumn).InformUser();
                        ("Source file: " + source.FilePath).InformUser();
                        return false; // signal error to caller's caller loop (break)
                    }
                    // Contract.Requires/Ensures is occasionally left inside method offset
                    // Quick check for "C" before using Regex
                    // Use Regex here! "Contract" and "." and "Requires/Ensures"
                    // can be separated by spaces and newlines
                    if (text[0] == 'C' && contractRegex.IsMatch(text)) {
                        sp.BranchPoints = new List<BranchPoint>();
                    } 
                    // "in" keyword?
                    if (text == "in") {
                        // Remove generated ::MoveNext branches within "in" keyword
                        // Not always removed in CecilSymbolManager (enumerated KeyValuePair)
                        sp.BranchPoints = new List<BranchPoint>();
                    }
                }
            }
            return true;
        }
Example #15
0
        public void MethodIsNotGeneratedFullNameIsEmpty()
        {
            // arrange
            var method = new Method
            {
                FullName = string.Empty
            };

            // act
            var result = method.IsGenerated;

            // assert
            Assert.False (result);
        }
Example #16
0
        private static void TransformSequences_RemoveCompilerGeneratedBranches(Method method, CodeCoverageStringTextSource source, ref long startOffset, ref long finalOffset)
        {
            // order SequencePoints by source order (Line/Column)
            var sourceLineOrderedSps = method.SequencePoints.OrderBy(sp => sp.StartLine).ThenBy(sp => sp.StartColumn).Where(sp => sp.FileId == method.FileRefUniqueId).ToArray();

            // get "{" if on first two positions
            for (int index = 0; index < Math.Min (2, sourceLineOrderedSps.Length); index++) {
                if (source.GetText(sourceLineOrderedSps[0]) == "{") {
                    startOffset = sourceLineOrderedSps[0].Offset;
                    break;
                }
            }
            // get "}" if on last position
            if (source.GetText(sourceLineOrderedSps.Last()) == "}") {
                finalOffset = sourceLineOrderedSps.Last().Offset;
            }
        }
Example #17
0
        private static bool TransformSequences_RemoveCompilerGeneratedBranches (Method method, CodeCoverageStringTextSource source)
        {
            // Do we have C# source?
            if (source.FileType == FileType.CSharp) {

                if (source.FileFound) {

                    // initialize offset with unreachable values
                    long startOffset = long.MinValue;
                    long finalOffset = long.MaxValue;

                    if (!method.IsGenerated) {
                        // fill offsets with values
                        TransformSequences_RemoveCompilerGeneratedBranches(method, source, ref startOffset, ref finalOffset);
                    }

                    if (!TransformSequences_RemoveCompilerGeneratedBranches (method, source, startOffset, finalOffset)) {
                        return false; // return error/failure to caller
                    }

                } else {

                    // Do as much possible without source
                    // This will remove generated branches within "{", "}" and "in" (single-line SequencePoints)
                    // but cannot remove Code Contract ccrewite generated branches
                    foreach (var sp in method.SequencePoints) {
                        if (sp.BranchPoints.Count != 0
                            && sp.StartLine == sp.EndLine
                            && sp.EndColumn - sp.StartColumn <= 2) {

                            // Zero, one or two character sequence point should not contain branches
                            // Never found 0 character sequencePoint
                            // Never found 1 character sequencePoint except "{" and "}"
                            // Never found 2 character sequencePoint except "in" keyword
                            // Afaik, c# cannot express branch condition in one or two characters of source code
                            // Keyword "do" does not generate SequencePoint 
                            sp.BranchPoints = new List<BranchPoint>();
                        }
                    }
                }
            }
            return true;
        }
Example #18
0
 private static void CalculateNPathComplexity(Method method)
 {
     method.NPathComplexity = 0;
     var nPaths = new Dictionary<int, int>();
     if (method.BranchPoints.Any())
     {
         foreach (var bp in method.BranchPoints.Where(b => b != null))
         {
             if (nPaths.ContainsKey(bp.Offset))
             {
                 nPaths[bp.Offset] += 1;
             }
             else
             {
                 nPaths.Add(bp.Offset, 1);
             }
         }
     }
     foreach (var branches in nPaths.Values)
     {
         if (method.NPathComplexity == 0)
         {
             method.NPathComplexity = branches;
         }
         else
         {
             method.NPathComplexity *= branches;
         }
     }
 }
Example #19
0
        private static void CalculateCyclomaticComplexity(Method method, Class @class)
        {
            method.Summary.MinCyclomaticComplexity = Math.Max(1, method.CyclomaticComplexity);
            method.Summary.MaxCyclomaticComplexity = method.Summary.MinCyclomaticComplexity;

            if (@class.Summary.MinCyclomaticComplexity == 0)
                @class.Summary.MinCyclomaticComplexity = method.Summary.MinCyclomaticComplexity;

            @class.Summary.MinCyclomaticComplexity = Math.Min(@class.Summary.MinCyclomaticComplexity,
                method.CyclomaticComplexity);
            @class.Summary.MaxCyclomaticComplexity = Math.Max(@class.Summary.MaxCyclomaticComplexity,
                method.CyclomaticComplexity);
        }
Example #20
0
        private static void ProcessMethodData(Method method, Class @class)
        {
            if (method.MethodPoint != null)
            {
                method.Visited = (method.MethodPoint.VisitCount > 0);
            }

            method.Summary.NumBranchPoints = method.BranchPoints.Length;
            method.Summary.VisitedBranchPoints = method.BranchPoints.Count(pt => pt.VisitCount != 0);
            method.Summary.NumSequencePoints = method.SequencePoints.Length;
            method.Summary.VisitedSequencePoints = method.SequencePoints.Count(pt => pt.VisitCount != 0);

            if (method.Summary.NumSequencePoints > 0)
                method.Summary.NumBranchPoints += 1;

            if (method.Summary.VisitedSequencePoints > 0)
                method.Summary.VisitedBranchPoints += 1;

            if (method.FileRef != null)
            {
                method.Summary.NumMethods = 1;
                method.Summary.VisitedMethods = (method.Visited) ? 1 : 0;
            }

            AddPoints(@class.Summary, method.Summary);
            CalculateCoverage(method.Summary);

            method.SequenceCoverage = method.Summary.SequenceCoverage;
            method.BranchCoverage = method.Summary.BranchCoverage;

            CalculateNPathComplexity(method);

            CalculateCyclomaticComplexity(method, @class);
        }
        public PropertyMethodNode(Method method)
            : base(method)
        {

        }
Example #22
0
		public MethodNode(Method method)
		{
			Method = method;
		}
Example #23
0
 private static void GetMethodsForType(IEnumerable<TypeDefinition> typeDefinitions, Class type, List<Method> methods, File[] files)
 {
     foreach (var typeDefinition in typeDefinitions)
     {
         if (typeDefinition.FullName == type.FullName)
         {
             foreach (var methodDefinition in typeDefinition.Methods)
             {
                 if (!methodDefinition.IsConstructor)
                 {
                     var method = new Method() { Name = methodDefinition.FullName, MetadataToken = methodDefinition.MetadataToken.ToInt32() };
                     var definition = methodDefinition;
                     method.FileRef = files.Where(x => x.FullPath == GetFirstFile(definition)).Select(x => new FileRef() {UniqueId = x.UniqueId}).FirstOrDefault();
                     methods.Add(method);
                 }
             }
         }
         if (typeDefinition.HasNestedTypes) GetMethodsForType(typeDefinition.NestedTypes, type, methods, files);
     }
 }
Example #24
0
        public void MethodCallnameStandard()
        {
            // arrange
            var method = new Method
            {
                FullName = "System.Void DD.Collections.BitSetArray::_SetItems(System.Collections.Generic.IEnumerable`1<System.Int32>)"
            };

            // act
            var result = method.CallName;

            // assert
            Assert.True (result == "_SetItems");
        }
Example #25
0
        private static Method BuildMethod(IEnumerable<File> files, IFilter filter, MethodDefinition methodDefinition, bool alreadySkippedDueToAttr)
        {
            var method = new Method();
            method.Name = methodDefinition.FullName;
            method.IsConstructor = methodDefinition.IsConstructor;
            method.IsStatic = methodDefinition.IsStatic;
            method.IsGetter = methodDefinition.IsGetter;
            method.IsSetter = methodDefinition.IsSetter;
            method.MetadataToken = methodDefinition.MetadataToken.ToInt32();

            if (alreadySkippedDueToAttr || filter.ExcludeByAttribute(methodDefinition))
                method.SkippedDueTo = SkippedMethod.Attribute;
            else if (filter.ExcludeByFile(GetFirstFile(methodDefinition)))
                method.SkippedDueTo = SkippedMethod.File;

            var definition = methodDefinition;
            method.FileRef = files.Where(x => x.FullPath == GetFirstFile(definition))
                .Select(x => new FileRef() {UniqueId = x.UniqueId}).FirstOrDefault();
            return method;
        }
Example #26
0
        public void MethodCallNameTwice()
        {
            // arrange
            var method = new Method
            {
                FullName = "System.Boolean DD.Collections.BitSetArray::BitSetArray_<_SetItems>b__b_0(System.Int32)"
            };

            // act twice to cover cached result
            var result = method.CallName;
            result = method.CallName;

            // assert
            Assert.True (result == "BitSetArray_<_SetItems>b__b_0");
        }