Code
Query Language 1.8 Specification
CQL
1.8
CQL
1.8 is supported by NDepend 2.9 and higher
Copyright
SMACCHIA.COM S.A.R.L 2006/2007/2008/2009
All
right reserved
The CQL language and real-world
needs
Storing CQL queries and constraints
in your C# or VB.NET source code
Some examples of queries and
constraints written in CQL
Examples of code Quality constraints
Examples of naming constraints
Examples of design constraints
Examples of encapsulation
constraints
Examples of queries on the graph of
dependencies
Examples of queries on the
inheritance tree
Examples of queries to get extremum
WARN IF xxx IN: Query vs. Constraint
TOP xxx: Restrict the number of rows
in the result
FROM / OUT OF xxx: Domain of search
WHERE xxx: Define a set of
conditions
ORDER BY xxx: Order rows of the
result
Kind of Code Elements’ Names
Prefixes
The OPTIONAL: Code Elements’ Names
Prefix
ABT
T (Association Between Types)
LCOM
T (Lack Of Cohesion Of Methods)
LCOMHS T (Lack Of Cohesion Of Methods
Henderson-Sellers)
CQL test coverage metrics conditions
ContainsNamespaceDependencyCycle A
ContainsMethodDependencyCycle M
CQL boolean conditions dedicated to
Build Comparison
CQL boolean conditions dedicated to
Optimal Encapsulation
CQL boolean conditions dedicated to
Purity / Side-Effects / Mutability
CQL is a
language which allows writing queries on the code structure of any.NET
application, independently of the .NET language used (C#, VB.NET, C++/CLI …).
For example, the following CQL query returns all the methods of your
application with more than 200 IL instructions, ordered from the biggest to the
smallest:
SELECT METHODS WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC
You might
wish to avoid methods with more than 200 IL instructions since they are hard to
maintain. After having shrunk all your methods, you certainly want to be
notified when during development a method exceeds this threshold. The CQL
language addresses this need by allowing the transformation of queries into
constraints. For example, here is our previous query rewritten as a constraint:
WARN IF Count >
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.
The tool VisualNDepend
allows the editing and execution of CQL queries and constraints. A GUI allows
you to have a unique understanding of your application. VisualNDepend
can also be used to generate reports during each build of your application.

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


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 >
Or maybe,
all generated methods are in dedicated assemblies, namespaces or types:
WARN IF Count >
Or maybe,
you prefer to mention each one explicitly:
WARN IF Count >
You can also
mix all these features in the same constraint:
WARN IF Count >
NDepend
stores your CQL queries and constraints in the project file. As the source code is the design you might prefer storing your CQL queries and
constraints directly in your source code (C#, VB.NET...). To do so, you must
reference the assembly ./Lib/NDepend.CQL.dll and use the attribute NDepend.CQL.CQLConstraintAttribute
in your code.
WARN IF Count >
// METHODS WHERE NbILInstructions > 200 are extremely complex and
// should be split in smaller methods
// (except if they are
automatically generated by a tool).
WARN IF Count >
// 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 >
// 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 >
// 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 >
// 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 >
// 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 >
// 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