errorProne.atl 4.28 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
library errorProne;

---------------------------------- Missing break in switch---------------------------------------------

-- Returns a set of measures for each switch statement that violates the rule : missing break in switch
helper def: missingBreakInSwitch(): Set(smm!Measure) = 
	java!SwitchStatement.allInstances()
		-> select (switchStatement | thisModule.switchStatementContainsMissingBreaks(switchStatement))
		-> collect (switchStatement | thisModule.createMeasureForMissingBreakInSwitch(switchStatement))
;

-- Returns true if the switch statement contains missing breaks, false otherwise 
helper def: switchStatementContainsMissingBreaks(ss: java!SwitchStatement): Boolean = 
	-- If the number of switch cases (omitting those that empty => indicates intentional fallout) is bigger than
	-- the number of break statements => we don't have a break statement for every switch case 
	-- in that case, return true, else false
	(thisModule.nbBranchesOfASwitchStatement(ss) - thisModule.nbIntentionalFallThroughOfASwitchStatement(ss)) > thisModule.nbBreakStatementOfASwitchStatement(ss)
;

20
21
22
23
24
25
--------------------------------------------- DoNotExtendJavaLangThrowable ---------------------------------------------

-- Rule for metrics DoNotExtendJavaLangThrowable
helper def: doNotExtendJavaLangThrowable() : Set(smm!Measure) =
	-- select all class with a superTyper
	java!ClassDeclaration.allInstances()->select(it | it.superClass <> OclUndefined)
26
27
		-- select all class create by the user
		->select(it2| it2.proxy = false)
28
		-- select all class who extend Throwable
29
		->select(it3| it3.superClass.type.name = 'Throwable')
30
		-- collect all results and send an error message
31
32
		->collect(it4|thisModule.MeasureDoNotExtendJavaLangThrowable(it4))
	;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
--------------------------------------------- SuspiciousEqualsMethodName---------------------------------------------

--Detects the declaration of methods whose name and parameters looks like the equals(Object) method, which denote an intention to override the equals(Object) method.
--A method that looks like equals(Object) is named 'equals', or 'equal' wich is a common typo, and  the parameters and return type can be wrong typed.
helper def: suspiciousEqualsMethodName() : Set(smm!Measure) =
	java!MethodDeclaration.allInstances() 
		-> select(method | method.hasParameters() and method.hasReturnType())
		-> select(method | thisModule.isWrongEqualsDeclaration(method)) 
		-> collect(method | thisModule.MeasureSuspiciousEqualsMethodName(method));

--Detects if a method looks like the equals(Object) method.
helper def: isWrongEqualsDeclaration(method : java!MethodDeclaration) : Boolean = 
	method.name = 'equals' or method.name = 'equal' and --'equal' method name can be a typo
	(
		(
			method.parameters.size() = 1 and --there is only one parameter and the type of this parameter is wrong, or the return type of the method is wrong, or both.
		 	not(method.parameters.first().type.type.name = 'Object') or 
			not(method.returnType.type.name = 'boolean')
		)
		or
		(
			method.parameters.size() = 2 and --there are two parameters, and everything is well typed
			method.parameters->forAll(param | param.type.type.name = 'Object') and
			method.returnType.type.name = 'boolean'
		)
	)
	or
	(
		method.name = 'equal' and --the method is well typed but there is a typo
		method.parameters.size() = 1 and 
		method.parameters.first().type.type.name = 'Object' and
		method.returnType.type.name = 'boolean'
	);
	
	

	
--Allows to have the signature of a method as a String.
helper context java!MethodDeclaration def: toString() : String = 
	if self.hasReturnType() then 
		self.returnType.type.name
	else
		''
	endif 
	+ ' ' + self.name + '(' + 
	if self.hasParameters() then
		let params : String = self.parameters->collect(param | param.type.type.name + ' ' + param.name).toString()
		in params.substring(12, params.size()-2).regexReplaceAll('\'', '') 
	else
		''
	endif
	+ ')';
			
--Indicates whether a MethodDeclaration has a return type.
helper context java!MethodDeclaration def: hasReturnType() : Boolean = 
	not self.returnType.oclIsUndefined();

--Indicates whether a MethodDeclaration has parameters.
helper context java!MethodDeclaration def: hasParameters() : Boolean = 
	not self.parameters.isEmpty();

--------------------------------------------------------------------------------------------------------