Advanced Concepts
Code Critic provides an extensible framework for writing your own project-specific reviews. This section describes how you can add your own code reviews.
Framework Configuration Maps
The QA Code Critic configuration map contains the hierarchy of reviews, the engine that runs the reviews (CcFramework application), and the user interface including the Code Critic Results Browser (CcUserInterface application).
To load the framework separately (without the UI) and run specific doIts directly, load only the CcFramework application.
Code Critic Framework Classes
You can add a review through subclassing. The location of your class in the hierarchy depends on what your review does and on what code element it operates on. Use the following table to decide which framework class to subclass.
| | |
configuration map | Y | N | CtConfigurationMapMeasure |
application | Y | CtLoadedApplicationMeasure |
application | N | CtApplicationMeasure |
subapplication | Y | CtLoadedSubApplicationMeasure |
subapplication | N | CtSubApplicationMeasure |
entire class | Y | CtEntireClassMeasure |
class | Y | CtLoadedClassMeasure |
class extension | Y | CtClassExtensionMeasure |
class definition | Y | CtLoadedClassDefinitionMeasure |
class definition | N | CtClassDefinitionMeasure |
method | Y | CtLoadedMethodMeasure |
method | N | CtMethodMeasure |
Table 9 — Subclassing CtMeasure.
Implementing Your Review Subclass
The work of a review is performed in the method #measure:. This method takes the code element as a parameter and returns nil (if the review found no problems) or an instance of CcComplaint.
Mandatory Methods
CtMeasure defines a set of methods categorized as override mandatory. These methods must be overridden in your subclass.
Optional Methods
CtMeasure defines a set of methods categorized as override optional. These methods will often be overridden in your subclass; however, failure to override them does not result in an error.
Example
The following example shows how to add a review that raises a warning when classes are too deep in the hierarchy.
CcDeepHierarchy class
CtLoadedClassDefinitionMeasure subclass: #CcDeepHierarchy
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
CcDeepHierarchy public class methods
defaultProperties
"Answer the receiver's default properties.
PARAMETERS
None
RETURN VALUE
<OrderedCollection of SqaProperty>"
^super defaultProperties
add:(
SqaIntegerProperty new
label: 'Allowed number of superclasses';
name: #acceptableSuperclasses;
comment: 'The maximum number of allowed super classes';
value: 5;
yourself);
yourself
group
"Answer the functional group the receiver is in.
In addition to being grouped by the type of object they
apply to (Application, Class, etc.) measures are also organized
into functional groups. A measure belongs to one group.
Group names are also used when generating the user interface.
PARAMETERS
None
RETURN VALUE
<String>"
^'Inheritance'
descriptionText
"Answer the description text for the receiver.
PARAMETERS
None
RETURN VALUE
<String>"
^' Warn if a class is nested too deep in a class hierarchy.’
adviceText
"Answer the advice text for the receiver.
PARAMETERS
None
RETURN VALUE
<String>"
^' A class that has too many superclasses may be difficult to maintain.
Review your class structure and check whether the class actually needs to inherit
behavior from its superclasses.'
isReview
"Answer true if the receiver is a review
otherwise answer false.
PARAMETERS
None
RETURN VALUE
<Boolean>"
^true
label
"Answer a single line label briefly describing the receiver.
PARAMETERS
None
RETURN VALUE
<String>"
^'Too deep in hierarchy'
loaded
“When the receiver has been loaded, execute the
appropriate initialization.
PARAMETERS
None
RETURN VALUE
None”
CcDeepHierarchy resetProperties
CcDeepHierarchy public instance methods
measure: aClass
"Measure aClass for the number of superclasses.
Warn if the number of superclasses is higher than the
#acceptableSuperclasses property value.
RETURN VALUE
<nil | CcComplaint>"
| propertyValue |
(propertyValue := self propertyValueAt: #acceptableSuperclasses) isNil
ifTrue:[^nil].
aClass allSuperclasses size > propertyValue
ifTrue:[
^self
defaultReviewOf: aClass
result: (
CcComplaint new
message: 'Too deep in hierarchy';
yourself)]
ifFalse:[^nil]
Last modified date: 05/19/2020