Dependency Graph

Online documentation:

Dependency Matrix

Online documentation:

Visualizing Code Metrics through Treemaping

With the Online documentation, understand how Treemaping can help you see patterns in your code base, that would be hard to spot with other ways.

Abstractness versus Instability Diagram

The Abstractness versus Instability Diagram helps to detect which assemblies are potentially painful to maintain (i.e concrete and stable) and which assemblies are potentially useless (i.e abstract and instable).

Online documentation:

For beginners: Where to start

Code queries and rules results are truncated to list a maximum of 100 code elements in this report

Does this report gets too large?

The list contains only code elements refactored or added since the baseline for comparison.

The setting Recent Violations Only is enabled

Why should I enable the setting Recent Violations Only ?

Quick Tips

Main
Main \ Rules
Main \ Rules \ Code Quality
Main \ Rules \ Object Oriented Design
Main \ Rules \ Design
Main \ Rules \ Dead Code
Main \ Rules \ Visibility
Main \ Rules \ Naming Conventions
Main \ Rules \ Source Files Organization
Main \ Rules \ .NET Framework Usage
Main \ Rules \ .NET Framework Usage \ System
Main \ Group of Queries \ Object Oriented Design
Main \ Group of Queries \ API Breaking Changes
Main \ Group of Queries \ Code Diff Summary
Main \ Group of Queries \ Test and Code Coverage
Main \ Group of Queries \ Dead Code
Main \ Metrics \ Application Statistics
Main \ Metrics \ Assemblies Metrics
Main \ Metrics \ Namespaces Metrics
Main \ Metrics \ Types Metrics
Main \ Assemblies Dependencies
Main \ Namespaces Dependencies
Main \ Types Dependencies
Main \ Build Order
Main \ Analysis Log
Main \ Trend Charts
ndepend report summary application nameNew Projectreport build date11-28-2014 20:34:14analysis duration00:01ndepend version 5.4.1.8430baseline for comparison Not Defined. To define a Baseline for Comparison, please read this online documentation. code coverage data Not Defined. To import Code Coverage Data, please read this online documentation.
Get started.Quick tips.Back to NDepend. The present HTML report is a summary of data gathered by the analysis.
It is recommended to use the NDepend interactive UI capabilities
to make the most of NDepend by mastering all aspects of your code.

Diagrams

.NET Assemblies Dependency Graph
Dependency Graph
View as ?fullscaled
.NET Assemblies Dependency Matrix
Dependency Matrix
View as ?fullscaled
Treemap View
Treemap Metric View
View as ?fullscaled
Abstractness versus Instability
Abstractness vs. Instability
View as ?fullscaled

Application Metrics

Note: Further Application Statistics are available.
# Lines of Code
405      
0 (NotMyCode)
# Types
6      
2   Assemblies      
2   Namespaces      
50   Methods      
5   Fields      
4   Source Files      
Comment
37.88%      
247   Lines of Comment      
Method Complexity
30   Max      
1.83   Average      
Code Coverage by TestsN/A because no coverage data specified
Third-Party Usage
3   Assemblies used      
13   Namespaces used      
60   Types used      
109   Methods used      
2   Fields used      

Rules summary

115222This section lists all Rules violated, and Rules or Queries with Error
  • Number of Rules or Queries with Error (syntax error, exception thrown, time-out): 0
  • Number of Rules violated: 24

Summary of Rules violated

graphHelp Rules can be checked live at
development-time, from within Visual
Studio. Online documentation.
graphHelp NDepend rules report too many flaws on
existing code base? Use the option
Recent Violations Only!
warningCritical Some Critical Rules are violated. Critical Rules
can be used to break the build process if
violated. Online documentation.
Name# MatchesElementsGroup
warningCritical   Methods too complex - critical
1 methodsCode Quality
warning   Quick summary of methods to refactor
3 methodsCode Quality
warning   Methods too big
3 methodsCode Quality
warning   Methods too complex
1 methodsCode Quality
warning   Methods potentially poorly commented
1 methodsCode Quality
warning   Types with too many methods
1 typesCode Quality
warning   Types with too many fields
1 typesCode Quality
warning   Types with poor cohesion
1 typesCode Quality
warning   Class with no descendant should be sealed if possible
3 typesObject Oriented Design
warning   A stateless class or structure might be turned into a static type
2 typesObject Oriented Design
warning   Non-static classes should be instantiated or turned to static
2 typesObject Oriented Design
warning   Methods should be declared static if possible
26 methodsObject Oriented Design
warning   Avoid namespaces with few types
2 namespacesDesign
warning   Nested types should not be visible
1 typesDesign
warningCritical   Potentially dead Methods
1 methodsDead Code
warning   Methods that could have a lower visibility
33 methodsVisibility
warning   Types that could have a lower visibility
2 typesVisibility
warning   Instance fields should be prefixed with a 'm_'
5 fieldsNaming Conventions
warning   Methods name should begin with an Upper character
1 methodsNaming Conventions
warning   Avoid methods with name too long
1 methodsNaming Conventions
warning   Namespace name should correspond to file location
3 typesSource Files Organization
warning   Mark assemblies with CLSCompliant
2 assembliesSystem
warning   Mark assemblies with ComVisible
1 assembliesSystem
warning   Remove calls to GC.Collect()
1 methodsSystem

Application Statistics

Stat # Occurences Avg StdDev Max
Properties on interfaces interfaces 00-1 properties on
Methods on interfaces interfaces 00-1 methods on
Arguments on methods on interfaces methods 00-1 arguments on
Public properties on classes 6 Classes 0.831.865 public properties on Mathos.Parser.MathParser
Public methods on classes 6 classes 99.8729 public methods on MathosTest.MathParserTest
Arguments on public methods on classes 54 methods 0.350.723 arguments on Mathos.Parser.MathParser..ctor(Boolean,Boolean,Boolean)
IL instructions in non-abstract methods 98 methods 35.5882.27619 IL instructions in Mathos.Parser.MathParser..ctor(Boolean,Boolean,Boolean)
Cyclomatic complexity on non abstract Methods 98 Methods 2.646.09 CC = 43 for Mathos.Parser.MathParser.Scanner(String)

Assemblies Metrics

If you wish to define thresholds on assemblies' Code Metrics, consider writing some Rules.
Clicking column header arrows sorts values.
Clicking column header title text redirect to the online Code Metric definition.
Assemblies # lines of code# IL instruction # Types # Abstract Types # lines of comment% Comment% CoverageAfferent CouplingEfferent CouplingRelational CohesionInstabilityAbstractnessDistance
MathosParserTests v1.0.0.01691229507731-0271100
MathParser v1.0.9.123622581017041-43110.8900.08

If you wish to define thresholds on types' Code Metrics, consider writing some Rule.
Clicking column header arrows sorts values.
Clicking column header title text redirect to the online Code Metric definition.

Types Metrics : Code Quality

Type Name Type Rank# Lines Of Code# IL Instructions# Lines Of Comment% CommentCyclomatic ComplexityIL Cyclomatic Complexity% CoverageAfferent CouplingEfferent Coupling Type Namespace
MathParser4.44236225814337.73116186-431Mathos.Parser
MathParserTest+BenchmarkUtil0.4516660036-110MathosTest
MathParserTest+<>c__DisplayClass140.45216---3-17MathosTest
MathParserTest+<>c__DisplayClass190.45324---4-17MathosTest
MathParserTest+<>c__DisplayClass1c0.45110---2-16MathosTest
MathParserTest0.1514711136028.994558-029MathosTest


  

Types Metrics : Code Members and Inheritance

Type Name # Instance Methods Nb Static Methods Nb Properties # Fields# Children ClassesDepth Of Inheritance Tree Type Namespace
MathParser183153601Mathos.Parser
MathParserTest+BenchmarkUtil110001MathosTest
MathParserTest+<>c__DisplayClass14300201MathosTest
MathParserTest+<>c__DisplayClass19400301MathosTest
MathParserTest+<>c__DisplayClass1c200201MathosTest
MathParserTest3080801MathosTest


  

Types Metrics : Lack Of Cohesion Of Methods and Association Between Classes

Type Name Lack Of Cohesion Of MethodsLack Of Cohesion Of Methods HSAssociation Between Classes Type Namespace
MathParser0.840.8987Mathos.Parser
MathParserTest+BenchmarkUtil008MathosTest
MathParserTest+<>c__DisplayClass14003MathosTest
MathParserTest+<>c__DisplayClass19004MathosTest
MathParserTest+<>c__DisplayClass1c002MathosTest
MathParserTest0058MathosTest

Namespaces Metrics

If you wish to define thresholds on namespaces' Code Metrics, consider writing some Code Rules.
Clicking column header arrows sorts values.
Clicking column header title text redirect to the online Code Metric definition.
Namespaces # lines of code# IL instruction # Types # lines of comment% Comment% CoverageAfferent CouplingEfferent Coupling
MathosTest169122956026-07
Mathos.Parser2362258114738-17

571
Code Quality  

warningCritical    Critical Rule warning: Methods too complex - critical
// <Name>Methods too complex - critical</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  
m.ILCyclomaticComplexity > 40 && 
  
m.ILNestingDepth > 5
  
orderby m.ILCyclomaticComplexity descending,
          
m.ILNestingDepth descending
select new { m, m.ILCyclomaticComplexity, m.ILNestingDepth }

// Methods with ILCyclomaticComplexity > 40 and ILNestingDepth  > 4
// are really too complex and should be split 
// in smaller methods, or even types.
// See the definition of the ILCyclomaticComplexity metric here 
// http://www.ndepend.com/Metrics.aspx#ILCC
// See the definition of the ILNestingDepth metric here 
// http://www.NDepend.com/Metrics.aspx#ILNestingDepth

1 methods matched

methodIL Cyclomatic Complexity (ILCC)IL Nesting DepthFull Name
Scanner(String)437Mathos.Parser.MathParser.Scanner(String)

Statistics

Stat   IL Cyclomatic Complexity (ILCC)   IL Nesting Depth
Sum:437
Average:437
Minimum:437
Maximum:437
Standard deviation:00
Variance:00
warning    Rule warning: Quick summary of methods to refactor
// <Name>Quick summary of methods to refactor</Name>
warnif count > 0 from m in JustMyCode.Methods where 
                                    
// Code Metrics' definitions
  m.NbLinesOfCode > 30 ||           // http://www.ndepend.com/Metrics.aspx#NbLinesOfCode
  // We've commented # IL Instructions, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions.
  // m.NbILInstructions > 200 ||       // http://www.ndepend.com/Metrics.aspx#NbILInstructions
  m.CyclomaticComplexity > 20 ||    // http://www.ndepend.com/Metrics.aspx#CC
  m.ILCyclomaticComplexity > 50 ||  // http://www.ndepend.com/Metrics.aspx#ILCC
  m.ILNestingDepth > 5 ||           // http://www.ndepend.com/Metrics.aspx#ILNestingDepth
  m.NbParameters > 5 ||             // http://www.ndepend.com/Metrics.aspx#NbParameters
  m.NbVariables > 8 ||              // http://www.ndepend.com/Metrics.aspx#NbVariables
  m.NbOverloads > 6                 // http://www.ndepend.com/Metrics.aspx#NbOverloads

select new { m, m.NbLinesOfCode, m.NbILInstructions, m.CyclomaticComplexity, 
             
m.ILCyclomaticComplexity, m.ILNestingDepth, 
             
m.NbParameters, m.NbVariables, m.NbOverloads } 

3 methods matched

methods# lines of code (LOC)# IL instructionsCyclomatic Complexity (CC)IL Cyclomatic Complexity (ILCC)IL Nesting Depth# Parameters# Variables# OverloadsFull Name
.ctor(Boolean,Boolean,Boolean)616194352301Mathos.Parser.MathParser..ctor(Boolean ,Boolean,Boolean)
Scanner(String)4039630437141Mathos.Parser.MathParser.Scanner(String)
MathParserLogic(List<String>)3933014245191Mathos.Parser.MathParser.MathParserLogic (List<String>)

Statistics

Stat   # lines of code (LOC)   # IL instructions   Cyclomatic Complexity (CC)   IL Cyclomatic Complexity (ILCC)   IL Nesting Depth   # Parameters   # Variables   # Overloads
Sum:1401 34548102145133
Average:46.67448.3316344.671.674.331
Minimum:393304242101
Maximum:6161930437391
Standard deviation:10.14123.6510.717.792.050.943.680
Variance:102.8915 289114.6760.674.220.8913.560
warning    Rule warning: Methods too big
// <Name>Methods too big</Name>
warnif count > 0 from m in JustMyCode.Methods where 
   
m.NbLinesOfCode > 30
   
// We've commented # IL Instructions, because with LINQ syntax, a few lines of code can compile to hundreds of IL instructions.
   // || m.NbILInstructions > 200
   orderby m.NbLinesOfCode descending,
           
m.NbILInstructions descending
select new { m, m.NbLinesOfCode, m.NbILInstructions }

