Commit a95198e3 authored by Alexis LORET's avatar Alexis LORET
Browse files

Merge branch 'master' into 'master'

# Conflicts:
#   src/main/atl/analysis.atl
parents 06416ee4 56a00f14
......@@ -6,4 +6,42 @@ Le nom du fichier `xmi` utilisé pour valider une règle doit avoir le même nom
que cette règle, dans le format _kebab case_.
Par exemple, si la règle s'appelle `UseArrayListInsteadOfVector`, le nom du
fichier xmi doit être `use-array-list-instead-of-vector.xmi`.
\ No newline at end of file
fichier xmi doit être `use-array-list-instead-of-vector.xmi`.
== Commentaires
Distinguez les commentaires internes et externes des règles.
Les commentaires externes s'adressent aux utilisateurs des règles.
Ils expliquent ce que fait la règle.
Ils sont précédés d'un triple tiret: "---".
Les commentaires internes s'adressent aux autres développeurs.
Ils expliquent _comment_ la règle fonctionne.
Ils peuvent aussi expliquer certains choix pas évidents en première lecture.
Par exemple:
[source]
----
--- Returns the number of empty switch cases of a switch statement
helper def: nbEmptySwitchCasesOfASwitchStatement(ss:java!SwitchStatement) : Integer =
-- Gets the number of SwitchCases whoses next sibling is also a SwitchCase
-- and adds the last one if it's a switch case
ss.statements
->excluding(ss.statements.last())
->select(statement |
statement.oclIsTypeOf(java!SwitchCase) and
thisModule.nextSiblingIsSwitchCase(ss.statements.indexOf(statement), ss.statements)
).size() +
ss.statements->select(statement
| statement = ss.statements.last() and statement.oclIsTypeOf(java!SwitchCase)).size()
;
----
== Écriture des règles
Essayez de garder les règles simples.
Évitez d'utiliser les déclarations `iterate`, qui rendent les règles moins lisibles.
Les déclarations `if/then/else` sont strictement interdites.
\ 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="biginteger-instantiation">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="BigIntegerInstantiationNotPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.0">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="val">
<initializer xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0">
<arguments xsi:type="java:StringLiteral" originalCompilationUnit="//@compilationUnits.0" escapedValue="&quot;1&quot;"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.1" name="BigIntegerInstantiationPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.1">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.1" name="val">
<initializer xsi:type="java:MethodInvocation" originalCompilationUnit="//@compilationUnits.1" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1">
<arguments xsi:type="java:NumberLiteral" originalCompilationUnit="//@compilationUnits.1" tokenValue="1"/>
<expression xsi:type="java:TypeAccess" type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="math" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="BigInteger" proxy="true" usagesInImports="//@compilationUnits.0/@imports.0 //@compilationUnits.1/@imports.0" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer/@expression">
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="BigInteger" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@ownedElements.1/@ownedPackages.1/@ownedElements.2"/>
</parameters>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" name="valueOf" proxy="true" usages="//@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@orphanTypes.1"/>
</parameters>
</bodyDeclarations>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.1"/>
<superClass type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</ownedElements>
</ownedPackages>
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="Number" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superClass">
<superInterfaces type="//@ownedElements.1/@ownedPackages.2/@ownedElements.0"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Comparable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superInterfaces.0 //@ownedElements.1/@ownedPackages.1/@ownedElements.2/@superInterfaces.1">
<typeParameters name="T" proxy="true"/>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" name="String" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0/@type">
<superInterfaces type="//@ownedElements.1/@ownedPackages.2/@ownedElements.0"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.1"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.3"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="CharSequence" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.2/@superInterfaces.2"/>
</ownedPackages>
<ownedPackages name="io" proxy="true">
<ownedElements xsi:type="java:InterfaceDeclaration" name="Serializable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.1/@ownedElements.0/@superInterfaces.0 //@ownedElements.1/@ownedPackages.1/@ownedElements.2/@superInterfaces.0"/>
</ownedPackages>
</ownedElements>
<orphanTypes xsi:type="java:PrimitiveTypeInt" name="int"/>
<orphanTypes xsi:type="java:PrimitiveTypeLong" name="long" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@parameters.0/@type"/>
<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="BigIntegerInstantiationNotPass.java" originalFilePath="/home/alexis/eclipse-workspace/biginteger-instantiation/src/BigIntegerInstantiationNotPass.java" types="//@ownedElements.0/@ownedElements.0">
<imports originalCompilationUnit="//@compilationUnits.0" importedElement="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</compilationUnits>
<compilationUnits name="BigIntegerInstantiationPass.java" originalFilePath="/home/alexis/eclipse-workspace/biginteger-instantiation/src/BigIntegerInstantiationPass.java" types="//@ownedElements.0/@ownedElements.1">
<imports originalCompilationUnit="//@compilationUnits.1" importedElement="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</compilationUnits>
</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="boolean-instantiation">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="BooleanInstantiationNotPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.0">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="bool">
<initializer xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0">
<arguments xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.1" name="BooleanInstantiationPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.1">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.1" name="bool">
<initializer xsi:type="java:MethodInvocation" originalCompilationUnit="//@compilationUnits.1" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1">
<arguments xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.1" value="true"/>
<expression xsi:type="java:TypeAccess" type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="Boolean" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer/@expression">
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="Boolean" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@orphanTypes.4"/>
</parameters>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" name="valueOf" proxy="true" usages="//@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@orphanTypes.4"/>
</parameters>
</bodyDeclarations>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Comparable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superInterfaces.1">
<typeParameters name="T" proxy="true"/>
</ownedElements>
</ownedPackages>
<ownedPackages name="io" proxy="true">
<ownedElements xsi:type="java:InterfaceDeclaration" name="Serializable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@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" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0/@type //@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@parameters.0/@type"/>
<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="BooleanInstantiationNotPass.java" originalFilePath="/home/alexis/eclipse-workspace/boolean-instantiation/src/BooleanInstantiationNotPass.java" types="//@ownedElements.0/@ownedElements.0"/>
<compilationUnits name="BooleanInstantiationPass.java" originalFilePath="/home/alexis/eclipse-workspace/boolean-instantiation/src/BooleanInstantiationPass.java" types="//@ownedElements.0/@ownedElements.1"/>
</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="byte-instantiation">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="ByteInstantiationNotPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.0">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="val">
<initializer xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0">
<arguments xsi:type="java:CastExpression" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:NumberLiteral" originalCompilationUnit="//@compilationUnits.0" tokenValue="0"/>
<type type="//@orphanTypes.8"/>
</arguments>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.1" name="ByteInstantiationPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.1">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.1" name="val">
<initializer xsi:type="java:MethodInvocation" originalCompilationUnit="//@compilationUnits.1" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1">
<arguments xsi:type="java:CastExpression" originalCompilationUnit="//@compilationUnits.1">
<expression xsi:type="java:NumberLiteral" originalCompilationUnit="//@compilationUnits.1" tokenValue="0"/>
<type type="//@orphanTypes.8"/>
</arguments>
<expression xsi:type="java:TypeAccess" type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="Byte" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer/@expression">
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="Byte" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@orphanTypes.8"/>
</parameters>
</bodyDeclarations>
<bodyDeclarations xsi:type="java:MethodDeclaration" name="valueOf" proxy="true" usages="//@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@orphanTypes.8"/>
</parameters>
</bodyDeclarations>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.2"/>
<superClass type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" name="Number" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superClass //@ownedElements.1/@ownedPackages.2/@ownedElements.0/@superClass">
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Comparable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superInterfaces.0 //@ownedElements.1/@ownedPackages.2/@ownedElements.0/@superInterfaces.0">
<typeParameters name="T" proxy="true"/>
</ownedElements>
</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>
<ownedPackages name="math" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="BigInteger" proxy="true" usagesInImports="//@compilationUnits.1/@imports.0">
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.2"/>
<superClass type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
</ownedElements>
</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" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer/@arguments.0/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@fragments.0/@initializer/@arguments.0/@type //@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0/@type //@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.1/@parameters.0/@type"/>
<compilationUnits name="ByteInstantiationNotPass.java" originalFilePath="/home/alexis/eclipse-workspace/byte-instantiation/src/ByteInstantiationNotPass.java" types="//@ownedElements.0/@ownedElements.0"/>
<compilationUnits name="ByteInstantiationPass.java" originalFilePath="/home/alexis/eclipse-workspace/byte-instantiation/src/ByteInstantiationPass.java" types="//@ownedElements.0/@ownedElements.1">
<imports originalCompilationUnit="//@compilationUnits.1" importedElement="//@ownedElements.1/@ownedPackages.2/@ownedElements.0"/>
</compilationUnits>
</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="test">
<ownedElements name="test">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="Foo">
<modifier/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="bar">
<modifier/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:IfStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="&amp;&amp;">
<rightOperand xsi:type="java:InstanceofExpression" originalCompilationUnit="//@compilationUnits.0">
<rightOperand type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0"/>
</rightOperand>
<leftOperand xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="!=">
<rightOperand xsi:type="java:NullLiteral" originalCompilationUnit="//@compilationUnits.0"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0"/>
</leftOperand>
</expression>
<thenStatement xsi:type="java:Block" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// just drop the &quot;x != null&quot; check" enclosedByParent="true"/>
</thenStatement>
</statements>
<statements xsi:type="java:IfStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="||">
<rightOperand xsi:type="java:InstanceofExpression" originalCompilationUnit="//@compilationUnits.0">
<rightOperand type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0"/>
</rightOperand>
<leftOperand xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="==">
<rightOperand xsi:type="java:NullLiteral" originalCompilationUnit="//@compilationUnits.0"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0"/>
</leftOperand>
</expression>
<thenStatement xsi:type="java:Block" originalCompilationUnit="//@compilationUnits.0"/>
</statements>
<statements xsi:type="java:IfStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="&amp;&amp;">
<rightOperand xsi:type="java:InstanceofExpression" originalCompilationUnit="//@compilationUnits.0">
<rightOperand type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0"/>
</rightOperand>
<leftOperand xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="!=">
<rightOperand xsi:type="java:NullLiteral" originalCompilationUnit="//@compilationUnits.0"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1"/>
</leftOperand>
</expression>
<thenStatement xsi:type="java:Block" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// just drop the &quot;x != null&quot; check" enclosedByParent="true"/>
</thenStatement>
</statements>
<statements xsi:type="java:IfStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="&amp;&amp;">
<rightOperand xsi:type="java:InstanceofExpression" originalCompilationUnit="//@compilationUnits.0">
<rightOperand type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1"/>
</rightOperand>
<leftOperand xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="!=">
<rightOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1"/>
<leftOperand xsi:type="java:NullLiteral" originalCompilationUnit="//@compilationUnits.0"/>
</leftOperand>
</expression>
<thenStatement xsi:type="java:Block" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// just drop the &quot;x != null&quot; check" enclosedByParent="true"/>
</thenStatement>
</statements>
<statements xsi:type="java:IfStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:InfixExpression" originalCompilationUnit="//@compilationUnits.0" operator="&amp;&amp;">
<rightOperand xsi:type="java:InstanceofExpression" originalCompilationUnit="//@compilationUnits.0">
<rightOperand type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<leftOperand xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1"/>
</rightOperand>
<leftOperand xsi:type="java:BooleanLiteral" originalCompilationUnit="//@compilationUnits.0" value="true"/>
</expression>
<thenStatement xsi:type="java:Block" originalCompilationUnit="//@compilationUnits.0">
<comments xsi:type="java:LineComment" originalCompilationUnit="//@compilationUnits.0" content="// just drop the &quot;x != null&quot; check" enclosedByParent="true"/>
</thenStatement>
</statements>
</body>
<parameters originalCompilationUnit="//@compilationUnits.0" name="x" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@expression/@leftOperand/@leftOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@expression/@rightOperand/@leftOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@expression/@leftOperand/@leftOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@expression/@rightOperand/@leftOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.2/@expression/@rightOperand/@leftOperand">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</parameters>
<parameters originalCompilationUnit="//@compilationUnits.0" name="y" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.2/@expression/@leftOperand/@leftOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.3/@expression/@leftOperand/@rightOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.3/@expression/@rightOperand/@leftOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.4/@expression/@rightOperand/@leftOperand">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</parameters>
<returnType type="//@orphanTypes.5"/>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="Object" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1/@type"/>
<ownedElements xsi:type="java:ClassDeclaration" name="String" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@expression/@rightOperand/@rightOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@expression/@rightOperand/@rightOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.2/@expression/@rightOperand/@rightOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.3/@expression/@rightOperand/@rightOperand //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.4/@expression/@rightOperand/@rightOperand">
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.2"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.3"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Comparable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.1/@superInterfaces.1">
<typeParameters name="T" proxy="true"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="CharSequence" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.1/@superInterfaces.2"/>
</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" 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="Foo.java" originalFilePath="E:\Henri\Documents\Projet Gerson\test\src\test\Foo.java" commentList="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@thenStatement/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.2/@thenStatement/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.3/@thenStatement/@comments.0 //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.4/@thenStatement/@comments.0" package="//@ownedElements.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="string-instantiation">
<ownedElements name="(default package)">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="StringInstantiationNotPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.0">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.0" name="val">
<initializer xsi:type="java:ClassInstanceCreation" originalCompilationUnit="//@compilationUnits.0" method="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0">
<arguments xsi:type="java:StringLiteral" originalCompilationUnit="//@compilationUnits.0" escapedValue="&quot;Bonjour&quot;"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</initializer>
</fragments>
</bodyDeclarations>
</ownedElements>
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.1" name="StringInstantiationPass">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:FieldDeclaration" originalCompilationUnit="//@compilationUnits.1">
<modifier visibility="private"/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
<fragments originalCompilationUnit="//@compilationUnits.1" name="val">
<initializer xsi:type="java:StringLiteral" originalCompilationUnit="//@compilationUnits.1" escapedValue="&quot;Bonjour&quot;"/>
</fragments>
</bodyDeclarations>
</ownedElements>
</ownedElements>
<ownedElements name="java" proxy="true">
<ownedPackages name="lang" proxy="true">
<ownedElements xsi:type="java:ClassDeclaration" name="String" proxy="true" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@type //@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer/@type //@ownedElements.1/@ownedPackages.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0/@type //@ownedElements.0/@ownedElements.1/@bodyDeclarations.0/@type">
<bodyDeclarations xsi:type="java:ConstructorDeclaration" name="String" proxy="true" usages="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@fragments.0/@initializer">
<parameters name="arg0" proxy="true">
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</parameters>
</bodyDeclarations>
<superInterfaces type="//@ownedElements.1/@ownedPackages.1/@ownedElements.0"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.1"/>
<superInterfaces type="//@ownedElements.1/@ownedPackages.0/@ownedElements.2"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="Comparable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superInterfaces.1">
<typeParameters name="T" proxy="true"/>
</ownedElements>
<ownedElements xsi:type="java:InterfaceDeclaration" name="CharSequence" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@superInterfaces.2"/>
</ownedPackages>
<ownedPackages name="io" proxy="true">
<ownedElements xsi:type="java:InterfaceDeclaration" name="Serializable" proxy="true" usagesInTypeAccess="//@ownedElements.1/@ownedPackages.0/@ownedElements.0/@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="StringInstantiationNotPass.java" originalFilePath="/home/alexis/eclipse-workspace/string-instantiation/src/StringInstantiationNotPass.java" types="//@ownedElements.0/@ownedElements.0"/>
<compilationUnits name="StringInstantiationPass.java" originalFilePath="/home/alexis/eclipse-workspace/string-instantiation/src/StringInstantiationPass.java" types="//@ownedElements.0/@ownedElements.1"/>
</java:Model>
......@@ -31,8 +31,8 @@ rule Java2SMM {
helper def: allMeasures(project : java!Model): Set(smm!Measure) =
Set{
-- Example rule
--
--Example rule
thisModule.numberOfClasses(),
-- Multithreading rules
......@@ -46,6 +46,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
--
thisModule.avoidDollarSigns(),
thisModule.avoidPrefixingMethodParameters(),
thisModule.duplicateImport(),
thisModule.avoidUsingNativeCode(),
thisModule.extendsObject(),
thisModule.fieldDeclarationsShouldBeAtStartOfClass(),
......@@ -81,6 +82,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
thisModule.tooManyFields(),
thisModule.tooManyMethods(),
thisModule.SimplifyBooleanAssertion(),
thisModule.simplifyConditional(),
-- Performance rules
--
......@@ -89,12 +91,16 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
thisModule.avoidPrintStackTrace(),
thisModule.avoidRethrowingException(),
thisModule.avoidUsingShortType(),
thisModule.doNotInitBigIntegerWithNew(),
thisModule.doNotInitBooleanWithNew(),
thisModule.doNotInitByteWithNew(),
thisModule.doNotInitIntegerWithNew(),
thisModule.doNotInitStringWithNew(),
thisModule.emptyStatementBlock(),
thisModule.inefficientEmptyStringCheck(),
thisModule.inefficientEmptyStringCheck2(),
-- #FIXME:
-- thisModule.insufficientStringBufferDeclaration(),
thisModule.integerInstantiation(),
-- #FIXME:
-- thisModule.startsWith(),
thisModule.stringToString(),
......@@ -547,6 +553,68 @@ rule MeasureAvoidUsingNativeCode(classDeclaration : java!ClassDeclaration) {
}
}
-- ------------------------------------------- BigIntegerInstantiation ---------------------------------------------
--- creates a Measure when a BigInteger is instantiated with a "new BigInteger()" statement.
rule MeasureBigIntegerInstantiation(variable : java!CompilationUnit) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'BigIntegerInstantiation',
shortDescription <- 'Don’t create instances of already existing BigInteger (BigInteger.ZERO, BigInteger.ONE) and for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN)'
),
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' an instantiation of BigInteger must be BigInteger.valueOf().'
)
do {
noc;
}
}
-- ------------------------------------------- BooleanInstantiation ---------------------------------------------
--- creates a Measure when a Boolean is instantiated with a "new Boolean()" statement.
rule MeasureBooleanInstantiation(variable : java!CompilationUnit) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'BooleanInstantiation',
shortDescription <- 'Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead. Note that new Boolean() is deprecated since JDK 9 for that reason.'
),
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' an instantiation of Boolean must be Boolean.TRUE, Boolean.FALSE or Boolean.valueOf().'
)
do {
noc;
}
}
-- ------------------------------------------- ByteInstantiation ---------------------------------------------
--- creates a Measure when a Byte is instantiated with a "new Byte()" statement.
rule MeasureByteInstantiation(variable : java!CompilationUnit) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'ByteInstantiation',
shortDescription <- 'Calling new Byte() causes memory allocation that can be avoided by the static Byte.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Byte() is deprecated since JDK 9 for that reason.'
),
measurement: smm!DirectMeasurement (
error<-'In the Class '+ variable.name + ' an instantiation of Byte must be Byte.valueOf().'
)
do {
noc;
}
}
--- A Measure instance if the class violates the rule CloneMethodMustBePublic.
rule MeasureCloneMethodMustBePublic(w: java!MethodDeclaration) {
to
......@@ -1544,6 +1612,27 @@ rule MeasureSimplifyBooleanAssertion(i : java!PrefixExpression) {
}
}
-- ------------------------------------------- SimplifyConditional ---------------------------------------------
--- Triggers the rule when a variable is compared to null and then tested in instanceof
rule MeasureSimplifyConditional(class : String, method: String) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'SimplifyConditional',
shortDescription <- 'Test if a variable is null is useless before an "instanceof".'
),
measurement: smm!DirectMeasurement (
error<-'The method ' + method + ' in ' + class + ' contains null check followed by an instanceof check on the same variable.'
)
do {
noc;
}
}