Commit 1a604225 authored by Gerson SUNYE's avatar Gerson SUNYE
Browse files

Merge branch 'AvoidThrowingNewInstanceOfSameException' into 'master'

Avoid throwing new instance of same exception

See merge request naomod/mde/projet-2019!37
parents 0c295f8c 14f7f444
<?xml version="1.0" encoding="ASCII"?>
<java:Model xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://www.eclipse.org/MoDisco/Java/0.2.incubation/java" name="test-projet">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="AvoidThrowingNewInstanceOfSameException">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="method1">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:TryStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ThrowStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// do something" prefixOfParent="true"/>
<expression xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0">
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</expression>
</statements>
</body>
<catchClauses originalCompilationUnit="//@compilationUnits.0">
<exception originalCompilationUnit="//@compilationUnits.0" name="se" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression/@arguments.0">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</exception>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ThrowStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// harmless comment" prefixOfParent="true"/>
<expression xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1">
<arguments xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@catchClauses.0/@exception"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</expression>
</statements>
</body>
</catchClauses>
</statements>
</body>
<thrownExceptions type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="method2">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// Good behavior" prefixOfParent="true"/>
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:TryStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// do something" enclosedByParent="true"/>
</body>
<catchClauses originalCompilationUnit="//@compilationUnits.0">
<exception originalCompilationUnit="//@compilationUnits.0" name="se" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression/@arguments.0">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</exception>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ThrowStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// harmless comment" prefixOfParent="true"/>
<expression xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.1/@ownedElements.0/@bodyDeclarations.0">
<arguments xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@catchClauses.0/@exception"/>
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</expression>
</statements>
</body>
</catchClauses>
</statements>
</body>
<thrownExceptions type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="method3">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:TryStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// do something" enclosedByParent="true"/>
</body>
<catchClauses originalCompilationUnit="//@compilationUnits.0">
<exception originalCompilationUnit="//@compilationUnits.0" name="se" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</exception>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ThrowStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// harmless comment" prefixOfParent="true"/>
<expression xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@body/@statements.0/@catchClauses.0/@exception"/>
</statements>
</body>
</catchClauses>
</statements>
</body>
<thrownExceptions type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="method4">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:TryStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// do something" enclosedByParent="true"/>
</body>
<catchClauses originalCompilationUnit="//@compilationUnits.0">
<exception originalCompilationUnit="//@compilationUnits.0" name="se" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression/@expression">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</exception>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ExpressionStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// harmless comment" prefixOfParent="true"/>
<expression xsi:type="java:MethodInvocation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.1/@ownedElements.1/@bodyDeclarations.0">
<expression xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@body/@statements.0/@catchClauses.0/@exception"/>
</expression>
</statements>
</body>
</catchClauses>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="method5">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:TryStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// do something" enclosedByParent="true"/>
</body>
<catchClauses originalCompilationUnit="//@compilationUnits.0">
<exception originalCompilationUnit="//@compilationUnits.0" name="se">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</exception>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ThrowStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// harmless comment" prefixOfParent="true"/>
<expression xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.1/@ownedElements.0/@bodyDeclarations.1">
<arguments xsi:type="java:StringLiteral" originalCompilationUnit="//@compilationUnits.0" escapedValue="&quot;Autre message&quot;"/>
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</expression>
</statements>
</body>
</catchClauses>
</statements>
</body>
<thrownExceptions type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="io" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="IOException" proxy="true" usagesInImports="//@compilationUnits.0/@imports.0" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@thrownExceptions.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@body/@statements.0/@expression/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@catchClauses.0/@exception/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression/@type">
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="IOException" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@body/@statements.0/@expression"/>
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="IOException" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression">
<parameters name="arg0" proxy="true">
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.1"/>
</parameters>
</bodyDeclarations>
<superClass type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Serializable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.1/@superInterfaces.0 //@ownedElements.1/@ownedPackages.1/@ownedElements.2/@superInterfaces.0"/>
</ownedPackages>
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="Exception" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superClass //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@thrownExceptions.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@catchClauses.0/@exception/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@thrownExceptions.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@body/@statements.0/@catchClauses.0/@exception/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@body/@statements.0/@catchClauses.0/@exception/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@thrownExceptions.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@body/@statements.0/@catchClauses.0/@exception/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression/@type">
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="Exception" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression">
<parameters name="arg0" proxy="true">
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.1"/>
</parameters>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="Exception" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression">
<parameters name="arg0" proxy="true">
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.2"/>
</parameters>
</bodyDeclarations>
<superClass type="//@ownedElements.1/@ownedPackages.1/@ownedElements.1"/>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" name="Throwable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.0/@superClass //@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@parameters.0/@type //@ownedElements.1/@ownedPackages.1/@ownedElements.0/@bodyDeclarations.0/@parameters.0/@type">
<bodyDeclarations xsi:type="java:MethodDeclaration" name="printStackTrace" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@body/@statements.0/@catchClauses.0/@body/@statements.0/@expression"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" name="String" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.0/@bodyDeclarations.1/@parameters.0/@type">
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.3"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.4"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Comparable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.2/@superInterfaces.1">
<typeParameters name="T" proxy="true"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="CharSequence" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.2/@superInterfaces.2"/>
</ownedPackages>
</ownedElements>
<orphanTypes xsi:type="java:PrimitiveTypeInt" name="int"/>
<orphanTypes xsi:type="java:PrimitiveTypeLong" name="long"/>
<orphanTypes xsi:type="java:PrimitiveTypeFloat" name="float"/>
<orphanTypes xsi:type="java:PrimitiveTypeDouble" name="double"/>
<orphanTypes xsi:type="java:PrimitiveTypeBoolean" name="boolean"/>
<orphanTypes xsi:type="java:PrimitiveTypeVoid" name="void" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@returnType //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@returnType //@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@returnType //@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@returnType //@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@returnType"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="AvoidThrowingNewInstanceOfSameException.java" originalFilePath="D:\Documents\Cours\M2-ALMA\Gerson\test-projet\src\AvoidThrowingNewInstanceOfSameException.java" commentList="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@body/@statements.0/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@catchClauses.0/@body/@statements.0/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@body/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.1/@body/@statements.0/@catchClauses.0/@body/@statements.0/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@body/@statements.0/@body/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.2/@body/@statements.0/@catchClauses.0/@body/@statements.0/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@body/@statements.0/@body/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.3/@body/@statements.0/@catchClauses.0/@body/@statements.0/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@body/@statements.0/@body/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.4/@body/@statements.0/@catchClauses.0/@body/@statements.0/@comments.0" types="//@ownedElements.0/@ownedElements.0">
<imports originalCompilationUnit="//@compilationUnits.0" importedElement="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</compilationUnits>
</java:Model>
......@@ -38,8 +38,8 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
-- Multithreading rules
--
thisModule.dontCallThreadRun(),
thisModule.useNotifyAllInsteadOfNotify(),
thisModule.avoidThreadGroup(),
thisModule.useNotifyAllInsteadOfNotify(),
-- Code Style rules
--
......@@ -68,8 +68,8 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
-- Error prone rules
--
thisModule.missingBreakInSwitch()
thisModule.missingBreakInSwitch(),
thisModule.avoidThrowingNewInstanceOfSameException()
};
......@@ -391,6 +391,26 @@ rule measureAvoidThreadGroup(variable : java!VariableDeclarationFragment) {
}
}
--------------------------------------------- AvoidThrowingNewInstanceOfSameException ---------------------------------------------
-- A Measure instance if the class violates the rule 'AvoidThrowingNewInstanceOfSameException'.
rule MeasureAvoidThrowingNewInstanceOfSameException(catch : java!CatchClause) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'AvoidThrowingNewInstanceOfSameException',
shortDescription <- 'Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to code size and runtime complexity.'
),
measurement: smm!DirectMeasurement (
error <-'The class '+ catch.originalCompilationUnit.name + ' has a method that rethrows a caught exception wrapped inside a new instance of the same type.'
)
do {
noc;
}
}
--------------------------------------------- ReturnEmptyArrayRatherThanNull ---------------------------------------------
-- creates a new Measure when a method returns an empty method rather than null
rule MesureReturnEmptyArrayRatherThanNull(method : java!ReturnStatement) {
......@@ -410,6 +430,7 @@ rule MesureReturnEmptyArrayRatherThanNull(method : java!ReturnStatement) {
noc;
}
}
--------------------------------------------- ExcessiveParameterList ---------------------------------------------
-- creates a new Measure when a method has more than 10 parameters
rule MesureExcessiveParameterList(method : java!MethodDeclaration) {
......
......@@ -65,3 +65,23 @@ helper def:isWrongUsageIndexOfChar(s:java!MethodInvocation): Boolean =
else
false
endif;
--------------------------------------------- avoidThrowingNewInstanceOfSameException ---------------------------------------------
-- Returns a set of Measures for each catch block throws a new instance of the caught exception
helper def: avoidThrowingNewInstanceOfSameException() : Set(smm!Measure) =
java!CatchClause.allInstances() ->iterate(catch; catchRes : Set(smm!Measure) = Set{} |
if catch.body <> OclUndefined
then catch.body.statements
-> select(catchStatement | catchStatement.oclIsTypeOf(java!ThrowStatement)
and catchStatement.expression.oclIsTypeOf(java!ClassInstanceCreation))
-> select(catchStatement | catchStatement.expression.type.type.name = catch.exception.type.type.name)
-> collect(catchStatement | catchStatement.expression.arguments)
-> iterate(arguments; argumentsRes : Set(smm!Measure) = Set{} |
arguments
-> select(argument | argument.oclIsTypeOf(java!SingleVariableAccess))
-> select(argument | argument.variable.name = catch.exception.name)
-> collect(argument | thisModule.MeasureAvoidThrowingNewInstanceOfSameException(catch))
)
else catchRes
endif
);
\ No newline at end of file
Supports Markdown
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