Code Query Language 1.8 Specification

CQL 1.8

 

 

CQL 1.8 is supported by NDepend 2.9 and higher, including NDepend 3.x versions

http://www.NDepend.com

 

 

Copyright SMACCHIA.COM S.A.R.L 2006/2007/2008/2009

All right reserved

 

 


 

Content

Content 2

Introduction. 5

CQL and VisualNDepend. 5

Learning the CQL language. 6

The CQL language and real-world needs. 7

Storing CQL queries and constraints in your C# or VB.NET source code. 7

Some examples of queries and constraints written in CQL. 8

Examples of code Quality constraints. 8

Examples of naming constraints. 10

Examples of design constraints. 10

Examples of encapsulation constraints. 10

Examples of queries on the graph of dependencies. 11

Examples of queries on the inheritance tree. 12

Examples of queries to get extremum... 13

CQL queries elements. 14

SELECT METHODS. 14

SELECT FIELDS. 14

SELECT TYPES. 14

SELECT NAMESPACES. 15

SELECT ASSEMBLIES. 15

WARN IF xxx IN: Query vs. Constraint 15

TOP xxx: Restrict the number of rows in the result 15

FROM / OUT OF xxx: Domain of search. 16

WHERE xxx: Define a set of conditions. 16

ORDER BY xxx: Order rows of the result 17

Comments. 17

Query naming. 17

CQL name conditions. 17

Kind of Code Elements’ Names Prefixes. 20

The OPTIONAL: Code Elements’ Names Prefix. 20

NameLike “regex”  ANTMF. 21

NameIs “name”  ANTMF. 21

FullNameLike “name”  ANTMF. 21

FullNameIs “name”  ANTMF. 21

CQL metric conditions. 22

NbLinesOfCode  ANTM... 22

NbILInstructions  ANTM... 23

NbLinesOfComment  ANTM... 23

PercentageComment  ANTM... 24

NbMethods  ANTM... 24

NbFields  ANTF. 25

NbTypes ANT. 25

NbNamespaces AN.. 25

NbInterfacesImplemented  T. 26

NbParameters M... 26

NbVariables  M... 26

NbOverloads M... 27

CyclomaticComplexity  TM... 27

ILCyclomaticComplexity  TM... 28

ILNestingDepth  M... 28

SizeOfInst  TF. 29

TypeRank  T. 29

MethodRank  M... 30

DepthOfInheritance  T. 30

NbChildren  T. 30

FieldCa F. 31

MethodCe M... 31

MethodCa M... 31

TypeCe  T. 32

TypeCa  T. 32

NamespaceCe N.. 33

NamespaceCa N.. 33

ABT  T (Association Between Types). 33

LCOM  T (Lack Of Cohesion Of Methods). 34

LCOMHS  T (Lack Of Cohesion Of Methods Henderson-Sellers). 34

AssemblyLevel A.. 35

NamespaceLevel N.. 35

TypeLevel T. 35

MethodLevel T. 35

Abstractness  A.. 36

Instability  A.. 36

NormDistFromMainSeq  A.. 36

DistFromMainSeq  A.. 37

RelationalCohesion  A.. 37

AsmCa  A.. 37

AsmCe  A.. 38

CQL test coverage metrics conditions. 38

PercentageCoverage  ANTM... 38

NbLinesOfCodeCovered  ANTM... 39

NbLinesOfCodeNotCovered  ANTM... 39

PercentageBranchCoverage  M... 39

IsExcludedFromCoverage ANTM... 40

CQL code structure conditions. 41

IsUsing  ANTM... 41

DepthOfIsUsing  ANTM... 42

IsDirectlyUsing  ANTM... 42

IsUsedBy  ANTMF. 43

DepthOfIsUsedBy  ANTMF. 43

IsDirectlyUsedBy  ANTMF. 44

CreateA  M... 45

DepthOfCreateA  M... 45

DeriveFrom  T. 45

DepthOfDeriveFrom  T. 46

Implement  T. 46

HasAttribute  ATMF. 46

IsOfType  F. 46

ReturnType  M... 46

CQL boolean conditions. 47

IsPublic  TMF. 47

IsInternal  TMF. 47

IsProtected  TMF. 47

IsProtectedOrInternal  TMF. 47

IsProtectedAndInternal  TMF. 48

IsPrivate  TMF. 48

IsInFrameworkAssembly  NTMF. 48

IsFrameworkAssembly  A.. 48

IsEnumValue  F. 48

IsConstructor  M... 49

IsPropertySetter  M... 49

IsPropertyGetter  M... 49

IsStatic  TMF. 49

IsOverloaded  M... 49

IsVirtual  M... 50

IsAbstract  TM... 50

IsExplicitInterfaceImpl  M... 50

IsUsingBoxing  TM... 50

IsUsingUnboxing  TM... 50

IsUsingPinning  TM... 51

IsGeneric  TM... 51

IsUsingPointers  TM... 51

IsFinalizer  M... 51

HasFinalizer T. 51

HasLevel ANTM... 52

ContainsNamespaceDependencyCycle A.. 52

ContainsTypeDependencyCycle T. 52

ContainsMethodDependencyCycle M... 52

IsEntryPoint  M... 52

IsOperator  M... 53

IsIndexerSetter  M... 53

IsIndexerGetter  M... 53

IsLiteral  F. 53

IsInitOnly  F. 53

IsEventAdder  M... 54

IsEventRemover  M... 54

IsEventDelegateObject  F. 54

IsClassConstructor  M... 54

IsClass  T. 54

IsStructure  T. 55

IsEnumeration  T. 55

IsInterface  T. 55

IsSealed  T. 55

IsNested  T. 55

IsSerializable  T. 56

IsDelegate  T. 56

IsAttributeClass  T. 56

IsExceptionClass  T. 56

IsGeneratedByCompiler  TMF. 56

IsObsolete  TMF. 57

IsSpecialName  TMF. 57

CQL boolean conditions dedicated to Build Comparison. 57

WasAdded  ANTMF. 57

WasRemoved  ANTMF. 58

CodeWasChanged ANTM... 58

CommentsWereChanged ANTM... 59

VisibilityWasChanged TMF. 59

WasChanged  ANTMF. 59

BecameObsolete TMF. 60

IsUsedRecently ANTMF. 60

IsNotUsedAnymore ANTMF. 60

IsUsedDifferently ANT. 60

IsInNewerBuild ANTMF. 61

IsInOlderBuild ANTMF. 61

CQL boolean conditions dedicated to Optimal Encapsulation. 61

CouldBeInternal  NTMF. 62

CouldBeInternalProtected  TMF. 62

CouldBeProtected  TMF. 62

CouldBePrivate  TMF. 63

ShouldBePublic  TMF. 63

CQL boolean conditions dedicated to Purity / Side-Effects / Mutability. 64

IsImmutable  TF. 64

ChangesObjectState  M... 65

ChangesTypeState  M... 65

ReadsMutableObjectState  M... 66

ReadsMutableTypeState  M... 66

ReadsImmutableObjectState  M... 66

ReadsImmutableTypeState  M... 66

IsWritingField  M... 67

DepthOfIsWritingField  M... 67

IsDirectlyWritingField  M... 67

CQL 1.1 new features. 68

CQL 1.2 new features. 68

CQL 1.3 new features. 69

CQL 1.4 new features. 69

CQL 1.5 new features. 70

CQL 1.6 new features. 70

CQL 1.7 new features. 70

CQL 1.8 new features. 71

 

Introduction

