Commit acc79f17 authored by Gerson Sunyé's avatar Gerson Sunyé
Browse files

Rule declarations reorganization

parent 1c1c51f2
library bestPractices; library bestPractices;
--------------------------------------------- AvoidPrintStackTrace --------------------------------------------- --- Rule for metrics AvoidFieldNameMatchingMethodName : return the set of class Measures that violates the rule.
--Goes through all the methods to check if the following rule is followed:
--Avoid printStackTrace()
helper def: avoidPrintStackTrace() : Set(smm!Measure) =
java!MethodInvocation.allInstances()
-> select (m | m.method.name = 'printStackTrace')
-> collect (m | thisModule.MeasureAvoidPrintStackTrace(m))
;
--------------------------------------------- AvoidFieldNameMatchingMethodName ---------------------------------------------
-- Rule for metrics AvoidFieldNameMatchingMethodName : return the set of class Measures that violates the rule.
helper def: avoidFieldNameMatchingMethodName() : Set(smm!Measure) = helper def: avoidFieldNameMatchingMethodName() : Set(smm!Measure) =
-- Browse through all class -- Browse through all class
java!ClassDeclaration.allInstances()->iterate(i; res : Set(smm!Measure) = Set{} | java!ClassDeclaration.allInstances()->iterate(i; res : Set(smm!Measure) = Set{} |
...@@ -28,116 +16,134 @@ helper def: avoidFieldNameMatchingMethodName() : Set(smm!Measure) = ...@@ -28,116 +16,134 @@ helper def: avoidFieldNameMatchingMethodName() : Set(smm!Measure) =
) )
); );
--------------------------------------------- EmptyStatementBlock ---------------------------------------------
--- Goes through all the methods to check if the following rule is followed:
--- Avoid printStackTrace()
helper def: avoidPrintStackTrace() : Set(smm!Measure) =
java!MethodInvocation.allInstances()
-> select (m | m.method.name = 'printStackTrace')
-> collect (m | thisModule.MeasureAvoidPrintStackTrace(m))
;
-- #TODO: Add comment
helper def: avoidReassigningParameters(): Set(smm!Measure) =
java!AbstractMethodDeclaration.allInstances()->select(method |
method.parameters.size() > 0 and not method.body.oclIsUndefined() -- need at least one parameter and a body
)->collect(method |
method.body.statements->select(statement |
statement.oclIsTypeOf(java!ExpressionStatement) -- statement must be an expression
)->collect(expressionStatement |
expressionStatement.expression
)->select(expression |
expression.oclIsTypeOf(java!Assignment) -- the expression must be an assignment
)->select(assignment |
assignment.leftHandSide.oclIsTypeOf(java!SingleVariableAccess) -- the receiving end of the assignment must be a variable access
)->select(assignment |
method.parameters->collect(singleVariableDeclaration |
singleVariableDeclaration.name -- for each parameter of the method we retrieve its name
)->includes(assignment.leftHandSide.variable.name) -- one of the parameter is on the receiving of an assignment
)->collect(assignment |
thisModule.MeasureAvoidReassigningParameters(assignment)
)
)->flatten();
--Detects the use of empty statements blocks. These blocks serve no purpose and should be removed --- Rule for metrics AvoidStringBufferField
-- TODO: improve comment
helper def: avoidStringBufferField() : Set(smm!Measure) =
java!FieldDeclaration.allInstances()
->select(dec | dec.type <> OclUndefined )
->select(dec | ( dec.type.type.name = 'StringBuffer' or dec.type.type.name = 'StringBuilder'))
->collect(dec | thisModule.MeasureAvoidStringBufferField(dec));
--- Detects the use of empty statements blocks. These blocks serve no purpose and should be removed
helper def: emptyStatementBlock() : Set(smm!Measure) = helper def: emptyStatementBlock() : Set(smm!Measure) =
java!Block.allInstances() java!Block.allInstances()
->select(block | block.statements.isEmpty()) ->select(block | block.statements.isEmpty())
->collect(block | thisModule.MeasureEmptyStatementBlock(block)); ->collect(block | thisModule.MeasureEmptyStatementBlock(block));
--------------------------------------------- SwitchDensity --------------------------------------------- --- Rule for metrics ForLoopVariableCount
-- Rule for metrics SwitchDensity : -- TODO: improve comment
helper def: switchDensity() : Set (smm!Measure) = helper def: forLoopVariableCount(): Set(smm!Measure) =
-- Browse through all Switch Statements java!ForStatement.allInstances()->select(forStatement |
java!SwitchStatement.allInstances()->iterate(switchCase; res : Set(smm!Measure) = Set{} | forStatement.nbLocalVariableDeclarations() > 1
switchCase.statements )->collect(forStatement | thisModule.MeasureForLoopVariableCount(forStatement));
->select(switchStatement | switchStatement.oclIsTypeOf(java!Block))
->select(switchStatement | switchStatement.statements <> OclUndefined)
->select(switchStatement | switchStatement.statements.size() -1 >= 10)
->collect(switchStatement | thisModule.MeasureSwitchDensity(switchCase))
);
--------------------------------------------- useAssertTrueInsteadOfAssertEquals ---------------------------------------------
helper def: useAssertTrueInsteadOfAssertEquals() : Set(smm!Measure) =
-- Browse through all methods use
java!MethodInvocation.allInstances()
--Check if the method use is assertEqual and a Boolean is used
->select(assert | assert.method.name = 'assertEquals')
->select(assert | thisModule.isWrongUseAssertTrueInsteadOfAssertEquals(assert))
->collect(assert | thisModule.MesureUseAssertTrueInsteadOfAssertEquals(assert));
helper def: isWrongUseAssertTrueInsteadOfAssertEquals(m:java!MethodInvocation) : Boolean = --- Checks if it's a BooleanLiteral
--Shorten the path m.arguments.last() to lastArgument and check if it's a boolean
let lastArgument : java!Expression = m.arguments.last() in lastArgument.isBoolean();
--Checks if it's a BooleanLiteral
helper context java!BooleanLiteral def: isBoolean() : Boolean = true; helper context java!BooleanLiteral def: isBoolean() : Boolean = true;
--Checks if the type of a Expression is Boolean
--- Checks if the type of a Expression is Boolean
helper context java!Expression def: isBoolean() : Boolean = helper context java!Expression def: isBoolean() : Boolean =
self.variable.variablesContainer.isBoolean(); self.variable.variablesContainer.isBoolean();
--Checks if the type of a VariableDeclarationStatement is Boolean
--- Checks if the type of a VariableDeclarationStatement is Boolean
helper context java!VariableDeclarationStatement def: isBoolean() : Boolean = helper context java!VariableDeclarationStatement def: isBoolean() : Boolean =
self.type.type.name= 'boolean'; self.type.type.name= 'boolean';
--Use in case of Boolean.TRUE or Boolean.FALSE
--- Use in case of Boolean.TRUE or Boolean.FALSE
helper context java!FieldDeclaration def: isBoolean() : Boolean = helper context java!FieldDeclaration def: isBoolean() : Boolean =
self.abstractTypeDeclaration.name = 'Boolean'; self.abstractTypeDeclaration.name = 'Boolean';
-- #TODO: Add comment
--------------------------------------------- AvoidStringBufferField ---------------------------------------------
-- Rule for metrics AvoidStringBufferField
helper def: avoidStringBufferField() : Set(smm!Measure) =
java!FieldDeclaration.allInstances()
->select(dec | dec.type <> OclUndefined )
->select(dec | ( dec.type.type.name = 'StringBuffer' or dec.type.type.name = 'StringBuilder'))
->collect(dec | thisModule.MeasureAvoidStringBufferField(dec));
---------------------------------------------UseAssertSameInsteadOfAssertTrue---------------------------------------------
helper def: useAssertSameInsteadOfAssertTrue() : Set(smm!Measure) =
-- Browse through all methods use
java!MethodInvocation.allInstances()
--Check if the method use is assertTrue and check if == is used
->select(assert | assert.method.name = 'assertTrue')
->select(assert | thisModule.isWrongUseAssertSameInsteadOfAssertTrue(assert))
->collect(assert | thisModule.MesureUseAssertSameInsteadOfAssertTrue(assert));
helper def: isWrongUseAssertSameInsteadOfAssertTrue(m:java!MethodInvocation) : Boolean = helper def: isWrongUseAssertSameInsteadOfAssertTrue(m:java!MethodInvocation) : Boolean =
--Browse through all arguments of the method assertTrue and see if == is used --Browse through all arguments of the method assertTrue and see if == is used
(m.arguments->select(t|t.oclIsTypeOf(java!InfixExpression))->select(t|t.operator.toString() = '==')->collect(t|t).notEmpty()); (m.arguments->select(t|t.oclIsTypeOf(java!InfixExpression))->select(t|t.operator.toString() = '==')->collect(t|t).notEmpty());
--------------------------------------------- ForLoopVariableCount --------------------------------------------- -- #TODO: Add comment
helper def: isWrongUseAssertTrueInsteadOfAssertEquals(m:java!MethodInvocation) : Boolean =
-- Rule for metrics ForLoopVariableCount --Shorten the path m.arguments.last() to lastArgument and check if it's a boolean
helper def: forLoopVariableCount(): Set(smm!Measure) = let lastArgument : java!Expression = m.arguments.last() in lastArgument.isBoolean();
java!ForStatement.allInstances()->select(forStatement |
forStatement.nbLocalVariableDeclarations() > 1 --- Returns the number of declared local variables in the for loop
)->collect(forStatement | thisModule.MeasureForLoopVariableCount(forStatement));
-- Returns the number of declared local variables in the for loop
helper context java!ForStatement def: nbLocalVariableDeclarations(): Integer = helper context java!ForStatement def: nbLocalVariableDeclarations(): Integer =
self.initializers->iterate(expression; acc: Integer = 0 | self.initializers->iterate(expression; acc: Integer = 0 |
acc + expression.nbLocalVariableDeclarations() acc + expression.nbLocalVariableDeclarations()
); );
-- A loop initializer can contains any Expression but we care about only VariableDeclarationExpression --- A loop initializer can contains any Expression but we care about only VariableDeclarationExpression
helper context java!Expression def: nbLocalVariableDeclarations(): Integer = helper context java!Expression def: nbLocalVariableDeclarations(): Integer =
0; 0;
-- #TODO: Add comment
helper context java!VariableDeclarationExpression def: nbLocalVariableDeclarations(): Integer = helper context java!VariableDeclarationExpression def: nbLocalVariableDeclarations(): Integer =
self.fragments.size(); -- The fragments collection contains all the variable declarations of an initializer* self.fragments.size(); -- The fragments collection contains all the variable declarations of an initializer*
-- Initializer* : for(int x = 0; ...), "int x = 0" is the initializer part of the for loop -- Initializer* : for(int x = 0; ...), "int x = 0" is the initializer part of the for loop
--------------------------------------------- AvoidReassigningParameters --------------------------------------------- --- Rule for metrics SwitchDensity :
-- #TODO: Improve comment
helper def: switchDensity() : Set (smm!Measure) =
-- Browse through all Switch Statements
java!SwitchStatement.allInstances()->iterate(switchCase; res : Set(smm!Measure) = Set{} |
switchCase.statements
->select(switchStatement | switchStatement.oclIsTypeOf(java!Block))
->select(switchStatement | switchStatement.statements <> OclUndefined)
->select(switchStatement | switchStatement.statements.size() -1 >= 10)
->collect(switchStatement | thisModule.MeasureSwitchDensity(switchCase))
);
-- #TODO: Add comment
helper def: useAssertSameInsteadOfAssertTrue() : Set(smm!Measure) =
-- Browse through all methods use
java!MethodInvocation.allInstances()
--Check if the method use is assertTrue and check if == is used
->select(assert | assert.method.name = 'assertTrue')
->select(assert | thisModule.isWrongUseAssertSameInsteadOfAssertTrue(assert))
->collect(assert | thisModule.MesureUseAssertSameInsteadOfAssertTrue(assert));
-- #TODO: Add comment
helper def: useAssertTrueInsteadOfAssertEquals() : Set(smm!Measure) =
-- Browse through all methods use
java!MethodInvocation.allInstances()
--Check if the method use is assertEqual and a Boolean is used
->select(assert | assert.method.name = 'assertEquals')
->select(assert | thisModule.isWrongUseAssertTrueInsteadOfAssertEquals(assert))
->collect(assert | thisModule.MesureUseAssertTrueInsteadOfAssertEquals(assert));
-- Attention !!!
-- Before adding a rule to the end of file, ensure that you are respecting the
-- alphabetical order for rule declarations.
helper def: avoidReassigningParameters(): Set(smm!Measure) =
java!AbstractMethodDeclaration.allInstances()->select(method |
method.parameters.size() > 0 and not method.body.oclIsUndefined() -- need at least one parameter and a body
)->collect(method |
method.body.statements->select(statement |
statement.oclIsTypeOf(java!ExpressionStatement) -- statement must be an expression
)->collect(expressionStatement |
expressionStatement.expression
)->select(expression |
expression.oclIsTypeOf(java!Assignment) -- the expression must be an assignment
)->select(assignment |
assignment.leftHandSide.oclIsTypeOf(java!SingleVariableAccess) -- the receiving end of the assignment must be a variable access
)->select(assignment |
method.parameters->collect(singleVariableDeclaration |
singleVariableDeclaration.name -- for each parameter of the method we retrieve its name
)->includes(assignment.leftHandSide.variable.name) -- one of the parameter is on the receiving of an assignment
)->collect(assignment |
thisModule.MeasureAvoidReassigningParameters(assignment)
)
)->flatten();
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment