Commit 43ddce4c authored by Gerson SUNYE's avatar Gerson SUNYE
Browse files

Merge branch 'AvoidReassigningParameters' into 'master'

fix #618 "AvoidReassigningParameters"

Closes #618

See merge request !140
parents 43a40d83 6b222303
<?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="testIdenticalCatchBranches">
<ownedElements name="test">
<ownedElements xsi:type="java:ClassDeclaration" originalCompilationUnit="//@compilationUnits.0" name="Main">
<modifier visibility="public"/>
<bodyDeclarations xsi:type="java:MethodDeclaration" originalCompilationUnit="//@compilationUnits.0" name="test">
<modifier visibility="public" static="true"/>
<body originalCompilationUnit="//@compilationUnits.0">
<statements xsi:type="java:ExpressionStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:Assignment" originalCompilationUnit="//@compilationUnits.0">
<leftHandSide xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.0"/>
<rightHandSide xsi:type="java:StringLiteral" originalCompilationUnit="//@compilationUnits.0" escapedValue="&quot;5&quot;"/>
</expression>
</statements>
<statements xsi:type="java:ExpressionStatement" originalCompilationUnit="//@compilationUnits.0">
<expression xsi:type="java:Assignment" originalCompilationUnit="//@compilationUnits.0" operator="+=">
<leftHandSide xsi:type="java:SingleVariableAccess" variable="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1"/>
<rightHandSide xsi:type="java:NumberLiteral" originalCompilationUnit="//@compilationUnits.0" tokenValue="3"/>
</expression>
</statements>
</body>
<parameters originalCompilationUnit="//@compilationUnits.0" name="a" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.0/@expression/@leftHandSide">
<modifier/>
<type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.0"/>
</parameters>
<parameters originalCompilationUnit="//@compilationUnits.0" name="b" usageInVariableAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@body/@statements.1/@expression/@leftHandSide">
<modifier/>
<type type="//@orphanTypes.0"/>
</parameters>
<parameters originalCompilationUnit="//@compilationUnits.0" name="c">
<modifier/>
<type type="//@orphanTypes.4"/>
</parameters>
<returnType type="//@orphanTypes.5"/>
</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/@parameters.0/@type">
<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" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.1/@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" usagesInTypeAccess="//@ownedElements.0/@ownedElements.0/@bodyDeclarations.0/@parameters.2/@type"/>
<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="Main.java" originalFilePath="D:\Arthur\eclipse-workspace-atl\testIdenticalCatchBranches\src\test\Main.java" package="//@ownedElements.0" types="//@ownedElements.0/@ownedElements.0"/>
</java:Model>
......@@ -124,6 +124,7 @@ helper def: allMeasures(project : java!Model): Set(smm!Measure) =
thisModule.UseProperClassLoader(),
-- Best practices rules
thisModule.avoidReassigningParameters(),
thisModule.avoidStringBufferField(),
thisModule.forLoopVariableCount(),
thisModule.switchDensity(),
......@@ -1856,4 +1857,25 @@ rule MeasureFieldDeclarationsShouldBeAtStartOfClass(class: java!ClassDeclaration
do {
noc;
}
}
------------------------------------------- AvoidReassigningParameters ----------------------------------------------
-- A Measure instance if the class violates the rule AvoidReassigningParameters.
rule MeasureAvoidReassigningParameters(assignment: java!SingleVariableAccess) {
to
om: smm!ObservedMeasure (
measure <- noc,
measurements <- measurement
),
noc: smm!DimensionalMeasure (
name <- 'AvoidReassigningParameters',
shortDescription <- 'Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.'
),
measurement: smm!DirectMeasurement (
error<- assignment.leftHandSide.variable.name + ' should not be reassigned'
)
do {
noc;
}
}
\ No newline at end of file
......@@ -117,3 +117,27 @@ helper context java!Expression def: nbLocalVariableDeclarations(): Integer =
helper context java!VariableDeclarationExpression def: nbLocalVariableDeclarations(): Integer =
self.fragments.size(); -- The fragments collection contains all the variable declarations of an initializer*
-- Initializer* : for(int x = 0; ...), "int x = 0" is the initializer part of the for loop
--------------------------------------------- AvoidReassigningParameters ---------------------------------------------
helper def: avoidReassigningParameters(): Set(smm!Measure) =
java!AbstractMethodDeclaration.allInstances()->select(method |
method.parameters.size() > 0 -- need at least 1 parameter
)->collect(method |
method.body.statements->select(statement |
statement.oclIsTypeOf(java!ExpressionStatement) -- statement must be an expression
)->collect(expressionStatement |
expressionStatement.expression
)->select(expression |
expression.oclIsTypeOf(java!Assignment) -- the expression must be an assignment
)->select(assignment |
assignment.leftHandSide.oclIsTypeOf(java!SingleVariableAccess) -- the receiving end of the assignment must be a variable access
)->select(assignment |
method.parameters->collect(singleVariableDeclaration |
singleVariableDeclaration.name -- for each parameter of the method we retrieve its name
)->includes(assignment.leftHandSide.variable.name) -- one of the parameter is on the receiving of an assignment
)->collect(assignment |
thisModule.MeasureAvoidReassigningParameters(assignment)
)
)->flatten();
\ No newline at end of file
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