// Methods where NbLinesOfCode > 30 or NbILInstructions > 200
// are extremely complex and should be split in smaller methods.
// See the definition of the NbLinesOfCode metric here 
// http://www.ndepend.com/Metrics.aspx#NbLinesOfCode

3 methods matched

methods# lines of code (LOC)# IL instructionsFull Name
.ctor(Boolean,Boolean,Boolean)61619Mathos.Parser.MathParser..ctor(Boolean ,Boolean,Boolean)
Scanner(String)40396Mathos.Parser.MathParser.Scanner(String)
MathParserLogic(List<String>)39330Mathos.Parser.MathParser.MathParserLogic (List<String>)

Statistics

Stat   # lines of code (LOC)   # IL instructions
Sum:1401 345
Average:46.67448.33
Minimum:39330
Maximum:61619
Standard deviation:10.14123.65
Variance:102.8915 289
warning    Rule warning: Methods too complex
// <Name>Methods too complex</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  
m.CyclomaticComplexity > 20 ||
  
m.ILCyclomaticComplexity > 40 ||
  
m.ILNestingDepth > 5
  
orderby m.CyclomaticComplexity descending,
          
m.ILCyclomaticComplexity descending,
          
m.ILNestingDepth descending
select new { m, m.CyclomaticComplexity, 
                
m.ILCyclomaticComplexity,
                
m.ILNestingDepth  }

// Methods where CyclomaticComplexity > 20 
// or ILCyclomaticComplexity > 40
// or ILNestingDepth > 4
// are hard to understand and maintain
// and should be split in smaller methods.
// See the definition of the complexity metrics here:
// http://www.ndepend.com/Metrics.aspx#CC
// http://www.ndepend.com/Metrics.aspx#ILCC
// http://www.NDepend.com/Metrics.aspx#ILNestingDepth

1 methods matched

methodCyclomatic Complexity (CC)IL Cyclomatic Complexity (ILCC)IL Nesting DepthFull Name
Scanner(String)30437Mathos.Parser.MathParser.Scanner(String)

Statistics

Stat   Cyclomatic Complexity (CC)   IL Cyclomatic Complexity (ILCC)   IL Nesting Depth
Sum:30437
Average:30437
Minimum:30437
Maximum:30437
Standard deviation:000
Variance:000
warning    Rule warning: Methods potentially poorly commented
// <Name>Methods potentially poorly commented</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  
m.PercentageComment < 20 && 
  
m.NbLinesOfCode > 20  
  
orderby m.PercentageComment ascending
select new { m, m.PercentageComment, m.NbLinesOfCode, m.NbLinesOfComment }

// Methods where %Comment < 20 and that have 
// at least 20 lines of code might need to be more commented.
// See the definition of the Comments metric here 
// http://www.ndepend.com/Metrics.aspx#PercentageComment
// http://www.ndepend.com/Metrics.aspx#NbLinesOfComment 

1 methods matched

methodPercentage Comment# lines of code (LOC)# lines of commentFull Name
ProgrammaticallyParse(String,Boolean ,Boolean)12284Mathos.Parser.MathParser .ProgrammaticallyParse(String,Boolean ,Boolean)

Statistics

Stat   Percentage Comment   # lines of code (LOC)   # lines of comment
Sum:12284
Average:12284
Minimum:12284
Maximum:12284
Standard deviation:000
Variance:000
warning    Rule warning: Types with too many methods
// <Name>Types with too many methods</Name>
warnif count > 0 from t in JustMyCode.Types 

  
// Optimization: Fast discard of non-relevant types 
  where t.Methods.Count() > 20

  
// Don't match these methods
  let methods = t.Methods.Where(
       
m => !(m.IsConstructor || m.IsClassConstructor ||
              
m.IsGeneratedByCompiler ||
              
m.IsPropertyGetter || m.IsPropertySetter ||
              
m.IsEventAdder || m.IsEventRemover))

  
where methods.Count() > 20 
  
orderby methods.Count() descending
select new { t, 
             
nbMethods = methods.Count(),
             
instanceMethods = methods.Where(m => !m.IsStatic), 
             
staticMethods = methods.Where(m => m.IsStatic)}

// Types where number of methods is greater than 20 
// might be hard to understand and maintain 
// but there might be cases where it is relevant 
// to have a high number of methods. 
// For example, the System.Windows.Forms.DataGridView 
// standard class has more than 1000 methods.

1 types matched

typenbMethodsinstanceMethodsstaticMethodsFull Name
MathParserTest2929 methods0 methodMathosTest.MathParserTest

Statistics

Stat   nbMethods   instanceMethods   staticMethods
Sum:2900
Average:2900
Minimum:2900
Maximum:2900
Standard deviation:000
Variance:000
warning    Rule warning: Types with too many fields
// <Name>Types with too many fields</Name>
warnif count > 0 from t in JustMyCode.Types where 
  
t.Fields.Count() > 20 && 
  
!t.IsEnumeration 
  
orderby t.Fields.Count() descending
select new { t, t.InstanceFields, t.StaticFields, t.SizeOfInst }

// Types where Fields.Count() > 20 and not IsEnumeration 
// might be hard to understand and maintain 
// but there might be cases where it is relevant 
// to have a high number of fields. 
// For example, the System.Windows.Forms.Control 
// standard class has more than 200 fields.

1 types matched

typeInstanceFieldsStaticFieldsSize of instanceFull Name
MathParser5 fields31 fields20Mathos.Parser.MathParser

Statistics

Stat   InstanceFields   StaticFields   Size of instance
Sum:0020
Average:0020
Minimum:0020
Maximum:0020
Standard deviation:000
Variance:000
warning    Rule warning: Types with poor cohesion
// <Name>Types with poor cohesion</Name>
warnif count > 0 from t in JustMyCode.Types where 
  
(t.LCOM > 0.8 || t.LCOMHS > 0.95) && 
  
t.NbFields > 10 && 
  
t.NbMethods >10 
  
orderby t.LCOM descending, t.LCOMHS descending
select new { t, t.LCOM, t.LCOMHS, 
                
t.NbMethods, t.NbFields }

// Types where LCOM > 0.8 and NbFields > 10 
// and NbMethods >10 might be problematic. 
// However, it is very hard to avoid such 
// non-cohesive types. The LCOMHS metric
// is often considered as more efficient to 
// detect non-cohesive types.
// See the definition of the LCOM metric here 
// http://www.ndepend.com/Metrics.aspx#LCOM

1 types matched

typeLack of Cohesion Of Methods (LCOM)LCOM Henderson-Sellers (LCOMHS)# Methods# FieldsFull Name
MathParser0.840.894936Mathos.Parser.MathParser

Statistics

Stat   Lack of Cohesion Of Methods (LCOM)   LCOM Henderson-Sellers (LCOMHS)   # Methods   # Fields
Sum:0.840.894936
Average:0.840.894936
Minimum:0.840.894936
Maximum:0.840.894936
Standard deviation:0000
Variance:0000

940
Object Oriented Design  

warning    Rule warning: Class with no descendant should be sealed if possible
// <Name>Class with no descendant should be sealed if possible</Name>
warnif count > 0 from t in JustMyCode.Types where 
  
t.IsClass && 
  
t.NbChildren ==0 && 
 
!t.IsSealed && 
 
!t.IsStatic 
  
// && !t.IsPublic <-- You might want to add this condition 
  //                    if you are developing a framework
  //                    with classes that are intended to be 
  //                    sub-classed by your clients.
  orderby t.NbLinesOfCode descending
select new { t, t.NbLinesOfCode }

3 types matched

types# lines of code (LOC)Full Name
MathParser236Mathos.Parser.MathParser
MathParserTest147MathosTest.MathParserTest
MathParserTest+BenchmarkUtil16MathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat   # lines of code (LOC)
Sum:399
Average:133
Minimum:16
Maximum:236
Standard deviation:90.36
Variance:8 164
warning    Rule warning: A stateless class or structure might be turned into a static type
// <Name>A stateless class or structure might be turned into a static type</Name>
// This rule indicates stateless types that might 
// eventually be turned into static classes.
warnif count > 0 from t in JustMyCode.Types where
  
!t.IsStatic &&                  
  
!t.IsGeneric &&
   
t.InstanceFields.Count() == 0 &&

   
// Don't match:
   // --> types that implement some interfaces.
   t.NbInterfacesImplemented == 0 &&

   
// --> or classes that have sub-classes children.                            
   t.NbChildren == 0 &&

   
// --> or classes that have a base class
   ((t.IsClass && t.DepthOfDeriveFrom("System.Object".AllowNoMatch()) == 1) ||
     
t.IsStructure) 

   
select t  

2 types matched

typesFull Name
MathParserTestMathosTest.MathParserTest
MathParserTest+BenchmarkUtilMathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat
Sum:
Average:
Minimum:
Maximum:
Standard deviation:
Variance:
warning    Rule warning: Non-static classes should be instantiated or turned to static
// <Name>Non-static classes should be instantiated or turned to static</Name>
// Notice that classes only instantiated through reflection, like plug-in root classes
// are matched by this rules.
warnif count > 0
from t in JustMyCode.Types
where  t.IsClass &&
    
//!t.IsPublic &&   // if you are developing a framework, 
                       // you might not want to match public classes
      !t.IsStatic && 
      
!t.IsAttributeClass && // Attributes class are never seen as instantiated
      !t.DeriveFrom("System.MarshalByRefObject".AllowNoMatch()) // Types instantiated through remoting infrastructure
       
// find the first constructor of t called
let ctorCalled = t.Constructors.FirstOrDefault(ctor => ctor.NbMethodsCallingMe > 0)

// match t if none of its constructors is called.
where ctorCalled == null
select new { t, t.Visibility }

2 types matched

typesVisibilityFull Name
MathParserTestPublicMathosTest.MathParserTest
MathParserTest+BenchmarkUtilPublicMathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat   Visibility
Sum:0
Average:0
Minimum:0
Maximum:0
Standard deviation:0
Variance:0
warning    Rule warning: Methods should be declared static if possible
// <Name>Methods should be declared static if possible</Name>
warnif count > 0

// When an instance method can be safely declared as static you should declare it as static.
// Since it doesn't use any instance data and method of its type and base-types,
// you should consider if such a method could be moved to a static utility class
// or if it is strongly related enough to its current declaring type to stay in it.
//
// Turning an instance method into a static method is a micro performance optimization
// since a static method is a bit cheaper to invoke than an instance method.

from t in JustMyCode.Types.Where(t =>
   
!t.IsStatic && !t.IsInterface &&
   
!t.IsEnumeration && !t.IsDelegate &&
   
!t.IsGeneratedByCompiler)

let methodsThatCanBeMadeStatic = 
   
from m in t.InstanceMethods

   
// An instance method can be turned to static if it is not virtual, 
   // not using the this reference and also, not using
   // any of its class or base classes instance fields or instance methods.
   where !m.IsAbstract && !m.IsVirtual &&
         
!m.AccessThis && !m.IsExplicitInterfaceImpl &&

          
// Optimization: Using FirstOrDefault() avoid to check all members, 
          //               as soon as one member is found
          //               we know the method m cannot be made static.
          m.MembersUsed.FirstOrDefault(
              
mUsed => !mUsed.IsStatic && 
                       
(mUsed.ParentType == t || 
                        
t.DeriveFrom(mUsed.ParentType))
          
) == null 
   
select m

from m in methodsThatCanBeMadeStatic
let staticFieldsUsed = m.ParentType.StaticFields.UsedBy(m).Where(f => !f.IsGeneratedByCompiler)
select new { m, staticFieldsUsed }

26 methods matched

methodsstaticFieldsUsedFull Name
BasicArithmetics()0 fieldMathosTest.MathParserTest .BasicArithmetics()
AdvancedArithmetics()0 fieldMathosTest.MathParserTest .AdvancedArithmetics()
ConditionStatements()0 fieldMathosTest.MathParserTest .ConditionStatements()
ProgrmaticallyAddVariables()0 fieldMathosTest.MathParserTest .ProgrmaticallyAddVariables()
NumberTimesTwoCustomFunction(Decimal[])0 fieldMathosTest.MathParserTest .NumberTimesTwoCustomFunction(Decimal[])
CustomFunctionsWithSeverelArguments()0 fieldMathosTest.MathParserTest .CustomFunctionsWithSeverelArguments()
NegativeNumbers()0 fieldMathosTest.MathParserTest .NegativeNumbers()
Trigemoetry()0 fieldMathosTest.MathParserTest.Trigemoetry()
CustomizeOperators()0 fieldMathosTest.MathParserTest .CustomizeOperators()
DecimalOperations()0 fieldMathosTest.MathParserTest .DecimalOperations()
DifferentCultures()0 fieldMathosTest.MathParserTest .DifferentCultures()
funcs(Decimal[])0 fieldMathosTest.MathParserTest.funcs (Decimal[])
ExecutionTime()0 fieldMathosTest.MathParserTest.ExecutionTime( )
BuiltInFunctions()0 fieldMathosTest.MathParserTest .BuiltInFunctions()
ExceptionCatching()0 fieldMathosTest.MathParserTest .ExceptionCatching()
StrangeStuff()0 fieldMathosTest.MathParserTest.StrangeStuff()
TestLongExpression()0 fieldMathosTest.MathParserTest .TestLongExpression()
TestSpeedRegExVsStringReplce()0 fieldMathosTest.MathParserTest .TestSpeedRegExVsStringReplce()
CultureIndepndenceCommaBug()0 fieldMathosTest.MathParserTest .CultureIndepndenceCommaBug()
SpeedTests()0 fieldMathosTest.MathParserTest.SpeedTests()
DetailedSpeedTestWithOptimization()0 fieldMathosTest.MathParserTest .DetailedSpeedTestWithOptimization()
CultureTest()0 fieldMathosTest.MathParserTest.CultureTest()
DetailedSpeedTestWithOutOptimization()0 fieldMathosTest.MathParserTest .DetailedSpeedTestWithOutOptimization()
CommaPIBug()0 fieldMathosTest.MathParserTest.CommaPIBug()
Abs(Decimal)0 fieldMathosTest.MathParserTest.Abs(Decimal)
Correction(String)0 fieldMathos.Parser.MathParser.Correction (String)