CQL is a language which allows writing queries on the code structure of any.NET application, independently of the .NET language used (C#, VB.NET, C++/CLI …). For example, the following CQL query returns all the methods of your application with more than 200 IL instructions, ordered from the biggest to the smallest:

 

SELECT METHODS WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC

 

You might wish to avoid methods with more than 200 IL instructions since they are hard to maintain. After having shrunk all your methods, you certainly want to be notified when during development a method exceeds this threshold. The CQL language addresses this need by allowing the transformation of queries into constraints. For example, here is our previous query rewritten as a constraint:

 

WARN IF Count > 0 IN SELECT METHODS WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC

 

With almost a hundred keywords, the CQL language allows you to deal with various conditions on your code structure. It allows to write code quality constraints, naming constraints, design constraints, encapsulation constraints, queries on the graph of dependencies, queries on the inheritance tree,  queries to get the biggest or smallest code elements according to almost 30 metrics and much more.

 

CQL and VisualNDepend

The tool VisualNDepend allows the editing and execution of CQL queries and constraints. A GUI allows you to have a unique understanding of your application. VisualNDepend can also be used to generate reports during each build of your application.

 

VisualNDepend2_Big

 

Learning the CQL language

Writing CQL queries and constraints is straightforward thanks to the three following features:

 

VisualNDependCQLEditor

 

VisualNDependCQLEditor2

The CQL language and real-world needs

The CQL language has been conceived to understand and control real-world application. In a real-world environment, there are often exceptions (like automatically generated methods which are often very big) and you need to allow a few particular methods to exceed this threshold without being bothered by our previous constraint. The CQL language offers numerous features allowing you to deal with such exceptions. For example, all generated methods might contain the word “Generated” in their names:

 

WARN IF Count > 0 IN SELECT METHODS WHERE  NbILInstructions > 200 AND !NameLike "Generated" ORDER BY NbILInstructions DESC

 

Or maybe, all generated methods are in dedicated assemblies, namespaces or types:

 

WARN IF Count > 0 IN SELECT METHODS OUT OF NAMESPACES "MyApp.Generated1","MyApp.Generated2" WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC

 

Or maybe, you prefer to mention each one explicitly:

 

WARN IF Count > 0 IN SELECT METHODS WHERE NbILInstructions > 200 AND !(NameIs "Method1(Int32)" OR FullNameIs "MyApp.MyType.Method2(String)" ) ORDER BY NbILInstructions DESC

 

You can also mix all these features in the same constraint:

 

WARN IF Count > 0 IN SELECT METHODS OUT OF NAMESPACES "MyApp.Generated1","MyApp.Generated2" WHERE NbILInstructions > 200 AND !(NameIs "Method1(Int32)" OR FullNameIs "MyApp.MyType.Method2(String)" ) AND !NameLike "Generated" ORDER BY NbILInstructions DESC

Storing CQL queries and constraints in your C# or VB.NET source code

NDepend stores your CQL queries and constraints in the project file. As the source code is the design you might prefer storing your CQL queries and constraints directly in your source code (C#, VB.NET...). To do so, you must reference the assembly ./Lib/NDepend.CQL.dll and use the attribute NDepend.CQL.CodeRuleAttribute in your code.

Some examples of queries and constraints written in CQL

Examples of code Quality constraints

WARN IF Count > 0 IN SELECT METHODS WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC

// METHODS WHERE NbILInstructions > 200 are extremely complex and

// should be split in smaller methods

// (except if they are automatically generated by a tool).

 

WARN IF Count > 0 IN SELECT METHODS WHERE ILCyclomaticComplexity > 40 ORDER BY ILCyclomaticComplexity DESC

// METHODS WHERE ILCyclomaticComplexity > 20 are hard to understand and maintain.

// METHODS WHERE ILCyclomaticComplexity > 40 are extremely complex and should be split

// in smaller methods (except if they are automatically generated by a tool).

 

WARN IF Count > 0 IN SELECT METHODS WHERE NbParameters > 5 ORDER BY NbParameters DESC

// METHODS WHERE NbParameters > 5 might be painful to call and might degrade performance.

// You should prefer using additional properties/fields to the declaring type to handle

// numerous states. Another alternative is to provide a class or structure dedicated to

// handle arguments passing (for example see the class System.Diagnostics.ProcessStartInfo

// and the method System.Diagnostics.Process.Start(ProcessStartInfo))

 

WARN IF Count > 0 IN SELECT METHODS WHERE NbVariables > 15 ORDER BY NbVariables DESC

// METHODS WHERE NbVariables > 8 are hard to understand and maintain.

// METHODS WHERE NbVariables > 15 are extremely complex and should be split in

// smaller methods (except if they are automatically generated by a tool).

 

WARN IF Count > 0 IN SELECT TYPES WHERE NbMethods > 20 ORDER BY LCOM DESC

// TYPES WHERE NbMethods > 20 might be hard to understand and maintain

// but there might be cases where it is relevant to have a high value for NbMethods.

// For example, the System.Windows.Forms.DataGridView standard class has more than 1000 methods.

 

WARN IF Count > 0 IN SELECT TYPES WHERE NbFields > 20 AND !IsEnumeration

// TYPES WHERE NbFields > 20 AND !IsEnumeration might be hard to understand and maintain

// but there might be cases where it is relevant to have a high value for NbFields.

// For example, the System.Windows.Forms.Control standard class has more than 200 fields.

// The value of the metric SizeOfInst might be a better indicator of complex type.

 

WARN IF Count > 0 IN SELECT TYPES WHERE SizeOfInst > 64 ORDER BY SizeOfInst DESC

// TYPES WHERE SizeOfInst > 64 might degrade performance (depending on the number of

// instances created at runtime) and might be hard to maintain.

// However it is not a rule since sometime there is no alternative

// (the size of instances of the System.Net.NetworkInformation.SystemIcmpV6Statistics

// standard class is 2064 bytes).

 

WARN IF Count > 0 IN SELECT TYPES WHERE LCOM > 0.8 AND NbFields > 10 AND NbMethods >10 ORDER BY LCOM DESC

// 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.

 

WARN IF Count > 0 IN SELECT TYPES WHERE LCOMHS > 1.0 AND NbFields > 10 AND NbMethods >10 ORDER BY LCOMHS DESC

// TYPES WHERE LCOMHS > 1.0 AND NbFields > 10 AND NbMethods >10 should be avoided.

// Note that this constraint is stronger than the constraint

// TYPES WHERE LCOM > 0.8 AND NbFields > 10 AND NbMethods >10.

 

SELECT TYPES WHERE DepthOfInheritance > 6 ORDER BY DepthOfInheritance DESC

// TYPES WHERE DepthOfInheritance > 6 might be hard to maintain. However it is not

// a rule since sometime your classes might inherit from tier classes which have a

// high value for depth of inheritance. For example, the average depth of inheritance

// for framework classes which derive from System.Windows.Forms.Control is 5.3.

 

WARN IF Count > 0 IN SELECT TYPES WHERE (SizeOfInst > 200 ) ORDER BY SizeOfInst DESC

// Type with big instances can be problematic

// (Obviously the SizeOfInst metric does not do a deep traverse.

//  Any instance reference field will count for 4 bytes.

//  It is also unable to cop with generic types properly)

 

WARN IF Percentage > 5 IN SELECT METHODS WHERE IsUsingBoxing OR IsUsingUnboxing

// With generics, boxing and unboxing should be very rare.

 

WARN IF Percentage > 15 IN SELECT ASSEMBLIES WHERE NormDistFromMainSeq > 0.7 ORDER BY NormDistFromMainSeq DESC

 

WARN IF Count > 0 IN SELECT ASSEMBLIES WHERE RelationalCohesion < 1.5 OR RelationalCohesion > 4.0

// As classes inside an assembly should be strongly related,

// the cohesion should be high. On the other hand, a value which is too high may

// indicate over-coupling. A good range for RelationalCohesion is 1.5 to 4.0.

Examples of naming constraints

WARN IF Count > 0 IN SELECT FIELDS WHERE NameLike "^m_" AND IsStatic

// A static field should not be named 'm_XXX'

 

WARN IF Count > 0 IN SELECT FIELDS WHERE NameLike "^s_" AND !IsStatic

// A non-static field should not be named 's_XXX'

 

WARN IF Count > 0 IN SELECT TYPES WHERE IsInterface AND !NameLike "^I"

// The name of an interface should begin with a 'I'

 

WARN IF Count > 0 IN SELECT TYPES WHERE IsExceptionClass AND !NameLike "Exception$"

// The name of an exception class should end with 'Exception'

 

WARN IF Count > 0 IN SELECT TYPES WHERE IsAttributeClass AND !NameLike "Attribute$"

// The name of an attribute class should end with 'Attribute'

 

WARN IF Count > 0 IN SELECT TYPES WHERE

   !NameLike "^[A-Z]" AND // The name of a type should begin with an Upper letter.

   !NameLike "__StaticArrayInit" AND  // Except __StaticArrayInit generated type

   !NameLike "<"                      // Except C# compiler generated type

 

WARN IF Count > 0 IN SELECT METHODS WHERE

   !NameLike "^[A-Z]" AND

   !(IsClassConstructor OR IsConstructor OR

     IsPropertyGetter  OR IsPropertySetter OR

     IsIndexerGetter OR IsIndexerSetter OR

     IsEventAdder OR IsEventRemover OR

     IsOperator)

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

Examples of design constraints

WARN IF Count > 0 IN SELECT TYPES WHERE SizeOfInst ==0 AND !IsStatic AND !IsGeneric

// It indicate stateless types that might eventually be turned into static classes.

 

Examples of encapsulation constraints

WARN IF Count > 0 IN SELECT FIELDS WHERE (IsPublic OR IsInternal) AND !(IsEnumValue OR IsLiteral OR IsInitOnly)

// A field should not be public or internal, except for performance reasons.

 

WARN IF Count > 0 IN SELECT TYPES WHERE IsNested AND (IsPublic OR IsInternal)

// A nested type should not be public or internal.

 

WARN IF Count > 0 IN SELECT TYPES OUT OF NAMESPACES "System.Xml" WHERE DepthOfIsUsing "System.Xml.XmlChildNodes" == 1

// Restrict the possibility of using the type "System.Xml.XmlChildNodes" only to certain namespace.

 

WARN IF Count > 0 IN SELECT METHODS OUT OF NAMESPACES "System.Xml" WHERE

DepthOfIsUsing  "System.Xml.XmlNamedNodeMap.InsertNodeAt(Int32,XmlNode)"== 1

// Restrict the possibility of calling the method "System.Xml.XmlNamedNodeMap.InsertNodeAt(Int32,XmlNode)"

// only to certain namespace.

 

WARN IF Count > 0 IN SELECT METHODS OUT OF TYPES

"System.Xml.XmlDocumentFragment",

"System.Xml.XmlEntityReference",

"System.Xml.XmlDocumentType",

"System.Xml.XmlEntity",

"System.Xml.XmlDocument",

"System.Xml.XmlAttribute",

"System.Xml.XmlElement" WHERE DepthOfCreateA "System.Xml.XmlLoader" ==1 ORDER BY DepthOfCreateA

// Restrict the possibility of creating an instance of "System.Xml.XmlLoader" only to certain type.

 

WARN IF Count > 0 IN SELECT METHODS OUT OF NAMESPACES "System.Xml"

WHERE DepthOfCreateA "System.Xml.XmlLoader" == 1 ORDER BY DepthOfCreateA

// Restrict the possibility of creating an instance of "System.Xml.XmlLoader" only to certain namespaces.

 

WARN IF Count > 1 IN SELECT NAMESPACES OUT OF ASSEMBLIES "System.Windows.Forms"

WHERE DepthOfIsUsing "System.Windows.Forms.Internal" == 1

// Restrict the possibility of using a namespace only to one assembly.

 

WARN IF Count > 0 IN SELECT METHODS OUT OF NAMESPACES "System.Windows.Forms" WHERE

DepthOfIsUsing "System.Windows.Forms.DataGridView+HitTestInfo.typeInternal" == 1

// Restrict the possibility of using the field

// "System.Windows.Forms.DataGridView+HitTestInfo.typeInternal"

// only to certain namespace.

Examples of queries on the graph of dependencies

SELECT METHODS WHERE IsUsing "System.Xml.XmlWriter..ctor()" ORDER BY DepthOfIsUsing

// 'IsUsing/IsUsedBy/DepthOfIsUsing/DepthOfIsUsedBy' conditions are useful

// to understand who calls statically who for example to anticipate future impacts

// of some refactoring or to provide some customized encapsulation constraints.

 

SELECT METHODS WHERE DepthOfIsUsing "System.Xml.XmlWriter..ctor()" <=3

// 'IsUsing/IsUsedBy/DepthOfIsUsing/DepthOfIsUsedBy' conditions are useful

// to understand who calls statically who for example to anticipate future impacts

// of some refactoring or to provide some customized encapsulation constraints.

 

SELECT METHODS WHERE

IsUsedBy "System.Xml.Serialization.SoapSchemaImporter.ImportMembersMapping(String,String,SoapSchemaMember[])"

ORDER BY DepthOfIsUsedBy

// 'IsUsing/IsUsedBy/DepthOfIsUsing/DepthOfIsUsedBy' conditions are useful

// to understand who calls statically who for example to anticipate future impacts

// of some refactoring or to provide some customized encapsulation constraints.

 

SELECT METHODS WHERE CreateA "System.Xml.XmlWriter" ORDER BY DepthOfCreateA

// 'CreateA'/'DepthOfCreateA' conditions can be useful to enforce some constraints on design patterns such as factory

// where the ctors must be called only from certain methods or certain type.

 

SELECT METHODS WHERE DepthOfCreateA "System.Xml.XmlDocument" < 10 ORDER BY DepthOfCreateA

// 'CreateA'/'DepthOfCreateA' conditions can be useful to enforce some constraints on design patterns such as factory

// where the ctors must be called only from certain methods or certain type.

 

SELECT METHODS WHERE IsUsing "System.Xml.XmlWriter.WriteEndElement()"

 

SELECT METHODS WHERE IsUsing  "System.Web.Security.PassportIdentity.LoginUser()"

                  OR IsUsedBy "System.Web.Security.PassportIdentity.LoginUser()"

// 'IsUsing/IsUsedBy/DepthOfIsUsing/DepthOfIsUsedBy' conditions are useful

// to understand who calls statically who for example to anticipate future impacts

// of some refactoring or to provide some customized encapsulation constraints.

 

SELECT TYPES WHERE DepthOfIsUsedBy "System.Net.Sockets.Socket" > 2 ORDER BY DepthOfIsUsedBy

// Try to play with the numeric intellisense by selecting the 2 and moving the trackbar.

// A 'IsUsing/IsUsed' relation between two types A and B is created by NDepend as soon as

// there is a 'IsCalled/IsUsedBy' relation between a method of A and a method of B.

 

SELECT NAMESPACES WHERE DepthOfIsUsedBy "System.Net.Sockets" <=2

// Try to play with the numeric intellisense by selecting the 2 and moving the trackbar.

// A 'IsUsing/IsUsed' relation between two namespaces A and B is created by NDepend as soon as

// there is a 'IsUsing/IsUsed' relation between a type of A and a type of B.

Examples of queries on the inheritance tree

SELECT TYPES WHERE DeriveFrom "System.Windows.Forms.Control" ORDER BY DepthOfDeriveFrom DESC

 

SELECT TYPES WHERE DeriveFrom "System.Web.UI.Control" ORDER BY DepthOfDeriveFrom DESC

 

SELECT TYPES WHERE DepthOfDeriveFrom "System.Windows.Forms.Control" == 1

// Select classes which derive directly from control.

 

SELECT TYPES WHERE Implement "System.Web.UI.IDataSource"

 

SELECT TYPES WHERE Implement "System.Web.IHttpHandler" ORDER BY NbILInstructions DESC

 

SELECT TYPES WHERE NbChildren > 5 ORDER BY NbChildren DESC

Examples of queries to get extremum

SELECT TOP 10 METHODS WHERE !IsConstructor AND !IsClassConstructor ORDER BY NbILInstructions DESC

// Try to play with the numeric intellisense by selecting the 2 and moving the trackbar.

 

SELECT TOP 10 TYPES FROM ASSEMBLIES "System.Web" ORDER BY NbMethods DESC

// Illustrate the 'FROM' domain of search definition.

 

SELECT TOP 10 METHODS OUT OF NAMESPACES "System.Windows.Forms" ORDER BY NbVariables  DESC

// Illustrate the 'OUT OF' domain of search definition.

 

SELECT TOP 10  METHODS ORDER BY NbParameters ,NbVariables ASC, NbILInstructions DESC

// Illustrate the fact that several 'ORDER BY' clause can be specified.

// By default the 'ASC' option is chosen.

// Check in the Query Result panel that 4 columns are displayed.

 

SELECT TOP 10 TYPES ORDER BY  TypeCa DESC

// TypeCa: Afferent Coupling

// The Afferent Coupling for a particular type is the number of types that depends directly on it.

 

SELECT TOP 10 TYPES ORDER BY  TypeCe DESC

// TypeCe: Efferent Coupling

// The Efferent Coupling for a particular type is the number of types it directly depends on..

 

SELECT TOP 10 METHODS WHERE !IsConstructor AND !IsClassConstructor ORDER BY NbParameters DESC

 

SELECT TOP 10 METHODS WHERE IsPropertyGetter OR IsPropertySetter ORDER BY NbILInstructions DESC

 

SELECT TOP 10 TYPES WHERE IsClass ORDER BY NbILInstructions DESC

 

SELECT TOP 10 TYPES WHERE IsStructure ORDER BY NbILInstructions DESC

 

SELECT TOP 10 TYPES WHERE IsClass ORDER BY NbFields DESC

 

SELECT TOP 10 TYPES WHERE IsStructure ORDER BY NbFields DESC

 

SELECT TOP 10 TYPES WHERE IsClass ORDER BY SizeOfInst DESC

 

SELECT TOP 10 TYPES WHERE IsStructure ORDER BY SizeOfInst DESC

 

SELECT TOP 10 NAMESPACES ORDER BY NbILInstructions DESC

 

SELECT TOP 10 ASSEMBLIES ORDER BY NbILInstructions DESC

 

SELECT ASSEMBLIES ORDER BY NbILInstructions DESC

CQL queries elements

SELECT METHODS

The SELECT METHODS expression allows to select all kind of methods. You can use a combination of following conditions to select some particular methods:

NameLike NameIs FullNameIs

NbILInstructions NbMethods NbParameters NbVariables ILCyclomaticComplexity

IsUsing DepthOfIsUsing  IsDirectlyUsing IsUsedBy DepthOfIsUsedBy IsDirectlyUsedBy CreateA DepthOfCreateA

IsPublic IsInternal IsProtected IsProtectedOrInternal IsProtectedAndInternal IsPrivate IsConstructor IsPropertySetter IsPropertyGetter IsStatic IsVirtual IsAbstract IsUsingBoxing IsUsingUnboxing IsGeneric IsUsingPointers IsOperator IsIndexerSetter IsIndexerGetter IsEventAdder IsEventRemover IsClassConstructor

SELECT FIELDS

The SELECT FIELDS expression allows to select all kind of fields. You can use a combination of following conditions to select some particular field:

NameLike NameIs FullNameIs

NbFields SizeOfInst

IsOfType

IsPublic IsInternal IsProtected IsProtectedOrInternal IsProtectedAndInternal IsPrivate IsEnumValue IsStatic IsLiteral IsInitOnly IsEventDelegateObject

IsUsedBy DepthOfIsUsedBy IsDirectlyUsedBy

SELECT TYPES

The SELECT TYPES expression allows to select all kind of types. You can use a combination of following conditions to select some particular types:

NameLike NameIs FullNameIs

NbILInstructions NbMethods NbFields NbTypes ILCyclomaticComplexity SizeOfInst DepthOfInheritance NbChildren TypeCe TypeCa ABT LCOM LCOMHS

IsUsing DepthOfIsUsing  IsDirectlyUsing IsUsedBy DepthOfIsUsedBy IsDirectlyUsedBy DeriveFrom DepthOfDeriveFrom Implement

IsPublic IsInternal IsProtected IsProtectedOrInternal IsProtectedAndInternal IsPrivate IsStatic IsAbstract IsUsingBoxing IsUsingUnboxing IsGeneric IsUsingPointers IsClass IsStructure IsEnumeration IsInterface IsSealed IsNested IsDelegate IsAttributeClass IsExceptionClass

SELECT NAMESPACES

The SELECT NAMESPACES expression allows to select some namespaces. You can use a combination of following conditions to select some particular namespaces:

NameLike NameIs FullNameIs

NbILInstructions NbMethods NbFields NbTypes NbNamespaces

IsUsing DepthOfIsUsing  IsDirectlyUsing IsUsedBy DepthOfIsUsedBy IsDirectlyUsedBy

SELECT ASSEMBLIES

The SELECT ASSEMBLIES expression allows to select some assemblies. You can use a combination of following conditions to select some particular assemblies:

NameLike NameIs FullNameIs

NbILInstructions NbMethods NbFields NbTypes NbNamespaces Abstracness Instability NormDistFromMainSeq DistFromMainSeq RelationalCohesion AsmCa AsmCe

IsUsing DepthOfIsUsing  IsDirectlyUsing IsUsedBy DepthOfIsUsedBy IsDirectlyUsedBy

WARN IF xxx IN: Query vs. Constraint

You can transform every CQL query into a CQL constraint by adding a WARN IF xxx IN expression at the beginning. There are two kinds of CQL constraint.

WARN IF Count > 2 IN SELECT METHODS WHERE NbILInstructions > 200

 

WARN IF Count <= 40 IN SELECT TYPES WHERE IsExceptionClass

 

 

WARN IF Percentage > 5 IN SELECT METHODS WHERE IsUsingBoxing

 

WARN IF Percentage <= 10 IN SELECT TYPES FROM ASSEMBLIES "System" WHERE IsStatic

 

WARN IF xxx IN expressions are optional.

TOP xxx: Restrict the number of rows in the result

You can restrict the number of code elements selected thanks to a TOP xxx expression. For example:

 

SELECT TOP 10 METHODS ORDER BY NbILInstructions DESC

 

SELECT TOP 10 TYPES WHERE IsStructure ORDER BY SizeOfInst DESC

 

It is likely that queries which contain a TOP xxx expression also take advantage of an ORDER BY xxx expression.

 

TOP xxx expressions are optional.

FROM / OUT OF xxx: Domain of search

You can restrict the domain of search for code elements by using a FROM / OUT OF xxx expression. By default, the domain of search is the whole set of application assemblies.

 

A FROM / OUT OF xxx expression can be defined as a set of assemblies, namespaces or types when the kind of code elements requested is METHODS or FIELDS. For example:

 

SELECT METHODS FROM ASSEMBLIES "System" WHERE IsAbstract 

 

SELECT FIELDS OUT OF NAMESPACES "System.Net","System.XML" WHERE IsInitOnly

 

SELECT METHODS OUT OF TYPES "System.Xml.XmlWriter" WHERE CreateA "System.Xml.XmlWriter"

 

A FROM / OUT OF xxx expression can be defined as a set of assemblies or namespaces when the kind of code elements requested is TYPES. For example:

 

SELECT TYPES FROM ASSEMBLIES "System","System.XML" WHERE IsDelegate

 

SELECT TYPES OUT OF NAMESPACES "System.Windows.Forms" WHERE IsUsing "System.Windows.Forms.Control"

 

A FROM / OUT OF xxx expression can be defined as a set of assemblies when the kind of code elements requested is NAMESPACES. For example:

 

SELECT NAMESPACES OUT OF ASSEMBLIES "System.Windows.Forms" WHERE DepthOfIsUsing "System.Windows.Forms" == 2

 

The FROM / OUT OF xxx feature is not available when the kind of code elements requested is ASSEMBLIES.

 

FROM / OUT OF xxx expressions are optional.

WHERE xxx: Define a set of conditions

You can define a set of condition thanks to:

For example:

 

SELECT METHODS WHERE

     (  NbILInstructions > 200 OR

        ILCyclomaticComplexity > 50 OR

        NbParameters > 5 OR

        NbVariables > 8 )

     AND

     !( NameLike "InitializeComponent" OR NameLike "Generated")

 

WHERE xxx expressions are optional but each query must have either a WHERE xxx expression or an ORDER BY xxx expression or both.

ORDER BY xxx: Order rows of the result

You can communicate to the CQL runtime engine how to sort code elements selected thanks to the ORDER BY xxx expression. Several metrics can be mentioned. Each metric mentioned can be followed by one of the keyword ASC or DESC to precise the order of sort. The first metric mentioned will be the last one used for sorting. For example:

 

SELECT TYPES ORDER BY NbILInstructions

 

SELECT METHODS ORDER BY NbILInstructions, NbParameters DESC, NbVariables ASC

 

ORDER BY xxx expressions are optional but each query must have either a WHERE xxx expression or an ORDER BY xxx expression or both.

 

You can use following metrics to sort your result:

NbILInstructions NbMethods NbFields NbTypes NbNamespaces NbParameters NbVariables ILCyclomaticComplexity SizeOfInst DepthOfInheritance NbChildren TypeCe TypeCa ABT LCOM LCOMHS Abstracness Instability NormDistFromMainSeq DistFromMainSeq RelationalCohesion AsmCa AsmCe DepthOfIsUsing DepthOfIsUsedBy DepthOfCreateA DepthOfDeriveFrom

Comments

You can insert comments ŕ la C++/C#/Java in your CQL queries, for example:

 

SELECT METHODS /*Comment 1*/ ORDER

BY NbILInstructions // Comment 2

Query naming

 

New in CQL version 1.4

 

You can name your queries using the <Name> </Name> tags inside a line of a comment. Query name are then displayed in VisualNDepend in lieu of the whole query and can be more meaningful than the whole query itself:

 

// <Name>Methods too big (NbLinesOfCode)</Name>

WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbLinesOfCode > 30 ORDER BY NbLinesOfCode DESC

CQL name conditions

First of all, here are some C# code extracted from regression tests of NDepend that illustrates how code elements are named in NDepend:

 

using System.Collections.Generic;

using NDepend.CQL;

 

// Test the anonymous namespace name : ""

[assembly: CQLConstraint(@"WARN IF Count != 7 IN SELECT METHODS FROM NAMESPACES """" ORDER BY NbILInstructions DESC")]

 

[CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""TypeInAnonymousNamespace""")]

class TypeInAnonymousNamespace {

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""TypeInAnonymousNamespace.MethodWithArrayParam(String[])""")]

   internal static int MethodWithArrayParam(string[] args) { return 5; }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""TypeInAnonymousNamespace.MethodWithPointerParam(Int32*)""")]

   unsafe internal static void MethodWithPointerParam(int* arg) { }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""TypeInAnonymousNamespace.MethodWithOutParam(ref.Int32)""")]

   internal static void MethodWithOutParam(out int arg) { arg = 8; }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""TypeInAnonymousNamespace.MethodWithRefParam(ref.String)""")]

   internal static void MethodWithRefParam(ref string arg) { }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""TypeInAnonymousNamespace.MethodWithGenericParam(Dictionary<Int32,Dictionary<Int32,String>>)""")]

   internal static void MethodWithGenericParam(Dictionary<int, Dictionary<int, string>> arg) { }

}

 

 

[CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""IInterfaceInAnonymousNamespace""")]

