Commit d01450b6 authored by E19C506H's avatar E19C506H
Browse files

Fix Issues #699, #738, #780, #784, #799, #819, #862, #871

parent 623a7089
<?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">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="Foo" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer/@expression/@type">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.0">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="cl">
<initializer xsi:type="java:MethodInvocation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.1/@bodyDeclarations.0">
<expression xsi:type="java:TypeLiteral" originalCompilationUnit="//@compilationUnits.0">
<type type="//@ownedElements.0/@ownedElements.0"/>
</expression>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="ClassLoader" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@type"/>
<ownedElements xsi:type="java:ClassDeclaration" name="Class" proxy="true">
<bodyDeclarations xsi:type="java:MethodDeclaration" name="getClassLoader" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedPackages.0/@ownedElements.0"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedPackages.0/@ownedElements.2"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedPackages.0/@ownedElements.1"/>
<typeParameters name="T" proxy="true"/>
</ownedElements>
<ownedPackages name="reflect" proxy="true">
<ownedElements xsi:type="java:InterfaceDeclaration" name="GenericDeclaration" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.1/@superInterfaces.1">
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedPackages.0/@ownedElements.1"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="AnnotatedElement" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedPackages.0/@ownedElements.0/@superInterfaces.0 //@ownedElements.1/@ownedPackages.0/@ownedElements.1/@superInterfaces.3"/>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Type" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.1/@superInterfaces.2"/>
</ownedPackages>
</ownedPackages>
<ownedPackages name="io" proxy="true">
<ownedElements xsi:type="java:InterfaceDeclaration" name="Serializable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.1/@superInterfaces.0"/>
</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"/>
<orphanTypes xsi:type="java:PrimitiveTypeChar" name="char"/>
<orphanTypes xsi:type="java:PrimitiveTypeShort" name="short"/>
<orphanTypes xsi:type="java:PrimitiveTypeByte" name="byte"/>
<compilationUnits name="Foo.java" originalFilePath="D:\workSpace\Test\src\Foo.java" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
......@@ -54,6 +54,7 @@ helper def: allMeasures(project: java!Model): Set(smm!Measure) =
thisModule.CloneMethodMustBePublic(),
thisModule.AvoidEnumAsIdentifier(),
thisModule.AvoidCatchingNPE(),
thisModule.UseProperClassLoader(),
-- Design rules
--
thisModule.tooManyFields(),
......@@ -1187,7 +1188,7 @@ rule MesureAvoidNoPackageDeclaration(class : java!CompilationUnit) {
shortDescription <- 'you need to declare some package.'
),
measurement: smm!DirectMeasurement (
error <- 'In the ' + class.name + ' class have no package declaration'
error <- class.name + ' class have no package declaration'
)
do {
......@@ -1204,8 +1205,7 @@ rule MeasureUnconditionalIfStatement(w: java!IfStatement) {
),
noc: smm!DimensionalMeasure (
name <- 'UnconditionalIfStatement',
shortDescription <- ': UnconditionalIfStatement finds all instances where a'
+ ' UnconditionalIfStatement statement does nothing.'
shortDescription <- ': UnconditionalIfStatement'
),
measurement: smm!DirectMeasurement (
error <- 'UnconditionalIfStatement is detected in ' + w.originalCompilationUnit.name
......@@ -1224,10 +1224,10 @@ rule MeasureEmptyInitializer(w: java!Initializer) {
),
noc: smm!DimensionalMeasure (
name <- 'EmptyInitializer',
shortDescription <- ': EmptyInitializer finds '
shortDescription <- ': EmptyInitializer'
),
measurement: smm!DirectMeasurement (
error <- 'do not declare an EmptyInitializer, EmptyInitializer is detected in ' + w.originalCompilationUnit.name + ' this block need to be deleted'
error <- ' class '+w.originalCompilationUnit.name +' hase an empty Initializer! do not declare an EmptyInitializer, EmptyInitializer! this block need to be deleted'
)
do {
noc;
......@@ -1246,7 +1246,7 @@ rule MeasureExcessiveClassLength(w: java!MethodDeclaration) {
shortDescription <- ': class file lengths are usually indications that the class may be burdened with excessive responsibilities that could be provided by external classes or functions'
),
measurement: smm!DirectMeasurement (
error <- w.originalCompilationUnit.name+ 'has a block with more than 1000 line of code per a method it may need a separation in the code'
error <- ' class '+w.originalCompilationUnit.name+ ' has a block with more than 1000 line of code per a method it may need a separation in the code'
)
do {
noc;
......@@ -1262,10 +1262,10 @@ rule MeasureCloneMethodMustBePublic(w: java!MethodDeclaration) {
),
noc: smm!DimensionalMeasure (
name <- 'CloneMethodMustBePublic',
shortDescription <- 'CloneMethodMustBePublic'
shortDescription <- ': Clone Method Must Be Public'
),
measurement: smm!DirectMeasurement (
error <- w.originalCompilationUnit.name+ 'the clone methode in here need to be public '
error <- ' class '+w.originalCompilationUnit.name+ ' has a clone methode witch need to be public '
)
do {
noc;
......@@ -1281,10 +1281,10 @@ rule MeasureAvoidEnumAsIdentifier(w: java!VariableDeclaration) {
),
noc: smm!DimensionalMeasure (
name <- 'AvoidEnumAsIdentifier',
shortDescription <- 'AvoidEnumAsIdentifier'
shortDescription <- ': Avoid Enum As Identifier'
),
measurement: smm!DirectMeasurement (
error <- w.originalCompilationUnit.name+ 'has a variable named to enum witch is a reserved name'
error <- ' class '+w.originalCompilationUnit.name+ ' has a variable named to enum witch is a reserved name'
)
do {
noc;
......@@ -1300,14 +1300,34 @@ rule MeasureAvoidCatchingNPE(w: java!CatchClause) {
),
noc: smm!DimensionalMeasure (
name <- 'AvoidCatchingNPE',
shortDescription <- 'AvoidCatchingNPE'
shortDescription <- ': Avoid Catching NullPointerExceptions'
),
measurement: smm!DirectMeasurement (
error <- w.originalCompilationUnit.name+ ' in this class there is a Code that Code should never
error <- ' class '+w.originalCompilationUnit.name+ ' has a Code that should never
throw NullPointerExceptions under normal circumstances. A catch block may hide the
original error, causing other, more subtle problems later on.'
)
do {
noc;
}
}
-- A Measure instance if the class violates the rule UseProperClassLoader.
rule MeasureUseProperClassLoader(w: java!MethodInvocation) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'UseProperClassLoader',
shortDescription <- ': Use ProperClassLoader'
),
measurement: smm!DirectMeasurement (
error <- ' class'+ w.originalCompilationUnit.name+ ' Use a statement with getClassLoader(),
use Thread.currentThread().getContextClassLoader() instead '
)
do {
noc;
}
}
\ No newline at end of file
......@@ -69,28 +69,56 @@ helper def: longVariable() : Set(smm!Measure) =
---- heloer for issus #699, #738, #780, #784, #799, #819, #862
-- Rule for metrics noPackageDeclaration : return the set of class Measures that violates the rule.
----- Fix Issues #699, #738, #780, #784, #799, #819, #862, #871
--- helper noPackageDeclaration
--- get all the compilation units
--- check if this units contains a defined package or not
--- if there is make a call for MesureAvoidNoPackageDeclaration rule
--- with the detected units
helper def: noPackageDeclaration() : Set(smm!Measure) =
java!CompilationUnit.allInstances()
->select(compUnit | compUnit.package.oclIsUndefined())
->collect(err | thisModule.MesureAvoidNoPackageDeclaration(err));
-- Rule for metrics UnconditionalIfStatement : return the set of class Measures that violates the rule.
--- helper UnconditionalIfStatement
--- get all the the used ifstatements and make a selection on all those that contains
--- an only expression in which its type is BooleanLiteral type like (true) or (false)
--- if there is collect them and make a call for MeasureUnconditionalIfStatement rule
--- with the detected ifstatments
helper def: UnconditionalIfStatement() : Set(smm!Measure) =
java!IfStatement.allInstances()
->select( w | w.expression.oclIsTypeOf(java!BooleanLiteral))
->collect(w | thisModule.MeasureUnconditionalIfStatement(w));
-- Rule for metrics EmptyInitializer : return the set of class Measures that violates the rule.
--- helper EmptyInitializer
--- get all the the used Initializer make a selection on all those that
--- has nothing inside theire body (empty initialize),
--- check if the contained statments size equals to 0
--- if there is collect them and make a call for MeasureEmptyInitializer rule
--- with the detected Initializer
helper def: EmptyInitializer() : Set(smm!Measure) =
java!Initializer.allInstances()
->select( w | w.body.statements.size() = 0)
->collect(w | thisModule.MeasureEmptyInitializer(w));
-- Rule for metrics ExcessiveClassLength : return the set of class Measures that violates the rule.
--- helper ExcessiveClassLength
--- get all the declaredMethods inside the class
--- check if theire body is defined or not
--- if it is check if this body containes a declared statements or not
--- if it is check if the number of this statement is bigger than 1000
--- in this case make a collection and make call for MeasureExcessiveClassLength rule
--- with the detected MethodDeclaration
helper def: ExcessiveClassLength() : Set(smm!Measure) =
java!MethodDeclaration.allInstances()
->select (w | w.body <> OclUndefined )
......@@ -98,22 +126,44 @@ helper def: ExcessiveClassLength() : Set(smm!Measure) =
->select (w| w.body.statements.size() > 1000)
->collect(w | thisModule.MeasureExcessiveClassLength(w));
-- Rule for metrics ExcessiveClassLength : return the set of class Measures that violates the rule.
--- helper CloneMethodMustBePublic
--- get all the declaredMethods inside the class
--- check if is clone methode or not
--- check if its modifier is defined
--- check if its visibilty access is different from public
--- if it is the case make collection and make a call for MeasureExcessiveClassLength rule
--- with the detected MethodDeclaration
helper def: CloneMethodMustBePublic() : Set(smm!Measure) =
java!MethodDeclaration.allInstances()
->select (w | w.modifier <> OclUndefined )
->select (w | w.name = 'clone')
->select (w | w.modifier <> 'public')
->collect(w | thisModule.MeasureCloneMethodMustBePublic(w));
-- Rule for metrics AvoidEnumAsIdentifier : return the set of class Measures that violates the rule.
--- helper AvoidEnumAsIdentifier
-- modisco do not allow to convert a class with error
-- and a field with enum decleration is already detected by Java compiler
-- so we need at least to change the name of enum to Enum to work
--- get all the declared variable inside the class
--- check if their name are defined and
--- if it's different than reserved key word 'enum''
--- if it is not the case make collection and make a call for MeasureAvoidEnumAsIdentifier rule
--- with the detected VariableDeclaration
helper def: AvoidEnumAsIdentifier() : Set(smm!Measure) =
java!VariableDeclaration.allInstances()
->select (w | w.name <> OclUndefined )
->select (w | w.name = 'enum')
->collect(w | thisModule.MeasureCloneMethodMustBePublic(w));
->collect(w | thisModule.MeasureAvoidEnumAsIdentifier(w));
-- Rule for metrics AvoidCatchingNPE : return the set of class Measures that violates the rule.
--- helper AvoidCatchingNPE
--- get all the catchClause inside the class
--- check if the name of type for the typeAccess is equals to 'NullPointerException'
--- if it is the case make collection and make a call for MeasureAvoidCatchingNPE rule
--- with the detected VariableDeclaration
helper def: AvoidCatchingNPE() : Set(smm!Measure) =
java!CatchClause.allInstances()
->select (w | w.exception.type.type.name = 'NullPointerException')
......@@ -121,3 +171,15 @@ helper def: AvoidCatchingNPE() : Set(smm!Measure) =
--- helper UseProperClassLoader
--- get all the MethodInvocation inside the class
--- check if the invocked method name is equals to getClassLoader
--- if it is the case make collection and make a call for MeasureUseProperClassLoader rule
--- with the detected MethodInvocation
helper def: UseProperClassLoader() : Set(smm!Measure) =
java!MethodInvocation.allInstances()
->select (w | w.method.name='getClassLoader')
->collect(w | thisModule.MeasureUseProperClassLoader(w));
Markdown is supported
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