documentation.atl 7.39 KB
Newer Older
Roxane MARECHAL's avatar
Roxane MARECHAL committed
1
2
3
4
library documentation;

--------------------------------------------- CommentRequired ---------------------------------------------

5
--- Returns a set of measures for each element where comments are required but are missing
Roxane MARECHAL's avatar
Roxane MARECHAL committed
6
7
8
9
10
11
12
13
14
15
16
17
helper def: commentRequired() : Set(smm!Measure) = 
	
	java!BodyDeclaration.allInstances()
		-> select (elem | elem.proxy = false)
		
		-- Get only elements concerned by the CommentRequired properties
		-> select (elem | thisModule.commentRequiredPropertyDefinitions().getKeys().contains(elem.oclType().name))
		
		-> select (elem | thisModule.violatesCommentRequired(elem))
		-> collect (elem | thisModule.MeasureCommentRequired(elem, thisModule.violatedCommentRequiredProperties(elem)))
;

18
--- Returns true if there exists a CommentRequired property denoting that the given element requires a comment but does not have any
Roxane MARECHAL's avatar
Roxane MARECHAL committed
19
20
21
22
23
24
25
26
27
28
29
30
31
helper def: violatesCommentRequired(elem: java!BodyDeclaration): Boolean =

	-- An element violates a property if there's at least one that's violated,
	(thisModule.commentRequiredPropertyDefinitions().get(elem.oclType().name)
	->exists(propertyTuple | thisModule.matchesCommentRequiredProperty('Required',elem, propertyTuple)))
	
	-- AND IF it doesn't match any 'Ignored' properties
	.and(
		not thisModule.commentRequiredPropertyDefinitions().get(elem.oclType().name)
		->exists(propertyTuple | thisModule.matchesCommentRequiredProperty('Ignored',elem, propertyTuple))
	)
;

32
--- Returns as a string, the list of CommentRequired properties (comments required but missing) that the given element violates 
Roxane MARECHAL's avatar
Roxane MARECHAL committed
33
34
35
helper def: violatedCommentRequiredProperties(elem: java!BodyDeclaration): String = 
	
	-- Get the set of property tuples associated to elem by using elem data type as key to the Map
36
	let propertyNames:String = '' in thisModule.commentRequiredPropertyDefinitions().get(elem.oclType().name)
Roxane MARECHAL's avatar
Roxane MARECHAL committed
37
38
39
	
	-- Concatenate to propertyNames : the name of each property rules that matches requirements for elem
	->select(propertyTuple | thisModule.matchesCommentRequiredProperty('Required',elem, propertyTuple))
40
	->collect(tuple | propertyNames.concat(tuple.property))
Roxane MARECHAL's avatar
Roxane MARECHAL committed
41
42
;
	
43
--- Returns true if the CommentRequired property tuple applies to the given element, false otherwise
Roxane MARECHAL's avatar
Roxane MARECHAL committed
44
45
46
47
48
49
50
51
52
53
54
55
56
helper def: matchesCommentRequiredProperty(
	value:String, -- is either 'Required' or 'Ignore'
	elem: java!BodyDeclaration, 
	tuple: TupleType(property:String, value:Boolean, modifier: String, annotation: String)): Boolean = 
	
	-- Check whether this rule is required
	(tuple.value=value)
	
	-- Check the given element has comments
	.and(not thisModule.hasComments(elem))

	-- Check correspondance with modifier vibility
	.and(
57
		tuple.modifier.isEmpty() or tuple.modifier = elem.modifier.visibility.name)
Roxane MARECHAL's avatar
Roxane MARECHAL committed
58
		
Roxane Kang Maréchal's avatar
Roxane Kang Maréchal committed
59
	-- Check correspondance with annotation
Roxane MARECHAL's avatar
Roxane MARECHAL committed
60
	.and(
61
		tuple.annotation.isEmpty() or 
62
63
		elem.annotations
			->exists(annotation | annotation.type.type.name = tuple.annotation))
Roxane MARECHAL's avatar
Roxane MARECHAL committed
64
65
66
		
	-- Check correspondance with prefixes
	.and(
67
68
69
		tuple.prefixes.isEmpty() or
		tuple.prefixes->exists(p | elem.getBodyDeclarationName().startsWith(p))
		)
Roxane MARECHAL's avatar
Roxane MARECHAL committed
70
71
;
	
72
--- Returns true if the elem has comments, false otherwise
Roxane MARECHAL's avatar
Roxane MARECHAL committed
73
74
75
76
helper def: hasComments(elem: java!BodyDeclaration): Boolean = 
	not elem.comments.isEmpty()
;

77
--- Defines properties denoting whether comments are required (or unwanted) for specific language elements
Roxane MARECHAL's avatar
Roxane MARECHAL committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
-- Can add, delete or modify properties here to customize them just like in PMD
helper def: commentRequiredPropertyDefinitions() :
	Map(
		String, -- Key 	 -> the name of java element data type
		Set(	-- Value -> set of property tuples associated to a java element data type 
			TupleType(				
				property:String, 		-- Name of the property
				value:String, 			-- Possible values ['Required','Ignored']
				modifier: String, 		-- Indicates whether the property concerns 'private', 'protected' or 'public' elements
				annotation: String, 	-- Indicates whether the property concerns elements with annotations (e.g Override) 
				prefixes: Set(String)))	-- Filters concerned elements by their prefixes (usefull for getting accesssors or serialVersionUID fields)
		) = 
	Map {
	
		-- Configure comment requirement properties for method declarations
		('MethodDeclaration',
			Set {
95
				Tuple{property='methodWithOverrideCommentRequirement', value='Ignored', modifier='', annotation='Override', prefixes=Set{}},
Roxane MARECHAL's avatar
Roxane MARECHAL committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
				Tuple{property='publicMethodCommentRequirement', value='Required', modifier='public', annotation='', prefixes=Set{}},
				Tuple{property='protectedMethodCommentRequirement', value='Required', modifier='protected', annotation='', prefixes=Set{}}, 
				Tuple{property='protectedMethodCommentRequirement', value='Required', modifier='none', annotation='', prefixes=Set{}}, -- protected is also defined as 'none' in the java model
				Tuple{property='accessorCommentRequirement', value='Ignored', modifier='', annotation='', prefixes=Set{'get','set'}}	
			}
		),
		
		-- Configure comment requirement properties for field declarations
		('FieldDeclaration',
		 	Set{
				Tuple{property='fieldCommentRequirement', value='Required', modifier='', annotation='', prefixes=Set{}},
				Tuple{property = 'serialVersionUIDCommentRequired', value='Ignored', modifier='', annotation='', prefixes=Set{'serialVersionUID'}},
				Tuple{property = 'serialPersistentFieldsCommentRequired', value='Ignored', modifier='', annotation='', prefixes=Set{'serialPersistentFields'}}
		 		
				-- Not by default in PMD but just to test genericity of rule customization :
				-- Tuple{property='protectedFieldCommentRequirement', value='Ignored', modifier='protected', annotation='', prefixes=Set{}},
				-- Tuple{property='protectedFieldCommentRequirement', value='Ignored', modifier='none', annotation='', prefixes=Set{}}
			}
		),
		
		-- Configure comment requirement properties for class declarations
		('ClassDeclaration', 
		 	Set{
				Tuple{property='headerCommentRequirement', value='Required', modifier='', annotation='', prefixes=Set{}}
		 	}
		),
		
		-- Configure comment requirement properties for enums
		('EnumDeclaration', 
		 	Set{
				Tuple{property='enumCommentRequirement', value=true, modifier='', annotation='', prefixes=Set{}}
		 	}
		)
};

-------------------------------------------------------------------------------------------------------------------
Ronan GUEGUEN's avatar
Ronan GUEGUEN committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
-----------------------------------CommentContent------------------------------

helper def: badWordDefinition(): Set(String) =
	
	-- Returns a set of forbidden words
	Set{'jerk','idiot','slut','whore','anus','assfucker','tapir','motherfucker','fuck','lardass','cumslut','cunt','shit','Rob Schneider'}

;

helper def: matchedBadWord(elem : Sequence(String)): Sequence(String) =
	
	-- Returns true if the string is one of the bad words
	elem -> select(word |  thisModule.badWordDefinition().includes(word.toLowerCase())) -- Returns every bad words found 
;

helper def: commentContent(): Set(smm!Measure) =
	
	java!ASTNode.allInstances()
		-> reject (node | node.comments.isEmpty()) 					-- Rejects all instances that do not contain comments
		-> collect (node | thisModule.violatedCommentContent(node))
		-> reject(seq | seq.isEmpty())								
		-> collect (elem | thisModule.MeasureCommentContent(elem))  -- Select all instances that contains a bad word in one of its comments
;

helper def: violatedCommentContent(node : java!ASTNode): Sequence(String) =
	
	node.comments
	-> reject (comment | comment.content.isEmpty())
	-> collect (comment | comment.content.split('[ ,.:!?;/]'))
	-> collect (words | thisModule.matchedBadWord(words))
	-> reject (words | words.isEmpty()) -> flatten()
;
Roxane MARECHAL's avatar
Roxane MARECHAL committed
164