interface IInterfaceInAnonymousNamespace {

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""IInterfaceInAnonymousNamespace.NonGenericMethod(Int16)""")]

   int NonGenericMethod(short i);

}

 

namespace Test {

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.GenericClass<K,V>""")]

   class GenericClass<K, V> {

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.GenericClass<K,V>.GenericMethod<U>(U)""")]

      int GenericMethod<U>(U u) { return 7; }

   }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.GenericStructure<X>""")]

   struct GenericStructure<X> {

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.GenericStructure<X>.GenericMethod<U>(U)""")]

      int GenericMethod<U>(U u) { return 8; }

   }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.IGenericInterface<S,T>""")]

   interface IGenericInterface<S, T> {

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.IGenericInterface<S,T>.GenericMethod<U>(U)""")]

      int GenericMethod<U>(U u);

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.IGenericInterface<S,T>.NonGenericMethod(S)""")]

      int NonGenericMethod(S s);

   }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.INonGenericInterface""")]

   interface INonGenericInterface {

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.INonGenericInterface.GenericMethod<P>(P)""")]

      int GenericMethod<P>(P p);

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.INonGenericInterface.NonGenericMethod(Int32)""")]

      int NonGenericMethod(int i);

   }

 

   [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.C1<I,J>""")]

   class C1<I, J> : IGenericInterface<I, J>, INonGenericInterface, IInterfaceInAnonymousNamespace {

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.IInterfaceInAnonymousNamespace.NonGenericMethod(Int16)""")]

      int IInterfaceInAnonymousNamespace.NonGenericMethod(short i) {

         return i;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.IGenericInterface<I,J>.GenericMethod<U>(U)""")]

      int IGenericInterface<I,J>.GenericMethod<U>(U u) {

         return 6;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.IGenericInterface<I,J>.NonGenericMethod(I)""")]

      int IGenericInterface<I, J>.NonGenericMethod(I i) {

         return 6;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.INonGenericInterface.GenericMethod<P>(P)""")]

      int INonGenericInterface.GenericMethod<P>(P p) {

         return 6;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.INonGenericInterface.NonGenericMethod(Int32)""")]

      int INonGenericInterface.NonGenericMethod(int i) {

         return 6;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.GenericMethod<P>(P)""")]

      public int GenericMethod<P>(P p) {

         return 6;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>.NonGenericMethod(Int32)""")]

      public int NonGenericMethod(int i) {

         return 6;

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.C1<I,J>+C2<Q,R,S>""")]

      class C2<Q, R, S> {

         [CQLConstraint(@"WARN IF Count != 1 IN SELECT METHODS WHERE FullNameIs ""Test.C1<I,J>+C2<Q,R,S>.GenericMethod<P>(P)""")]

         public int GenericMethod<P>(P p) {

            return 6;

         }

      }

 

      [CQLConstraint(@"WARN IF Count != 1 IN SELECT TYPES WHERE FullNameIs ""Test.C1<I,J>+C3""")]

      class C3 { }

 

   }

}

