multithreading.atl 2.72 KB
Newer Older
Gerson Sunyé's avatar
Gerson Sunyé committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
library multithreading;

--------------------------------------------- DontCallThreadRun ---------------------------------------------

--Goes through all the methods to check if the following rule is followed:
--Don't call Thread.run()
helper def: dontCallThreadRun() : Set(smm!Measure) =
	java!MethodInvocation.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{}  | 
	
		if (thisModule.isDontCallThreadRun(i))
			then res->union(Set{thisModule.MeasureDontCallThreadRun(i)})
			else res
		endif
	);

--Detect a wrong usage of the method Thread.run()
--return true if run() is called on a Thread variable or on a Thread instance creation
helper def:isDontCallThreadRun(s:java!MethodInvocation): Boolean =
	if s.method.name = 'run' then
		--check if the method is called like this: 
		--t.run() where t is of type Thread
		if s.expression.oclType().toString() = 'java!SingleVariableAccess' then
			if s.expression.variable.variablesContainer.type.type.name.toString() = 'Thread' then 
				true 
			else false 
			endif
		--check if the method run is called like this:
		--new Thread().run();
		else 
			if s.expression.oclType().toString() = 'java!ClassInstanceCreation' then
				if s.expression.method.name.toString() = 'Thread' then 
					true
				else false
				endif
			else false
			endif
		endif	
	else false
	endif;

--------------------------------------------- AvoidThreadGroup  ---------------------------------------------

--Goes through all the variables to check if the following rule is followed:
--Avoid using java.lang.ThreadGroup;
helper def: avoidThreadGroup() : Set(smm!Measure) =
	java!VariableDeclarationFragment.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{}  | 
	
		if (thisModule.isThreadGroup(i))
			then res->union(Set{thisModule.measureAvoidThreadGroup(i)})
			else res
		endif
		
	);

--Detect a wrong usage of the variable type java.lang.ThreadGroup
--return true if the variable of type java.lang.ThreadGroup
helper def:isThreadGroup(s:java!VariableDeclarationFragment): Boolean =
	if s.variablesContainer.type.type.name.toString() = 'ThreadGroup' then
		true
	else
		false
	endif;
63
64
65
66
67
68
69
70
71
72
73
74
	
--------------------------------------------- UseNotifyAllInsteadOfNotify ---------------------------------------------

-- Returns a set of measures each time the method 'notify()' is used instead of 'notifyAll()'
helper def: useNotifyAllInsteadOfNotify(): Set(smm!Measure) =
	
	-- Get the method declarations of notify() and for each of their MethodInvocation usages, create a measure
	java!MethodDeclaration.allInstances()
		->select(methodDeclaration | methodDeclaration.name = 'notify')
		->collect (methodDeclaration |methodDeclaration.usages
			->collect(methodInvocation | thisModule.MeasureUseNotifyAllInsteadOfNotify(methodInvocation)))
;