Statistics

Stat   staticFieldsUsed
Sum:0
Average:0
Minimum:0
Maximum:0
Standard deviation:0
Variance:0

1220
Design  

warning    Rule warning: Avoid namespaces with few types
// <Name>Avoid namespaces with few types</Name>
warnif count > 0 from n in JustMyCode.Namespaces 
let types = n.ChildTypes.Where(t => !t.IsGeneratedByCompiler)
where 
  
types.Count() < 5 
  
orderby types.Count() ascending
select new { n, types } 

// Make sure that there is a logical organization 
// to each of your namespaces, and that there is a 
// valid reason for putting types in a sparsely 
// populated namespace. Namespaces should contain 
// types that are used together in most scenarios. 
// When their applications are mutually exclusive, 
// types should be located in separate namespaces

2 namespaces matched

namespacestypesFull Name
Mathos.Parser1 typeMathos.Parser
MathosTest2 typesMathosTest

Statistics

Stat   types
Sum:0
Average:0
Minimum:0
Maximum:0
Standard deviation:0
Variance:0
warning    Rule warning: Nested types should not be visible
// <Name>Nested types should not be visible</Name>
warnif count > 0 from t in JustMyCode.Types where 
  
t.IsNested && 
 
!t.IsGeneratedByCompiler &&
 
!t.IsPrivate 
select new { t, t.NbLinesOfCode, t.Visibility } 


// A nested type is a type declared within the 
// scope of another type. Nested types are useful 
// for encapsulating private implementation details 
// of the containing type. Used for this purpose, 
// nested types should not be externally visible. 
// Do not use externally visible nested types for 
// logical grouping or to avoid name collisions; 
// instead, use namespaces.

1 types matched

type# lines of code (LOC)VisibilityFull Name
MathParserTest+BenchmarkUtil16PublicMathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat   # lines of code (LOC)   Visibility
Sum:160
Average:160
Minimum:160
Maximum:160
Standard deviation:00
Variance:00

301
Dead Code  

  • 3 validated Rule(s)
  • 0 Rule(s) violated
  • 1 Rules or Queries with Error (syntax error, exception thrown, time-out)
warningCritical    Critical Rule warning: Potentially dead Methods
// <Name>Potentially dead Methods</Name>
warnif count > 0
// Filter procedure for methods that should'nt be considered as dead
let canMethodBeConsideredAsDeadProc = new Func<IMethod, bool>(
    
m => !m.IsPubliclyVisible &&       // Public methods might be used by client applications of your assemblies.
         !m.IsEntryPoint &&            // Main() method is not used by-design.
         !m.IsExplicitInterfaceImpl && // The IL code never explicitely calls explicit interface methods implementation.
         !m.IsClassConstructor &&      // The IL code never explicitely calls class constructors.
         !m.IsFinalizer &&             // The IL code never explicitely calls finalizers.
         !m.IsVirtual &&               // Only check for non virtual method that are not seen as used in IL.
         !(m.IsConstructor &&          // Don't take account of protected ctor that might be call by a derived ctors.
           m.IsProtected) &&
         
!m.IsEventAdder &&            // The IL code never explicitely calls events adder/remover.
         !m.IsEventRemover &&
         
!m.IsGeneratedByCompiler &&
         
!m.ParentType.IsDelegate &&

         
// Methods tagged with these two attributes are called by the serialization infrastructure.
         !m.HasAttribute("System.Runtime.Serialization.OnSerializingAttribute".AllowNoMatch()) &&
         
!m.HasAttribute("System.Runtime.Serialization.OnDeserializedAttribute".AllowNoMatch()) &&

         
// If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute and adapt this rule.
         !m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()))

// Get methods unused
let methodsUnused = 
   
from m in JustMyCode.Methods where 
   
m.NbMethodsCallingMe == 0 && 
   
canMethodBeConsideredAsDeadProc(m)
   
select m

// Dead methods = methods used only by unused methods (recursive)
let deadMethodsMetric = methodsUnused.FillIterative(
   
methods => // Unique loop, just to let a chance to build the hashset.
              from o in (new object()).ToEnumerable()
              
// Use a hashet to make Intersect calls much faster!
              let hashset = methods.ToHashSet()
              
from m in codeBase.Application.Methods.UsedByAny(methods).Except(methods)
              
where canMethodBeConsideredAsDeadProc(m) &&
                    
// Select methods called only by methods already considered as dead
                    hashset.Intersect(m.MethodsCallingMe).Count() == m.NbMethodsCallingMe
              
select m)

from m in JustMyCode.Methods.Intersect(deadMethodsMetric.DefinitionDomain)
select new { m, m.MethodsCallingMe, depth = deadMethodsMetric[m] }

1 methods matched

methodMethodsCallingMedepthFull Name
funcs(Decimal[])0 method0MathosTest.MathParserTest.funcs (Decimal[])

Statistics

Stat   MethodsCallingMe   depth
Sum:00
Average:00
Minimum:00
Maximum:00
Standard deviation:00
Variance:00

920
Visibility  

warning    Rule warning: Methods that could have a lower visibility
// <Name>Methods that could have a lower visibility</Name>
// This rule tells which methods can be declared with a lower visibility.
// (like 'private' is a visibility lower than 'internal' which is lower than 'public').
// Reducing visibility is a good practice because this fosters encapsulation
// and with it maintainability and extensibility.
        
warnif count > 0 from m in JustMyCode.Methods where 
  
m.Visibility != m.OptimalVisibility &&
  
!m.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
  
!m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
  
// If you don't want to link NDepend.API.dll, you can use your own attributes and adapt this rule.
  
  
// Eliminate default constructor from the result.
  // Whatever the visibility of the declaring class,
  // default constructors are public and introduce noise
  // in the current rule.
  !( m.IsConstructor && m.IsPublic && m.NbParameters == 0) &&

  
// Don't decrease the visibility of Main() methods.
  !m.IsEntryPoint

select new { m, 
             
m.Visibility , 
             
CouldBeDeclared = m.OptimalVisibility,
             
m.MethodsCallingMe }

33 methods matched

methodsVisibilityCouldBeDeclaredMethodsCallingMeFull Name
BasicArithmetics()PublicPrivate0 methodMathosTest.MathParserTest .BasicArithmetics()
AdvancedArithmetics()PublicPrivate0 methodMathosTest.MathParserTest .AdvancedArithmetics()
ConditionStatements()PublicPrivate0 methodMathosTest.MathParserTest .ConditionStatements()
ProgrmaticallyAddVariables()PublicPrivate0 methodMathosTest.MathParserTest .ProgrmaticallyAddVariables()
CustomFunctions()PublicPrivate0 methodMathosTest.MathParserTest .CustomFunctions()
NumberTimesTwoCustomFunction(Decimal[])PublicPrivate1 methodMathosTest.MathParserTest .NumberTimesTwoCustomFunction(Decimal[])
CustomFunctionsWithSeverelArguments()PublicPrivate0 methodMathosTest.MathParserTest .CustomFunctionsWithSeverelArguments()
NegativeNumbers()PublicPrivate0 methodMathosTest.MathParserTest .NegativeNumbers()
Trigemoetry()PublicPrivate0 methodMathosTest.MathParserTest.Trigemoetry()
CustomizeOperators()PublicPrivate0 methodMathosTest.MathParserTest .CustomizeOperators()
DecimalOperations()PublicPrivate0 methodMathosTest.MathParserTest .DecimalOperations()
DifferentCultures()PublicPrivate0 methodMathosTest.MathParserTest .DifferentCultures()
ExecutionTime()PublicPrivate0 methodMathosTest.MathParserTest.ExecutionTime( )
BuiltInFunctions()PublicPrivate0 methodMathosTest.MathParserTest .BuiltInFunctions()
ExceptionCatching()PublicPrivate0 methodMathosTest.MathParserTest .ExceptionCatching()
StrangeStuff()PublicPrivate0 methodMathosTest.MathParserTest.StrangeStuff()
TestLongExpression()PublicPrivate0 methodMathosTest.MathParserTest .TestLongExpression()
TestSpeedRegExVsStringReplce()PublicPrivate0 methodMathosTest.MathParserTest .TestSpeedRegExVsStringReplce()
CultureIndepndenceCommaBug()PublicPrivate0 methodMathosTest.MathParserTest .CultureIndepndenceCommaBug()
SpeedTests()PublicPrivate0 methodMathosTest.MathParserTest.SpeedTests()
DetailedSpeedTestWithOptimization()PublicPrivate0 methodMathosTest.MathParserTest .DetailedSpeedTestWithOptimization()
CultureTest()PublicPrivate0 methodMathosTest.MathParserTest.CultureTest()
DetailedSpeedTestWithOutOptimization()PublicPrivate0 methodMathosTest.MathParserTest .DetailedSpeedTestWithOutOptimization()
CommaPIBug()PublicPrivate0 methodMathosTest.MathParserTest.CommaPIBug()
ComparisonOfExpressions()PublicPrivate0 methodMathosTest.MathParserTest .ComparisonOfExpressions()
ComparisonOfNumericalAnswers()PublicPrivate0 methodMathosTest.MathParserTest .ComparisonOfNumericalAnswers()
CheckErrorBound(Decimal,Decimal)PublicPrivate2 methodsMathosTest.MathParserTest .CheckErrorBound(Decimal,Decimal)
Abs(Decimal)PublicPrivate1 methodMathosTest.MathParserTest.Abs(Decimal)
Benchmark(Action,Int32)PublicInternal3 methodsMathosTest.MathParserTest+BenchmarkUtil .Benchmark(Action,Int32)
get_OperatorList()PublicPrivate3 methodsMathos.Parser.MathParser .get_OperatorList()
set_OperatorAction(Dictionary<String ,Func<Decimal,Decimal,Decimal>>)PublicPrivate0 methodMathos.Parser.MathParser .set_OperatorAction(Dictionary<String ,Func<Decimal,Decimal,Decimal>>)
set_LocalFunctions(Dictionary<String ,Func<Decimal[],Decimal>>)PublicPrivate0 methodMathos.Parser.MathParser .set_LocalFunctions(Dictionary<String ,Func<Decimal[],Decimal>>)
set_LocalVariables(Dictionary<String ,Decimal>)PublicPrivate0 methodMathos.Parser.MathParser .set_LocalVariables(Dictionary<String ,Decimal>)

Statistics

Stat   Visibility   CouldBeDeclared   MethodsCallingMe
Sum:000
Average:000
Minimum:000
Maximum:000
Standard deviation:000
Variance:000
warning    Rule warning: Types that could have a lower visibility
// <Name>Types that could have a lower visibility</Name>
// This rule tells which types can be declared with a lower visibility.
// (like 'private' is a visibility lower than 'internal' which is lower than 'public').
// Reducing visibility is a good practice because this fosters encapsulation
// and with it maintainability and extensibility.
        
warnif count > 0 from t in JustMyCode.Types where 

  
t.Visibility != t.OptimalVisibility &&

  
// If you don't want to link NDepend.API.dll, you can use your own attributes and adapt this rule.
 !t.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
 
!t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&

  
// Static types that define only const fields cannot be seen as used in IL code.
  // They don't have to be tagged with CannotDecreaseVisibilityAttribute.
  !( t.IsStatic && 
    
!t.Methods.Any(m => !m.IsClassConstructor) && 
    
!t.Fields.Any(f => !f.IsLiteral && !(f.IsStatic && f.IsInitOnly))) &&

  
// A type used by an interface that has the same visibility
  // cannot have its visibility decreased, else a compilation error occurs!
  !t.TypesUsingMe.Any(tUser => 
        
tUser.IsInterface && 
        
tUser.Visibility == t.Visibility)

select new { t, t.Visibility , 
                
CouldBeDeclared = t.OptimalVisibility, 
                
t.TypesUsingMe }

2 types matched