Kind of Code Elements’ Names Prefixes

Sometime, 2 different kinds of code elements can have the same name. For example, you can have one assembly named Foo, one namespace named Foo and one class named Foo. The IsUsing-like conditions takes a code element as parameter and need to resolve if it is an assembly, a namespace, a type, a method or a field.

 

SELECT METHODS WHERE IsDirectlyUsing "Foo"

 

Such a query cannot compile because it cannot infer which code element Foo it is referencing. This is why we need ASSEMBLY: NAMESPACE: TYPE: METHOD: and FIELD: prefixes.

 

SELECT METHODS WHERE IsDirectlyUsing "NAMESPACE:Foo"

The OPTIONAL: Code Elements’ Names Prefix

The OPTIONAL: prefix lets write some generic constraint. Suppose you want to be advised when a method is using the .NET Framework method: System.Threading.Thread.Sleep(Int32). You just have to write the following constraint:

 

WARN IF Count > 0 IN SELECT METHODS WHERE IsDirectlyUsing "System.Threading.Thread.Sleep(Int32)"

 

However, if you want to forbid the use of the Thread.Sleep() method, this method won’t be referenced anymore by the NDepend analysis because it just keep code elements from tier assemblies that are used from your application code. As a consequence, the constraint above won’t compile because the method referenced can’t be found.

 

