Geeks With Blogs
Josh Reuben
·        CQL is a SQL-like language (SELECT..FROM..WHERE) for static analysis of .NET code.
·        It is a nice complement to code contracts, & is usable in unit tests. If you've ever looked at creating custom FxCop rules using the archaic and undocumented Introspection API (see http://www.binarycoder.net/fxcop/html/index.html ), then you will appreciate the elegant CQL syntax for static analysis!
·        supported by NDepend http://www.NDepend.com  
How It Works
·        Lets dive into a contrived example - a CQL query that returns the top 10 methods of your application with more than 200 IL instructions:
SELECTTOP 10 METHODS
WHERENbILInstructions > 200
ORDERBYNbILInstructionsDESC
·        queries can also be specified as constraints: by adding a WARN IF xxx IN clause at the beginning. There are two kinds of CQL constraint: Count, Percentage.
WARNIFCount > 0IN
SELECTMETHODS
WHERENbILInstructions > 200
·        CQL supports many metric clauses that can be leveraged as constraints in WHERE & ORDERBY statements, using logical operators such as AND, OR
·        The tool VisualNDependIts CQL editor offers intellisense. allows the editing and execution of CQL queries and constraints - can generate reports during build.
·        The types of elements which a SELECTclause can refer to include: METHODS/ FIELDS/ TYPES/ NAMESPACESand ASSEMBLIES
·        The resultset can be filtered to retrieve matching elements using the NameLike  / NameIs , FullNameLike or FullNameIs clauses (e.g. WHERENameLike"XXX") . There is an additional  FROM / OUTOFclause that can refine a query against specific assemblies, namespaces or types:
SELECTMETHODS
OUTOFNAMESPACES"MyNS1","MyNS2" , "System.Xml"
WHERENbILInstructions > 200
ORFullNameLike"Control..ctor(String)"
 
·        NDepend stores CQL queries and constraints in the project file - to store CQL queries and constraints directly in source code, must reference the assembly ./Lib/NDepend.CQL.dll and use the attribute NDepend.CQL.CQLConstraintAttribute:
using System.Collections.Generic;
using NDepend.CQL;
 
[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;
}
·        The OPTIONAL: prefix indicate to the CQL compiler that if the code element is not found, an error should not be emitted;
WARN IF Count> 0IN
SELECTMETHODS
WHEREIsDirectlyUsing"OPTIONAL:System.Threading.Thread.Sleep(Int32)"
·        The OPTIONAL: prefix must always appear before an ASSEMBLY: NAMESPACE: TYPE: METHOD: or FIELD prefix.
·        Some metrics can be computed only if PDB files are present - PDB sequence points allow to obtain a logical LOC of code instead of a physical LOC (computed from source files). 2 significant advantages: coding style & language indenpendence. Only concrete code that is effectively executed is considered when computing LOC. see:  http://codebetter.com/blogs/patricksmacchia/archive/2007/10/05/why-is-it-useful-to-count-the-number-of-lines-of-code-loc.aspx
·        The following tables detail the relevant metrics. Applicability is abbreviated as follows:
o   A             - ASSEMBLIES
o   N            - NAMESPACES
o   T             - TYPES
o   M           - METHODS
o   F             - FIELDS
CQL metric conditions
Metric
Applicability
Return / Match
Code Smell
NbLinesOfCode
ANTM
#Lines of code
 
NbILInstructions
ANTM
#Lines of IL instructions
 
NbLinesOfComment
ANTM
#Lines of comments
 
PercentageComment
ANTM
%code that is comments
<20 OR > 40
NbMethods
ANT
#methods
TYPES WHERE NbMethods > 20
NbFields
ANT
#fields
TYPES WHERE NbFields > 20
NbTypes
AN
#Types
 
NbNamespaces
A
#Namespaces
 
NbInterfacesImplemented
T
# interfaces implemented by a type
 
NbParameters
M
#Parameters
METHODS WHERE NbParameters > 5
 
NbVariables
M
#Variables
METHODS WHERE NbVariables > 8
NbOverloads
 