typesVisibilityCouldBeDeclaredTypesUsingMeFull Name
MathParserTestPublicInternal0 typeMathosTest.MathParserTest
MathParserTest+BenchmarkUtilPublicPrivate1 typeMathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat   Visibility   CouldBeDeclared   TypesUsingMe
Sum:000
Average:000
Minimum:000
Maximum:000
Standard deviation:000
Variance:000

1430
Naming Conventions  

warning    Rule warning: Instance fields should be prefixed with a 'm_'
// <Name>Instance fields should be prefixed with a 'm_'</Name>
warnif count > 0 from f in Application.Fields where 
  
!f.NameLike (@"^m_") && 
  
!f.IsStatic && 
  
!f.IsLiteral && 
  
!f.IsGeneratedByCompiler  && 
  
!f.IsSpecialName && 
  
!f.IsEventDelegateObject
select new { f, f.SizeOfInst } 

// This naming convention provokes debate.
// Don't hesitate to customize the regex of 
// NameLike to your preference.

5 fields matched

fieldsSize of instanceFull Name
_operatorList4Mathos.Parser.MathParser._operatorList
_operatorAction4Mathos.Parser.MathParser._operatorAction
_localFunctions4Mathos.Parser.MathParser._localFunctions
_localVariables4Mathos.Parser.MathParser._localVariables
_cultureInfo4Mathos.Parser.MathParser._cultureInfo

Statistics

Stat   Size of instance
Sum:20
Average:4
Minimum:4
Maximum:4
Standard deviation:0
Variance:0
warning    Rule warning: Methods name should begin with an Upper character
// <Name>Methods name should begin with an Upper character</Name>
warnif count > 0 from m in JustMyCode.Methods where 
  
!m.NameLike (@"^[A-Z]") && 
  
!m.IsSpecialName && 
  
!m.IsGeneratedByCompiler
select m

// The name of a regular method should 
// begin with an Upper letter.

1 methods matched

methodFull Name
funcs(Decimal[])MathosTest.MathParserTest.funcs (Decimal[])

Statistics

Stat
Sum:
Average:
Minimum:
Maximum:
Standard deviation:
Variance:
warning    Rule warning: Avoid methods with name too long
// <Name>Avoid methods with name too long</Name>
warnif count > 0 from m in Application.Methods where 
 
!m.IsExplicitInterfaceImpl &&
 
!m.IsGeneratedByCompiler &&
 
((!m.IsSpecialName && m.SimpleName.Length > 35) ||
   
// Property getter/setter are prefixed with "get_" "set_" of length 4.
  ( m.IsSpecialName && m.SimpleName.Length - 4 > 35))

select new { m, m.SimpleName }

// The regex matches methods with name longer 
// than 35 characters.
// Method Name doesn't contain the type and namespace 
// prefix, FullName does.
// The regex computes the method name length from 
// the beginning until the first open parenthesis 
// or first lower than (for generic methods).
// Explicit Interface Implementation methods are 
// discarded because their names are prefixed 
// with the interface name.
      

1 methods matched

methodSimpleNameFull Name
DetailedSpeedTestWithOutOptimization()DetailedSpeedTestWithOutOptimizationMathosTest.MathParserTest .DetailedSpeedTestWithOutOptimization()

Statistics

Stat   SimpleName
Sum:0
Average:0
Minimum:0
Maximum:0
Standard deviation:0
Variance:0

510
Source Files Organization  

warning    Rule warning: Namespace name should correspond to file location
// <Name>Namespace name should correspond to file location</Name>

// For a good code organization, 
// do mirror the namespaces hierarchy and the source files directories tree.

warnif count > 0
from n in Application.Namespaces 

// Replace dots by spaces in namespace name
let dirCorresponding = n.Name.Replace('.', ' ')

// Look at source file decl of JustMyCode type's declared in n
from t in n.ChildTypes
where JustMyCode.Contains(t) && t.SourceFileDeclAvailable
from decl in t.SourceDecls
let sourceFilePath = decl.SourceFile.FilePath.ToString()

// Replace dots and path separators by spaces in source files names
where !sourceFilePath.Replace('.',' ').Replace('\\',' ').Contains(dirCorresponding)

select new { t, dirCorresponding , sourceFilePath  } 

3 types matched

typesdirCorrespondingsourceFilePathFull Name
MathParserTestMathosTestc:\Users\Artem Los\Documents\sss\mathosparser\MathosParser\MathosParserTests\UnitTest1.csMathosTest.MathParserTest
MathParserTest+BenchmarkUtilMathosTestc:\Users\Artem Los\Documents\sss\mathosparser\MathosParser\MathosParserTests\UnitTest1.csMathosTest.MathParserTest+BenchmarkUtil
MathParserMathos Parserc:\Users\Artem Los\Documents\sss\mathosparser\MathosParser\MathosParser\MathParser.csMathos.Parser.MathParser

Statistics

Stat   dirCorresponding   sourceFilePath
Sum:00
Average:00
Minimum:00
Maximum:00
Standard deviation:00
Variance:00

3030This group contains children groups
.NET Framework Usage  

  • 30 validated Rule(s)
  • 3 Rule(s) violated
  • 0 Rules or Queries with Error (syntax error, exception thrown, time-out)

1030
System  

warning    Rule warning: Mark assemblies with CLSCompliant
// <Name>Mark assemblies with CLSCompliant</Name>
warnif count > 0 from a in Application.Assemblies where 
  
!a.HasAttribute ("System.CLSCompliantAttribute".AllowNoMatch())
select a

// The Common Language Specification (CLS) defines 
// naming restrictions, data types, and rules to which 
// assemblies must conform if they are to be used 
// across programming languages. Good design dictates 
// that all assemblies explicitly indicate CLS 
// compliance with CLSCompliantAttribute. If the 
// attribute is not present on an assembly, the 
// assembly is not compliant.

2 assemblies matched

assembliesFull Name
MathosParserTestsMathosParserTests
MathParserMathParser

Statistics

Stat
Sum:
Average:
Minimum:
Maximum:
Standard deviation:
Variance:
warning    Rule warning: Mark assemblies with ComVisible
// <Name>Mark assemblies with ComVisible</Name>
warnif count > 0 from a in Application.Assemblies where 
  
!a.HasAttribute ("System.Runtime.InteropServices.ComVisibleAttribute".AllowNoMatch())
select a

// The ComVisibleAttribute attribute determines 
// how COM clients access managed code. Good design 
// dictates that assemblies explicitly indicate 
// COM visibility. COM visibility can be set for 
// an entire assembly and then overridden for 
// individual types and type members. If the 
// attribute is not present, the contents of 
// the assembly are visible to COM clients.

1 assemblies matched

assemblyFull Name
MathParserMathParser

Statistics

Stat
Sum:
Average:
Minimum:
Maximum:
Standard deviation:
Variance:
warning    Rule warning: Remove calls to GC.Collect()
// <Name>Remove calls to GC.Collect()</Name>
warnif count > 0 

let gcCollectMethods = ThirdParty.Methods.WithFullNameIn(
   
"System.GC.Collect()",
   
"System.GC.Collect(Int32)",
   
"System.GC.Collect(Int32,GCCollectionMode)")

from m in Application.Methods.UsingAny(gcCollectMethods)
select m

// It is preferrable to avoid calling GC.Collect() 
// explicitely in order to avoid some performance pitfall.
// More in information on this here:
// http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx

1 methods matched

methodFull Name
Benchmark(Action,Int32)MathosTest.MathParserTest+BenchmarkUtil .Benchmark(Action,Int32)

Statistics

Stat
Sum:
Average:
Minimum:
Maximum:
Standard deviation:
Variance:

Object Oriented Design

ok   Base class should not use derivatives
// <Name>Base class should not use derivatives</Name>
warnif count > 0 
from baseClass in JustMyCode.Types
where baseClass.IsClass && baseClass.NbChildren > 0 // <-- for optimization!
let derivedClassesUsed = baseClass.DerivedTypes.UsedBy(baseClass)
where derivedClassesUsed.Count() > 0
select new { baseClass, derivedClassesUsed }

No types matched

ok   Class shouldn't be too deep in inheritance tree
// <Name>Class shouldn't be too deep in inheritance tree</Name>
warnif count > 0 from t in JustMyCode.Types 
where t.IsClass
let baseClasses = t.BaseClasses.ExceptThirdParty()

// Warn for classes with 3 or more base classes.
// Notice that we don't count third-party classes 
// because this rule concerns your code design,
// not third-party libraries consumed design.
where baseClasses.Count() >= 3

select new { t, baseClasses, 
                
// The metric value DepthOfInheritance takes account
                // of third-party base classes
                t.DepthOfInheritance } 

// Branches too long in the derivation should be avoided.
// See the definition of the DepthOfInheritance metric here 
// http://www.ndepend.com/Metrics.aspx#DIT

No types matched

warning    Rule warning: Class with no descendant should be sealed if possible
// <Name>Class with no descendant should be sealed if possible</Name>
warnif count > 0 from t in JustMyCode.Types where 
  
t.IsClass && 
  
t.NbChildren ==0 && 
 
!t.IsSealed && 
 
!t.IsStatic 
  
// && !t.IsPublic <-- You might want to add this condition 
  //                    if you are developing a framework
  //                    with classes that are intended to be 
  //                    sub-classed by your clients.
  orderby t.NbLinesOfCode descending
select new { t, t.NbLinesOfCode }

3 types matched

types# lines of code (LOC)Full Name
MathParser236Mathos.Parser.MathParser
MathParserTest147MathosTest.MathParserTest
MathParserTest+BenchmarkUtil16MathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat   # lines of code (LOC)
Sum:399
Average:133
Minimum:16
Maximum:236
Standard deviation:90.36
Variance:8 164
ok   Overrides of Method() should call base.Method()
// <Name>Overrides of Method() should call base.Method()</Name>
// Overrides of Method() should refine the behavior of base.Method().
// If base.Method() is not called, the base behavior is not refined but it is replaced.
// Violations of this rule are a sign of design flaw,
// especially if the design provides valid reasons 
// that advocates that the base behavior must be replaced and not refined.
//
// Discussions on this topic are available here:
//  http://stackoverflow.com/questions/1107022/should-i-call-the-base-class-implementation-when-overriding-a-method-in-c-sharp
//  http://stackoverflow.com/questions/2945147/make-sure-base-method-gets-called-in-c-sharp

warnif count > 0
from t in Types  // Take account of third-party types too

// Bother only classes with descendant
where t.IsClass && t.NbChildren > 0

from mBase in t.InstanceMethods
where  mBase.IsVirtual &&
      
!mBase.IsThirdParty &&
      
!mBase.IsAbstract && 
      
!mBase.IsExplicitInterfaceImpl
from mOverride in mBase.OverridesDirectDerived
where !mOverride.IsUsing(mBase)
select new { mOverride, shouldCall = mBase, definedInBaseClass = mBase.ParentType }

No methods matched

ok   Do not hide base class methods
// <Name>Do not hide base class methods</Name>
// To fix a violation of this rule, remove or rename the method, or change the parameter signature 
// so that the method does not hide the base method.

// More on hiding vs. virtual usefulness here:
//  http://www.artima.com/intv/nonvirtual.html
//  http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx

warnif count > 0

// Define a lookup table indexing methods by their name including parameters signature.
let lookup = Methods.Where(m => !m.IsConstructor && !m.IsStatic && !m.IsGeneratedByCompiler)
                    
.ToLookup(m1 => m1.Name)

from t in Application.Types
where !t.IsStatic && t.IsClass &&
   
// Discard classes deriving directly from System.Object
   t.DepthOfInheritance > 1 
where t.BaseClasses.Any()

// For each methods not overriding any methods (new slot), 
// let's check if it hides by name some methods defined in base classe.
from m in t.InstanceMethods
where m.IsNewSlot && !m.IsExplicitInterfaceImpl && !m.IsGeneratedByCompiler

// Notice how lookup is used to quickly retrieve methods with same name as m.
// This makes the query 10 times faster than iterating each base methods to check their name.
let baseMethodsHidden = lookup[m.Name].Where(m1 => m1 != m && t.DeriveFrom(m1.ParentType))

where baseMethodsHidden.Count() > 0
select new { m, baseMethodsHidden }

No methods matched

warning    Rule warning: A stateless class or structure might be turned into a static type
// <Name>A stateless class or structure might be turned into a static type</Name>
// This rule indicates stateless types that might 
// eventually be turned into static classes.
warnif count > 0 from t in JustMyCode.Types where
  
!t.IsStatic &&                  
  
!t.IsGeneric &&
   
t.InstanceFields.Count() == 0 &&

   
// Don't match:
   // --> types that implement some interfaces.
   t.NbInterfacesImplemented == 0 &&

   
// --> or classes that have sub-classes children.                            
   t.NbChildren == 0 &&

   
// --> or classes that have a base class
   ((t.IsClass && t.DepthOfDeriveFrom("System.Object".AllowNoMatch()) == 1) ||
     
t.IsStructure) 

   
select t  

2 types matched

typesFull Name
MathParserTestMathosTest.MathParserTest
MathParserTest+BenchmarkUtilMathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat
Sum:
Average:
Minimum:
Maximum:
Standard deviation:
Variance:
warning    Rule warning: Non-static classes should be instantiated or turned to static
// <Name>Non-static classes should be instantiated or turned to static</Name>
// Notice that classes only instantiated through reflection, like plug-in root classes
// are matched by this rules.
warnif count > 0
from t in JustMyCode.Types
where  t.IsClass &&
    
//!t.IsPublic &&   // if you are developing a framework, 
                       // you might not want to match public classes
      !t.IsStatic && 
      
!t.IsAttributeClass && // Attributes class are never seen as instantiated
      !t.DeriveFrom("System.MarshalByRefObject".AllowNoMatch()) // Types instantiated through remoting infrastructure
       
// find the first constructor of t called
let ctorCalled = t.Constructors.FirstOrDefault(ctor => ctor.NbMethodsCallingMe > 0)

// match t if none of its constructors is called.
where ctorCalled == null
select new { t, t.Visibility }

2 types matched

typesVisibilityFull Name
MathParserTestPublicMathosTest.MathParserTest
MathParserTest+BenchmarkUtilPublicMathosTest.MathParserTest+BenchmarkUtil

Statistics

Stat   Visibility
Sum:0
Average:0
Minimum:0
Maximum:0
Standard deviation:0
Variance:0
warning    Rule warning: Methods should be declared static if possible
// <Name>Methods should be declared static if possible</Name>
warnif count > 0

// When an instance method can be safely declared as static you should declare it as static.
// Since it doesn't use any instance data and method of its type and base-types,
// you should consider if such a method could be moved to a static utility class
// or if it is strongly related enough to its current declaring type to stay in it.
//
// Turning an instance method into a static method is a micro performance optimization
// since a static method is a bit cheaper to invoke than an instance method.

from t in JustMyCode.Types.Where(t =>
   
!t.IsStatic && !t.IsInterface &&
   
!t.IsEnumeration && !t.IsDelegate &&
   
!t.IsGeneratedByCompiler)

let methodsThatCanBeMadeStatic = 
   
from m in t.InstanceMethods

   
// An instance method can be turned to static if it is not virtual, 
   // not using the this reference and also, not using
   // any of its class or base classes instance fields or instance methods.
   where !m.IsAbstract && !m.IsVirtual &&
         
!m.AccessThis && !m.IsExplicitInterfaceImpl &&

          
// Optimization: Using FirstOrDefault() avoid to check all members, 
          //               as soon as one member is found
          //               we know the method m cannot be made static.
          m.MembersUsed.FirstOrDefault(
              
mUsed => !mUsed.IsStatic && 
                       
(mUsed.ParentType == t || 
                        
t.DeriveFrom(mUsed.ParentType))
          
) == null 
   
select m

from m in methodsThatCanBeMadeStatic
let staticFieldsUsed = m.ParentType.StaticFields.UsedBy(m).Where(f => !f.IsGeneratedByCompiler)
select new { m, staticFieldsUsed }

26 methods matched

methodsstaticFieldsUsedFull Name
BasicArithmetics()0 fieldMathosTest.MathParserTest .BasicArithmetics()
AdvancedArithmetics()0 fieldMathosTest.MathParserTest .AdvancedArithmetics()
ConditionStatements()0 fieldMathosTest.MathParserTest .ConditionStatements()
ProgrmaticallyAddVariables()0 fieldMathosTest.MathParserTest .ProgrmaticallyAddVariables()
NumberTimesTwoCustomFunction(Decimal[])0 fieldMathosTest.MathParserTest .NumberTimesTwoCustomFunction(Decimal[])
CustomFunctionsWithSeverelArguments()0 fieldMathosTest.MathParserTest .CustomFunctionsWithSeverelArguments()
NegativeNumbers()0 fieldMathosTest.MathParserTest .NegativeNumbers()
Trigemoetry()0 fieldMathosTest.MathParserTest.Trigemoetry()
CustomizeOperators()0 fieldMathosTest.MathParserTest .CustomizeOperators()
DecimalOperations()0 fieldMathosTest.MathParserTest .DecimalOperations()
DifferentCultures()0 fieldMathosTest.MathParserTest .DifferentCultures()
funcs(Decimal[])0 fieldMathosTest.MathParserTest.funcs (Decimal[])
ExecutionTime()0 fieldMathosTest.MathParserTest.ExecutionTime( )
BuiltInFunctions()0 fieldMathosTest.MathParserTest .BuiltInFunctions()
ExceptionCatching()0 fieldMathosTest.MathParserTest .ExceptionCatching()
StrangeStuff()0 fieldMathosTest.MathParserTest.StrangeStuff()
TestLongExpression()0 fieldMathosTest.MathParserTest .TestLongExpression()
TestSpeedRegExVsStringReplce()0 fieldMathosTest.MathParserTest .TestSpeedRegExVsStringReplce()
CultureIndepndenceCommaBug()0 fieldMathosTest.MathParserTest .CultureIndepndenceCommaBug()
SpeedTests()0 fieldMathosTest.MathParserTest.SpeedTests()
DetailedSpeedTestWithOptimization()0 fieldMathosTest.MathParserTest .DetailedSpeedTestWithOptimization()
CultureTest()0 fieldMathosTest.MathParserTest.CultureTest()
DetailedSpeedTestWithOutOptimization()0 fieldMathosTest.MathParserTest .DetailedSpeedTestWithOutOptimization()
CommaPIBug()0 fieldMathosTest.MathParserTest.CommaPIBug()
Abs(Decimal)0 fieldMathosTest.MathParserTest.Abs(Decimal)
Correction(String)0 fieldMathos.Parser.MathParser.Correction (String)

Statistics

Stat   staticFieldsUsed
Sum:0
Average:0
Minimum:0
Maximum:0
Standard deviation:0
Variance:0
ok   Constructor should not call a virtual methods
// <Name>Constructor should not call a virtual methods</Name>

// Returns constructor of a non-sealed type calling virtual methods.
// In such a situation, if a derived class overrides the method,
// then the override method will be called before the derived constructor.
// This makes the class fragile to derive from.
//
// Violations reported can be solved by re-designing object initialisation
// or by marking the parent class as sealed, if possible.

warnif count > 0
from t in Application.Types where 
   
t.IsClass &&
  
!t.IsGeneratedByCompiler &&
  
!t.IsSealed

from ctor in t.Constructors 
let virtualMethodsCalled = from mCalled in ctor.MethodsCalled
                           
where mCalled.IsVirtual &&
                                
(mCalled.ParentType == t ||
                                 
t.DeriveFrom(mCalled.ParentType))
                           
select mCalled
where virtualMethodsCalled.Count() > 0

select new { ctor , 
             
virtualMethodsCalled, 
             
// If there is no derived type, it might be 
             // an opportunity to mark t as sealed.
             t.DerivedTypes }

No methods matched

ok   Avoid the Singleton pattern
//<Name>Avoid the Singleton pattern</Name>
warnif count > 0
from t in Application.Types
where !t.IsStatic && !t.IsAbstract && (t.IsClass || t.IsStructure)

// All ctors of a singleton are private
where t.Constructors.Where(ctor => !ctor.IsPrivate).Count() == 0

// A singleton contains one static field of its parent type, to reference the unique instance
let staticFieldInstances = t.StaticFields.WithFieldType(t)
where staticFieldInstances.Count() == 1
select new { t, staticFieldInstance = staticFieldInstances.First() }

// The Singleton pattern consists in syntactically enforcing that a class 
// has just one unique instance.
// At first glance, this pattern looks appealing and it is widely used.
// However, we discourage you from using singleton classes because experience
// shows that singletons often result in less testable and less maintainable code.
// More details available in these discussions:
//  http://codebetter.com/patricksmacchia/2011/05/04/back-to-basics-usage-of-static-members/
//  http://adamschepis.com/blog/2011/05/02/im-adam-and-im-a-recovering-singleton-addict/

No types matched

ok   Don't assign static fields from instance methods
// <Name>Don't assign static fields from instance methods</Name>
// Assigning static fields from instance methods leads to
// poorly maintainable and non thread-safe code.
// It is advised to assign static fields inline or from class constructor.
warnif count > 0
from f in Application.Fields where 
  
f.IsStatic &&
 
!f.IsLiteral &&
 
!f.IsInitOnly &&
 
!f.IsGeneratedByCompiler &&
  
// Contract API define such a insideContractEvaluation static field
  f.Name != "insideContractEvaluation"
let assignedBy = f.MethodsAssigningMe.Where(m => !m.IsStatic)
where assignedBy .Count() > 0
select new { f, assignedBy }

No fields matched

ok   Avoid empty interfaces
// <Name>Avoid empty interfaces</Name>
warnif count > 0 from t in JustMyCode.Types where 
  
t.IsInterface && 
  
t.NbMethods == 0
select new { t, t.TypesThatImplementMe }

// Interfaces define members that provide a behavior 
// or usage contract. The functionality described by 
// the interface can be adopted by any type, 
// regardless of where the type appears in the 
// inheritance hierarchy. A type implements an 
// interface by providing implementations for the 
// interface's members. An empty interface does not 
// define any members, and as such, does not define 
// a contract that can be implemented.

// If your design includes empty interfaces that 
// types are expected to implement, you are probably 
// using an interface as a marker, or a way of 
// identifying a group of types. If this identification 
// will occur at runtime, the correct way to accomplish
// this is to use a custom attribute. Use the presence 
// or absence of the attribute, or the attribute's 
// properties, to identify the target types. If the 
// identification must occurs at compile time, then using 
// an empty interface is acceptable.

No types matched

ok   Avoid types initialization cycles
// <Name>Avoid types initialization cycles</Name>
warnif count > 0

// The class constructor (also called static constructor, and named cctor in IL code)
// of a type, if any, is executed by the CLR at runtime, the first time the type is used.
// A cctor doesn't need to be explicitely declared in C# or VB.NET, to exist in compiled IL code.
// Having a static field inline initialization is enought to have 
// the cctor implicitely declared in the parent class or structure.
//
// If the cctor of a type t1 is using the type t2 and if the cctor of t2 is using t1,
// some type initialization unexpected and hard-to-diagnose buggy behavior can occur.
// Such a cyclic chain of initialization is not necessarily limited to two types
// and can embrace N types in the general case.
// More information on types initialization cycles can be found here:
// http://msmvps.com/blogs/jon_skeet/archive/2012/04/07/1808561.aspx
 
// The present code rule enumerates types initialization cycles.
// Some false positives can appear if some lambda expressions are defined 
// in cctors or in methods called by cctors. In such situation, this rule
// considers these lambda expressions as executed at type initialization time, 
// while it is not necessarily the case.
 
// Types initialization cycle can only happen between types of an assembly.
from assembly in Application.Assemblies
                
let cctorSuspects = assembly.ChildMethods.Where(
  
m => m.IsClassConstructor &&
       
// Optimization: types involved in a type cycle necessarily don't have type level.
       m.ParentType.Level == null)

where cctorSuspects.Count() > 1
let typesSuspects = cctorSuspects.ParentTypes().ToHashSet()

//
// dicoTmp associates to each type suspect T, a set of types from typesSuspects
// that contains at least a method or a field used directly or indirectly by the cctor of T.
//
let dicoTmp = cctorSuspects.ToDictionary(
    
cctor => cctor.ParentType,
    
cctor => ((IMember)cctor).ToEnumerable().FillIterative(
              
members => from m in members 
                         
from mUsed in (m is IMethod) ? (m as IMethod).MembersUsed : new IMember[0]
                         
where mUsed.ParentAssembly == assembly 
                         
select mUsed)
              
.DefinitionDomain
              
.Select(m => m.ParentType) // Don't need .Distinct() here, because of ToHashSet() below.
              .Except(cctor.ParentType)
              
.Intersect(typesSuspects)
              
.ToHashSet()
) 

//
// dico associates to each type suspect T, the set of types initialized (directly or indirectly)
// by the initialization of T. This second step is needed, because if a cctor of a type T1 
// calls a member of a type T2, not only the cctor of T1 triggers the initialization of T2,
// but also it triggers the initialization of all types that are initialized by T2 initialization.
//
let dico = typesSuspects.Where(t => dicoTmp[t].Count() > 0).ToDictionary(
   
typeSuspect => typeSuspect,
   
typeSuspect => typeSuspect.ToEnumerable().FillIterative(
                         
types => from t in types
                                  
from tUsed in dicoTmp[t]
                                  
select tUsed)
                   
.DefinitionDomain
                   
.Except(typeSuspect)
                   
.ToHashSet()
)


//
// Now that dico is prepared, detect the cctor cycles
//
from t in dico.Keys

   
// Thanks to the work done to build dico, it is now pretty easy
   // to spot types involved in an initialization cyle with t! 
   let usersAndUseds = from tTmp in dico[t]
                       
where dico.ContainsKey(tTmp) && dico[tTmp].Contains(t)
                       
select tTmp
   
where usersAndUseds.Count() > 0
 
   
// Here we've found type(s) both using and used by the suspect type.
   // A cycle involving the type t is found!
   let typeInitCycle = usersAndUseds.Append(t)


   
// Compute methodsCalled and fieldsUsed, useful to explore
   // how a cctor involved in a type initialization cycle, triggers other type initialization.
   let methodsCalledDepth = assembly.ChildMethods.DepthOfIsUsedBy(t.ClassConstructor)
   
let fieldsUsedDepth = assembly.ChildFields.DepthOfIsUsedBy(t.ClassConstructor)

   
let methodsCalled = methodsCalledDepth.DefinitionDomain.OrderBy(m => methodsCalledDepth[m]).ToArray()
   
let fieldsUsed = fieldsUsedDepth.DefinitionDomain.OrderBy(f => fieldsUsedDepth[f]).ToArray()

// Use the tick box to: Group cctors methods By parent types
select new { t.ClassConstructor, 
             
cctorsCycle= typeInitCycle.Select(tTmp => tTmp.ClassConstructor),

             
// methodsCalled and fieldsUsed are members used directly and indirectly by the cctor.
             // Export these members to the dependency graph (right click the cell Export/Append ... to the Graph)
             // and see how the cctor trigger the initialization of other types
             methodsCalled,
             
fieldsUsed 
}

No methods matched

API Breaking Changes

ok   API Breaking Changes: Types
// <Name>API Breaking Changes: Types</Name>
// This rule warns if a publicly visible type is 
// not publicly visible anymore or if it has been removed.
// Such type can break the code of your clients.

warnif count > 0 from t in codeBase.OlderVersion().Application.Types
where t.IsPubliclyVisible && 

     
// The type has been removed and its parent assembly hasn't been removed ...
     ( (t.WasRemoved() && !t.ParentAssembly.WasRemoved()) ||

     
// ... or the type is not publicly visible anymore
       !t.WasRemoved() && !t.NewerVersion().IsPubliclyVisible)

select new { t,
             
NewVisibility = (t.WasRemoved() ? " " : t.NewerVersion().Visibility.ToString()) }

No types matched

ok   API Breaking Changes: Methods
// <Name>API Breaking Changes: Methods</Name>
// This rule warns if a publicly visible method is 
// not publicly visible anymore or if it has been removed.
// Such method can break the code of your clients.

warnif count > 0 from m in codeBase.OlderVersion().Application.Methods
where m.IsPubliclyVisible && 

     
// The method has been removed and its parent type hasn't been removed ...
     ( (m.WasRemoved() && !m.ParentType.WasRemoved()) ||

     
// ... or the method is not publicly visible anymore
       !m.WasRemoved() && !m.NewerVersion().IsPubliclyVisible)

select new { m,
             
NewVisibility = (m.WasRemoved() ? " " : m.NewerVersion().Visibility.ToString()) }

No methods matched

ok   API Breaking Changes: Fields
// <Name>API Breaking Changes: Fields</Name>
// This rule warns if a publicly visible field is 
// not publicly visible anymore or if it has been removed.
// Such field can break the code of your clients.

warnif count > 0 from f in codeBase.OlderVersion().Application.Fields
where f.IsPubliclyVisible &&

     
// The field has been removed and its parent type hasn't been removed ...
     ( (f.WasRemoved() && !f.ParentType.WasRemoved()) ||

     
// ... or the field is not publicly visible anymore
       !f.WasRemoved() && !f.NewerVersion().IsPubliclyVisible)

select new { f,
             
NewVisibility = (f.WasRemoved() ? " " : f.NewerVersion().Visibility.ToString()) }

No fields matched

ok   API Breaking Changes: Interfaces and Abstract Classes
// <Name>API Breaking Changes: Interfaces and Abstract Classes</Name>
// This rule warns if a publicly visible interface or abstract class 
// has been changed and contains new abstract methods or 
// if some abstract methods have been removed.
// This can break the code of clients 
// that implement such interface or derive from such abstract class.

warnif count > 0 from tNewer in Application.Types where 
 
(tNewer.IsInterface || tNewer.IsClass && tNewer.IsAbstract) && 
  
tNewer.IsPubliclyVisible && 
  
tNewer.IsPresentInBothBuilds()

let tOlder = tNewer.OlderVersion() where tOlder.IsPubliclyVisible

let methodsRemoved = tOlder.Methods.Where(m => m.IsAbstract && m.WasRemoved())
let methodsAdded = tNewer.Methods.Where(m => m.IsAbstract && m.WasAdded())

where methodsAdded.Count() > 0 || methodsRemoved.Count() > 0
select new { tNewer, methodsAdded, methodsRemoved }

No types matched

ok   Broken serializable types
// <Name>Broken serializable types</Name>
// Find breaking changes in types marked with SerializableAttribute.
warnif count > 0

from t in Application.Types where

  
// Collect types tagged with SerializableAttribute
  t.HasAttribute("System.SerializableAttribute".AllowNoMatch())  && 
 
!t.IsDelegate &&
  
t.IsPresentInBothBuilds() &&
  
t.HasAttribute(t)

  
// Find newer and older versions of NonSerializedAttribute
  let newNonSerializedAttribute = ThirdParty.Types.WithFullName("System.NonSerializedAttribute").SingleOrDefault()
  
let oldNonSerializedAttribute = newNonSerializedAttribute == null ? null : newNonSerializedAttribute.OlderVersion()

  
// Find added or removed fields not marked with NonSerializedAttribute
  let addedInstanceField = from f in t.InstanceFields where 
                             
f.WasAdded() && 
                             
(newNonSerializedAttribute == null || !f.HasAttribute(newNonSerializedAttribute))
                           
select f
  
let removedInstanceField = from f in t.OlderVersion().InstanceFields where 
                             
f.WasRemoved() && 
                             
(oldNonSerializedAttribute == null || !f.HasAttribute(oldNonSerializedAttribute))
                           
select f
  
where addedInstanceField.Count() > 0 || removedInstanceField.Count() > 0

select new { t, addedInstanceField, removedInstanceField }

// From http://msdn.microsoft.com/library/system.serializableattribute.aspx :
//   All the public and private fields in a type that are marked by the 
//   SerializableAttribute  are serialized by default, unless the type 
//   implements the ISerializable interface to  override the serialization process. 
//   The default serialization process excludes fields that are marked 
//   with the NonSerializedAttribute attribute.

No types matched

ok   Avoid transforming immutable types into mutable types
// <Name>Avoid transforming immutable types into mutable types</Name>

// Immutability is a strong property on a type.
// Breaking immutability can result in serious problem for an algorithm consummer
// that has been written taking account of the type immutability.

// To visualize changes in code, right-click a matched type and select:
//  - Compare older and newer versions of source file
//  - Compare older and newer versions disassembled with Reflector

warnif count > 0 
from t in Application.Types where
  
t.IsPresentInBothBuilds() &&
 
!t.IsStatic &&
 
!t.IsImmutable && 
  
t.OlderVersion().IsImmutable

let mutableFields = from f in t.InstanceFields where !f.IsImmutable select f

select new { t, mutableFields }

No types matched

ok   Avoid changing enumerations Flags status
// <Name>Avoid changing enumerations Flags status</Name>

// Being tagged with the Flags attribute is a strong property for an enumeration.
// Changing the Flags status of an enumeration has significant impact for its client.
warnif count > 0 

let oldFlags = codeBase.OlderVersion().ThirdParty.Types.WithFullName("System.FlagsAttribute").SingleOrDefault()
let newFlags = ThirdParty.Types.WithFullName("System.FlagsAttribute").SingleOrDefault()
where oldFlags != null && newFlags != null

from t in Application.Types where
  
t.IsEnumeration &&
  
t.IsPresentInBothBuilds() 
let isFlags = t.HasAttribute(newFlags)
let wasFlags = t.OlderVersion().HasAttribute(oldFlags) 
where isFlags != wasFlags
select new { t, isFlags, wasFlags }

No types matched

ok   API: New publicly visible types
// <Name>API: New publicly visible types</Name>
// List types that are new in the public surface of your assemblies

from t in Application.Types
where t.IsPubliclyVisible && 

     
// The type has been removed and its parent assembly hasn't been removed ...
     ( (t.WasAdded() && !t.ParentAssembly.WasAdded()) ||

     
// ... or the type existed but was not publicly visible
       !t.WasAdded() && !t.OlderVersion().IsPubliclyVisible)

select new { t,
             
OldVisibility = (t.WasAdded() ? " " : t.OlderVersion().Visibility.ToString()) }

No types matched

ok   API: New publicly visible methods
// <Name>API: New publicly visible methods</Name>
// List methods that are new in the public surface of your assemblies

from m in Application.Methods
where m.IsPubliclyVisible && 

     
// The method has been removed and its parent assembly hasn'm been removed ...
     ( (m.WasAdded() && !m.ParentType.WasAdded()) ||

     
// ... or the t existed but was not publicly visible
       !m.WasAdded() && !m.OlderVersion().IsPubliclyVisible)

select new { m,
             
OldVisibility = (m.WasAdded() ? " " : m.OlderVersion().Visibility.ToString()) }

No methods matched

ok   API: New publicly visible fields
// <Name>API: New publicly visible fields</Name>
// List fields that are new in the public surface of your assemblies

from f in Application.Fields
where f.IsPubliclyVisible && 

     
// The method has been removed and its parent assembly hasn'f been removed ...
     ( (f.WasAdded() && !f.ParentType.WasAdded()) ||

     
// ... or the t existed but was not publicly visible
       !f.WasAdded() && !f.OlderVersion().IsPubliclyVisible)

select new { f,
             
OldVisibility = (f.WasAdded() ? " " : f.OlderVersion().Visibility.ToString()) }

No fields matched

Code Diff Summary

ok   New assemblies
// <Name>New assemblies</Name>
from a in Application.Assemblies where a.WasAdded()
select new { a, a.NbLinesOfCode }

No assemblies matched

ok   Assemblies removed
// <Name>Assemblies removed</Name>
from a in codeBase.OlderVersion().Application.Assemblies where a.WasRemoved()
select new { a, a.NbLinesOfCode }

No assemblies matched

ok   Assemblies where code was changed
// <Name>Assemblies where code was changed</Name>
from a in Application.Assemblies where a.CodeWasChanged()
select new { a, a.NbLinesOfCode, 
             
oldNbLinesOfCode = a.OlderVersion().NbLinesOfCode.GetValueOrDefault() ,
             
delta = (int) a.NbLinesOfCode.GetValueOrDefault() - a.OlderVersion().NbLinesOfCode.GetValueOrDefault() }

No assemblies matched

ok   New namespaces
// <Name>New namespaces</Name>
from n in Application.Namespaces where 
 
!n.ParentAssembly.WasAdded() &&
  
n.WasAdded()
select new { n, n.NbLinesOfCode }

No namespaces matched

ok   Namespaces removed
// <Name>Namespaces removed</Name>
from n in codeBase.OlderVersion().Application.Namespaces where 
 
!n.ParentAssembly.WasRemoved() &&
  
n.WasRemoved()
select new { n, n.NbLinesOfCode }

No namespaces matched

ok   Namespaces where code was changed
// <Name>Namespaces where code was changed</Name>
from n in Application.Namespaces where n.CodeWasChanged()
select new { n, n.NbLinesOfCode, 
             
oldNbLinesOfCode = n.OlderVersion().NbLinesOfCode.GetValueOrDefault() ,
             
delta = (int) n.NbLinesOfCode.GetValueOrDefault() - n.OlderVersion().NbLinesOfCode.GetValueOrDefault() }

No namespaces matched

ok   New types
// <Name>New types</Name>
from t in Application.Types where 
 
!t.ParentNamespace.WasAdded() &&
  
t.WasAdded()
select new { t, t.NbLinesOfCode }

No types matched

ok   Types removed
// <Name>Types removed</Name>
from t in codeBase.OlderVersion().Application.Types where 
 
!t.ParentNamespace.WasRemoved() &&
  
t.WasRemoved()
select new { t, t.NbLinesOfCode }

No types matched

ok   Types where code was changed
// <Name>Types where code was changed</Name>
// To visualize changes in code, right-click a matched type and select:
//  - Compare older and newer versions of source file
//  - Compare older and newer versions disassembled with Reflector

from t in Application.Types where t.CodeWasChanged() 
//select new { t, t.NbLinesOfCode }
select new { t, t.NbLinesOfCode, 
             
oldNbLinesOfCode = t.OlderVersion().NbLinesOfCode ,
             
delta = (int?) t.NbLinesOfCode - t.OlderVersion().NbLinesOfCode } 
/*from t in Application.Types where t.CodeWasChanged() && t.IsPresentInBothBuild
select new { t, t.NbLinesOfCode, 
             oldNbLinesOfCode = t.OlderVersion().NbLinesOfCode ,
             delta = (int) t.NbLinesOfCode - t.OlderVersion().NbLinesOfCode }*/

No types matched

ok   Heuristic to find types moved from one namespace or assembly to another
// <Name>Heuristic to find types moved from one namespace or assembly to another</Name>
let typesRemoved = codeBase.OlderVersion().Types.Where(t => t.WasRemoved())
let typesAdded = Types.Where(t => t.WasAdded())

