Commit 1c1c51f2 authored by Gerson Sunyé's avatar Gerson Sunyé
Browse files

Rules reorganization: rule declarations are now in alphabetical order. This...

Rules reorganization: rule declarations are now in alphabetical order. This should help to prevent conflicts
parent 06428213
......@@ -155,239 +155,243 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
-- creates a new Measure when String.valueOf is called to append its argument to a string
rule MeasureUselessStringValueOf(method : java!MethodInvocation) {
--- Creates an instance of Measure for the switch statement missing one or more break statements
-- To test, use input model : missing-break-in-switch.xmi
-- #TODO: rename rule
rule createMeasureForMissingBreakInSwitch(ss: java!SwitchStatement) {
to
om: smm!ObservedMeasure (
measure <- noc,
measure <- missingBreakInSwitch,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Useless string value of',
shortDescription <- 'No need to call String.valueOf to append to a string; just use the valueOf() argument directly.'
missingBreakInSwitch: smm!DimensionalMeasure (
name <- 'Missing break in Switch',
shortDescription <- 'Switch statements without break or return statements for each case option may indicate problematic behaviour. Empty cases are ignored as these indicate an intentional fall-through.'
),
measurement: smm!DirectMeasurement (
error<- 'The class '+ method.originalCompilationUnit.name + ' violates the rule useless string value of.'
)
measurement: smm!DirectMeasurement (
error <- 'Missing breaks in Switch in Class : ' + ss.originalCompilationUnit.name + '',
-- Indicates the number of breaks missing in the switch statement
value <- (thisModule.nbBranchesOfASwitchStatement(ss) - thisModule.nbIntentionalFallThroughOfASwitchStatement(ss)) - thisModule.nbBreakStatementOfASwitchStatement(ss)
)
do {
noc;
missingBreakInSwitch;
}
}
------------------------------------------------------------------------------------------
-- A Measure instance if the class violates the rule 'AvoidDollarSigns'.
rule MesureAvoidDollarSigns(node : java!ASTNode) {
-- ------------------------------------------- AbstractClassWithoutAnyMethod ---------------------------------------------
--- creates a new Measure when an abstract class does not provides any methods.
rule MeasureAbstractClassWithoutAnyMethod(i : java!ClassDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'AvoidDollarSigns',
shortDescription <- 'Avoid using dollar signs in variable/method/class/interface names.'
name <- 'AbstractClassWithoutAnyMethod',
shortDescription <- 'If an abstract class does not provides any methods, it may be acting as a simple data containerth...'
),
measurement: smm!DirectMeasurement (
error <- node.name + ' has dollar in ' + node.originalCompilationUnit.name
measurement: smm!DirectMeasurement (
error<-'The class anstract' + i.name + ' has not method.'
)
do {
noc;
}
}
-- A Measure instance if the class violates the rule 'ShortMethodName'.
rule MesureShortMethodName(method : java!MethodDeclaration) {
-- ------------------------------------------- AvoidCallingFinalize ---------------------------------------------
--- A Measure instance if the class violates the rule LongVariable.
rule MeasureAvoidCallingFinalize(methode : java!MethodInvocation) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ShortMethodName',
shortDescription <- 'Method names names that are very short are not helpful to the reader.'
name <- 'AvoidCallingFinalize',
shortDescription <- ': The method Object.finalize() is called by the garbage collector on an object when garbage collect... '
),
measurement: smm!DirectMeasurement (
error <- method.name + ' is too short in ' + method.originalCompilationUnit.name
error <- 'finalize() is called in class' + methode.originalCompilationUnit.name
)
do {
noc;
}
}
-- A Measure instance if the class violates the rule 'ShortClassName'.
rule MesureShortClassName(class : java!ClassDeclaration) {
--- A Measure instance if the class violates the rule AvoidCatchingNPE.
rule MeasureAvoidCatchingNPE(w: java!CatchClause) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ShortClassName',
shortDescription <- 'Short Classnames with fewer than e.g. five characters are not recommended.'
name <- 'AvoidCatchingNPE',
shortDescription <- ': Avoid Catching NullPointerExceptions'
),
measurement: smm!DirectMeasurement (
error <- 'The Class ' + class.name + ' is too short.'
error <- ' class '+w.originalCompilationUnit.name+ ' has a Code that should never
throw NullPointerExceptions under normal circumstances. A catch block may hide the
original error, causing other, more subtle problems later on.'
)
do {
noc;
}
}
-- A Measure instance if the variable violates the rule 'ShortVariableName'.
rule MesureShortVariableName(variable : java!VariableDeclaration) {
-- -----------------------------------------AvoidCatchingThrowable----------------------------------------------
--- A Measure instance if the class violate the rule MisLeadingVariableName
rule MeasureAvoidCatchingThrowable(catch :java!CatchClause) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ShortVariableName',
shortDescription <- 'Short Variable names with fewer than e.g. three characters are not recommended.'
name <- 'AvoidCatchingThrowable',
shortDescription <- 'Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as OutOfMemoryError that should be exposed and managed separately.'
),
measurement: smm!DirectMeasurement (
error <- 'The Variable ' + variable.name + ' is too short.'
error<- 'Throwable ' + catch.exception.name + ' should not be catched.'
)
do {
noc;
noc;
}
}
-- A Measure instance if the method violates the rule 'StringToString'.
rule MeasureStringToString(method : java!MethodInvocation) {
--- A Measure instance if the class violates the rule AvoidEnumAsIdentifier.
rule MeasureAvoidEnumAsIdentifier(w: java!VariableDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'StringToString',
shortDescription <- 'Avoid calling toString() on objects already known to be string instances; this is unnecessary.'
name <- 'AvoidEnumAsIdentifier',
shortDescription <- ': Avoid Enum As Identifier'
),
measurement: smm!DirectMeasurement (
error <- 'The Object ' + method.expression.variable.name + ' is already a String in ' + method.originalCompilationUnit.name
error <- ' class '+w.originalCompilationUnit.name+ ' has a variable named to enum witch is a reserved name'
)
do {
noc;
}
}
-- creates a new Measure when Thread.run() is used instead of Thread.start()
rule MeasureDontCallThreadRun(method : java!MethodDeclaration) {
-- ----------------------------------------- AvoidPrefixingMethodParameters----------------------------------------------
--- A Measure instance if the class violates the rule AvoidPrefixingMethodParameters.
rule MeasureAvoidPrefixingMethodParameters(method: java!MethodDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Don t call Thread.run()',
shortDescription <- 'Explicitly calling Thread.run() method will execute in the caller s thread of control. Instead, call Thread.start() for the intended behavior.'
name <- 'AvoidPrefixingMethodParameters',
shortDescription <- 'Prefixing parameters by ‘in’ or ‘out’ pollutes the name of the parameters and reduces code readability.'
),
measurement: smm!DirectMeasurement (
error<-'The class '+ method.originalCompilationUnit.name + ' violates the rule don t call Thread.run().'
error<- 'Bad parameters : ' + method.getIncorrectParameters() + ', for the method ' + method.name + ' defined in the file ' + method.originalCompilationUnit.name
)
do {
noc;
}
}
-- A Measure instance if the class violates the rule 'TooManyFields'.
rule MesureTooManyFields(class : java!ClassDeclaration) {
to
--- creates a new Measure when the method printStackTrace is used
rule MeasureAvoidPrintStackTrace(method : java!MethodInvocation) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'TooManyFields',
shortDescription <- 'Classes that have too many fields can become unwieldy and could be redesigned to have fewer field.'
name <- 'Avoid print stack trace',
shortDescription <- 'Avoid printStackTrace(); use a logger call instead.'
),
measurement: smm!DirectMeasurement (
error <- class.originalCompilationUnit.name + ' have too many fields'
measurement: smm!DirectMeasurement (
error<- 'The class '+ method.originalCompilationUnit.name + ' violates the rule avoid print stack trace.'
)
do {
noc;
}
}
-- creates a new Measure when the parameter of String.indexOf(char) is not of type char when checking for the index of a single character
rule MeasureUseIndexOfChar(method : java!MethodInvocation) {
-- ----------------------------------------- AvoidReassigningParameters ----------------------------------------------
--- A Measure instance if the class violates the rule AvoidReassigningParameters.
rule MeasureAvoidReassigningParameters(assignment: java!SingleVariableAccess) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Use index of char',
shortDescription <- 'Use String.indexOf(char) when checking for the index of a single character; it executes faster.'
name <- 'AvoidReassigningParameters',
shortDescription <- 'Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.'
),
measurement: smm!DirectMeasurement (
error<- 'The class '+ method.originalCompilationUnit.name + ' violates the rule index of char.'
error<- assignment.leftHandSide.variable.name + ' should not be reassigned'
)
do {
noc;
}
}
------------------------------------------------------------------------------------------
rule numberOfClasses() {
to
-- ------------------------------------------- AvoidRethrowingException ---------------------------------------------
---A Measure instance if the class violates the rule AvoidRethrowingException.
rule MeasureAvoidRethrowingException(statement : java!TryStatement) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Number of Classes'
name <- 'AvoidRethrowingException ',
shortDescription <- 'Avoid merely rethrowing an exception.'
),
measurement: smm!DirectMeasurement (
value <- java!ClassDeclaration.allInstances() -> reject(each | each.isProxy()) -> size()
measurement: smm!DirectMeasurement (
error<-'In the Class '+ statement.originalCompilationUnit.name + ' an exception was caught and merely rethrown.'
)
do {
noc;
}
}
-- Rule that creates an instance of Measure for the switch statement with too few branches passed in parameter
rule MeasureTooFewBranchesForASwitchStatement(switchStatement: java!SwitchStatement) {
}
-- ------------------------------------------- AvoidStringBufferField ---------------------------------------------
--- A Measure instance if the class violates AvoidStringBufferField .
rule MeasureAvoidStringBufferField(declaration : java!FieldDeclaration) {
to
om: smm!ObservedMeasure (
measure <- tooFewBranchesForASwitchStatement,
measure <- noc,
measurements <- measurement
),
tooFewBranchesForASwitchStatement: smm!DimensionalMeasure (
name <- 'TooFewBranchesForASwitchStatement',
shortDescription <- 'Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a few cases is ill-advised, since switches are not as easy to understand as if-then statements. In these cases use the if-then statement to increase code readability.'
noc: smm!DimensionalMeasure (
name <- 'AvoidStringBufferField',
shortDescription <- ': StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaksif ...'
),
measurement: smm!DirectMeasurement (
error <- 'Too few branches for SwitchStatement in Class : ' + switchStatement.originalCompilationUnit.name,
value <- thisModule.nbBranchesOfASwitchStatement(switchStatement)
error <- 'AvoidStringBufferField is detected in ' + declaration.originalCompilationUnit.name
)
do {
tooFewBranchesForASwitchStatement;
noc;
}
}
--------------------------------------------- ShortInstantiation ---------------------------------------------
-- A Measure instance if the class violates the rule 'ShortInstantiation'.
rule MeasureShortInstantiation(variable : java!CompilationUnit) {
--- creates a new Measure when Thread.run() is used instead of Thread.start()
rule measureAvoidThreadGroup(variable : java!VariableDeclarationStatement) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ShortInstantiation',
shortDescription <- 'Calling new Short() causes memory allocation that can be avoided by the static Short.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Short() is deprecated since JDK 9 for that reason.'
name <- 'Avoid Thread Group',
shortDescription <- 'Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread-safe.'
),
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' an instantiation of Short must be Short.ValueOf().'
error<-'The class '+ variable.originalCompilationUnit.name + ' violates the rule avoid thread group.'
)
do {
......@@ -395,401 +399,373 @@ rule MeasureShortInstantiation(variable : java!CompilationUnit) {
}
}
--------------------------------------------- LongInstantiation ---------------------------------------------
-- A Measure instance if the class violates the rule 'LongInstantiation'.
rule MeasureLongInstantiation(variable : java!CompilationUnit) {
to
-- ------------------------------------------- AvoidThrowingNewInstanceOfSameException ---------------------------------------------
--- A Measure instance if the class violates the rule 'AvoidThrowingNewInstanceOfSameException'.
rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'LongInstantiation',
shortDescription <- 'Calling new Long() causes memory allocation that can be avoided by the static Long.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Long() is deprecated since JDK 9 for that reason.'
name <- 'AvoidThrowingNewInstanceOfSameException',
shortDescription <- 'Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to code size and runtime complexity.'
),
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' an instantiation of Long must be Long.ValueOf().'
error <-'The class '+ catch.originalCompilationUnit.name + ' has a method that rethrows a caught exception wrapped inside a new instance of the same type.'
)
do {
noc;
}
}
--------------------------------------------- DoNotExtendJavaLangThrowable ---------------------------------------------
-- A Measure instance if the class violates the rule DoNotExtendJavaLangThrowable.
rule MeasureDoNotExtendJavaLangThrowable(variable : java!ClassDeclaration) {
-- ------------------- AvoidThrowingNullPointerException----------------------------------
--- A Measure instance if the class violates AvoidThrowingNullPointerException .
rule MeasureAvoidThrowingNullPointerException(c : java!ClassInstanceCreation) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'DoNotExtendJavaLangThrowable ',
shortDescription <- 'Extend Exception or RuntimeException instead of Throwable.'
name <- 'AvoidThrowingNullPointerException',
shortDescription <- 'Avoid throwing NullPointerExceptions manually. These are confusing because most people will assume that the virtual machine threw it'
),
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' should not extend Throwable but RuntimeException or Exception .'
measurement: smm!DirectMeasurement (
error <- 'AvoidThrowingNullPointerException is detected in ' + c.originalCompilationUnit.name
)
do {
noc;
}
}
-- Returns the number of branches in the switch statement passed in parameter
helper def: nbBranchesOfASwitchStatement(switchStatement:java!SwitchStatement) : Integer =
switchStatement.statements->select(each | each.oclIsTypeOf(java!SwitchCase)).size()
;
-- Returns the number of Fields in Class
helper def: numberFieldsInClasse(s:java!ClassDeclaration) : Integer =
-- Return the number of FieldDeclaration in a class.
s.bodyDeclarations-> select(r | r.oclIsTypeOf(java!FieldDeclaration))->size();
-- Returns the number of breaks of the switch statement passed in parameter
helper def: nbBreakStatementOfASwitchStatement(ss:java!SwitchStatement) : Integer =
ss.statements->select(each | each.oclIsTypeOf(java!BreakStatement)).size()
;
-- Returns the number of expressions of the switch statement passed in parameter
helper def: nbExpressionsStatementOfASwitchStatement(ss:java!SwitchStatement) : Integer =
ss.statements->select(each | each.oclIsTypeOf(java!ExpressionStatement)).size()
;
-- Returns the number of intentional fall-through (empty switch cases) of a switchStatement
helper def: nbIntentionalFallThroughOfASwitchStatement(ss:java!SwitchStatement) : Integer =
thisModule.nbBranchesOfASwitchStatement(ss) - thisModule.nbExpressionsStatementOfASwitchStatement(ss)
;
-- Creates an instance of Measure for the switch statement missing one or more break statements
-- To test, use input model : missing-break-in-switch.xmi
rule createMeasureForMissingBreakInSwitch(ss: java!SwitchStatement) {
--- A Measure instance if the class violates the rule 'AvoidUsingShortType'
rule MeasureAvoidUsingShortType(typeShort : java!VariableDeclarationStatement) {
to
om: smm!ObservedMeasure (
measure <- missingBreakInSwitch,
measure <- noc,
measurements <- measurement
),
missingBreakInSwitch: smm!DimensionalMeasure (
name <- 'Missing break in Switch',
shortDescription <- 'Switch statements without break or return statements for each case option may indicate problematic behaviour. Empty cases are ignored as these indicate an intentional fall-through.'
noc: smm!DimensionalMeasure (
name <- 'Avoid using short type',
shortDescription <- 'Java uses the \'short\' type to reduce memory usage, not to optimize calculation.'
+ ' In fact, the JVM does not have any arithmetic capabilities for the short type:'
+ ' the JVM must convert the short into an int, do the proper calculation and convert'
+ ' the int back to a short. Thus any storage gains found through use of the \'short\' type'
+ ' may be offset by adverse impacts on performance.'
),
measurement: smm!DirectMeasurement (
error <- 'Missing breaks in Switch in Class : ' + ss.originalCompilationUnit.name + '',
-- Indicates the number of breaks missing in the switch statement
value <- (thisModule.nbBranchesOfASwitchStatement(ss) - thisModule.nbIntentionalFallThroughOfASwitchStatement(ss)) - thisModule.nbBreakStatementOfASwitchStatement(ss)
error <- 'The class ' + typeShort.originalCompilationUnit.name + ' has \'short\' type variable.'
)
do {
missingBreakInSwitch;
noc;
}
}
-- A Measure instance if the class violates the rule 'TooManyMethods'.
rule MesureTooManyMethods(class : java!ClassDeclaration) {
--- A Measure instance if the class violates the rule CloneMethodMustBePublic.
rule MeasureCloneMethodMustBePublic(w: java!MethodDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'TooManyMethods',
shortDescription <- 'A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find a way to have more fine grained objects.'
name <- 'CloneMethodMustBePublic',
shortDescription <- ': Clone Method Must Be Public'
),
measurement: smm!DirectMeasurement (
error <- class.originalCompilationUnit.name + ' has too many methods'
error <- ' class '+w.originalCompilationUnit.name+ ' has a clone methode witch need to be public '
)
do {
noc;
}
}
-- A Measure instance if the class violates the rule ReturnFromFinallyBlock.
rule MesureReturnFromFinallyBlock(method : java!MethodDeclaration) {
--- Creates a measure instance when a bad word is found in a comment
rule MeasureCommentContent(element: Sequence(String)){
to
om: smm!ObservedMeasure (
measure <- noc,
measure <- commentContent,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'returnFromFinallyBlock',
shortDescription <- 'Avoid returning from a finally block, this can discard exceptions.'
commentContent: smm!DimensionalMeasure (
name <- 'CommentContent',
shortDescription <- 'A rule for the politically correct… we don’t want to offend anyone.'
),
measurement: smm!DirectMeasurement (
error <- 'The method ' + method.name + ' in the class ' + method.originalCompilationUnit.name + ' has a return statement in a finally block.'
error <- 'The words ' + element +' were found in a comment '
)
do {
noc;
}
do {
commentContent;
}
}
-- A Measure instance if the class violates the rule 'TooManyStaticImports'.
rule MesureTooManyStaticImports(class : java!CompilationUnit) {
--- Creates a measure instance for each element that violates the rule : CommentRequired
rule MeasureCommentRequired(element: java!BodyDeclaration, violatedProperties: Set(String)) {
to
om: smm!ObservedMeasure (
measure <- noc,
measure <- commentRequired,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'TooManyStaticImports',
shortDescription <- 'If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from (Sun 1.5 Language Guide).'
commentRequired: smm!DimensionalMeasure (
name <- 'CommentRequired',
shortDescription <- 'Denotes whether comments are required (or unwanted) for specific language elements.'
),
measurement: smm!DirectMeasurement (
error <- class.name + ' has too many static imports'
error <- 'Violated the properties ' + violatedProperties + ' in Class: ' + element.originalCompilationUnit.name + ' -> ' + element.oclType().name + ': ' + element.modifier.visibility + ' ' + element.getBodyDeclarationName()
)
do {
noc;
}
}
-- creates a new Measure when the method printStackTrace is used
rule MeasureAvoidPrintStackTrace(method : java!MethodInvocation) {
to
do {
commentRequired;
}
}
-- ------------------------------------------- MeasureCompareObjectsWithEquals ---------------------------------------------
--- A measure instance if the class violates the rule MeasureCompareObjectsWithEquals.
rule MeasureCompareObjectsWithEquals(expression : java!InfixExpression) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Avoid print stack trace',
shortDescription <- 'Avoid printStackTrace(); use a logger call instead.'
name <- 'CompareObjectsWithEquals',
shortDescription <- 'Use equals() to compare object references; avoid comparing them with ==.'
),
measurement: smm!DirectMeasurement (
error<- 'The class '+ method.originalCompilationUnit.name + ' violates the rule avoid print stack trace.'
error<-'The Class '+ expression.originalCompilationUnit.name + ' is using == instead of equals() to compare objects.'
)
do {
noc;
}
}
}
-- creates a new Measure when Thread.run() is used instead of Thread.start()
rule measureAvoidThreadGroup(variable : java!VariableDeclarationStatement) {
-- -----------------------------------------DoNotCallGarbageCollectionExplicitly----------------------------------------------
--- A Measure instance if the class violate the rule DoNotCallGarbageCollectionExplicitly
rule MeasureDoNotCallGarbageCollectionExplicitly(method : java!MethodInvocation) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Avoid Thread Group',
shortDescription <- 'Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread-safe.'
name <- 'DoNotCallGarbageCollectionExplicitly',
shortDescription <- 'Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised.'
),
measurement: smm!DirectMeasurement (
error<-'The class '+ variable.originalCompilationUnit.name + ' violates the rule avoid thread group.'
measurement: smm!DirectMeasurement (
error<- 'Garbage collector is called explicitly in ' + method.originalCompilationUnit.name
)
do {
noc;
noc;
}
}
--------------------------------------------- AvoidThrowingNewInstanceOfSameException ---------------------------------------------
-- A Measure instance if the class violates the rule 'AvoidThrowingNewInstanceOfSameException'.
rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) {
to
-- ----------------------------------------- DoNotCallSystemExit----------------------------------------------
--- A Measure instance if the class violates the rule DoNotCallSystemExit.
rule MeasureDoNotCallSystemExit(invocation : java!MethodInvocation) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'AvoidThrowingNewInstanceOfSameException',
shortDescription <- 'Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to code size and runtime complexity.'
name <- 'DoNotCallSystemExit',
shortDescription <- 'Applications should not call System.exit(), since only the web container or the application server should stop the JVM'
),
measurement: smm!DirectMeasurement (
error <-'The class '+ catch.originalCompilationUnit.name + ' has a method that rethrows a caught exception wrapped inside a new instance of the same type.'
error<- 'Do not call ' + invocation.method.getMethodClassName() + '.' + invocation.method.name + ' in the file ' + invocation.originalCompilationUnit.name
)
do {
noc;
}
}
--------------------------------------------- ReturnEmptyArrayRatherThanNull ---------------------------------------------
-- creates a new Measure when a method returns an empty method rather than null
rule MesureReturnEmptyArrayRatherThanNull(method : java!ReturnStatement) {
to
-- ------------------------------------------- DoNotExtendJavaLangError ---------------------------------------------
--- A Measure instance if the class violates the rule DoNotExtendJavaLangError.
rule MeasureDoNotExtendJavaLangError(variable : java!ClassDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ReturnEmptyArrayRatherThanNull',
shortDescription <- 'For any method that returns an array, it is a better to return an empty array rather than a null reference.'
name <- 'DoNotExtendJavaLangError ',
shortDescription <- 'Errors are system exceptions. Do not extend them.'
),
measurement: smm!DirectMeasurement (
error <- 'A method in the class ' + method.originalCompilationUnit.name + ' returns null instead of an empty array.'
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' Do not extend Error, Errors are system exceptions.'