Commit 2afee0c0 authored by BRAULT Benjamin's avatar BRAULT Benjamin
Browse files

Merge branch 'master' into 'SimplifyBooleanAssertion'

# Conflicts:
#   src/main/atl/analysis.atl
parents 6815a21f 14ea4dfd
......@@ -11,6 +11,6 @@ target/
/metrics.xmi
*.launch
analysis.launch
!analysis.launch
*.orig
*.orig
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.m2m.atl.adt.launching.atlTransformation">
<stringAttribute key="ATL File Name" value="/projet-2019/src/main/atl/analysis.atl"/>
<stringAttribute key="ATL VM" value="EMF-specific VM"/>
<stringAttribute key="ATL_COMPILER" value="atl2006"/>
<booleanAttribute key="IS_REFINING" value="false"/>
<mapAttribute key="Input">
<mapEntry key="IN" value="java"/>
</mapAttribute>
<mapAttribute key="Libs">
<mapEntry key="bestPractices" value="/projet-2019/src/main/atl/bestPractices.asm"/>
<mapEntry key="codestyle" value="/projet-2019/src/main/atl/codestyle.asm"/>
<mapEntry key="design" value="/projet-2019/src/main/atl/design.asm"/>
<mapEntry key="documentation" value="/projet-2019/src/main/atl/documentation.asm"/>
<mapEntry key="errorProne" value="/projet-2019/src/main/atl/errorProne.asm"/>
<mapEntry key="multithreading" value="/projet-2019/src/main/atl/multithreading.asm"/>
<mapEntry key="performance" value="/projet-2019/src/main/atl/performance.asm"/>
</mapAttribute>
<mapAttribute key="Model Handler">
<mapEntry key="java" value="EMF"/>
<mapEntry key="smm" value="EMF"/>
</mapAttribute>
<mapAttribute key="ModelType">
<mapEntry key="IN" value="MODELINPUT"/>
<mapEntry key="OUT" value="MODELOUTPUT"/>
<mapEntry key="java" value="METAMODELINPUT"/>
<mapEntry key="smm" value="METAMODELOUTPUT"/>
</mapAttribute>
<mapAttribute key="Options">
<mapEntry key="OPTION_CLEAR" value="true"/>
<mapEntry key="OPTION_CONTENT_TYPE" value="false"/>
<mapEntry key="OPTION_DERIVED" value="true"/>
<mapEntry key="allowInterModelReferences" value="false"/>
<mapEntry key="printExecutionTime" value="true"/>
<mapEntry key="step" value="false"/>
<mapEntry key="supportUML2Stereotypes" value="false"/>
</mapAttribute>
<listAttribute key="OrderedInput">
<listEntry value="IN"/>
</listAttribute>
<listAttribute key="OrderedOutput">
<listEntry value="OUT"/>
</listAttribute>
<mapAttribute key="Output">
<mapEntry key="OUT" value="smm"/>
</mapAttribute>
<mapAttribute key="Path">
<mapEntry key="IN" value="/projet-2019/input/example.xmi"/>
<mapEntry key="OUT" value="/projet-2019/output/metrics.xmi"/>
<mapEntry key="java" value="uri:http://www.eclipse.org/MoDisco/Java/0.2.incubation/java"/>
<mapEntry key="smm" value="uri:http://www.eclipse.org/MoDisco/SMM/1.0.Beta2/smm"/>
</mapAttribute>
<listAttribute key="Superimpose"/>
<stringAttribute key="bad_container_name" value="/projet-2019/analysis.launch"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
</launchConfiguration>
......@@ -2,24 +2,51 @@
# Pre-requisites : A correct analysis.launch file to serve as base
# This scripts generates for each input xmi, a corresponding ATL launch file
# Check parameter for current IN model name in analysis.launch
currentinput=""
base_file="build-tools/analysis.launch"
if [ -z "$1" ]
then
if [ ! -e $base_file ]
then
echo "Enter the name of current IN model in file analysis.launch (for e.g : ./gen-launch-config.sh comment-required)"
echo -e "No base file found. You can enter the name of a base file in parameter. For e.g.:\n./gen-launch-config.sh analysis.launch"
exit
fi
else
currentinput=$1
echo "Current input : $currentinput"
base_file=$1
fi
echo "Base file used: $base_file"
target_directory="launch_configurations" #Directory of all the launch configurations generated.
launch_group="atl_launch_group.launch" #Name of the Launch Group Configuration file.
delay=0 #Delay between each execution of the launch group, in seconds (must be an integer).
i=0 #Value used to distinguish the different configurations for the launch group
mkdir -p $target_directory
# These xml lines generates a Launch Group Configuration for Eclipse.
echo '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.debug.core.groups.GroupLaunchConfigurationType">' > $launch_group
# For each input file, generate the corresponding .launch file with this file's name as IN model
for file in input/*.xmi; do
filename=$(basename -- "$file") # get basename
filename="${filename%.*}" # remove extension
echo "$filename"
cp analysis.launch analysis-$filename.launch
sed -i "s/$currentinput/$filename/g" analysis-$filename.launch
echo "Replaced : $currentinput by $filename in file analysis-$filename.launch"
done
\ No newline at end of file
cp $base_file $target_directory/analysis-$filename.launch
echo "Created: analysis-$filename.launch"
sed -i "s/\/projet-2019\/input\/.*.xmi/\/projet-2019\/input\/$filename.xmi/g" $target_directory/analysis-$filename.launch # Replace the input in the .launch file.
echo '
<stringAttribute key="org.eclipse.debug.core.launchGroup.'"$i"'.action" value="DELAY"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.'"$i"'.actionParam" value="'"$delay"'"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.'"$i"'.adoptIfRunning" value="false"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.'"$i"'.enabled" value="true"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.'"$i"'.mode" value="run"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.'"$i"'.name" value="'"analysis-$filename"'"/>' >> $launch_group
((i++))
done
echo '
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
</launchConfiguration>' >> $launch_group
\ No newline at end of file
<?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="EmptyFinalizer">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="EmptyFinalizerMtd">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="finalize">
<modifier visibility="protected"/>
<body originalCompilationUnit="//@compilationUnits.0"/>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</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"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="EmptyFinalizerMtd.java" originalFilePath="C:\Users\HP\eclipse-workspace-modeling-two\EmptyFinalizer\src\EmptyFinalizerMtd.java" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
<?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="EmptyFinally">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="EmptyfinallyBlock">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="bar">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:TryStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:VariableDeclarationStatement" originalCompilationUnit="//@compilationUnits.0">
<type type="//@orphanTypes.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="x">
<initializer xsi:type="java:NumberLiteral" originalCompilationUnit="//@compilationUnits.0" tokenValue="2"/>
</fragments>
<modifier/>
</statements>
</body>
<finally originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// empty!" enclosedByParent="true"/>
</finally>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<orphanTypes xsi:type="java:PrimitiveTypeInt" name="int" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@body/@statements.0/@type"/>
<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"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="EmptyfinallyBlock.java" originalFilePath="C:\Users\HP\eclipse-workspace-modeling-two\EmptyFinally\src\EmptyfinallyBlock.java" commentList="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@finally/@comments.0" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
<?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="SwitchStatementEmpty">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="SwitchEmpty">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="bar">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:VariableDeclarationStatement" originalCompilationUnit="//@compilationUnits.0">
<type type="//@orphanTypes.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="x" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@expression">
<initializer xsi:type="java:NumberLiteral" originalCompilationUnit="//@compilationUnits.0" tokenValue="2"/>
</fragments>
<modifier/>
</statements>
<statements xsi:type="java:SwitchStatement" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// once there was code here" enclosedByParent="true"/>
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// but it's been commented out or something" enclosedByParent="true"/>
<expression xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@fragments.0"/>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<orphanTypes xsi:type="java:PrimitiveTypeInt" name="int" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@type"/>
<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"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="SwitchEmpty.java" originalFilePath="C:\Users\HP\eclipse-workspace-modeling-two\SwitchStatementEmpty\src\SwitchEmpty.java" commentList="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@comments.1" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
<?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="EmptySyncBlock">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="SyncBlock">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="bar">
<modifier visibility="public"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:SynchronizedStatement" originalCompilationUnit="//@compilationUnits.0">
<body originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// empty!" enclosedByParent="true"/>
</body>
<expression xsi:type="java:ThisExpression" originalCompilationUnit="//@compilationUnits.0"/>
</statements>
</body>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</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"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="SyncBlock.java" originalFilePath="C:\Users\HP\eclipse-workspace-modeling-two\EmptySyncBlock\src\SyncBlock.java" commentList="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@body/@comments.0" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
This diff is collapsed.
......@@ -47,6 +47,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
thisModule.tooManyStaticImports(),
thisModule.avoidDollarSigns(),
thisModule.shortClassName(),
thisModule.shortVariableName(),
thisModule.extendsObject(),
thisModule.unnecessaryReturn(),
thisModule.longVariable(),
......@@ -94,13 +95,22 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
thisModule.emptyTryBlock(),
thisModule.emptyWhileStmt(),
thisModule.dontImportSun(),
thisModule.emptySwitchStatement(),
thisModule.emptySynchronizedBlock(),
thisModule.emptyFinallyBlock(),
thisModule.emptyfinalizeMethod(),
--thisModule.doNotThrowExceptionInFinally(),
--thisModule.finalizeShouldBeProtected(),
-- Best practices rules
thisModule.avoidThrowingNewInstanceOfSameException(),
thisModule.useAssertTrueInsteadOfAssertEquals(),
thisModule.useAssertSameInsteadOfAssertTrue(),
thisModule.switchDensity()
--thisModule.replaceVectorToList()
--thisModule.unusedPrivateMethod ()
--thisModule.avoidStringBufferField()
};
......@@ -187,6 +197,26 @@ rule MesureShortClassName(class : java!ClassDeclaration) {
}
}
-- A Measure instance if the variable violates the rule 'ShortVariableName'.
rule MesureShortVariableName(variable : java!VariableDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ShortVariableName',
shortDescription <- 'Short Variable names with fewer than e.g. three characters are not recommended.'
),
measurement: smm!DirectMeasurement (
error <- 'The Variable ' + variable.name + ' is too short.'
)
do {
noc;
}
}
-- creates a new Measure when Thread.run() is used instead of Thread.start()
rule MeasureDontCallThreadRun(method : java!MethodInvocation) {
......@@ -1097,26 +1127,85 @@ rule MesureFinalizeShouldBeProtected(m : java!MethodDeclaration) {
noc;
}
}
-----------------------EmptySwitchStatement---------------------------------------------
-- -----A Measure instance if the class use a Vector instead of ArrayList
rule RuleUseArrayListInsteadOfVector(tab :java!Package) {
-- A Measure instance if the class violates the rule 'EmptySwitchStatement'
rule MeasureEmptySwitchStatement(switchStatement: java!SwitchStatement) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Use ArrayList Instead Of Vector',
shortDescription <- 'ArrayList is a much better Collection implementation than Vector'
noc: smm!DimensionalMeasure (
name <- 'Empty Switch Statement ',
shortDescription <- 'Empty Switch statements serve no purpose and should be removed.'
),
measurement: smm!DirectMeasurement (
error<- 'The Array Type Vector violates the rule Use ArrayList instead of Vector.'
error <- 'EmptyswitchStatement is detected in ' + switchStatement.originalCompilationUnit.name
)
do {
noc;
}
}
--------------------------------EmptySynchronizedBlock---------------------------------------------
-- A Measure instance if the class violates the rule 'EmptySynchronizedBlock'
rule MeasureEmptySynchronizedBlock(synchronizedBlock: java!SynchronizedStatement) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'Empty Synchronized Block ',
shortDescription <- 'Empty Synchronized Block serve no purpose and should be removed.'
),
measurement: smm!DirectMeasurement (
error <- 'EmptySynchronizedBlock is detected in ' + synchronizedBlock.originalCompilationUnit.name
)
do {
noc;
}
}
--------------------- EmptyFinallyBlock----------------------------------
--A measure instance if the class violates the rule EmptyFinallyBlock.
rule MeasureEmptyFinallyBlock(finallyBlock : java!TryStatement) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'EmptyFinallyBlock',
shortDescription <- ': Avoid empty Finally blocks - what s the point?'
),
measurement: smm!DirectMeasurement (
error <- 'EmptyFinallyBlock is detected in ' + finallyBlock.originalCompilationUnit.name
)
do {
noc;
}
}
--------------------- EmptyFinalizer----------------------------------
--A measure instance if the class violates the rule EmptyFinalizer.
rule MeasureEmptyFinalizer(finalizeMethod : java!MethodDeclaration) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'EmptyFinalizer',
shortDescription <- ': Avoid empty Finalizer - what s the point?'
),
measurement: smm!DirectMeasurement (
error <- 'EmptyFinalizer is detected in ' + finalizeMethod.originalCompilationUnit.name
)
do {
noc;
}
}
-------------------------------------------UseAssertSameInsteadOfAssertTrue----------------------------------------------
-- A Measure instance if the class violate the rule AssertSameInsteadOfAssertTrue
rule MesureUseAssertSameInsteadOfAssertTrue(tab :java!Package) {
......
......@@ -5,23 +5,10 @@ library bestPractices;
--Goes through all the methods to check if the following rule is followed:
--Avoid printStackTrace()
helper def: avoidPrintStackTrace() : Set(smm!Measure) =
java!MethodInvocation.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{} |
-- Add a new measurement if the argument of String.indexOf() is not of type char when checking for the index of a single character
if thisModule.isAvoidPrintStackTrace(i) then
res->union(Set{thisModule.MeasureAvoidPrintStackTrace(i)})
else
res
endif
);
--Detect a wrong usage of the method printStackTrace()
--return true if the method is called printStackTrace
helper def:isAvoidPrintStackTrace(s:java!MethodInvocation): Boolean =
if s.method.name = 'printStackTrace' then
true
else
false
endif;
java!MethodInvocation.allInstances()
-> select (m | m.method.name = 'printStackTrace')
-> collect (m | thisModule.MeasureAvoidPrintStackTrace(m))
;
--------------------------------------------- AvoidFieldNameMatchingMethodName ---------------------------------------------
......@@ -108,4 +95,4 @@ helper def: useAssertSameInsteadOfAssertTrue() : Set(smm!Measure) =
helper def: isWrongUseAssertSameInsteadOfAssertTrue(m:java!MethodInvocation) : Boolean =
--Browse through all arguments of the method assertTrue and see if == is used
(m.arguments->select(t|t.oclIsTypeOf(java!InfixExpression))->select(t|t.operator.toString() = '==')->collect(t|t).notEmpty());
\ No newline at end of file
......@@ -59,3 +59,16 @@ helper def: longVariable() : Set(smm!Measure) =
-> select( variable | variable.name.size() > 17)
-> collect (variable | thisModule.MeasureLongVariable(variable));
--------------------------------------------- ShortVariableName ---------------------------------------------
-- Rule for metrics shortVariableName : return the set of variables measures that violates the rule.
helper def: shortVariableName() : Set(smm!Measure) =
java!SingleVariableDeclaration.allInstances()
-> reject(each | each.isProxy() or not each.catchClause->oclIsUndefined() or not each.enhancedForStatement->oclIsUndefined())
-> select( i | i.name.size() < 3)
-> union( java!VariableDeclarationFragment.allInstances()
-> reject(each | each.isProxy() or each.variablesContainer.oclIsTypeOf(java!VariableDeclarationExpression))
-> select( i | i.name.size() < 3)
)
-> collect (i | thisModule.MesureShortVariableName(i));
......@@ -180,3 +180,47 @@ helper def: finalizeShouldBeProtected() : Set(smm!Measure) =
->select(m | m.name = 'finalize' and m.modifier.visibility.toString() <> 'protected')
->collect(m | thisModule.MesureFinalizeShouldBeProtected(m));
--------------------------------------------- EmptySwitchStatement ---------------------------------------------
--Detects the use of empty switch statements. These blocks serve no purpose and should be removed
helper def: emptySwitchStatement() : Set(smm!Measure) =
java!SwitchStatement.allInstances()
->select(switchStatement | switchStatement.statements.isEmpty())
->collect(switchStatement | thisModule.MeasureEmptySwitchStatement(switchStatement));
------------------------------------------ EmptySynchronizedBlock ---------------------------------------------
--Detects the use of empty synchronized block. These blocks serve no purpose and should be removed
helper def: emptySynchronizedBlock() : Set(smm!Measure) =
java!SynchronizedStatement.allInstances()
->select(synchronizedBlock | synchronizedBlock.body.statements.isEmpty() )
->collect(synchronizedBlock | thisModule.MeasureEmptySynchronizedBlock(synchronizedBlock));
---------------------------------------- EmptyFinallyBlock----------------------------------------------
-- Rule for metrics EmptyFinallyBlock
helper def: emptyFinallyBlock() : Set(smm!Measure) =
java!TryStatement.allInstances()
->select( finallyBlock | finallyBlock.finally.statements.isEmpty())
->collect(finallyBlock| thisModule.MeasureEmptyFinallyBlock(finallyBlock));
----------------------------------------- EmptyFinalizer----------------------------------------------
-- Rule for metrics EmptyFinalizer
helper def: emptyfinalizeMethod() : Set(smm!Measure) =
java!MethodDeclaration.allInstances()
->select( finalizeMethod | finalizeMethod.name = 'finalize' and finalizeMethod.body.statements.isEmpty())
->collect(finalizeMethod| thisModule. MeasureEmptyFinalizer(finalizeMethod));
......@@ -5,47 +5,37 @@ library multithreading;
--Goes through all the methods to check if the following rule is followed:
--Don't call Thread.run()
helper def: dontCallThreadRun() : Set(smm!Measure) =
java!MethodInvocation.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{} |
if (thisModule.isDontCallThreadRun(i))
then res->union(Set{thisModule.MeasureDontCallThreadRun(i)})
else res
endif
);
java!MethodInvocation.allInstances()
-> select (m | m.method.name='run' )
-> select (m | m.expression.isDontCallThreadRun() )
-> collect (m | thisModule.MeasureDontCallThreadRun(m));
--Detect a wrong usage of the method Thread.run()
--return true if run() is called on a Thread variable
helper context java!SingleVariableAccess def : isDontCallThreadRun(): Boolean =
--check if the method is called like this:
--t.run() where t is of type Thread
self.variable.variablesContainer.type.type.name.toString() = 'Thread';
--Detect a wrong usage of the method Thread.run()
--return true if run() is called on a Thread variable or on a Thread instance creation
helper def:isDontCallThreadRun(s:java!MethodInvocation): Boolean =
if s.method.name = 'run' then
--check if the method is called like this:
--t.run() where t is of type Thread
if s.expression.oclType().toString() = 'java!SingleVariableAccess' then
if s.expression.variable.variablesContainer.type.type.name.toString() = 'Thread' then
true
else false
endif
--check if the method run is called like this:
--new Thread().run();
else
if s.expression.oclType().toString() = 'java!ClassInstanceCreation' then
if s.expression.method.name.toString() = 'Thread' then
true
else false
endif
else false
endif
endif
else false
endif;
--return true if run() is called on a Thread instance creation
helper context java!ClassInstanceCreation def : isDontCallThreadRun(): Boolean =
--check if the method run is called like this:
--new Thread().run();
self.method.name.toString() = 'Thread';
--------------------------------------------- AvoidThreadGroup ---------------------------------------------
--Goes through all the variables to check if the following rule is followed:
--Avoid using java.lang.ThreadGroup;
helper def: avoidThreadGroup() : Set(smm!Measure) =
java!VariableDeclarationFragment.allInstances() ->
select(i | i.variablesContainer.type.toString() <> 'OclUndefined')->
select(s|s.variablesContainer.type.type.name.toString() = 'ThreadGroup')->collect(i | thisModule.measureAvoidThreadGroup(i) );
java!VariableDeclarationFragment.allInstances()
-> select(i | i.variablesContainer.type.toString() <> 'OclUndefined')
-> select(s|s.variablesContainer.type.type.name.toString() = 'ThreadGroup')
-> collect(i | thisModule.measureAvoidThreadGroup(i) );
--------------------------------------------- UseNotifyAllInsteadOfNotify ---------------------------------------------
......
......@@ -5,28 +5,10 @@ library performance;
--Goes through all the methods to check if the following rule is followed:
--No need to call String.valueOf to append to a string; just use the valueOf() argument directly.
helper def: uselessStringValueOf() : Set(smm!Measure) =
java!MethodInvocation.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{} |
-- Add a new measurement if the argument of String.indexOf() is not of type char when checking for the index of a single character
if thisModule.isUselessStringValueOf(i) then
res->union(Set{thisModule.MeasureUselessStringValueOf(i)})
else
res
endif
);
--Detect a wrong usage of the method String.valueOf()
--return true if String.valueOf is used to append an argument to a String
helper def:isUselessStringValueOf(s:java!MethodInvocation): Boolean =
if s.method.name='valueOf' then
if s.refImmediateComposite().oclType().toString() = 'java!InfixExpression' then
true
else
false
endif
else
false
endif
;
java!MethodInvocation.allInstances()
-> select (m | m.method.name='valueOf' )
-> select (m | m.refImmediateComposite().oclIsTypeOf(java!InfixExpression))
-> collect (m | thisModule.MeasureUselessStringValueOf(m));
------------------------------------ TooFewBranchesForASwitchStatement--------------------------------------
......@@ -41,30 +23,15 @@ helper def: tooFewBranchesForASwitchStatement(): Set(smm!Measure) =