bestPractices.atl 5.43 KB
Newer Older
Raphael PAGE's avatar
Raphael PAGE committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
library bestPractices;

--------------------------------------------- AvoidPrintStackTrace ---------------------------------------------

--Goes through all the methods to check if the following rule is followed:
--Avoid printStackTrace()
helper def: avoidPrintStackTrace() : Set(smm!Measure) =
	java!MethodInvocation.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{} |
		-- Add a new measurement if the argument of String.indexOf() is not of type char when checking for the index of a single character
		if thisModule.isAvoidPrintStackTrace(i) then
			res->union(Set{thisModule.MeasureAvoidPrintStackTrace(i)})
		else 
			res
		endif
	);

--Detect a wrong usage of the method printStackTrace()
--return true if the method is called printStackTrace
helper def:isAvoidPrintStackTrace(s:java!MethodInvocation): Boolean =
		if s.method.name = 'printStackTrace' then
			true
		else
			false
24
25
26
27
28
29
30
31
		endif;

--------------------------------------------- AvoidFieldNameMatchingMethodName ---------------------------------------------

-- Rule for metrics AvoidFieldNameMatchingMethodName : return the set of class Measures that violates the rule.
helper def: avoidFieldNameMatchingMethodName() : Set(smm!Measure) =
	-- Browse through all class
	java!ClassDeclaration.allInstances()->iterate(i; res : Set(smm!Measure) = Set{} |
32
		-- Foreach FieldDeclaration, check all methods
33
34
		i.bodyDeclarations->iterate(field; resIter : Set(smm!Measure) = Set{} | 
		if field.oclIsTypeOf(java!FieldDeclaration)
35
36
37
38
		then i.bodyDeclarations
			-- Check if the name method and the name field is the same
			->select(method | method.oclIsTypeOf(java!MethodDeclaration) and method.name = field.fragments.first().name)
			->collect(method | thisModule.MesureAvoidFieldNameMatchingMethodName(i, method))
39
40
41
		else res
		endif
	)
42
43
44
45
46
47
48
49
50
51
);

--------------------------------------------- EmptyStatementBlock ---------------------------------------------


--Detects the use of empty statements blocks. These blocks serve no purpose and should be removed
helper def: emptyStatementBlock() : Set(smm!Measure) =
	java!Block.allInstances()
		->select(block | block.statements.isEmpty())
		->collect(block | thisModule.MeasureEmptyStatementBlock(block));
52
53
54
55
56
57
58
59
60
61
62
63

--------------------------------------------- SwitchDensity  ---------------------------------------------
-- Rule for metrics SwitchDensity :
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))
	);
64
65
66
67
68
69

--------------------------------------------- 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
70
71
		->select(assert | assert.method.name = 'assertEquals')
		->select(assert | thisModule.isWrongUseAssertTrueInsteadOfAssertEquals(assert))
72
73
74
75
76
77
		->collect(assert | thisModule.MesureUseAssertTrueInsteadOfAssertEquals(assert));


helper def: isWrongUseAssertTrueInsteadOfAssertEquals(m:java!MethodInvocation) : Boolean = 
    --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();
78
	
79
80
81
82
83
84
85
86
87
88
89
90
	 --Checks if it's a BooleanLiteral
helper context java!BooleanLiteral def: isBoolean() : Boolean = true;
 --Checks if the type of a Expression is Boolean
helper context java!Expression def: isBoolean() : Boolean =
    self.variable.variablesContainer.isBoolean();
 --Checks if the type of a VariableDeclarationStatement is Boolean
helper context java!VariableDeclarationStatement def: isBoolean() : Boolean =
    self.type.type.name= 'boolean';
 --Use in case of Boolean.TRUE or Boolean.FALSE
helper context java!FieldDeclaration def: isBoolean() : Boolean =
    self.abstractTypeDeclaration.name = 'Boolean';

91
92
93
94
95
96

--------------------------------------------- AvoidStringBufferField  ---------------------------------------------
-- Rule for metrics AvoidStringBufferField
helper def: avoidStringBufferField() : Set(smm!Measure) =
	java!FieldDeclaration.allInstances()
		->select(dec | dec.type.type.name = 'StringBuffer' or dec.type.type.name = 'StringBuilder')
97
		->collect(dec | thisModule.MeasureAvoidStringBufferField(dec));
98
99
100
101
102
103
104
105
106
107
108
109
110

---------------------------------------------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 = 
    --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());
Hanane HADJI's avatar
Hanane HADJI committed
111