diff --git a/src/main/atl/analysis.atl b/src/main/atl/analysis.atl index 1176c1ead1ece0cbaefbe272d4dd00e9ab7025bb..27292affc907adbd97483ebc504d51fb52b98713 100644 --- a/src/main/atl/analysis.atl +++ b/src/main/atl/analysis.atl @@ -48,6 +48,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = thisModule.AvoidDollarSigns(), thisModule.shortClassName(), thisModule.extendsObject(), + thisModule.unnecessaryReturn(), -- Design rules -- @@ -59,6 +60,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = thisModule.returnEmptyArrayRatherThanNull(), thisModule.excessiveParameterList(), thisModule.finalFieldCouldBeStatic(), + thisModule.signatureDeclareThrowsException(), -- Performance rules -- @@ -82,6 +84,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = -- Best practicices rules thisModule.avoidThrowingNewInstanceOfSameException() + thisModule.switchDensity() }; @@ -741,3 +744,71 @@ rule MeasureExtendsObject(variable : java!ClassDeclaration) { noc; } } + +--------------------------------------------- SwitchDensity --------------------------------------------- +-- A Measure instance if the class violates the rule SwitchDensity. +rule MeasureSwitchDensity(switch : java!SwitchStatement) { + + to + om: smm!ObservedMeasure ( + measure <- noc, + measurements <- measurement + ), + noc: smm!DimensionalMeasure ( + + name <- 'SwitchDensity ', + shortDescription <- 'Statement to label ratio is too high (> 10)' + + ), + measurement: smm!DirectMeasurement ( + error<-'In the Class '+ switch.originalCompilationUnit.name + ' a switch case contains too many statements.' + ) + do { + noc; + } +} +--------------------------------------------- SignatureDeclareThrowsException --------------------------------------------- +-- A Measure instance if the class violates the rule SignatureDeclareThrowsException. +rule MeasureSignatureDeclareThrowsException(class : java!ClassDeclaration) { + + to + om: smm!ObservedMeasure ( + measure <- noc, + measurements <- measurement + ), + noc: smm!DimensionalMeasure ( + + name <- 'SignatureDeclareThrowsException ', + shortDescription <- 'A method/constructor should not explicitly throw the generic java.lang.Exception' + + ), + measurement: smm!DirectMeasurement ( + error<-'In the Class '+ class.name + ' a method/constructor explicitly throws the generic java.lang.Exception.' + ) + do { + noc; + } +} + +--------------------------------------------- UnnecessaryReturn --------------------------------------------- +-- A Measure instance if the class violates the rule UnnecessaryReturn. +rule MeasureUnnecessaryReturn(state : java!ReturnStatement) { + + to + om: smm!ObservedMeasure ( + measure <- noc, + measurements <- measurement + ), + noc: smm!DimensionalMeasure ( + + name <- 'UnnecessaryReturn ', + shortDescription <- 'Avoid the use of unnecessary return statements.' + + ), + measurement: smm!DirectMeasurement ( + error<-'In the Class '+ state.originalCompilationUnit.name + ' an unnecessary return was used.' + ) + do { + noc; + } +} diff --git a/src/main/atl/bestPractices.atl b/src/main/atl/bestPractices.atl index 830af1a31b2e96bc1d24f5b75d1d72a79b784e19..fa7b74c0ef4342238749446ec96422878b409d96 100644 --- a/src/main/atl/bestPractices.atl +++ b/src/main/atl/bestPractices.atl @@ -49,4 +49,16 @@ helper def: emptyStatementBlock() : Set(smm!Measure) = java!Block.allInstances() ->select(block | block.statements.isEmpty()) ->collect(block | thisModule.MeasureEmptyStatementBlock(block)); + +--------------------------------------------- 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)) + ); diff --git a/src/main/atl/codestyle.atl b/src/main/atl/codestyle.atl index abe47bedc3e4e2c71566e082a93287c4f7704cdb..b3eaa933ac70336a0bbafc6ac287f335d9650b3e 100644 --- a/src/main/atl/codestyle.atl +++ b/src/main/atl/codestyle.atl @@ -48,3 +48,11 @@ helper def: extendsObject() : Set(smm!Measure) = -- collect all results and send an error message ->collect(it4|thisModule.MeasureDoNotExtendJavaLangError(it4)) ; + +--------------------------------------------- UnnecessaryReturn --------------------------------------------- +-- Rule for metrics UnnecessaryReturn : +helper def: unnecessaryReturn() : Set (smm!Measure) = + -- Browse through all method declarations + java!ReturnStatement.allInstances() + ->select(state | not state.expression.oclIsTypeOf(java!SingleVariableAccess)) + ->collect(state | thisModule.MeasureUnnecessaryReturn(state)); diff --git a/src/main/atl/design.atl b/src/main/atl/design.atl index e844abf64a819ae2b2184d214505907bc4e4ea44..53720a8e9a4e1be0a51ff5fa8e4700206dc6ba4d 100644 --- a/src/main/atl/design.atl +++ b/src/main/atl/design.atl @@ -86,3 +86,23 @@ helper def: doNotExtendJavaLangError() : Set(smm!Measure) = helper def: finalFieldCouldBeStatic() : Set(smm!Measure) = -- Browse through all field that are final and not static java!FieldDeclaration.allInstances()->select(i | i.modifier <> OclUndefined)->select(i | i.modifier.inheritance->toString() = 'final' and not i.modifier.static)->collect(j | thisModule.MeasureFinalFieldCouldBeStatic(j)); + +--------------------------------------------- SignatureDeclareThrowsException --------------------------------------------- +-- Rule for metrics SignatureDeclareThrowsException : +helper def: signatureDeclareThrowsException() : Set (smm!Measure) = + -- Browse through all Switch Statements + java!ClassDeclaration.allInstances()->iterate(c; res : Set(smm!Measure) = Set{} | + c.bodyDeclarations + ->select(bodyDeclaration | bodyDeclaration.oclIsTypeOf(java!ConstructorDeclaration) + or bodyDeclaration.oclIsTypeOf(java!MethodDeclaration)) + + ->select(bodyDeclaration | bodyDeclaration.thrownExceptions <> OclUndefined) + ->collect(bodyDeclaration | bodyDeclaration.thrownExceptions)->iterate(thrownException; res1 : Set(smm!Measure) = Set{} | + thrownException + ->select(exception | exception.oclIsTypeOf(java!TypeAccess)) + ->select(exception | exception.type <> OclUndefined) + ->select(exception | exception.type.oclIsTypeOf(java!ClassDeclaration)) + ->select(exception | exception.type.name = 'Exception') + ->collect(exception | thisModule.MeasureSignatureDeclareThrowsException(c)) + ) + ); \ No newline at end of file