From 7f7099f93e6bc4b785033b2ecdc1d38678335428 Mon Sep 17 00:00:00 2001 From: Raphael Date: Fri, 13 Dec 2019 16:33:28 +0100 Subject: [PATCH 1/4] REMOVED ALL IF THEN ELSE --- src/main/atl/bestPractices.atl | 21 +++---------- src/main/atl/multithreading.atl | 56 ++++++++++++++------------------- src/main/atl/performance.atl | 55 +++++++------------------------- 3 files changed, 38 insertions(+), 94 deletions(-) diff --git a/src/main/atl/bestPractices.atl b/src/main/atl/bestPractices.atl index 42956c3..5e34589 100644 --- a/src/main/atl/bestPractices.atl +++ b/src/main/atl/bestPractices.atl @@ -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 --------------------------------------------- diff --git a/src/main/atl/multithreading.atl b/src/main/atl/multithreading.atl index efbb43a..081edc9 100644 --- a/src/main/atl/multithreading.atl +++ b/src/main/atl/multithreading.atl @@ -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 --------------------------------------------- diff --git a/src/main/atl/performance.atl b/src/main/atl/performance.atl index d6faad3..fc22f54 100644 --- a/src/main/atl/performance.atl +++ b/src/main/atl/performance.atl @@ -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) = --------------------------------------------- UseIndexOfChar--------------------------------------------- ---Goes through all the methods to check if the following rule is followed: +--Goes through all the MethodInvocation to check if the following rule is followed: --Use String.indexOf(char) when checking for the index of a single character; it executes faster. helper def: useIndexOfChar() : 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.isWrongUsageIndexOfChar(i) then - res->union(Set{thisModule.MeasureUseIndexOfChar(i)}) - else - res - endif - ); - ---Detect a wrong usage of the method String.indexOf(char) ---return true if the argument of String.indexOf(char) is not of type char when checking for the index of a single character -helper def:isWrongUsageIndexOfChar(s:java!MethodInvocation): Boolean = - if s.method.name = 'indexOf' then - if s.arguments.size() = 1 and s.arguments.first().oclType().toString() <> 'java!CharacterLiteral' then - true - else - false - endif - else - false - endif; + java!MethodInvocation.allInstances() + -> select (m | m.method.name='indexOf') + -> select (m | m.arguments.size() = 1) + -> select (m | not m.arguments.first().oclIsTypeOf(java!CharacterLiteral)) + -> collect (m | thisModule.MeasureUseIndexOfChar(m)) +; --------------------------------------------- avoidThrowingNewInstanceOfSameException --------------------------------------------- -- Returns a set of Measures for each catch block throws a new instance of the caught exception -- GitLab From c4fbb257f9471eb152fab61ae3464463b03b1342 Mon Sep 17 00:00:00 2001 From: Raphael Date: Fri, 13 Dec 2019 16:34:11 +0100 Subject: [PATCH 2/4] Revert "REMOVED ALL IF THEN ELSE" This reverts commit 7f7099f93e6bc4b785033b2ecdc1d38678335428. --- src/main/atl/bestPractices.atl | 21 ++++++++++--- src/main/atl/multithreading.atl | 56 +++++++++++++++++++-------------- src/main/atl/performance.atl | 55 +++++++++++++++++++++++++------- 3 files changed, 94 insertions(+), 38 deletions(-) diff --git a/src/main/atl/bestPractices.atl b/src/main/atl/bestPractices.atl index 5e34589..42956c3 100644 --- a/src/main/atl/bestPractices.atl +++ b/src/main/atl/bestPractices.atl @@ -5,10 +5,23 @@ 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() - -> select (m | m.method.name = 'printStackTrace') - -> collect (m | thisModule.MeasureAvoidPrintStackTrace(m)) -; + 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; --------------------------------------------- AvoidFieldNameMatchingMethodName --------------------------------------------- diff --git a/src/main/atl/multithreading.atl b/src/main/atl/multithreading.atl index 081edc9..efbb43a 100644 --- a/src/main/atl/multithreading.atl +++ b/src/main/atl/multithreading.atl @@ -5,37 +5,47 @@ 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() - -> 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'; - + java!MethodInvocation.allInstances() -> iterate(i; res : Set(smm!Measure) = Set{} | + + if (thisModule.isDontCallThreadRun(i)) + then res->union(Set{thisModule.MeasureDontCallThreadRun(i)}) + else res + endif + ); --Detect a wrong usage of the method Thread.run() ---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'; - - +--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; --------------------------------------------- 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 --------------------------------------------- diff --git a/src/main/atl/performance.atl b/src/main/atl/performance.atl index fc22f54..d6faad3 100644 --- a/src/main/atl/performance.atl +++ b/src/main/atl/performance.atl @@ -5,10 +5,28 @@ 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() - -> select (m | m.method.name='valueOf' ) - -> select (m | m.refImmediateComposite().oclIsTypeOf(java!InfixExpression)) - -> collect (m | thisModule.MeasureUselessStringValueOf(m)); + 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 + ; ------------------------------------ TooFewBranchesForASwitchStatement-------------------------------------- @@ -23,15 +41,30 @@ helper def: tooFewBranchesForASwitchStatement(): Set(smm!Measure) = --------------------------------------------- UseIndexOfChar--------------------------------------------- ---Goes through all the MethodInvocation to check if the following rule is followed: +--Goes through all the methods to check if the following rule is followed: --Use String.indexOf(char) when checking for the index of a single character; it executes faster. helper def: useIndexOfChar() : Set(smm!Measure) = - java!MethodInvocation.allInstances() - -> select (m | m.method.name='indexOf') - -> select (m | m.arguments.size() = 1) - -> select (m | not m.arguments.first().oclIsTypeOf(java!CharacterLiteral)) - -> collect (m | thisModule.MeasureUseIndexOfChar(m)) -; + 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.isWrongUsageIndexOfChar(i) then + res->union(Set{thisModule.MeasureUseIndexOfChar(i)}) + else + res + endif + ); + +--Detect a wrong usage of the method String.indexOf(char) +--return true if the argument of String.indexOf(char) is not of type char when checking for the index of a single character +helper def:isWrongUsageIndexOfChar(s:java!MethodInvocation): Boolean = + if s.method.name = 'indexOf' then + if s.arguments.size() = 1 and s.arguments.first().oclType().toString() <> 'java!CharacterLiteral' then + true + else + false + endif + else + false + endif; --------------------------------------------- avoidThrowingNewInstanceOfSameException --------------------------------------------- -- Returns a set of Measures for each catch block throws a new instance of the caught exception -- GitLab From 58a3a0e8c33ffb1c4da2efd7c7804479557c4ab1 Mon Sep 17 00:00:00 2001 From: Raphael Date: Fri, 13 Dec 2019 16:34:47 +0100 Subject: [PATCH 3/4] Revert "Revert "REMOVED ALL IF THEN ELSE"" This reverts commit c4fbb257f9471eb152fab61ae3464463b03b1342. --- src/main/atl/bestPractices.atl | 21 +++---------- src/main/atl/multithreading.atl | 56 ++++++++++++++------------------- src/main/atl/performance.atl | 55 +++++++------------------------- 3 files changed, 38 insertions(+), 94 deletions(-) diff --git a/src/main/atl/bestPractices.atl b/src/main/atl/bestPractices.atl index 42956c3..5e34589 100644 --- a/src/main/atl/bestPractices.atl +++ b/src/main/atl/bestPractices.atl @@ -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 --------------------------------------------- diff --git a/src/main/atl/multithreading.atl b/src/main/atl/multithreading.atl index efbb43a..081edc9 100644 --- a/src/main/atl/multithreading.atl +++ b/src/main/atl/multithreading.atl @@ -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 --------------------------------------------- diff --git a/src/main/atl/performance.atl b/src/main/atl/performance.atl index d6faad3..fc22f54 100644 --- a/src/main/atl/performance.atl +++ b/src/main/atl/performance.atl @@ -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) = --------------------------------------------- UseIndexOfChar--------------------------------------------- ---Goes through all the methods to check if the following rule is followed: +--Goes through all the MethodInvocation to check if the following rule is followed: --Use String.indexOf(char) when checking for the index of a single character; it executes faster. helper def: useIndexOfChar() : 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.isWrongUsageIndexOfChar(i) then - res->union(Set{thisModule.MeasureUseIndexOfChar(i)}) - else - res - endif - ); - ---Detect a wrong usage of the method String.indexOf(char) ---return true if the argument of String.indexOf(char) is not of type char when checking for the index of a single character -helper def:isWrongUsageIndexOfChar(s:java!MethodInvocation): Boolean = - if s.method.name = 'indexOf' then - if s.arguments.size() = 1 and s.arguments.first().oclType().toString() <> 'java!CharacterLiteral' then - true - else - false - endif - else - false - endif; + java!MethodInvocation.allInstances() + -> select (m | m.method.name='indexOf') + -> select (m | m.arguments.size() = 1) + -> select (m | not m.arguments.first().oclIsTypeOf(java!CharacterLiteral)) + -> collect (m | thisModule.MeasureUseIndexOfChar(m)) +; --------------------------------------------- avoidThrowingNewInstanceOfSameException --------------------------------------------- -- Returns a set of Measures for each catch block throws a new instance of the caught exception -- GitLab From 9d21a9a10cb9c1f413b57795d3b516e4c70bd87d Mon Sep 17 00:00:00 2001 From: Raphael Date: Fri, 20 Dec 2019 01:31:27 +0100 Subject: [PATCH 4/4] Fix #876, Fix #616, Fix #873, Fix #910 Simplified dontCallThreadRun and avoidThreadGroup. Those two rules were throwing an error when a bigger model was used as input. --- src/main/atl/analysis.atl | 6 +++--- src/main/atl/multithreading.atl | 26 ++++---------------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/main/atl/analysis.atl b/src/main/atl/analysis.atl index ed1e0c2..68cacf6 100644 --- a/src/main/atl/analysis.atl +++ b/src/main/atl/analysis.atl @@ -38,6 +38,8 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = -- Multithreading rules -- thisModule.useNotifyAllInsteadOfNotify(), + thisModule.avoidThreadGroup(), + thisModule.dontCallThreadRun(), -- Code Style rules -- @@ -72,7 +74,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = thisModule.emptyStatementBlock(), thisModule.avoidRethrowingException(), thisModule.integerInstantiation(), - thisModule.stringToString(), + -- thisModule.stringToString(), -- Documentation rules -- @@ -115,8 +117,6 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) = -- thisModule.doNotThrowExceptionInFinally(), -- thisModule.finalizeShouldBeProtected(), -- thisModule.avoidDollarSigns(), - -- thisModule.avoidThreadGroup(), - -- thisModule.dontCallThreadRun(), -- thisModule.returnEmptyArrayRatherThanNull(), -- thisModule.replaceVectorToList() -- thisModule.unusedPrivateMethod () diff --git a/src/main/atl/multithreading.atl b/src/main/atl/multithreading.atl index 081edc9..e7d8ebd 100644 --- a/src/main/atl/multithreading.atl +++ b/src/main/atl/multithreading.atl @@ -7,35 +7,17 @@ library multithreading; helper def: dontCallThreadRun() : Set(smm!Measure) = java!MethodInvocation.allInstances() -> select (m | m.method.name='run' ) - -> select (m | m.expression.isDontCallThreadRun() ) + -> select (m | m.method.abstractTypeDeclaration.name = 'Thread' ) -> 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 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!VariableDeclarationStatement.allInstances() + -> select(variable | variable.type.type.name = 'ThreadGroup') + -> collect(variable | thisModule.measureAvoidThreadGroup(variable) ); --------------------------------------------- UseNotifyAllInsteadOfNotify --------------------------------------------- -- GitLab