M
#overloads
* Helps reduce # ctors
METHODS WHERE NbOverloads > 6
CyclomaticComplexity
TM
#decisions that can be taken in a procedure
METHODS WHERE CC > 15
ILCyclomaticComplexity
TM
# jump/branch IL instructions
METHODS WHERE ILCC > 20
ILNestingDepth
M
max # encapsulated scopes inside a method body
METHODS WHERE ILND > 4
SizeOfInst
TF
Byte size of instances of a type
TYPES WHERE SizeOfInst > 64 - consider FlyWeight pattern
TypeRank
T
homothety of center – via PageRank à importance of type
 
MethodRank
M
"
 
DepthOfInheritance
T
# base classes
TYPES WHERE DOI > 6
NbChildren
T
# derived classes
 
FieldCa
F
Afferent Coupling - # methods that directly use the field
 
MethodCe
M
Efferent Coupling - #methods the method directly depends on
 
MethodCa
M
Afferent Coupling - # methods that directly use the method
 
TypeCe
T
Efferent Coupling - #types the type directly depends on
 
TypeCa
T
Afferent Coupling - # types that directly use the type
 
NamespaceCe
N
Efferent Coupling - #namespaces the namespace directly depends on
 
NamespaceCa
N
Afferent Coupling - # namespaces that directly use the namespace
 
ABT
T
Association Between Types - # members of others types it directly uses in the bodies of its methods
 
LCOM
T
Lack of cohesion of methods
TYPES WHERE LCOM > 0.8 AND NbFields > 10 AND NbMethods >10
LCOMHS
T
Lack Of Cohesion Of Methods
(Henderson-Sellers)
TYPES WHERE LCOMHS > 1.0 AND NbFields > 10 AND NbMethods >10
AssemblyLevel A / NamespaceLevel N / TypeLevel T / MethodLevel T
 
T
# of non BCL namespaces used
à discover dependency cycles
 
Abstractness
A
Ratio of abstract to concrete types
 
Instability
A
ratio of efferent coupling (AsmCe) to total coupling
 
NormDistFromMainSeq
A
High level indicator of assembly's balance between abstractness and stability
ASSEMBLIES WHERE NormDistFromMainSeq > 0.7
DistFromMainSeq
A
NormDistFromMainSeq / Sqrt(2)
 
RelationalCohesion
A
# internal relationships per type.
classes inside an assembly should be strongly related
ASSEMBLIES WHERE RelationalCohesion < 1.5 OR RelationalCohesion > 4.0
AsmCa
A
# types outside an assembly that depend on types within it
 
AsmCe
A
# types inside an assembly that depend on types outside it
 
 
CQL test coverage metrics conditions
Metric
Applicability
Return / Match
PercentageCoverage
ANTM
% of code coverage by tests
The closer to 100%, the better
NbLinesOfCodeCovered
ANTM
# lines of code covered
NbLinesOfCodeNotCovered
ANTM
# lines of code not covered
PercentageBranchCoverage
M
generated from underlying opcodes - compensates for method complexity.
determine which code statements need more testing.
 
IsExcludedFromCoverage
ANTM
 
 
Metric
Applicability
Return / Match
IsUsing
DepthOfIsUsing
ANTM
Code elements that directly / indirectly use a particular code element “XXX”
IsDirectlyUsing
 
ANTM
Code elements that directly use a particular code element “XXX”
IsUsedBy
DepthOfIsUsedBy
ANTMF
Code elements that are directly / indirectly used-by a particular code element “XXX”
IsDirectlyUsedBy
 
ANTMF
Code elements that are directly used by a particular code element “XXX”
CreateA
DepthOfCreateA
M
METHODS which directly / indirectly call a constructor of a particular type “XXX”
DeriveFrom
DepthOfDeriveFrom
T
TYPES which directly / indirectly derive from a particular type “XXX”
Implement
T
TYPES which implement a particular interface “XXX”
HasAttribute
ATMF
Code elements that are tagged with a particular attribute “XXX”
IsOfType
F
FIELDS of a particular type “XXX”
ReturnType
M
METHODS that return a particular type “XXX”
 