The OPTIONAL: prefix lets remedy this problem and indicate to the CQL compiler that if the code element is not found, an error should not be emitted:

 

WARN IF Count > 0 IN SELECT METHODS WHERE IsDirectlyUsing "OPTIONAL:System.Threading.Thread.Sleep(Int32)"

 

The OPTIONAL: prefix must always appear before an ASSEMBLY: NAMESPACE: TYPE: METHOD: or FIELD prefix.

NameLike “regex”  ANTMF

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS FIELDS

 

Remarks:  The keyword NameLike is used to select code elements whose names match a given regular expression. Regular expression accepts the suffix \i to ignore case.

 

Example:

Select all fields of application where the name begin with m_

SELECT FIELDS WHERE NameLike "^m_"

 

Select all fields of application where the name begin with m_ or M_

SELECT FIELDS WHERE NameLike "^m_\i"

NameIs “name”  ANTMF

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword NameIs is used to select code elements whose names are equal to a given string.

 

Example: Select all methods of application where the name is .ctor(String)

SELECT METHODS WHERE NameIs ".ctor(String)"

FullNameLike “name”  ANTMF

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword FullNameLike is used to select code elements whose full names match a given regular expression. Regular expression accepts the suffix \i to ignore case.

 

Example: Select all methods of application where the full name (i.e namespace.type.method) contains Database.