from tMoved in typesAdded.Join(
   
typesRemoved,
   
t => t.Name,
   
t => t.Name,
   
(tNewer, tOlder) => new { tNewer, 
                             
OlderParentNamespace = tOlder.ParentNamespace,
                             
OlderParentAssembly = tOlder.ParentAssembly  } ) 
select tMoved

No types matched

ok   Types directly using one or several types changed
// <Name>Types directly using one or several types changed</Name>
let typesChanged = Application.Types.Where(t => t.CodeWasChanged()).ToHashSet()

from t in JustMyCode.Types.UsingAny(typesChanged) where
  
!t.CodeWasChanged() && 
  
!t.WasAdded()
let typesChangedUsed = t.TypesUsed.Intersect(typesChanged) 
select new { t, typesChangedUsed }

No types matched

ok   Types indirectly using one or several types changed
// <Name>Types indirectly using one or several types changed</Name>
let typesChanged = Application.Types.Where(t => t.CodeWasChanged()).ToHashSet()

// 'depth' represents a code metric defined on types using
// directly or indirectly any type where code was changed.
let depth = JustMyCode.Types.DepthOfIsUsingAny(typesChanged) 

from t in depth.DefinitionDomain where
  
!t.CodeWasChanged() && 
  
!t.WasAdded()

let typesChangedDirectlyUsed = t.TypesUsed.Intersect(typesChanged) 
let depthOfUsingTypesChanged = depth[t]
orderby depthOfUsingTypesChanged 

select new { t, depthOfUsingTypesChanged, typesChangedDirectlyUsed }

No types matched

ok   New methods
// <Name>New methods</Name>
from m in Application.Methods where 
 
!m.ParentType.WasAdded() &&
  
m.WasAdded()
select new { m, m.NbLinesOfCode }

No methods matched

ok   Methods removed
// <Name>Methods removed</Name>
from m in codeBase.OlderVersion().Application.Methods where 
 
!m.ParentType.WasRemoved() &&
  
m.WasRemoved()
select new { m, m.NbLinesOfCode }

No methods matched

ok   Methods where code was changed
// <Name>Methods where code was changed</Name>
// To visualize changes in code, right-click a matched method and select:
//  - Compare older and newer versions of source file
//  - Compare older and newer versions disassembled with Reflector

from m in Application.Methods where m.CodeWasChanged()
select new { m, m.NbLinesOfCode, 
             
oldNbLinesOfCode = m.OlderVersion().NbLinesOfCode ,
             
delta = (int?) m.NbLinesOfCode - m.OlderVersion().NbLinesOfCode }

No methods matched

ok   Methods directly calling one or several methods changed
// <Name>Methods directly calling one or several methods changed</Name>
let methodsChanged = Application.Methods.Where(m => m.CodeWasChanged()).ToHashSet()

from m in JustMyCode.Methods.UsingAny(methodsChanged ) where
  
!m.CodeWasChanged() && 
  
!m.WasAdded()
let methodsChangedCalled = m.MethodsCalled.Intersect(methodsChanged) 
select new { m, methodsChangedCalled }

No methods matched

ok   Methods indirectly calling one or several methods changed
// <Name>Methods indirectly calling one or several methods changed</Name>
let methodsChanged = Application.Methods.Where(m => m.CodeWasChanged()).ToHashSet()

// 'depth' represents a code metric defined on methods using
// directly or indirectly any method where code was changed.
let depth = JustMyCode.Methods.DepthOfIsUsingAny(methodsChanged) 

from m in depth.DefinitionDomain where
  
!m.CodeWasChanged() && 
  
!m.WasAdded()

let methodsChangedDirectlyUsed = m.MethodsCalled.Intersect(methodsChanged) 
let depthOfUsingMethodsChanged = depth[m]
orderby depthOfUsingMethodsChanged 

select new { m, depthOfUsingMethodsChanged, methodsChangedDirectlyUsed }

No methods matched

ok   New fields
// <Name>New fields</Name>
from f in Application.Fields where 
 
!f.ParentType.WasAdded() &&
  
f.WasAdded()
select new { f }

No fields matched

ok   Fields removed
// <Name>Fields removed</Name>
from f in codeBase.OlderVersion().Application.Fields where 
 
!f.ParentType.WasRemoved() &&
  
f.WasRemoved()
select new { f }

No fields matched

ok   Third party types that were not used and that are now used
// <Name>Third party types that were not used and that are now used</Name>
from t in ThirdParty.Types where t.IsUsedRecently()
select new { t, t.Methods, t.Fields, t.TypesUsingMe }

No types matched

ok   Third party types that were used and that are not used anymore
// <Name>Third party types that were used and that are not used anymore</Name>
from t in codeBase.OlderVersion().Types where t.IsNotUsedAnymore()
select new { t, t.Methods, t.Fields, TypesThatUsedMe = t.TypesUsingMe }

No types matched

ok   Third party methods that were not used and that are now used
// <Name>Third party methods that were not used and that are now used</Name>
from m in ThirdParty.Methods where 
  
m.IsUsedRecently() &&
 
!m.ParentType.IsUsedRecently()
select new { m, m.MethodsCallingMe }

No methods matched

ok   Third party methods that were used and that are not used anymore
// <Name>Third party methods that were used and that are not used anymore</Name>
from m in codeBase.OlderVersion().Methods where 
  
m.IsNotUsedAnymore() &&
 
!m.ParentType.IsNotUsedAnymore()
select new { m, MethodsThatCalledMe = m.MethodsCallingMe}

No methods matched

ok   Third party fields that were not used and that are now used
// <Name>Third party fields that were not used and that are now used</Name>
from f in ThirdParty.Fields where 
  
f.IsUsedRecently() &&
 
!f.ParentType.IsUsedRecently()
select new { f, f.MethodsUsingMe }

No fields matched

ok   Third party fields that were used and that are not used anymore
// <Name>Third party fields that were used and that are not used anymore</Name>
from f in codeBase.OlderVersion().Fields where 
  
f.IsNotUsedAnymore() &&
 
!f.ParentType.IsNotUsedAnymore()
select new { f, MethodsThatUsedMe = f.MethodsUsingMe }

No fields matched

Test and Code Coverage

ok   C.R.A.P method code metric
// <Name>C.R.A.P method code metric</Name>
// Change Risk Analyzer and Predictor (i.e. CRAP) code metric
// This code metric helps in pinpointing overly complex and untested code.
// Reference: http://www.artima.com/weblogs/viewpost.jsp?thread=215899
// Formula:   CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)
warnif count > 0
from m in JustMyCode.Methods

// Don't match too short methods
where m.NbLinesOfCode > 10

let CC = m.CyclomaticComplexity
let uncov = (100 - m.PercentageCoverage) / 100f
let CRAP = (CC * CC * uncov * uncov * uncov) + CC
where CRAP != null && CRAP > 30
orderby CRAP descending, m.NbLinesOfCode descending
select new { m, CRAP, CC, uncoveredPercentage = uncov*100, m.NbLinesOfCode }

No methods matched

ok   Complex methods partially covered by tests should be 100% covered
// <Name>Complex methods partially covered by tests should be 100% covered</Name>
warnif count > 0 from m in JustMyCode.Methods 
 
where 
     
// These metrics' definitions are available here: 
     // http://www.ndepend.com/Metrics.aspx#MetricsOnMethods
     (  m.NbLinesOfCode > 30 || 
        
m.ILCyclomaticComplexity > 50 || 
        
m.ILNestingDepth > 4 || 
        
m.NbVariables > 8) && 

     
// Take care only of complex methods 
     // already partially covered, but not completely covered.
     m.PercentageCoverage > 0 &&
     
m.PercentageCoverage < 100

  
orderby m.NbLinesOfCodeNotCovered ascending,
          
m.NbLinesOfCode descending
select new { m, m.PercentageCoverage, m.NbLinesOfCode, 
             
m.NbLinesOfCodeCovered, m.NbLinesOfCodeNotCovered, 
             
m.ILCyclomaticComplexity, m.ILNestingDepth, m.NbVariables }  

No methods matched

ok   Method changed poorly covered
// <Name>Method changed poorly covered</Name>
from m in Application.Methods where 
  
m.PercentageCoverage < 30 && 
  
m.CodeWasChanged() 
  
orderby m.NbLinesOfCode descending, 
           
m.NbLinesOfCodeNotCovered ,
           
m.PercentageCoverage
select new { m, m.PercentageCoverage, m.NbLinesOfCode, 
             
m.NbLinesOfCodeNotCovered }  

No methods matched

ok   Method added poorly covered
// <Name>Method added poorly covered</Name>
from m in Application.Methods where
  
m.NbLinesOfCode > 0 &&
  
m.PercentageCoverage < 30 && 
  
m.WasAdded() 
  
orderby m.NbLinesOfCode descending, 
           
m.NbLinesOfCodeNotCovered ,
           
m.PercentageCoverage
select new { m, m.PercentageCoverage, m.NbLinesOfCode, 
             
m.NbLinesOfCodeNotCovered } 

No methods matched

ok   Types 95% to 99% covered
// <Name>Types 95% to 99% covered</Name>
from t in Application.Types where 
  
t.PercentageCoverage >= 95 && 
  
t.PercentageCoverage <= 99 &&
 
!t.IsGeneratedByCompiler

  
let methodsCulprit = t.Methods.Where(m => m.PercentageCoverage < 100)

  
orderby t.NbLinesOfCode descending , 
           
t.NbLinesOfCodeNotCovered ,
           
t.PercentageCoverage
select new { t, t.PercentageCoverage, t.NbLinesOfCode, 
             
t.NbLinesOfCodeNotCovered, methodsCulprit } 

// Having types 100% covered by tests is a good idea because 
// the small portion of code hard to cover, is also the 
// portion of code that is the most likely to contain bugs.

No types matched

ok   Namespaces 95% to 99% covered
// <Name>Namespaces 95% to 99% covered</Name>
from n in Application.Namespaces where 
  
n.PercentageCoverage >= 95 && 
  
n.PercentageCoverage <= 99 

  
let methodsCulprit = n.ChildMethods.Where(m => m.PercentageCoverage < 100)

  
orderby n.NbLinesOfCode descending , 
           
n.NbLinesOfCodeNotCovered ,
           
n.PercentageCoverage
select new { n, n.PercentageCoverage, n.NbLinesOfCode, 
             
n.NbLinesOfCodeNotCovered, methodsCulprit  } 

// Having types 100% covered by tests is a good idea because 
// the small portion of code hard to cover, is also the 
// portion of code that is the most likely to contain bugs.

No namespaces matched

ok   Types tagged with FullCoveredAttribute should be 100% covered
// <Name>Types tagged with FullCoveredAttribute should be 100% covered</Name>
warnif count > 0 
from t in Application.Types where
  
t.HasAttribute ("NDepend.Attributes.FullCoveredAttribute".AllowNoMatch()) &&
  
t.PercentageCoverage < 100

let notFullCoveredMethods = t.Methods.Where(
                               
m =>  m.NbLinesOfCode> 0 && 
                                     
m.PercentageCoverage < 100 &&
                                    
!m.HasAttribute("NDepend.Attributes.UncoverableByTestAttribute".AllowNoMatch()))

orderby t.NbLinesOfCodeNotCovered descending 

select new { t, t.PercentageCoverage, t.NbLinesOfCodeNotCovered, notFullCoveredMethods,
                
t.NbLinesOfCode, t.NbLinesOfCodeCovered }

// By using a FullCoveredAttribute, you can signify to developers
// that a class is, and must remain in the future, 100% covered by tests.
// If you don't want to link NDepend.API.dll, 
// you can use your own attribute and adapt this rule.

// Having types 100% covered by tests is a good idea because 
// the small portion of code hard to cover, is also the 
// portion of code that is the most likely to contain bugs.

No types matched

ok   Types 100% covered should be tagged with FullCoveredAttribute
// <Name>Types 100% covered should be tagged with FullCoveredAttribute</Name>
warnif count > 0 from t in JustMyCode.Types where
 
!t.HasAttribute ("NDepend.Attributes.FullCoveredAttribute".AllowNoMatch()) &&
  
t.PercentageCoverage == 100 &&
 
!t.IsGeneratedByCompiler
select new { t, t.NbLinesOfCode }

// By using a FullCoveredAttribute, you can signify to developers
// that a class is, and must remain in the future, 100% covered by tests.
// If you don't want to link NDepend.API.dll, you can use your own attribute and adapt this rule.

// Having types 100% covered by tests is a good idea because 
// the small portion of code hard to cover, is also the 
// portion of code that is the most likely to contain bugs.

No types matched

ok   Types not covered at all
// <Name>Types not covered at all</Name>
from t in Application.Types where 
  
t.PercentageCoverage == 0
  
orderby t.NbLinesOfCode descending
select new { t, t.NbLinesOfCode } 

No types matched

