Code Query Language 1.8 Specification

CQL 1.8

 

 

CQL 1.8 is supported by VBDepend

http://www.VBDepend.com

 

 

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

All right reserved

 

 


 

Content

Content 2

Introduction. 5

CQL and VisualVBDepend. 5

Learning the CQL language. 6

The CQL language and real-world needs. 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 PROJECTS. 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

FullNameIs “name”  ANTMF. 21

CQL metric conditions. 21

NbLinesOfCode  ANTM... 21

NbLinesOfCode  ANTM... 22

NbLinesOfComment  ANTM... 23

PercentageComment  ANTM... 23

NbMethods  ANTM... 24

NbFields  ANTF. 24

NbTypes ANT. 25

NbNamespaces AN.. 25

NbParameters M... 26

NbVariables  M... 26

NbOverloads M... 26

CyclomaticComplexity  TM... 27

SizeOfInst  TF. 28

TypeRank  T. 29

MethodRank  M... 29

DepthOfInheritance  T. 30

NbChildren  T. 30

FieldCa F. 30

MethodCe M... 31

MethodCa M... 31

TypeCe  T. 32

TypeCa  T. 32

NamespaceCe N.. 32

NamespaceCa N.. 33

ABT  T (Association Between Types). 33

LCOM  T (Lack Of Cohesion Of Methods). 33

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

AssemblyLevel A.. 35

NamespaceLevel N.. 35

TypeLevel T. 35

MethodLevel T. 35

Abstractness  A.. 35

Instability  A.. 36

NormDistFromMainSeq  A.. 36

DistFromMainSeq  A.. 37

RelationalCohesion  A.. 37

ProjectCa  A.. 37

ProjectCe  A.. 38

CQL code structure conditions. 40

IsUsing  ANTM... 41

DepthOfIsUsing  ANTM... 41

IsDirectlyUsing  ANTM... 42

IsUsedBy  ANTMF. 43

DepthOfIsUsedBy  ANTMF. 43

IsDirectlyUsedBy  ANTMF. 44

CreateA  M... 44

DepthOfCreateA  M... 45

DeriveFrom  T. 45

DepthOfDeriveFrom  T. 45

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

IsStatic  TMF. 49

IsOverloaded  M... 49

IsVirtual  M... 50

IsAbstract  TM... 50

IsTemplate  TM... 51

IsUsingPointers  TM... 51

IsFinalizer  M... 51

HasFinalizer T. 51

HasLevel ANTM... 52

ContainsNamespaceDependencyCycles A.. 52

ContainsTypeDependencyCycles T. 52

ContainsMethodDependencyCycles M... 52

IsEntryPoint  M... 52

IsOperator  M... 52

IsLiteral  F. 53

IsClassConstructor  M... 54

IsClass  T. 54

IsStructure  T. 54

IsEnumeration  T. 55

IsInterface  T. 55

IsExceptionClass  T. 56

IsObsolete  TMF. 57

CQL boolean conditions dedicated to Build Comparison. 57

WasAdded  ANTMF. 57

WasRemoved  ANTMF. 58

CodeWasChanged ANTM... 58

CommentsWereChanged ANTM... 58

VisibilityWasChanged TMF. 59

WasChanged  ANTMF. 59

BecameObsolete TMF. 59

IsUsedRecently ANTMF. 60

IsNotUsedAnymore ANTMF. 60

IsUsedDifferently ANT. 60

IsInNewerBuild ANTMF. 61

IsInOlderBuild ANTMF. 61

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

IsImmutable  TF. 64

ChangesObjectState  M... 65

ChangesTypeState  M... 65

ReadsMutableObjectState  M... 65

ReadsMutableTypeState  M... 66

ReadsImmutableObjectState  M... 66

ReadsImmutableTypeState  M... 66

IsWritingField  M... 67

DepthOfIsWritingField  M... 67

IsDirectlyWritingField  M... 67

 

Introduction

CQL is a language which allows writing queries on the code structure of any.NET and C++ application.

 For example, the following CQL query returns all the methods of your application with more than 200 lines, ordered from the biggest to the smallest:

 

SELECT METHODS WHERE NbLinesOfCode > 200 ORDER BY NbLinesOfCode DESC

 

You might wish to avoid methods with more than 200 lines 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 NbLinesOfCode > 200 ORDER BY NbLinesOfCode 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 VisualVBDepend

The tool VisualVBDepend allows the editing and execution of CQL queries and constraints. A GUI allows you to have a unique understanding of your application. VisualVBDepend 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  NbLinesOfCode > 200 AND !NameLike "Generated" ORDER BY NbLinesOfCode DESC

 

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

 

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

 

Or maybe, you prefer to mention each one explicitly:

 

WARN IF Count > 0 IN SELECT METHODS WHERE NbLinesOfCode > 200 AND !(NameIs "Method1(Int32)" OR FullNameIs "MyApp.MyType.Method2(String)" ) ORDER BY NbLinesOfCode 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 NbLinesOfCode > 200 AND !(NameIs "Method1(Int32)" OR FullNameIs "MyApp.MyType.Method2(String)" ) AND !NameLike "Generated" ORDER BY NbLinesOfCode DESC

Storing CQL queries and constraints in your C++ source code

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

Some examples of queries and constraints written in CQL

Examples of code Quality constraints

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

// METHODS WHERE NbLinesOfCode > 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 > 15 IN SELECT PROJECTS WHERE NormDistFromMainSeq > 0.7 ORDER BY NormDistFromMainSeq DESC

 

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

// As classes inside an project 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

   !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]"

// 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 !IsTemplate

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

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

 

 

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 PROJECTS "System.Windows.Forms"

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

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

 

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 VBDepend 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 VBDepend 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 NbLinesOfCode 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 NbLinesOfCode DESC

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

 

SELECT TOP 10 TYPES FROM PROJECTS "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, NbLinesOfCode 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 NbLinesOfCode DESC

 

SELECT TOP 10 TYPES WHERE IsClass ORDER BY NbLinesOfCode DESC

 

SELECT TOP 10 TYPES WHERE IsStructure ORDER BY NbLinesOfCode 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 NbLinesOfCode DESC

 

SELECT TOP 10 PROJECTS ORDER BY NbLinesOfCode DESC

 

SELECT PROJECTS ORDER BY NbLinesOfCode 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

NbLinesOfCode 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 IsTemplate 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

NbLinesOfCode 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 IsTemplate 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

NbLinesOfCode NbMethods NbFields NbTypes NbNamespaces

IsUsing DepthOfIsUsing  IsDirectlyUsing IsUsedBy DepthOfIsUsedBy IsDirectlyUsedBy

SELECT PROJECTS

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

NameLike NameIs FullNameIs

NbLinesOfCode 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 NbLinesOfCode > 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 PROJECTS "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 NbLinesOfCode 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 projects.

 

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

 

SELECT METHODS FROM PROJECTS "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 projects or namespaces when the kind of code elements requested is TYPES. For example:

 

SELECT TYPES FROM PROJECTS "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 projects when the kind of code elements requested is NAMESPACES. For example:

 

