From 12da66873618fd34599df59cddc94c2348162eee Mon Sep 17 00:00:00 2001 From: Faenya Date: Thu, 5 Dec 2019 20:39:14 +0100 Subject: [PATCH] Fix Issue 715 UnnecessaryReturn, Issue 755 SignatureDeclareThrowsException, Issue 763 SwitchDensity --- src/main/atl/analysis.atl | 71 ++++++++++++++++++++++++++++++++++ src/main/atl/bestPractices.atl | 12 ++++++ src/main/atl/codestyle.atl | 8 ++++ src/main/atl/design.atl | 20 ++++++++++ 4 files changed, 111 insertions(+) diff --git a/src/main/atl/analysis.atl b/src/main/atl/analysis.atl index 1176c1e..27292af 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 830af1a..fa7b74c 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 abe47be..b3eaa93 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 e844abf..53720a8 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 -- GitLab