SELECT METHODS WHERE FullNameLike "Database"

FullNameIs “name”  ANTMF

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword FullNameIs is used to select code elements whose full names are equal to a given string. Note that there can’t be more than one code element which matches a FullNameIs condition.

 

Example: Select all methods of application where the full name is System.Windows.Forms.ToolStripMenuItem..ctor(String)

SELECT METHODS WHERE FullNameIs "System.Windows.Forms.ToolStripMenuItem..ctor(String)"

CQL metric conditions

NbLinesOfCode  ANTM

New in CQL version 1.1

 

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS

Remarks:  This metric (known as LOC) can be computed only if PDB files are present. NDepend computes this metric directly from the info provided in PDB files. The LOC for a method is equals to the number of sequence point found for this method in the PDB file. A sequence point is used to mark a spot in the IL code that corresponds to a specific location in the original source. More info about sequence points here.Notice that sequence points which correspond to C# braces‘{‘ and ‘}’ are not taken account.

Computing the number of lines of code from PDB’s sequence points allows to obtain a logical LOC of code instead of a physical LOC (i.e directly computed from source files).
2 significant advantages of logical LOC over physical LOC are:

Notice that the LOC for a type is the sum of its methods’ LOC, the LOC for a namespace is the sum of its types’ LOC, the LOC for an assembly is the sum of its namespaces’ LOC and the LOC for an application is the sum of its assemblies LOC. Here are some observations:

Related Link:

Why is it useful to count the number of Lines Of Code (LOC) ?

How do you count your number of Lines Of Code (LOC) ?

 

 

Example:

SELECT METHODS WHERE NbLinesOfCode > 20

 

You can also use the NbILInstructions keyword to order the rows in the result list.

SELECT TOP 10 TYPES ORDER BY NbLinesOfCode DESC

 

Recommendations:

METHODS WHERE NbLinesOfCode > 20 are hard to understand and maintain. METHODS WHERE NbILInstructions > 40 are extremely complex and should be split in smaller methods (except if they are automatically generated by a tool).

There is no particular recommendation for NbLinesOfCode values on ASSEMBLIES, NAMESPACES and TYPES.

NbILInstructions  ANTM

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS

 

Remarks: The number of IL instruction of some code elements might be 0, for example for abstract method, interface or enumeration.

 

Example:

SELECT METHODS WHERE NbILInstructions > 200

 

You can also use the NbILInstructions keyword to order the rows in the result list.

SELECT TOP 10 TYPES ORDER BY NbILInstructions DESC

 

Recommendations:

METHODS WHERE NbILInstructions > 100 are hard to understand and maintain. METHODS WHERE NbILInstructions > 200 are extremely complex and should be split in smaller methods (except if they are automatically generated by a tool).

There is no particular recommendation for NbILInstructions values on ASSEMBLIES, NAMESPACES and TYPES.

 

NbLinesOfComment  ANTM

New in CQL version 1.2

 

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS

Remarks: This metric can be computed only if PDB files are present and if corresponding source files can be found. The number of lines of comment is computed as follow:

Notice that this metric is not an additive metric (i.e for example, the number of lines of comment of a namespace can be greater than the number of lines of comment over all its types).

 

Example:

SELECT METHODS WHERE NbLinesOfComment > 10

 

You can also use the NbLinesOfComment keyword to order the rows in the result list.

SELECT TOP 10 TYPES ORDER BY NbLinesOfComment DESC

 

Recommendations:

This metric is not helpful to asses the quality of source code. We prefer to use the metric PercentageComment.

 

PercentageComment  ANTM

New in CQL version 1.2

 

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS

 

Remarks: This metric is computed with the following formula:
PercentageComment = 100*
NbLinesOfComment / (NbLinesOfComment + NbLinesOfCode)

 

Example:

SELECT METHODS WHERE PercentageComment < 10

 

You can also use the PercentageComment keyword to order the rows in the result list.

SELECT TOP 10 TYPES ORDER BY PercentageComment DESC

 

Recommendations:

Code where the percentage of comment is lower than 20% should be more commented. However overly commented code (>40%) is not necessarily a blessing as it can be considered as an insult to the intelligence of the reader.

 

NbMethods  ANTM

Applicable on: ASSEMBLIES NAMESPACES TYPES METHODS

 

Remarks: The value of the NbMethods metric is equal to 1 for all methods, no matter it is static or not, it is abstract, it is a constructor, it is a property accessor ….

 

Example:

SELECT TYPES WHERE NbMethods > 10

 

You can also use the NbMethods keyword to order the rows in the result list.

SELECT TOP 10 NAMESPACES ORDER BY NbMethods ASC

 

Recommendations:

TYPES WHERE NbMethods > 20 might be hard to understand and maintain but there might be cases where it is relevant to have a high value for NbMethods. For example, the System.Windows.Forms.DataGridView framework class has more than 1000 methods.

There is no particular recommendation for NbMethods values on ASSEMBLIES and NAMESPACES.

NbFields  ANTF

Applicable on: ASSEMBLIES NAMESPACES TYPES FIELDS

 

Remarks: The value of the NbFields metric is equal to 1 for all fields, no matter it is static or not, it is an enumeration value, it is literal ….

 

Example:

SELECT TYPES WHERE NbFields < 10

 

You can also use the NbFields keyword to order the rows in the result list.

SELECT TOP 10 NAMESPACES ORDER BY NbFields ASC

 

Recommendations:

TYPES WHERE NbFields > 20 AND !IsEnumeration might be hard to understand and maintain but there might be cases where it is relevant to have a high value for NbFields. For example, the System.Windows.Forms.Control framework class has more than 200 fields. The value of the metric SizeOfInst might be a better indicator to pinpoint complex types.

There is no particular recommendation for NbFields values on ASSEMBLIES and NAMESPACES.

NbTypes ANT

Applicable on: ASSEMBLIES NAMESPACES TYPES

 

Remarks: The value of the NbTypes metric is equal to 1 for all types, no matter it is a class, an interface, a structure, a delegate, a nested type….

 

Examples:

SELECT ASSEMBLIES WHERE NbTypes > 10

 

You can also use the NbTypes  keyword to order the rows in the result list.

SELECT TOP 10 NAMESPACES ORDER BY NbTypes ASC

 

Recommendations:

There is no particular recommendation for NbTypes values on ASSEMBLIES and NAMESPACES.

 

NbNamespaces AN

Applicable on: ASSEMBLIES NAMESPACES

 

Remarks: The value of the NbNamespaces metric is equal to 1 for all namespaces.

 

Example:

SELECT ASSEMBLIES WHERE NbNamespaces == 10