SELECT NAMESPACES OUT OF PROJECTS "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 PROJECTS.

 

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

     (  NbLinesOfCode > 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 NbLinesOfCode

 

SELECT METHODS ORDER BY NbLinesOfCode, 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:

NbLinesOfCode 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#/Visual Basic 6 and VBA in your CQL queries, for example:

 

SELECT METHODS /*Comment 1*/ ORDER

BY NbLinesOfCode // 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 VisualVBDepend 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 VBDepend that illustrates how code elements are named in VBDepend:

 

using System.Collections.Generic;

using VBDepend.CQL;

 

// Test the anonymous namespace name : ""

[project: CQLConstraint(@"WARN IF Count != 7 IN SELECT METHODS FROM NAMESPACES """" ORDER BY NbLinesOfCode 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 project 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 project, 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 VBDepend analysis because it just keep code elements from tier projects 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: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks:  The keyword NameLike is used to select code elements whose names match a given regular expression.

 

Example:

Select all fields of application where the name begin with m_

SELECT FIELDS WHERE NameLike "^m_"

NameIs “name”  ANTMF

Applicable on: PROJECTS 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)"

FullNameIs “name”  ANTMF

Applicable on: PROJECTS 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: PROJECTS NAMESPACES TYPES METHODS

Remarks:  This metric (known as LOC) can be computed only if PDB files are present. VBDepend 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 project is the sum of its namespaces’ LOC and the LOC for an application is the sum of its projects 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 NbLinesOfCode 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 NbLinesOfCode > 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 PROJECTS, NAMESPACES and TYPES.

NbLinesOfCode  ANTM

Applicable on: PROJECTS 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 NbLinesOfCode > 200

 

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

SELECT TOP 10 TYPES ORDER BY NbLinesOfCode DESC

 

Recommendations:

METHODS WHERE NbLinesOfCode > 100 are hard to understand and maintain. METHODS WHERE NbLinesOfCode > 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 NbLinesOfCode values on PROJECTS, NAMESPACES and TYPES.

 

NbLinesOfComment  ANTM

New in CQL version 1.2

 

Applicable on: PROJECTS 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: PROJECTS 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: PROJECTS 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 PROJECTS and NAMESPACES.

NbFields  ANTF

Applicable on: PROJECTS 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 PROJECTS and NAMESPACES.

NbTypes ANT

Applicable on: PROJECTS 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 PROJECTS 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 PROJECTS and NAMESPACES.

 

NbNamespaces AN

Applicable on: PROJECTS NAMESPACES

 

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

 

Example:

SELECT PROJECTS WHERE NbNamespaces == 10

 

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

SELECT TOP 10 PROJECTS ORDER BY NbNamespaces DESC

 

Recommendations:

There is no particular recommendation for NbNamespaces values on PROJECTS.

NbBasesClasses  T

Applicable on: TYPES

 

Remarks: The value of the NbBasesClasses metric is equal the number of classes derived  by a type.

 

Example:

SELECT TYPES WHERE NbBasesClasses > 3

 

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

SELECT TOP 10 TYPES ORDER BY NbBasesClasses DESC

NbParameters M

Applicable on: METHODS

 

Remarks: The keyword NbParameters is used to define a condition on the number of parameters in METHODS. Note that the this reference passed as parameters to instance methods in IL is not taken account by the underlying metric.

 

Example:

SELECT METHODS WHERE NbParameters > 2

 

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

SELECT TOP 10 METHODS ORDER BY NbParameters DESC

 

Recommendations:

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

NbVariables  M

Applicable on: METHODS

 

Remarks: The keyword NbVariables is used to define a condition on the number of local variables declared in METHODS.

 

Example:

SELECT METHODS WHERE NbParameters > 2

 

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

SELECT TOP 10 METHODS ORDER BY NbParameters DESC

 

Recommendations:

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

 

NbOverloads M

New in CQL version 1.8

 

Applicable on: METHODS

 

Remarks: The keyword NbOverloads is used to define a condition on the number of overloads of a METHODS. If a method is not overloaded, its NbOverloads value is equals to 1. This metric is also applicable to constructors.

 

Example:

SELECT METHODS WHERE NbOverloads > 6

 

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

SELECT TOP 10 METHODS ORDER BY NbOverloads DESC

 

Recommendations:

METHODS WHERE NbOverloads > 6 might be a problem to maintain and provoke higher coupling than necessary. This might also reveal a potential misused of the C# and VB.NET language that since C#3 and VB9 support object initialization. This feature helps reducing the number of constructors of a class.

CyclomaticComplexity  TM

New in CQL version 1.2

 

Applicable on: TYPES METHODS

 

Remarks: Cyclomatic complexity is a popular procedural software metric equal to the number of decisions that can be taken in a procedure. Concretely, in C# the CC of a method is the number of following expressions found in the body of the method:

if | while | for | foreach | case | default | continue | goto | && | || | catch | ternary operator ?: | ??

Following expressions are not counted for CC computation:

else | do | switch | try | using | throw | finally | return | object creation | method call | field access

Adapted to the OO world, this metric is defined both on methods and classes/structures (as the sum of its methods CC). Notice that the CC of an anonymous method is not counted when computing the CC of its outer method.

 

Example:

SELECT METHODS WHERE CyclomaticComplexity > 30

 

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

SELECT TOP 10 METHODS ORDER BY CyclomaticComplexity DESC

 

Recommendations:

Methods where CC is higher than 15 are hard to understand and maintain. Methods where CC is higher than 30 are extremely complex and should be split in smaller methods (except if they are automatically generated by a tool).

SizeOfInst  TF

Applicable on: TYPES FIELDS

 

Remarks: The size of instances of an instance field is defined as the size, in bytes, of instances of its type. The size of instance of a static field is equal to 0. The size of instances of a class or a structure is defined as the sum of size of instances of its fields plus the size of instances of its base class. Fields of reference types (class, interface, delegate…) always count for 4 bytes while the footprint of fields of value types (structure, int, byte, double…) might vary. Size of instances of an enumeration is equal to the size of instances of the underlying numeric primitive type. It is computed from the value__ instance field (all enumerations have such a field when compiled in IL). Size of instances of generic types might be erroneous because we can’t statically know the footprint of parameter types (except when they have the class constraint).

 

Example:

SELECT TYPES WHERE SizeOfInst > 12

 

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

SELECT TOP 10 TYPES ORDER BY SizeOfInst DESC

 

Recommendations:

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 framework class is 2064 bytes).

TYPES WHERE SizeOfInst ==0 AND !IsStatic AND !IsTemplate indicate stateless types that might eventually be turned into static classes.

There is no particular recommendation for SizeOfInst values on FIELDS.

TypeRank  T

New in CQL version 1.1

Applicable on: TYPES

 

Remarks: TypeRank values are computed by applying the Google PageRank algorithm on the graph of types' dependencies. A homothety of center 0.15 is applied to make it so that the average of TypeRank is 1.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT TYPES WHERE TypeRank > 0.7

 

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

SELECT TYPES WHERE TypeRank > 0.7 ORDER BY TypeRank DESC

 

Recommendations:

Types with high TypeRank should be more carefully tested because bugs in such types will likely be more catastrophic.

MethodRank  M

New in CQL version 1.1

 

Applicable on: METHODS

 

Remarks: MethodRank values are computed by applying the Google PageRank algorithm on the graph of methods' dependencies. A homothety of center 0.15 is applied to make it so that the average of MethodRank is 1.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT METHODS WHERE MethodRank > 0.7

 

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

SELECT METHODS WHERE MethodRank > 0.7 ORDER BY MethodRank DESC

 

Recommendations:

Methods with high MethodRank should be more carefully tested because bugs in such methods will likely be more catastrophic.

DepthOfInheritance  T

Applicable on: TYPES

 

Remarks: The depth of inheritance for a class is defined as its number of base classes (including the System.Object class thus depth of inheritance >= 1).  The depth of inheritance for an interface is equal to 0. The depth of inheritance for a value type (structure, enumeration) is equal to 2 since they all derive directly from System.ValueType.

 

Example:

SELECT TYPES WHERE DepthOfInheritance > 4

 

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

SELECT TOP 10 TYPES ORDER BY DepthOfInheritance DESC

 

Recommendations:

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.

NbChildren  T

Applicable on: TYPES

 

Remarks: The number of children for a class is the number of sub-classes (no matter their positions in the sub branch of the inheritance tree). The number of children for an interface is the number of types that implement it. Types with numerous children are central type (the framework interface System.ComponentModel.IComponent is implemented by hundreds of classes).

 

Example:

SELECT TYPES WHERE NbChildren > 10

 

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

SELECT TOP 10 TYPES ORDER BY NbChildren DESC

 

Recommendations:

There is no particular recommendation for NbChildren values on TYPES.

FieldCa F

New in CQL version 1.1

 

Applicable on: FIELDS

 

Remarks: The Afferent Coupling for a particular field is the number of methods that directly use it.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT FIELDS WHERE FieldCa > 10

 

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

SELECT TOP 10 FIELDS ORDER BY FieldCa DESC

 

Recommendations:

There is no particular recommendation for FieldCa values on FIELDS.

MethodCe M

New in CQL version 1.1

 

Applicable on: METHODS

 

Remarks: The Efferent Coupling for a particular method is the number of methods it directly depends on. Notice that methods declared in framework projects are taken into account.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT METHODS WHERE MethodCe > 10

 

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

SELECT TOP 10 METHODS ORDER BY MethodCe DESC

 

Recommendations:

There is no particular recommendation for MethodCe values on METHODS.

MethodCa M

New in CQL version 1.1

 

Applicable on: METHODS

 

Remarks: The Afferent Coupling for a particular method is the number of methods that depends directly on it.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT METHODS WHERE MethodCa > 10

 

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

SELECT TOP 10 METHODS ORDER BY MethodCa DESC

 

Recommendations:

There is no particular recommendation for MethodCa values on METHODS.

TypeCe  T

Applicable on: TYPES

 

Remarks: The efferent coupling for a particular type is the number of types it directly depends on. Types with high efferent coupling are more complex than others but you can’t avoid them.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT TYPES WHERE TypeCe > 10

 

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

SELECT TOP 10 TYPES ORDER BY TypeCe DESC

 

Recommendations:

There is no particular recommendation for TypeCe values on TYPES.

TypeCa  T

Applicable on: TYPES

 

Remarks: The afferent coupling for a particular type is the number of types that depends directly on it. Types with high afferent coupling are central type. The fact the public class System.Web.AspNetHostingPermissionAttribute holds one of the highest afferent coupling of the framework is a good indication of the commitment of Microsoft on security.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT TYPES WHERE TypeCa > 10

 

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

SELECT TOP 10 TYPES ORDER BY TypeCa DESC

 

Recommendations:

There is no particular recommendation for TypeCa values on TYPES.

NamespaceCe N

New in CQL version 1.1

 

Applicable on: NAMESPACES

 

Remarks: The Efferent Coupling for a particular namespace is the number of namespaces it directly depends on. Notice that namespaces declared in framework projects are taken into account.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT NAMESPACES WHERE NamespaceCe > 10

 

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

SELECT TOP 10 NAMESPACES ORDER BY NamespaceCe DESC

 

Recommendations:

There is no particular recommendation for NamespaceCe values on NAMESPACES.

NamespaceCa N

New in CQL version 1.1

 

Applicable on: NAMESPACES

 

Remarks: The Afferent Coupling for a particular namespace is the number of namespaces that depends directly on it.

 

Related Link: Code metrics on Coupling, Dead Code, Design flaws and Re-engineering

 

Example:

SELECT NAMESPACES WHERE NamespaceCa > 10

 

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

SELECT TOP 10 NAMESPACES ORDER BY NamespaceCa DESC

 

Recommendations:

There is no particular recommendation for NamespaceCa values on NAMESPACES.

 

ABT  T (Association Between Types)

Applicable on: TYPES

 

Remarks: The Association Between Types metric for a particular class or structure is the number of members of others types it directly uses in the bodies of its methods. Types with high Association Between Types are more complex than others but you can’t avoid them.

 

Example:

SELECT TYPES WHERE ABT > 100

 

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

SELECT TOP 10 TYPES ORDER BY ABT DESC

 

Recommendations:

There is no particular recommendation for ABT values on TYPES.

LCOM  T (Lack Of Cohesion Of Methods)

Applicable on: TYPES

 

Remarks: The single responsibility principle states that a class should have more than one reason to change. Such a class is said to be cohesive. A high LCOM value generally pinpoints a poorly cohesive class. There are several LCOM metrics. The LCOM takes its values in the range [0-1]. The LCOMHS (HS stands for Henderson-Sellers) takes its values in the range [0-2]. Note that the LCOMHS metric is often considered as more efficient to detect non-cohesive types. A LCOMHS value higher than 1 should be considered alarming.

 

Here are algorithms used by VBDepend to compute LCOM metrics:

Where:

 

Example:

SELECT TYPES WHERE LCOM > 0.8

 

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

SELECT TOP 10 TYPES ORDER BY LCOM DESC

 

Recommendations:

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.

 

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

Applicable on: TYPES

 

Remarks: See the section LCOM  T (Lack Of Cohesion Of Methods) for the definition of the LCOMHS metric.

 

Example:

SELECT TYPES WHERE LCOMHS > 1.1

 

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

SELECT TOP 10 TYPES ORDER BY BY LCOMHS DESC

 

Recommendations:

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.

 

 

ProjectLevel A

NamespaceLevel N

TypeLevel T

MethodLevel T

 

New in CQL version 1.2

 

Applicable on: TYPES

Remarks: The Level value for a namespace is defined as follow:

Level metric definitions for projects, types and methods are inferred from the above definition.
This metric has been first defined by John Lakos in his book
Large-Scale C++ Software Design.

Related Link: Layering, the Level metric and the Discourse of Method

 

Example:

SELECT TYPES WHERE TypeLevel == 10

 

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

SELECT PROJECTS ORDER BY ProjectLevel DESC

 

Recommendations:

This metric helps objectively classify the projects, namespaces, types and methods as high level,mid level or low level. There is no particular recommendation for high or small values.
This metric is also useful to discover dependency cycles in your application. For instance if some namespaces are matched by the following CQL query, it means that there is some dependency cycles between the namespaces of your application:

SELECT NAMESPACES WHERE !HasLevel AND !IsInFrameworkAssembly

 

 

Abstractness  A

Applicable on: PROJECTS

 

Remarks: The ratio of the number of internal abstract types (i.e abstract classes and interfaces) to the number of internal types. The range for this metric is 0 to 1, with Abstracness=0 indicating a completely concrete project and Abstracness=1 indicating a completely abstract project.

 

Example:

SELECT PROJECTS WHERE Abstractness  > 0.15

 

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

SELECT TOP 10 PROJECTS ORDER BY Abstractness DESC

 

Recommendations:

There is no particular recommendation for Abstracness values on PROJECTS.

Instability  A

Applicable on: PROJECTS

 

Remarks: The ratio of efferent coupling (AsmCe) to total coupling. Instability = AsmCe / (AsmCe + AsmCa). This metric is an indicator of the package's resilience to change. The range for this metric is 0 to 1, with Instability=0 indicating a completely stable package and Instability=1 indicating a completely instable package.

 

Example:

SELECT PROJECTS WHERE Instability > 0.15

 

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

SELECT TOP 10 PROJECTS ORDER BY Instability DESC

 

Recommendations:

There is no particular recommendation for Instability values on PROJECTS.

NormDistFromMainSeq  A

Applicable on: PROJECTS

 

Remarks: The perpendicular normalized distance of an project from the idealized line Abstracness + Instability = 1 (called main sequence). This metric is an indicator of the project's balance between abstractness and stability. An project squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal projects are either completely abstract and stable (Instability=0, Abstracness=1) or completely concrete and instable (Instability=1, Abstracness=0). The range for this metric is 0 to 1, with NormDistFromMainSeq=0 indicating an project that is coincident with the main sequence and NormDistFromMainSeq=1 indicating an project that is as far from the main sequence as possible. The picture in the report of VBDepend reveals if an project is in the zone of pain (Instability and Abstracness both close to 0) or in the zone of uselessness (Instability and Abstracness both close to 1).

 

Example:

SELECT PROJECTS WHERE NormDistFromMainSeq > 0.5

 

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

SELECT TOP 10 PROJECTS ORDER BY NormDistFromMainSeq DESC

 

Recommendations:

PROJECTS WHERE NormDistFromMainSeq > 0.7 might be problematic. However, in the real world it is very hard to avoid such projects. Therefore, you should allow a small percentage of your projects to violate this constraint. WARN IF Percentage > 15 IN SELECT PROJECTS WHERE NormDistFromMainSeq > 0.7.

DistFromMainSeq  A

Applicable on: PROJECTS

 

Remarks: The metric DistFromMainSeq is equal to NormDistFromMainSeq / Sqrt(2). The range for this metric is thus 0 to 0.7071(…).

 

Example:

SELECT PROJECTS WHERE DistFromMainSeq > 0.3

 

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

SELECT TOP 10 PROJECTS ORDER BY DistFromMainSeq DESC

 

Recommendations:

See NormDistFromMainSeq recommendations.

RelationalCohesion  A

Applicable on: PROJECTS

 

Remarks: Average number of internal relationships per type. Let R be the number of type relationships that are internal to this project (i.e that do not connect to types outside the project). Let N be the number of types within the project. RelationalCohesion = (R + 1)/ N.  The extra 1 in the formula prevents RelationalCohesion=0 when N=1. The relational cohesion represents the relationship that this project has to all its types.

 

Example:

SELECT PROJECTS WHERE RelationalCohesion < 4

 

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

SELECT TOP 10 PROJECTS ORDER BY RelationalCohesion DESC

 

Recommendations:

As classes inside an project should be strongly related, the cohesion should be high. On the other hand, too high values may indicate over-coupling. A good range for RelationalCohesion is 1.5 to 4.0. PROJECTS WHERE RelationalCohesion < 1.5 OR RelationalCohesion > 4.0 might be problematic.

ProjectCa  A

Applicable on: PROJECTS

 

Remarks: The number of types outside this project that depend on types within this project. High afferent coupling indicates that the concerned projects have many responsibilities.

 

Example:

SELECT PROJECTS WHERE ProjectCa > 10

 

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

SELECT TOP 10 PROJECTS ORDER BY ProjectCa DESC

 

Recommendations:

There is no particular recommendation for ProjectCa values on PROJECTS.

AsmCe  A

Applicable on: PROJECTS

 

Remarks: The number of types inside this project that depends on types outside this project. High efferent coupling indicates that the concerned project is dependant.

 

Example:

SELECT PROJECTS WHERE ProjectCe > 10

 

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

SELECT TOP 10 PROJECTS ORDER BY ProjectCe DESC

 

Recommendations:

There is no particular recommendation for ProjectCe values on PROJECTS.

CQL code structure conditions

Here are some definitions:

 

Related Links:

·         Deconstructing Software

·         Keep your code structure clean

·         Hints on how to componentize existing code

IsUsing  ANTM

Enhanced in CQL version 1.1

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS

 

Remarks: The keyword IsUsing is used to select code elements (PROJECTS NAMESPACES TYPES METHODS) which use directly or indirectly a particular code element “XXX”. The column DepthOfIsUsing “XXX” appears automatically in the table result. A code element which uses directly the code element “XXX” has a DepthOfIsUsing “XXX” value equal to 1. A code element which uses directly a code element which uses directly the code element “XXX”  has a DepthOfIsUsing “XXX” value equal to 2 etc…

 

Since CQL 1.1, the code element referred by the IsUsing clause is not necessarily at the same level as the code elements returned by the query. In the following example the IsUsing clause is referring to a namespace (System.Net) while the query is returning some methods.

SELECT TYPES WHERE IsUsing "System.Net" ORDER BY DepthOfIsUsing

 

Example:

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

 

SELECT TYPES WHERE IsUsing "System.Net.Sockets "

 

SELECT NAMESPACES WHERE IsUsing "System.Net.Sockets.Socket"

 

SELECT PROJECTS WHERE IsUsing "System.Net.Sockets.Socket"

 

In this context, you can also use the DepthOfIsUsing keyword to order the rows in the result list.

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

 

SELECT TYPES WHERE IsUsing "System.Net.Sockets " ORDER BY DepthOfIsUsing

 

SELECT NAMESPACES WHERE IsUsing "System.Net.Sockets.Socket" ORDER BY DepthOfIsUsing

 

SELECT PROJECTS WHERE IsUsing "System.Net.Sockets.Socket" ORDER BY DepthOfIsUsing

DepthOfIsUsing  ANTM

Enhanced in CQL version 1.1

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS

 

Remarks: See the section IsUsing ANTM for the definition of the DepthOfIsUsing metric.

 

Since CQL 1.1, the code element referred by the DepthOfIsUsing clause is not necessarily at the same level as the code elements returned by the query. In the following example the DepthOfIsUsing clause is referring to a namespace (System.Net) while the query is returning some types.

SELECT TYPES WHERE DepthOfIsUsing "System.Net" < 3 ORDER BY DepthOfIsUsing

 

Examples:

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

 

SELECT TYPES WHERE DepthOfIsUsing "System.Net.Sockets.Socket" < 3

 

SELECT NAMESPACES WHERE DepthOfIsUsing "System.Net.Sockets" < 3

 

SELECT PROJECTS WHERE DepthOfIsUsing "System" < 3

 

In this context, you can also use the DepthOfIsUsing keyword to order the rows in the result list.

SELECT METHODS WHERE DepthOfIsUsing "System.Xml.XmlWriter.WriteEndElement()" < 3 ORDER BY DepthOfIsUsing

 

SELECT TYPES WHERE DepthOfIsUsing "System.Net.Sockets.Socket" < 3 ORDER BY DepthOfIsUsing

 

SELECT NAMESPACES WHERE DepthOfIsUsing "System.Net.Sockets" < 3 ORDER BY DepthOfIsUsing

 

SELECT PROJECTS WHERE DepthOfIsUsing "System" < 3 ORDER BY DepthOfIsUsing

IsDirectlyUsing  ANTM

New in CQL version 1.1

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS

 

Remarks: The keyword IsDirectlyUsing is used to select code elements (PROJECTS NAMESPACES TYPES METHODS) which use directly a particular code element “XXX”. The column DepthOfIsUsing “XXX” appears automatically in the table result. The clause IsDirectlyUsing “XXX” is equivalent to the clause DepthOfIsUsing “XXX” == 1.

 

Example:

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

 

In this context, you can also use the DepthOfIsUsing keyword to order the rows in the result list.

SELECT METHODS WHERE IsDirectlyUsing "System.Xml.XmlWriter.WriteEndElement()" BY DepthOfIsUsing

 

IsUsedBy  ANTMF

Enhanced in CQL version 1.1

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsUsedBy is used to select code elements (PROJECTS, NAMESPACES TYPES METHODS FIELDS) which are directly or indirectly used by a particular code element “XXX”. The column DepthOfIsUsedBy “XXX” appears automatically in the table result. The code element “XXX” has a DepthOfIsUsedBy “XXX” value equal to 0. A code element which is used by directly the code element “XXX” has a DepthOfIsUsedBy “XXX” value equal to 1. A code element which is used by directly a code element which is used by directly the code element “XXX”  has a DepthOfIsUsedBy “XXX” value equal to 2 etc…

 

Since CQL 1.1, the code element referred by the IsUsedBy clause is not necessarily at the same level as the code elements returned by the query. In the following example the IsUsedBy clause is referring to a namespace (System.Net) while the query is returning some types.

SELECT TYPES WHERE IsUsedBy "System.Net"

 

Examples:

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

 

SELECT TYPES WHERE IsUsedBy "System.Net.Sockets.Socket"

 

SELECT NAMESPACES WHERE IsUsedBy "System.Net.Sockets"

 

SELECT PROJECTS WHERE IsUsedBy "System"

 

In this context, you can also use the DepthOfIsUsedBy keyword to order the rows in the result list.

SELECT METHODS WHERE IsUsedBy "System.Xml.XmlWriter.WriteEndElement()" ORDER BY DepthOfIsUsedBy

 

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

 

SELECT NAMESPACES WHERE IsUsedBy "System.Net.Sockets" ORDER BY DepthOfIsUsedBy

 

SELECT PROJECTS WHERE IsUsedBy "System" ORDER BY DepthOfIsUsedBy

DepthOfIsUsedBy  ANTMF

Enhanced in CQL version 1.1

 

Applicable on: PROJECTS NAMESPACES TYPES FIELDS

 

Remarks: See the section IsUsedBy ANTMF for the definition of the DepthOfIsUsedBy metric.

 

Since CQL 1.1, the code element referred by the DepthOfIsUsedBy clause is not necessarily at the same level as the code elements returned by the query. In the following example the DepthOfIsUsedBy clause is referring to a namespace (System.Net) while the query is returning some types.

SELECT TYPES WHERE DepthOfIsUsedBy "System.Net" < 3 ORDER BY DepthOfIsUsedBy

 

Examples:

SELECT METHODS WHERE DepthOfIsUsedBy "System.Xml.XmlWriter.WriteEndElement()" ORDER BY DepthOfIsUsedBy

 

SELECT TYPES WHERE DepthOfIsUsedBy "System.Net.Sockets.Socket" < 3

 

SELECT NAMESPACES WHERE DepthOfIsUsedBy "System.Net.Sockets" < 3

 

SELECT PROJECTS WHERE DepthOfIsUsedBy "System" < 3

 

In this context, you can also use the DepthOfIsUsedBy keyword to order the rows in the result list.

SELECT METHODS WHERE DepthOfIsUsedBy "System.Xml.XmlWriter.WriteEndElement()" ORDER BY DepthOfIsUsedBy

 

SELECT TYPES WHERE DepthOfIsUsedBy "System.Net.Sockets.Socket" < 3 ORDER BY DepthOfIsUsedBy

 

SELECT NAMESPACES WHERE DepthOfIsUsedBy "System.Net.Sockets" < 3 ORDER BY DepthOfIsUsedBy

 

SELECT PROJECTS WHERE DepthOfIsUsedBy "System" < 3 ORDER BY DepthOfIsUsedBy

IsDirectlyUsedBy  ANTMF

New in CQL version 1.1

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsDirectlyUsedBy is used to select code elements (PROJECTS, NAMESPACES TYPES METHODS FIELDS) which are directly used by a particular code element “XXX”. The column DepthOfIsUsedBy “XXX” appears automatically in the table result. The clause IsDirectlyUsedBy “XXX” is equivalent to the clause DepthOfIsUsedBy “XXX” == 1.

 

Examples:

SELECT TYPES WHERE IsDirectlyUsedBy "System.Net.Sockets.Socket"

 

In this context, you can also use the DepthOfIsUsedBy keyword to order the rows in the result list.

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

CreateA  M

Applicable on: METHODS

 

Remarks: The keyword CreateA is used to select METHODS which call directly or indirectly a constructor of a particular type “XXX”. The column DepthOfCreateA “XXX” appears automatically in the table result. A constructor of the type “XXX” has a DepthOfCreateA “XXX” value equal to 0.  A method which calls directly a constructor of “XXX” has a DepthOfCreateA “XXX” value equal to 1. A method which calls directly a method which calls directly a constructor of “XXX” has a DepthOfCreateA “XXX” value equal to 2 etc…

 

Example:

SELECT METHODS WHERE CreateA "System.Xml.XmlWriter"

 

In this context, you can also use the DepthOfCreateA keyword to order the rows in the result list.

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

DepthOfCreateA  M

Applicable on: METHODS

 

Remarks: See the section CreateA M for the definition of the DepthOfCreateA metric.

 

Example:

SELECT METHODS WHERE DepthOfCreateA "System.Xml.XmlWriter" < 3

 

In this context, you can also use the DepthOfCreateA keyword to order the rows in the result list.

SELECT METHODS WHERE DepthOfCreateA "System.Xml.XmlWriter" < 3 ORDER BY DepthOfCreateA

DeriveFrom  T

Applicable on: TYPES

 

Remarks: The keyword DeriveFrom is used to select TYPES which derive from directly or indirectly a particular class “XXX”. The column DepthOfDeriveFrom “XXX” appears automatically in the table result. The class “XXX” has a DepthOfDeriveFrom “XXX” value equal to 0. A class which derives directly from the class “XXX” has a DepthOfDeriveFrom “XXX” value equal to 1. A class which derives directly from a class which derives directly from  the class “XXX”  has a DepthOfDeriveFrom “XXX” value equal to 2 etc…

 

Example:

SELECT TYPES WHERE DeriveFrom "System.Windows.Forms.Control"

 

In this context, you can also use the DepthOfDeriveFrom keyword to order the rows in the result list.

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

DepthOfDeriveFrom  T

Applicable on: TYPES

 

Remarks: See the section DeriveFrom T for the definition of the DepthOfDeriveFrom metric.

 

Example:

SELECT TYPES WHERE DepthOfDeriveFrom "System.Windows.Forms.Control"> 3

 

In this context, you can also use the DepthOfDeriveFromkeyword to order the rows in the result list.

SELECT TYPES WHERE DepthOfDeriveFrom "System.Windows.Forms.Control"> 3

ORDER BY DepthOfDeriveFrom

Implement  T

Applicable on: TYPES

 

Remarks: The keyword Implement is used to select TYPES which implement or extend a particular interface “XXX”.

 

Example:

SELECT TYPES WHERE Implement "System.Web.IHttpHandler"

HasAttribute  ATMF

Applicable on: PROJECTS TYPES METHODS FIELDS

 

Remarks: The keyword HasAttribute is used to select PROJECTS TYPES METHODS and FIELDS that are tagged with a particular attribute “XXX”.

 

Example:

SELECT METHODS WHERE HasAttribute "NUnit.Framework.Test"

IsOfType  F

Applicable on: FIELDS

 

Remarks: The keyword IsOfType is used to select FIELDS of a particular type “XXX”.

 

Example:

SELECT FIELDS WHERE IsOfType "System.Uri"

ReturnType  M

New in CQL version 1.3

 

Applicable on: METHODS

 

Remarks: The keyword ReturnType is used to select FIELDS of a particular type “XXX”.

 

Example:

SELECT FIELDS WHERE IsOfType "System.Uri"

 

CQL boolean conditions

IsPublic  TMF

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword IsPublic is used to define a condition that matches public TYPES, METHODS or FIELDS.

 

Example:

SELECT METHODS WHERE IsPublic

IsProtected  TMF

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword IsProtected is used to define a condition that matches protected TYPES, METHODS or FIELDS. Note that a type can be declared as protected only if it is nested in another type.

 

Example:

SELECT METHODS WHERE IsProtected

IsPrivate  TMF

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword IsPrivate is used to define a condition that matches private TYPES, METHODS or FIELDS.

 

Example:

SELECT METHODS WHERE IsPrivate

IsInFrameworkAssembly  NTMF

New in CQL version 1.1

 

Applicable on: NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsInFrameworkAssembly is used to distinguish framework code elements from application code elements.

 

Example:

SELECT METHODS WHERE IsInFrameworkAssembly

IsFrameworkAssembly  A

New in CQL version 1.8

 

Applicable on: PROJECTS

 

Remarks: The keyword IsFrameworkAssembly is used to distinguish framework projects from application projects.

 

Example:

SELECT PROJECTS WHERE IsFrameworkAssembly

IsEnumValue  F

Applicable on: FIELDS

 

Remarks: The keyword IsEnumValue is used to define a condition that matches FIELDS which are values of enumerations.

 

Example:

SELECT FIELDS WHERE IsEnumValue

IsConstructor  M

Applicable on: METHODS

 

Remarks: The keyword IsConstructor is used to define a condition that matches METHODS which are instance constructors.

 

Example:

SELECT METHODS WHERE IsConstructor

IsStatic  TMF

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword IsStatic is used to define a condition that matches static TYPES, METHODS or FIELDS. A static type is a class which declares only static members.

 

Example:

SELECT METHODS WHERE IsStatic

IsOverloaded  M

Applicable on: METHODS

 

Remarks: The keyword IsOverloaded is used to define a condition that matches METHODS which are overloaded.

 

Example:

SELECT METHODS WHERE IsOverloaded

IsVirtual  M

Applicable on: METHODS

 

Remarks: The keyword IsVirtual is used to define a condition that matches METHODS which are virtual or override.

 

Example:

SELECT METHODS WHERE IsVirtual

IsAbstract  TM

Applicable on: TYPES METHODS

 

Remarks: The keyword IsAbstract is used to define a condition that matches TYPES or METHODS which are abstract. Note that interfaces and interfaces’ methods are considered as abstract.

 

Example:

SELECT TYPES WHERE IsAbstract AND !IsInterface

IsTemplate  TM

Applicable on: TYPES METHODS

 

Remarks: The keyword IsTemplate is used to define a condition that matches TYPES or METHODS which are generic.

 

Example:

SELECT TYPES WHERE IsTemplate

HasLevel ANTM

New in CQL version 1.2

 

Applicable on: TYPES

 

Remarks: The keyword HasLevel is used to detect dependencies cycle in the structure of your code. More details are available in the recommendation section of the Level metric.

 

Example:

SELECT NAMESPACES WHERE !HasLevel AND !IsInFrameworkAssembly

ContainsNamespaceDependencyCycles A

ContainsTypeDependencyCycles T

ContainsMethodDependencyCycles M

 

New in CQL version 1.2

 

Applicable on: TYPES

 

Remarks: These keywords allow to know which part of your code contains dependency cycles. Typically, you’ll want to ensure that there is no dependency cycle between namespaces of a same project but you’ll accept dependency cycles between types of a same namespace and between methods of a same type (this is recursion). Dependency cycles between projects are detected at the analysis level and are pinpointed in the VBDepend HTML report if they exist

 

Example:

SELECT PROJECTS WHERE ContainsNamespaceDependencyCycles

IsLiteral  F

Applicable on: FIELDS

 

Remarks: The keyword IsLiteral is used to define a condition that matches FIELDS which are literals. Literals fields are C# fields declared with the keyword const, VB.NET fields declared with the keyword Const and enumeration values.

 

Example:

SELECT METHODS WHERE IsLiteral AND !IsEnumValue

IsClassConstructor  M

Applicable on: METHODS

 

Remarks: The keyword IsClassConstructor is used to define a condition that matches METHODS which are class constructors (also sometimes referred as static constructors).

 

Example:

SELECT METHODS WHERE IsClassConstructor

IsClass  T

Applicable on: TYPES

 

Remarks: The keyword IsClass is used to define a condition that matches TYPES which are classes.

 

Example:

SELECT METHODS WHERE IsEventRemover AND !IsDelegate

IsStructure  T

Applicable on: TYPES

 

Remarks: The keyword IsStructure is used to define a condition that matches TYPES which are structures.

 

Example:

SELECT METHODS WHERE IsStructure

IsEnumeration  T

Applicable on: TYPES

 

Remarks: The keyword IsEnumeration is used to define a condition that matches TYPES which are enumerations.

 

Example:

SELECT METHODS WHERE IsEnumeration

IsInterface  T

Applicable on: TYPES

 

Remarks: The keyword IsInterface is used to define a condition that matches TYPES which are interfaces.

 

Example:

SELECT METHODS WHERE IsInterface

IsExceptionClass  T

Applicable on: TYPES

 

Remarks: The keyword IsExceptionClass is used to define a condition that matches TYPES which are exception classes. An exception class is class which derives directly or indirectly from the framework class System.Exception.

 

Example:

SELECT METHODS WHERE IsAttributeClass

IsObsolete  TMF

 

New in CQL version 1.3

 

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword IsObsolete is used to define a condition that matches TYPES METHODS and FIELDS that are tagged with the System.Obsolete attribute.

 

Example:

SELECT METHODS WHERE IsObsolete

CQL boolean conditions dedicated to Build Comparison

 

Related Link:

Ensure the quality of the code that will be developed this year

How to avoid regression bugs while adding new features

WasAdded  ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword WasAdded is used to define a condition that matches PROJECTS NAMESPACES TYPES METHODS and FIELDS that were added, i.e that exist in the newer build and not in the older one. This keyword forces the CQL execution to be done against the newer build and is then incompatible with keywords WasRemoved IsNotUsedAnymore IsInOlderBuild.

 

Example:

SELECT METHODS WHERE WasAdded

 

 

WasRemoved  ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword WasRemoved is used to define a condition that matches PROJECTS NAMESPACES TYPES METHODS and FIELDS that were removed, i.e that exist in the newer build and not in the older one. This keyword forces the CQL execution to be done against the older build and is then incompatible with keywords WasAdded IsUsedRecently and IsInNewerBuild.

 

Example:

SELECT METHODS WHERE WasRemoved

 

 

CodeWasChanged ANTM

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS

 

Remarks: The keyword CodeWasChanged is used to define a condition that matches PROJECTS NAMESPACES TYPES and METHODS where code were changed. An PROJECTS, a NAMESPACES or a TYPES is deemed as changed when it contains at least one method where code was changed or if it contains a child that has been added or deleted.

 

To know if the code of a method is changed, we compute 2 hash values, one on the IL instruction + name of other members called + string operand and the other one on integer operand. We need the second hash value to avoid setting CodeWasChanged on methods where IL code was just changed because of the modification of an enumeration type. Indeed, in this case the values of the enumeration are directly inserted in the body of the user methods by the compiler.

 

Example:

SELECT METHODS WHERE CodeWasChanged

 

 

CommentsWereChanged ANTM

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS

 

Remarks: The keyword CommentsWereChanged is used to define a condition that matches PROJECTS NAMESPACES TYPES and METHODS that where comments were changed. So far, the algorithm to detect if comments were changed is just based on line number and not on hash values meanings that this algorithm might miss some true positive.

 

Example:

SELECT METHODS WHERE CommentsWereChanged

 

 

VisibilityWasChanged TMF

 

New in CQL version 1.3

 

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword VisibilityWasChanged is used to define a condition that matches TYPES METHODS and FIELDS where visibility was changed.

 

Example:

SELECT METHODS WHERE VisibilityWasChanged

 

 

WasChanged  ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword WasChanged is used to define a condition that matches PROJECTS NAMESPACES TYPES METHODS and FIELDS that were changed.

·         A method is deemed as changed if its ReturnType was changed or its VisibilityWasChanged or its CodeWasChanged or if its CommentsWereChanged.

·         A field is deemed as changed if its IsOfTypewas changed or its VisibilityWasChanged.

·         A type is deemed as changed if its VisibilityWasChanged or if its CommentsWereChanged or if it contains a method or a field that WasChanged or WasAdded or WasRemoved.

·         A namespace is deemed as changed if it contains a type that WasChanged.

·         An project is deemed as changed if it contains a namespace that WasChanged.

 

Example:

SELECT METHODS WHERE WasChanged

 

 

BecameObsolete TMF

 

New in CQL version 1.3

 

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword BecameObsolete is used to define a condition that matches TYPES METHODS and FIELDS that was not tagged with the System.Obsolete attribute and is now tagged with this attribute in the newer build.

 

Example:

SELECT METHODS WHERE BecameObsolete

 

 

IsUsedRecently ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsUsedRecently is used to define a condition that matches framework PROJECTS or NAMESPACES TYPES METHODS and FIELDS declared in framework projects that were not used by the older build and that are now used by the newer build. This keyword forces the CQL execution to be done against the newer build and is then incompatible with keywords WasRemoved IsNotUsedAnymore IsInOlderBuild.

 

Example:

SELECT METHODS WHERE IsUsedRecently

 

 

IsNotUsedAnymore ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsNotUsedAnymore is used to define a condition that matches PROJECTS or NAMESPACES TYPES METHODS and FIELDS declared in framework projects that were used by the older build and that are now not used anymore by the newer build. This keyword forces the CQL execution to be done against the older build and is then incompatible with keywords WasAdded IsUsedRecently and IsInNewerBuild.

 

Example:

SELECT METHODS WHERE IsNotUsedAnymore

 

IsUsedDifferently ANT

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES

 

Remarks: The keyword IsUsedDifferently is used to define a condition that matches PROJECTS or NAMESPACES and TYPES  declared in framework projects that contains some code element (i.e NAMESPACES TYPES METHODS or FIELDS) that matches IsNotUsedAnymore or IsUsedRecently.

 

Example:

SELECT METHODS WHERE IsUsedDifferently

IsInNewerBuild ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsInNewerBuild is used to forces the CQL execution to be done against the newer build. It is then incompatible with keywords WasRemoved IsNotUsedAnymore IsInOlderBuild.

 

Example:

SELECT METHODS WHERE IsInNewerBuild

 

IsInOlderBuild ANTMF

 

New in CQL version 1.3

 

Applicable on: PROJECTS NAMESPACES TYPES METHODS FIELDS

 

Remarks: The keyword IsInOlderBuild is used to forces the CQL execution to be done against the older build. It is then incompatible with keywords WasAdded IsUsedRecently and IsInNewerBuild.

 

Example:

SELECT METHODS WHERE IsInOlderBuild

 

 

 

 

 

CQL boolean conditions dedicated to Optimal Encapsulation

 

Related Link: Optimal Encapsulation

CouldBeProtected  TMF

 

New in CQL version 1.5

 

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword CouldBeProtected is used to define a condition that matches public or internal TYPES METHODS and FIELDS that could be declared as protected in C# (Protected in VB.NET) within the context of the analyzed projects. A code element can be protected if it is not used outside of the classes that derive from the class it is declared in.

 

Notice that a type declared in the global scope (i.e that is not nested inside a class) cannot be declared as protected.

 

Example:

SELECT METHODS WHERE CouldBeProtected

 

CouldBePrivate  TMF

 

New in CQL version 1.5

 

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword CouldBePrivate is used to define a condition that matches public or internal TYPES METHODS and FIELDS that could be declared as private in C# (Private in VB.NET) within the context of the analyzed projects. A code element can be private if it is not used outside of the type it is declared in.

 

Notice that a type declared in the global scope (i.e that is not nested inside a class) cannot be declared as private.

 

 

Example:

SELECT METHODS WHERE CouldBePrivate

 

ShouldBePublic  TMF

 

New in CQL version 1.5

 

Applicable on: TYPES METHODS FIELDS

 

Remarks: The keyword ShouldBePublic is used to define a condition that matches internal TYPES METHODS and FIELDS that are used outside their declaring project thanks to the attribute System.Compilers.Services.InternalsVisibleToAttribute. In general, having code elements that are considered as ShouldBePublic is not a problem because it is made on purpose. However, it can be interesting to list them.

 

Example:

SELECT METHODS WHERE ShouldBePublic

 

 

 

 

 

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

 

 

IsImmutable  TF

 

For Type New in CQL version 1.4

For Field New in CQL version 1.8

 

Applicable on: TYPES FIELDS

 

Remarks on Immutable Types: The keyword IsImmutable is used to define a condition that matches immutable TYPES (classes and structures). A type is considered as immutable if its instance fields cannot be modified once an instance has been built by a constructor.

 

·         A stateless type (i.e a type without any instance field) is considered as immutable.

·         A type with at least one non-private instance field is considered as mutable (because such a field can be eventually modified outside the type).

·         A class that derives directly or indirectly from a mutable type is considered as mutable.

·         Enumeration, static type, type defined in framework projects and delegate classes are never considered as immutable. Although these types might match the definition of immutability, considering them as immutable would disturb developers while they care for their own code immutable types.

·         Particularly, classes that derive directly or indirectly from a class defined in a framework project that is not the System.Object class, is never considered as immutable.

·         Using the C# readonly keyword on your own instance field is a good way to achieve immutability.

·         Notice that if a type T has some instance fields that are of reference type, the object pointed by such a reference might be modified without breaking the immutability of T.

 

It is still possible to break immutability by using the C# keyword ref to allow a tier method to modify the state of an instance field. As .NET framework designers considered that the immutability of the class System.String can be broken using advanced means such as reflection or unsafe code, you should consider that using the C# keyword ref or reflection or unsafe code are advanced means to break immutability of your own types.

 

Immutable types are especially useful when you have to deal with multi-threading application. Indeed, accesses to instances of immutable types don’t need to be synchronized because such objects can’t be modified; hence all accesses are read-only accesses.

 

Remarks on Immutable Fields: The keyword IsImmutable is used to define a condition that matches immutable FIELDS (both static fields and instance fields). A static field is considered as immutable if it is private and if it is only written by the static constructor. An instance field is considered as immutable if it is private and if it is only written by its type’s constructor(s) or its type’s static constructor. Literal fields, enum value fields, fields defined in tier projects are never considered as immutable to avoid noise in your search for immutable fields.

 

A field that matches the IsInitOnly condition is always considered as immutable. In addition, a field that matches the IsImmutable condition can be safely marked as readonly (i.e this will provoke matching for IsInitOnly condition).

 

Related Link: Immutable types: understand their benefits and use them

 

Example:

SELECT TYPES WHERE IsImmutable

SELECT FIELDS WHERE IsImmutable AND !IsInitOnly

ChangesObjectState  M

 

New in CQL version 1.4

 

Applicable on: METHODS

 

Remarks: The keyword ChangesObjectState is used to define a condition that matches METHODS that explicitly modify an instance field of their type. Notice that constructors are matched. A static method or a class constructor can also be matched, for example, if it modifies the state of an object passed by reference. Notice also that an instance method of a type T that modifies an instance of T that is not the one referenced by the this reference is also matched. The idea is that methods that match ChangesObjectState complexify the program because they break type immutability (see IsImmutable).

 

Related Link: Immutable types: understand their benefits and use them

 

Example:

SELECT METHODS WHERE ChangesObjectState

ChangesTypeState  M

 

New in CQL version 1.4

 

Applicable on: METHODS

 

Remarks: The keyword ChangesTypeState is used to define a condition that matches METHODS that explicitly modify a static field of their type. Notice that class constructor, constructors, instance methods and static methods are matched.

 

Related Link: Immutable types: understand their benefits and use them

 

Example:

SELECT METHODS WHERE ChangesObjectState

ReadsMutableObjectState  M

 

New in CQL version 1.8

 

Applicable on: METHODS

 

Remarks: The keyword ReadsMutableObjectState is used to define a condition that matches METHODS that reads at least one mutable instance field. Field mutability is defined in IsImmutable condition definition.

 

Example:

SELECT METHODS WHERE ReadsMutableObjectState

ReadsMutableTypeState  M

 

New in CQL version 1.8

 

Applicable on: METHODS

 

Remarks: The keyword ReadsMutableTypeState is used to define a condition that matches METHODS that reads at least one mutable static field. Field mutability is defined in IsImmutable condition definition.

 

Example:

SELECT METHODS WHERE ReadsMutableTypeState

ReadsImmutableObjectState  M

 

New in CQL version 1.8

 

Applicable on: METHODS

 

Remarks: The keyword ReadsImmutableObjectState is used to define a condition that matches METHODS that reads at least one immutable instance field. Field mutability is defined in IsImmutable condition definition.

 

Example:

SELECT METHODS WHERE ReadsImmutableObjectState

ReadsImmutableTypeState  M

 

New in CQL version 1.8

 

Applicable on: METHODS

 

Remarks: The keyword ReadsImmutableTypeState is used to define a condition that matches METHODS that reads at least one immutable static field. Field mutability is defined in IsImmutable condition definition.

 

Example:

SELECT METHODS WHERE ReadsImmutableTypeState

IsWritingField  M

New in CQL 1.4

 

Applicable on: METHODS

 

Remarks: The keyword IsWritingField is used to select METHODS that write a particular field “XXX”, i.e that changes the state of the field “XXX”. The keyword IsWritingField matches also methods that indirectly write the field “XXX”, i.e that calls a method that writes the field “XXX”.

 

The column DepthOfIsWritingField “XXX” appears automatically in the table result. The methods that directly write the field “XXX” have a DepthOfIsWritingField “XXX” value equal to 0. A method that directly calls a method that directly write the field “XXX” has a DepthOfIsWritingField “XXX” value equal to 1. etc…

 

An instance constructor that initializes an instance field of its type is not matched.

A static constructor that initializes a static field of its class is not matched.

 

Examples:

SELECT METHODS WHERE IsWritingField "MyNamespace.MyType.m_Field"

 

In this context, you can also use the DepthOfIsWritingField keyword to order the rows in the result list.

SELECT METHODS WHERE IsWritingField "MyNamespace.MyType.m_Field" ORDER BY DepthOfIsWritingField DESC

DepthOfIsWritingField  M

New in CQL 1.4

 

Applicable on: METHODS

 

Remarks: See the section IsWritingField M for the definition of the DepthOfIsWritingField metric.

 

Example:

SELECT METHODS WHERE DepthOfIsWritingField "MyNamespace.MyType.m_Field" < 3

 

In this context, you can also use the DepthOfIsWritingField keyword to order the rows in the result list.

SELECT METHODS WHERE DepthOfIsWritingField "MyNamespace.MyType.m_Field" < 3 ORDER BY DepthOfIsWritingField DESC

IsDirectlyWritingField  M

New in CQL 1.4

 

Applicable on: METHODS

 

Remarks: The keyword IsDirectlyWritingField is used to select METHODS that write a particular field “XXX”, i.e that changes the state of the field “XXX”. The clause IsDirectlyWritingField “XXX” is equivalent to the clause DepthOfIsWritingField “XXX” == 1.

 

Example:

SELECT METHODS WHERE IsDirectlyWritingField "MyNamespace.MyType.m_Field"