Commit df618197 authored by RoxaneKM's avatar RoxaneKM
Browse files

Finalized helpers and rules for comment required

parent 09fae6e7
...@@ -9,8 +9,8 @@ uses design; ...@@ -9,8 +9,8 @@ uses design;
uses codestyle; uses codestyle;
uses multithreading; uses multithreading;
uses performance; uses performance;
uses documentation;
uses bestPractices; uses bestPractices;
uses documentation;
rule Java2SMM { rule Java2SMM {
from from
...@@ -367,7 +367,7 @@ rule MesureAvoidFieldNameMatchingMethodName(class : java!ClassDeclaration, metho ...@@ -367,7 +367,7 @@ rule MesureAvoidFieldNameMatchingMethodName(class : java!ClassDeclaration, metho
} }
} }
-- Creates a measure instance for each node that violates the rule : comment required -- Creates a measure instance for each element that violates the rule : comment required
rule MeasureCommentRequired(element: java!NamedElement, violatedProperties: Set(String)) { rule MeasureCommentRequired(element: java!NamedElement, violatedProperties: Set(String)) {
to to
om: smm!ObservedMeasure ( om: smm!ObservedMeasure (
...@@ -379,11 +379,19 @@ rule MeasureCommentRequired(element: java!NamedElement, violatedProperties: Set( ...@@ -379,11 +379,19 @@ rule MeasureCommentRequired(element: java!NamedElement, violatedProperties: Set(
shortDescription <- 'Denotes whether comments are required (or unwanted) for specific language elements.' shortDescription <- 'Denotes whether comments are required (or unwanted) for specific language elements.'
), ),
measurement: smm!DirectMeasurement ( measurement: smm!DirectMeasurement (
error <- 'Violated the properties -> ' + violatedProperties + ' in Class: ' + element.originalCompilationUnit.name + ' -> ' + element.oclType().name + ': ' + element.modifier.visibility + ' ' + element.name error <- 'Violated the properties -> ' + violatedProperties + ' in Class: ' + element.originalCompilationUnit.name + ' -> ' + element.oclType().name + ': ' + element.modifier.visibility + ' ' + thisModule.getNamedElementName(element)
) )
do { do {
commentRequired; commentRequired;
} }
} }
-- Returns the declaration name of a NamedElement
-- For field declarations, it is contained in "fragments"
helper def: getNamedElementName(elem: java!NamedElement): String =
if (elem.oclIsTypeOf(java!FieldDeclaration))
then elem.fragments.first().name
else elem.name
endif
;
...@@ -3,73 +3,98 @@ library documentation; ...@@ -3,73 +3,98 @@ library documentation;
-- Returs a set of measures for each element that violates the rule : comment required -- Returs a set of measures for each element that violates the rule : comment required
helper def: commentRequired() : Set(smm!Measure) = helper def: commentRequired() : Set(smm!Measure) =
java!NamedElement.allInstances() java!NamedElement.allInstances()
-> select (node | not node.oclIsTypeOf(java!Package) and node.proxy = false) -> select (elem | not elem.oclIsTypeOf(java!Package) and elem.proxy = false)
-> select (node | thisModule.commentRequiredPropertyCustomization().getKeys().contains(node.oclType().name)) -> select (elem | thisModule.commentRequiredPropertyCustomization().getKeys().contains(elem.oclType().name))
-> select (node | thisModule.violatesCommentRequired(node)) -> select (elem | thisModule.violatesCommentRequired(elem))
-> collect (node | thisModule.MeasureCommentRequired(node, thisModule.violatedCommentRequiredProperty(node))) -> collect (elem | thisModule.MeasureCommentRequired(elem, thisModule.violatedCommentRequiredProperty(elem)))
; ;
-- Returns true if the given node violates any of the "comment required" rule properties -- Returns true if the given elem violates any of the "comment required" rule properties
helper def: violatesCommentRequired(node: java!NamedElement): Boolean = helper def: violatesCommentRequired(elem: java!NamedElement): Boolean =
thisModule.commentRequiredPropertyCustomization().get(node.oclType().name) thisModule.commentRequiredPropertyCustomization().get(elem.oclType().name)
->exists(propertyTuple | thisModule.violatesCommentRequiredPropertyRequirements(node, propertyTuple)) ->exists(propertyTuple | thisModule.violatesCommentRequiredPropertyRequirements(elem, propertyTuple))
; ;
helper def: violatedCommentRequiredProperty(node: java!NamedElement): String = helper def: violatedCommentRequiredProperty(elem: java!NamedElement): String =
thisModule.commentRequiredPropertyCustomization().get(node.oclType().name) thisModule.commentRequiredPropertyCustomization().get(elem.oclType().name)
->select(propertyTuple | thisModule.violatesCommentRequiredPropertyRequirements(node, propertyTuple)) ->select(propertyTuple | thisModule.violatesCommentRequiredPropertyRequirements(elem, propertyTuple))
->iterate (tuple; propertyNames: String = '' | ->iterate (tuple; propertyNames: String = '' |
propertyNames.concat(tuple.property+';') propertyNames.concat(tuple.property+';')
) )
; ;
-- Returns true if the given property tuple applies to the given node, false otherwise -- Returns true if the given property tuple applies to the given elem, false otherwise
helper def: violatesCommentRequiredPropertyRequirements( helper def: violatesCommentRequiredPropertyRequirements(
node: java!NamedElement, elem: java!NamedElement,
tuple: TupleType(property:String, required:Boolean, modifier: String, annotation: String)): Boolean = tuple: TupleType(property:String, required:Boolean, modifier: String, annotation: String)): Boolean =
-- Check whether the given property tuple applies to the given node -- Check whether the given property tuple applies to the given elem:
-- Check if required
tuple.required tuple.required
.and(not thisModule.hasComments(node)) .and(not thisModule.hasComments(elem))
-- Check correspondance with modifier
.and( .and(
if (tuple.modifier.isEmpty()) then true if (tuple.modifier.isEmpty()) then true
else else
if (tuple.modifier = node.modifier.visibility.name) then true else false endif if (tuple.modifier = elem.modifier.visibility.name) then true else false endif
endif)
-- Check correspondance with annotation
.and(
if (tuple.annotation.isEmpty()) then true
else
if (elem.annotations.contains(tuple.annotation)) then true else false endif
endif)
-- Check correspondance with prefixes
.and(
if (tuple.prefixes.isEmpty()) then true
else
if (tuple.prefixes->exists(p | elem.name.startsWith(p))) then true else false endif
endif) endif)
; ;
-- Returns true if the node has comments, false otherwise -- Returns true if the elem has comments, false otherwise
helper def: hasComments(node: java!NamedElement): Boolean = helper def: hasComments(elem: java!NamedElement): Boolean =
not node.comments.isEmpty() not elem.comments.isEmpty()
; ;
-- Contains the default configuration for the "Comment required" rule -- Contains the default configuration for the "Comment required" rule
-- Can add, delete or modify properties here to customize them just like in PMD -- Can add, delete or modify properties here to customize them just like in PMD
helper def: commentRequiredPropertyCustomization() : helper def: commentRequiredPropertyCustomization() :
Map(String, Set(TupleType(property:String, required:Boolean, modifier: String, annotation: String))) = Map { Map(String, Set(TupleType(property:String, required:Boolean, modifier: String, annotation: String, prefixes: Set(String)))) = Map {
-- Configure comment requirement properties for method declarations -- Configure comment requirement properties for method declarations
('MethodDeclaration', ('MethodDeclaration',
Set { Set {
Tuple{property='methodWithOverrideCommentRequirement', required=false, modifier='', annotation='override'}, Tuple{property='methodWithOverrideCommentRequirement', required=false, modifier='', annotation='override', prefixes=Set{}},
Tuple{property='publicMethodCommentRequirement', required=true, modifier='public', annotation='override'}, Tuple{property='publicMethodCommentRequirement', required=true, modifier='public', annotation='override', prefixes=Set{}},
Tuple{property='protectedMethodCommentRequirement', required=true, modifier='protected', annotation=''} Tuple{property='protectedMethodCommentRequirement', required=true, modifier='protected', annotation='', prefixes=Set{}},
-- Tuple{property = 'accessorCommentRequirement', value='Ignored'}, Tuple{property='accessorCommentRequirement', required=false, modifier='', annotation='', prefixes=Set{'get,set'}}
-- Tuple{property = 'headerCommentRequirement', value='Required'},
} }
), ),
-- Configure field requirement properties for field declarations -- Configure comment requirement properties for field declarations
('FieldDeclaration', ('FieldDeclaration',
Set{ Set{
Tuple{property='fieldCommentRequirement', required=true, modifier='', annotation=''} Tuple{property='fieldCommentRequirement', required=true, modifier='', annotation='', prefixes=Set{}},
Tuple{property = 'serialVersionUIDCommentRequired', required=false, modifier='', annotation='', prefixes=Set{}},
Tuple{property = 'serialPersistentFieldsCommentRequired', required=false, modifier='', annotation='', prefixes=Set{}}
} }
) ),
-- TODO : find corresponding type for the following -- Configure comment requirement properties for class declarations
-- (java!ASTNode, Map{('enumCommentRequirement', 'Required')}), ('ClassDeclaration',
-- (java!ASTNode, Map{('serialVersionUIDCommentRequired', 'Ignored')}), Set{
-- (java!ASTNode, Map{('serialPersistentFieldsCommentRequired', 'Ignored')}) Tuple{property='headerCommentRequirement', required=true, modifier='', annotation='', prefixes=Set{}}
}
),
-- Configure coment requirement properties for enum
('EnumDeclaration',
Set{
Tuple{property='enumCommentRequirement', required=true, modifier='', annotation='', prefixes=Set{}}
}
)
}; };
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