ok   Namespaces not covered at all
// <Name>Namespaces not covered at all</Name>
from n in Application.Namespaces where 
  
n.PercentageCoverage == 0
  
orderby n.NbLinesOfCode descending
select new { n, n.NbLinesOfCode} 

No namespaces matched

ok   Test Methods
// <Name>Test Methods</Name>

// We advise to not include test assemblies in code analyzed by NDepend.
// But if you wish the current query to run properly, 
// you'll need to consider test assemblies in your list of application assemblies analyzed by NDepend..

let testAttr = ThirdParty.Types.WithNameIn("TestAttribute", "TestCaseAttribute")
let testMethods = Methods.TaggedWithAnyAttributes(testAttr)
from m in testMethods 
select m

No methods matched

ok   Methods directly called by test Methods
// <Name>Methods directly called by test Methods</Name>

// Lists all methods directly called by tests methods.
// Overrides of virtual and absract methods, called through polymorphism, are not listed.
// Methods solely invoked through a delegate are not listed.
// Methods solely invoked through reflection are not listed.

// We advise to not include test assemblies in code analyzed by NDepend.
// But if you wish the current query to run properly, 
// you'll need to consider test assemblies in your list of application assemblies analyzed by NDepend..

let testAttr = ThirdParty.Types.WithNameIn("TestAttribute", "TestCaseAttribute")
let testMethods = Methods.TaggedWithAnyAttributes(testAttr).ToHashSet()

// --- Uncomment this line if your test methods are in dedicated test assemblies ---
//let testAssemblies = testMethods.ParentAssemblies().ToHashSet()

from m in Application.Methods.UsedByAny(testMethods)

// --- Uncomment this line if your test methods are in dedicated test assemblies ---
//where !testAssemblies.Contains(m.ParentAssembly)

select new { m , 
             
calledByTests = m.MethodsCallingMe.Intersect(testMethods ),
             
// --- Uncomment this line if your project import some coverage data ---
             // m.PercentageCoverage 
}

No methods matched

ok   Methods directly and indirectly called by test Methods
// <Name>Methods directly and indirectly called by test Methods</Name>

// Lists all methods called directly or indirectly by tests methods.
// Overrides of virtual and absract methods, called through polymorphism, are not listed.
// Methods solely invoked through a delegate are not listed.
// Methods solely invoked through reflection are not listed.

// We advise to not include test assemblies in code analyzed by NDepend.
// But if you wish the current query to run properly, 
// you'll need to consider test assemblies in your list of application assemblies analyzed by NDepend.

let testAttr = from t in ThirdParty.Types.WithNameIn("TestAttribute", "TestCaseAttribute") select t
let testMethods = Methods.TaggedWithAnyAttributes(testAttr)

// --- Uncomment this line if your test methods are in dedicated test assemblies ---
// let testAssemblies = testMethods.ParentAssemblies().ToHashSet()

let depthOfCalledByTest = Application.Methods.DepthOfIsUsedByAny(testMethods)
from pair in depthOfCalledByTest
where pair.Value > 0 
orderby pair.Value ascending
// --- Uncomment this line if your test methods are in dedicated test assemblies ---
//&& !testAssemblies.Contains(pair.CodeElement.ParentAssembly)

select new { 
  
method = pair.CodeElement, 
  
// (depthOfCalledByTests == 1) means that the method is directly called by tests
  // (depthOfCalledByTests == 2) means that the method is directly called by a method directly called by tests
  // ...
  depthOfCalledByTests = pair.Value,
  
// --- Uncomment this line if your project import some coverage data ---
  // m.PercentageCoverage
}

No methods matched

Dead Code

ok   Potentially dead Types
// <Name>Potentially dead Types</Name>
warnif count > 0
// Filter procedure for types that should'nt be considered as dead
let canTypeBeConsideredAsDeadProc = new Func<IType, bool>(
   
t => !t.IsPublic && //   Public types might be used by client applications of your assemblies.
         t.Name != "Program" && 
        
!t.IsGeneratedByCompiler &&

         
// If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute and adapt this rule.
        !t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&

        
// Exclude static types that define only const fields
        // because they cannot be seen as used in IL code.
        !(t.IsStatic && t.NbMethods == 0 && !t.Fields.Where(f => !f.IsLiteral).Any()))


// Select types unused
let typesUnused = 
   
from t in JustMyCode.Types where
   
t.NbTypesUsingMe == 0 && canTypeBeConsideredAsDeadProc(t)
   
select t

// Dead types = types used only by unused types (recursive)
let deadTypesMetric = typesUnused.FillIterative(
types => from t in codeBase.Application.Types.UsedByAny(types).Except(types)
         
where canTypeBeConsideredAsDeadProc(t) &&
               
t.TypesUsingMe.Intersect(types).Count() == t.NbTypesUsingMe
         
select t)

from t in deadTypesMetric.DefinitionDomain
select new { t, t.TypesUsingMe, depth = deadTypesMetric[t] }

No types matched

warningCritical    Critical Rule warning: Potentially dead Methods
// <Name>Potentially dead Methods</Name>
warnif count > 0
// Filter procedure for methods that should'nt be considered as dead
let canMethodBeConsideredAsDeadProc = new Func<IMethod, bool>(
    
m => !m.IsPubliclyVisible &&       // Public methods might be used by client applications of your assemblies.
         !m.IsEntryPoint &&            // Main() method is not used by-design.
         !m.IsExplicitInterfaceImpl && // The IL code never explicitely calls explicit interface methods implementation.
         !m.IsClassConstructor &&      // The IL code never explicitely calls class constructors.
         !m.IsFinalizer &&             // The IL code never explicitely calls finalizers.
         !m.IsVirtual &&               // Only check for non virtual method that are not seen as used in IL.
         !(m.IsConstructor &&          // Don't take account of protected ctor that might be call by a derived ctors.
           m.IsProtected) &&
         
!m.IsEventAdder &&            // The IL code never explicitely calls events adder/remover.
         !m.IsEventRemover &&
         
!m.IsGeneratedByCompiler &&
         
!m.ParentType.IsDelegate &&

         
// Methods tagged with these two attributes are called by the serialization infrastructure.
         !m.HasAttribute("System.Runtime.Serialization.OnSerializingAttribute".AllowNoMatch()) &&
         
!m.HasAttribute("System.Runtime.Serialization.OnDeserializedAttribute".AllowNoMatch()) &&

         
// If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute and adapt this rule.
         !m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()))

// Get methods unused
let methodsUnused = 
   
from m in JustMyCode.Methods where 
   
m.NbMethodsCallingMe == 0 && 
   
canMethodBeConsideredAsDeadProc(m)
   
select m

// Dead methods = methods used only by unused methods (recursive)
let deadMethodsMetric = methodsUnused.FillIterative(
   
methods => // Unique loop, just to let a chance to build the hashset.
              from o in (new object()).ToEnumerable()
              
// Use a hashet to make Intersect calls much faster!
              let hashset = methods.ToHashSet()
              
from m in codeBase.Application.Methods.UsedByAny(methods).Except(methods)
              
where canMethodBeConsideredAsDeadProc(m) &&
                    
// Select methods called only by methods already considered as dead
                    hashset.Intersect(m.MethodsCallingMe).Count() == m.NbMethodsCallingMe
              
select m)

from m in JustMyCode.Methods.Intersect(deadMethodsMetric.DefinitionDomain)
select new { m, m.MethodsCallingMe, depth = deadMethodsMetric[m] }

1 methods matched

methodMethodsCallingMedepthFull Name
funcs(Decimal[])0 method0MathosTest.MathParserTest.funcs (Decimal[])

Statistics

Stat   MethodsCallingMe   depth
Sum:00
Average:00
Minimum:00
Maximum:00
Standard deviation:00
Variance:00
ok   Potentially dead Fields
// <Name>Potentially dead Fields</Name>
warnif count > 0
from f in JustMyCode.Fields where
   
f.NbMethodsUsingMe == 0 && 
   
!f.IsPublic &&     // Although not recommended, public fields might be used by client applications of your assemblies.
   !f.IsLiteral &&    // The IL code never explicitely uses literal fields.
   !f.IsEnumValue &&  // The IL code never explicitely uses enumeration value.
   f.Name !=  "value__"  && // Field named 'value__' are relative to enumerations and the IL code never explicitely uses them.
   !f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
   
!f.IsGeneratedByCompiler
   
// If you don't want to link NDepend.API.dll, you can use your own IsNotDeadCodeAttribute and adapt this rule.
select f

No fields matched

ok   Wrong usage of IsNotDeadCodeAttribute
// <Name>Wrong usage of IsNotDeadCodeAttribute</Name>

// This IsNotDeadCodeAttribute can be used to signify that 
// despite a member could be removed without provoking any syntax error 
// (we also say it is dead code), your intention is to not remove this member.
// Default 'Dead Code' code rules take account of this attribute.
// IsNotDeadCodeAttribute is defined in NDepend.API.dll
// If you don't want to link NDepend.API.dll, you can use 
// your own IsNotDeadCodeAttribute and adapt this rule.
warnif count == 1

let tAttr = Types.WithFullName("NDepend.Attributes.IsNotDeadCodeAttribute").FirstOrDefault()
where tAttr != null

// Get types that do a wrong usage of IsNotDeadCodeAttribute
let types = from t in Application.Types where 
   
t.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&

   
( // types used don't need to be tagged with IsNotDeadCodeAttribute!
     t.NbTypesUsingMe > 0  ||
   
     
// Static types that define only const fields cannot be seen as used in IL code.
     // They don't need to be tagged with IsNotDeadCodeAttribute.
     (t.IsStatic && t.NbMethods == 0 && !t.Fields.Where(f => !f.IsLiteral).Any())
   
)
   
select t

// Get methods that do a wrong usage of IsNotDeadCodeAttribute
let methods = from m in Application.Methods where 
   
m.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
   
m.NbMethodsCallingMe > 0
   
select m

// Get fields that do a wrong usage of IsNotDeadCodeAttribute
let fields = from f in Application.Fields where 
   
f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
   
f.NbMethodsUsingMe > 0
   
select f

where types.Count() > 0 || methods.Count() > 0 || fields.Count() > 0
select new { tAttr, types , methods, fields }

No types matched

Trend Charts


Lines of Code


Rules Violated


Rules Violations


Percentage Coverage by Tests

No Trend Data has been logged for this Chart.

Max


Average


Third-Party Usage

Assemblies Dependencies

Assembly Depends on Is referenced by
MathosParserTests v1.0.0.0mscorlib v4.0.0.0 ; MathParser v1.0.9.1 ; System v4.0.0.0 ; -
MathParser v1.0.9.1mscorlib v4.0.0.0 ; System v4.0.0.0 ; System.Core v4.0.0.0 ; MathosParserTests v1.0.0.0 ;

Assemblies Build Order

  1. MathosParserTests
  2. MathParser

Assemblies Build Order

  1. MathosParserTests
  2. MathParser

Analysis Log : Information and Warnings

Here are Logs emitted during NDepend analysis.
The Warnings can reveal potential flaws concerning the health of the build process.
A particular warn can be disabled through the NDepend interactive UI, panel Error List, tick the checkbox Disabled corresponding to the warn to disable.


Message
warningCriticalBegin full analysis with NDepend v5.4.1.8430
warningCriticalNo Baseline for Comparison loaded.
warningCriticalCan't load the assembly {Microsoft.VisualStudio.QualityTools.UnitTestFramework}: Can't find the .NET assembly {Microsoft.VisualStudio.QualityTools.UnitTestFramework} in specified folders. Has it been compiled properly? Is the NDepend project missing the containing folder of the .NET assembly?
warningCriticalConcurrent mode
warningCritical.NET Assemblies loaded from {C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319} mscorlib.dll v4.0.0.0 System.dll v4.0.0.0 System.Core.dll v4.0.0.0
warningCriticalNo application or third party assembly found in directory {C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\WPF}
warningCritical.NET Assembly loaded from {C:\Users\Artem Los\Documents\sss\mathosparser\MathosParser\MathosParser\bin\Debug} MathParser.dll v1.0.9.1
warningCritical.NET Assembly loaded from {C:\Users\Artem Los\Documents\sss\mathosparser\MathosParser\MathosParserTests\bin\Debug} MathosParserTests.dll v1.0.0.0
warningCriticalAssembly {Microsoft.VisualStudio.QualityTools.UnitTestFramework} is referenced by {MathosParserTests} but is not found.
warningCritical4 source files parsed ; all source files found ; all source files in-sync with PDB
warningCritical0 code rule has been extracted from code.
warningCriticalNo dependency cycle detected in assemblies referencement graph.
warningCritical11-28-2014 20:34:13 Analyse dependencies of your application.
warningCritical11-28-2014 20:34:13 Log trend metrics values.
warningCritical11-28-2014 20:34:13 Execute queries and rules
warningCritical2 critical rules are violated. - Methods too complex - critical - Potentially dead Methods
warningCritical11-28-2014 20:34:14 NDepend analysis done. Duration: 00:01
warningCritical11-28-2014 20:34:14 Building the report (standard).