CQL boolean conditions
Metric
Applicability
Return / Match
IsPublic
IsInternal
IsProtected
IsProtectedAndInternal
IsPrivate
TMF
Elements that match the scope
IsInFrameworkAssembly
IsFrameworkAssembly
NMTF
A
distinguish framework code elements from application code elements.
F
FIELDS which are values of enumerations.
M
METHODS which are instance constructors
M
METHODS which are property setters
M
METHODS which are property getters
TMF
 
M
METHODS which are overloaded
M
METHODS which are virtual or override
TM
TYPES or METHODS which are abstract. Note that interfaces and interfaces’ methods are considered as abstract
M
METHODS which are explicit interface method implementation
TM
TYPES or METHODS which are using the box IL instruction
TM
TYPES or METHODS which are using the unbox IL instruction
TM
TYPES or METHODS which are using pinning
TM
TYPES or METHODS which are generic
TM
 TYPES or METHODS which are using pointers. (in unsafe mode).
M
METHODS which override Object.Finalize()
T
TYPES which define a finalizer
ANTM
detect dependencies cycle in the code structure
ContainsTypeDependencyCycle
ContainsMethodDependencyCycle
A
T
M
determine which part of code contains dependency cycles
IsEntryPoint
M
METHODS which are entry point of their assemblies
M
METHODS which are operator implementations
M
METHODS which are indexer setters
M
METHODS which are indexer getters
F
FIELDS which are literals - Const and enum values
F
FIELDS which are readonly
M
METHODS which are event adders
M
METHODS which are event removers
F
FIELDS which are event delegate object
IsClassConstructor
M
METHODS which are class constructors
T
TYPES which are classes
T
TYPES which are structures
T
TYPES which are enums
T
TYPES which are interfaces
T
matches TYPES which are sealed. Note static classes and structures are marked as sealed
T
TYPES which are nested
T
TYPES which are serializable
T
TYPES which are delegates
T
TYPES which are attribute classes (derived from System.Attribute)
T
TYPES which are exception classes (derive from System.Exception )
TMF
Code elements that are generated by the compiler to handle anonymous methods and iterators
IsObsolete
TMF
Code attributes tagged with System.Obsolete attribute
TMF
Code elements that returns true for Type / FieldInfo SpecialName property
CQL boolean conditions dedicated to Build Comparison
Metric
Applicability
WasAdded
ANTMF
ANTMF
ANTM
CommentsWereChanged
ANTM
VisibilityWasChanged
TMF
ANTMF
BecameObsolete
TMF
IsUsedRecently
ANTMF
IsNotUsedAnymore
ANTMF
IsUsedDifferently
ANT
IsInNewerBuild
ANTMF
IsInOlderBuild
ANTMF
Metric
Applicability
Return / Match
CouldBeInternal
NTMF
public TYPESMETHODS and FIELDS that could be declared as internal
TMF
public TYPESMETHODS and FIELDS that could be declared as protected internal
TMF
 
TMF
 
TMF
internal TYPESMETHODS and FIELDS that are used outside their declaring assembly via InternalsVisibleToAttribute
Metric
Applicability
Return / Match
TF
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.
M
METHODS that explicitly modify an instance field of their type.
M
METHODS that explicitly modify a static field of their type.
M
METHODS that reads at least one mutable instance field.
M
METHODS that reads at least one mutable static field.
M
METHODS that reads at least one immutable instance field.
M
METHODS that reads at least one immutable static field
M
METHODS that write a particular field “XXX”, i.e that changes the state of the field “XXX”.
M
A method that directly calls a method that directly write the field “XXX” has a DepthOfIsWritingField “XXX” value equal to 1. etc
M
equivalent to the clause DepthOfIsWritingField “XXX” == 1.
 
 
cheers,
Josh
Posted on Tuesday, September 13, 2011 12:21 PM Meta-Programming | Back to top


Comments on this post: Code Query Language - for static analysis

# re: Code Query Language - for static analysis
Requesting Gravatar...
There are lot of things that need to be remembered in order to fully utilize its advantages. - Dennis Wong YOR Health
Left by Robert Nyers on Jan 03, 2017 6:50 AM

Your comment:
 (will show your gravatar)


Copyright © JoshReuben | Powered by: GeeksWithBlogs.net