Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
fr.inria.coming.codefeatures.codeanalyze.VariableAnalyzer Maven / Gradle / Ivy
package fr.inria.coming.codefeatures.codeanalyze;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import fr.inria.coming.codefeatures.Cntx;
import fr.inria.coming.codefeatures.CodeElementInfo;
import fr.inria.coming.codefeatures.CodeFeatures;
import fr.inria.coming.utils.MapCounter;
import fr.inria.coming.utils.StringDistance;
import fr.inria.coming.utils.VariableResolver;
import spoon.reflect.code.CtAssignment;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtConstructorCall;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtFor;
import spoon.reflect.code.CtForEach;
import spoon.reflect.code.CtIf;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.code.CtLocalVariable;
import spoon.reflect.code.CtLoop;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.code.CtWhile;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtConstructor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtEnum;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtVariable;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.CtScanner;
import spoon.reflect.visitor.filter.LineFilter;
import spoon.reflect.visitor.filter.TypeFilter;
public class VariableAnalyzer extends AbstractCodeAnalyzer {
public VariableAnalyzer(CodeElementInfo inputinfo) {
super(inputinfo);
}
@Override
public void analyze() {
analyzeV1_V6_V16(elementinfo.varsAffected,elementinfo.element, elementinfo.context, elementinfo.allMethods,
elementinfo.invocationsFromClass, elementinfo.parentClass);
analyzeV2_AffectedDistanceVarName(elementinfo.varsAffected, elementinfo.varsInScope, elementinfo.element, elementinfo.context);
analyzeV3_AffectedHasConstant(elementinfo.varsAffected, elementinfo.element, elementinfo.context);
analyzeV4(elementinfo.varsAffected, elementinfo.element, elementinfo.context);
analyzeV5_AffectedVariablesInTransformation(elementinfo.varsAffected, elementinfo.element, elementinfo.context);
analyzeV8_TypesVarsAffected(elementinfo.varsAffected, elementinfo.element, elementinfo.context);
analyzeV9_VarSimilarLiteral(elementinfo.element, elementinfo.context, elementinfo.parentClass, elementinfo.varsAffected);
analyzV10_AffectedWithCompatibleTypes(elementinfo.varsAffected, elementinfo.varsInScope, elementinfo.element, elementinfo.context);
analyzV11_ConditionWithCompatibleTypes(elementinfo.varsAffected, elementinfo.varsInScope, elementinfo.element, elementinfo.context);
analyzeV1213_ReplaceVarGetAnotherInvocation(elementinfo.varsAffected, elementinfo.context, elementinfo.invocationsFromClass,
elementinfo.constructorcallsFromClass);
analyzeV14_VarInstanceOfClass(elementinfo.varsAffected, elementinfo.context, elementinfo.parentClass);
analyzeV15_LastthreeVariableIntroduction(elementinfo.varsAffected, elementinfo.element, elementinfo.context);
analyzeV17_IsEnum(elementinfo.varsAffected, elementinfo.context, elementinfo.parentClass);
analyzeFeature_Extend(elementinfo.varsAffected, elementinfo.element, elementinfo.context, elementinfo.parentClass,
elementinfo.statements);
analyzeV18_HasMethodSimilarInName (elementinfo.varsAffected, elementinfo.context, elementinfo.invocationsFromClass,
elementinfo.allMethods, elementinfo.constructorcallsFromClass, elementinfo.parentClass);
analyzeV19_VarWithSpecialName (elementinfo.varsAffected, elementinfo.context);
}
private void analyzeV19_VarWithSpecialName (List varsAffected, Cntx context) {
try {
for (CtVariableAccess aVarAffected : varsAffected) {
boolean V19WithSpecialName = false;
String varname= aVarAffected.getVariable().getSimpleName().toLowerCase();
if(varname.endsWith("length") || varname.endsWith("size") || varname.endsWith("count") || varname.endsWith("value")
|| varname.endsWith("key") || varname.equals("class"))
V19WithSpecialName =true;
if(!V19WithSpecialName && aVarAffected.getType()!=null && aVarAffected.getType().getSimpleName().toLowerCase().endsWith("exception"))
V19WithSpecialName =true;
writeGroupedInfo(context, adjustIdentifyInJson(aVarAffected),
CodeFeatures.V19_With_Special_Name,
V19WithSpecialName, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void analyzeV18_HasMethodSimilarInName (List varsAffected, Cntx context,
List invocationsFromClass, List allMethodsFromClass,
List allconstructorcallsFromClass, CtClass parentClass) {
try {
for (CtVariableAccess aVarAffected : varsAffected) {
boolean V18HasMethodSimilarInName = false;
String varname= aVarAffected.getVariable().getSimpleName();
varname=varname.replaceAll("[^a-zA-Z0-9]", "");
for (CtInvocation invInClass : invocationsFromClass) {
String methodname=invInClass.getExecutable().getSimpleName();
if(varname.length()>3) {
if(methodname.toLowerCase().endsWith(varname.toLowerCase())) {
V18HasMethodSimilarInName = true;
break;
}
}
}
if(!V18HasMethodSimilarInName) {
for (Object omethod : allMethodsFromClass) {
if (!(omethod instanceof CtMethod))
continue;
CtMethod anotherMethod = (CtMethod) omethod;
String methodname=anotherMethod.getSimpleName();
if(varname.length()>3) {
if(methodname.toLowerCase().endsWith(varname.toLowerCase())) {
V18HasMethodSimilarInName = true;
break;
}
}
}
}
if(!V18HasMethodSimilarInName) {
for (CtConstructorCall certainconstructorcallinclass : allconstructorcallsFromClass) {
String methodname=getSimplenameForConstructorCall(certainconstructorcallinclass);
if(varname.length()>3) {
if(methodname.toLowerCase().endsWith(varname.toLowerCase())) {
V18HasMethodSimilarInName = true;
break;
}
}
}
}
if(!V18HasMethodSimilarInName) {
List allconstructorsinclass = parentClass.getElements(new TypeFilter<>(CtConstructor.class));
for (CtConstructor certainconstructorinclass : allconstructorsinclass) {
String methodname=certainconstructorinclass.getSimpleName();
if(varname.length()>3) {
if(methodname.toLowerCase().endsWith(varname.toLowerCase())) {
V18HasMethodSimilarInName = true;
break;
}
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(aVarAffected),
CodeFeatures.V18_Has_Method_Similar_In_Name,
V18HasMethodSimilarInName, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void analyzeFeature_Extend(List varsAffected, CtElement originalElement, Cntx context,
CtClass parentClass, List allstatementsinclass ) {
for (CtVariableAccess varAffected : varsAffected) {
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V1_LOCAL_VAR_NOT_USED,
analyze_AffectedVariablesUsed (Arrays.asList(varAffected), originalElement, allstatementsinclass),
"FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V1_LOCAL_VAR_NOT_ASSIGNED,
analyze_AffectedAssigned (Arrays.asList(varAffected), originalElement),
"FEATURES_VARS");
boolean[] varfeatures = analyze_SametypewithGuard(Arrays.asList(varAffected), originalElement, parentClass,
allstatementsinclass);
if(varfeatures != null) {
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V2_SIMILAR_OBJECT_TYPE_WITH_NORMAL_GUARD,
varfeatures[0], "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V5_SIMILAR_PRIMITIVE_TYPE_WITH_NORMAL_GUARD,
varfeatures[1], "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V2_SIMILAR_OBJECT_TYPE_WITH_NULL_GUARD,
varfeatures[2], "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V5_SIMILAR_PRIMITIVE_TYPE_WITH_NULL_GUARD,
varfeatures[3], "FEATURES_VARS");
}
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V4_Field_NOT_USED,
analyze_AffectedFielfs(Arrays.asList(varAffected), originalElement, parentClass), "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V4_Field_NOT_ASSIGNED,
analyze_AffectedFieldAssigned(Arrays.asList(varAffected), originalElement, parentClass), "FEATURES_VARS");
boolean[] varvalue78 = analyze_AffectedObjectLastAppear(Arrays.asList(varAffected), originalElement, allstatementsinclass);
if(varvalue78 != null) {
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V7_OBJECT_USED_IN_ASSIGNMENT,
varvalue78[0], "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V8_PRIMITIVE_USED_IN_ASSIGNMENT,
varvalue78[1], "FEATURES_VARS");
}
}
}
/**
* Check is a variable affected is compatible with a method type or parameter
*
* @param varsAffected
* @param element
* @param context
*/
private void analyzeV1_V6_V16(List varsAffected, CtElement element, Cntx context,
List allMethods, List invocationsFromClass, CtClass parentclass) {
try {
// v1: For each involved variable, whether has method definitions or method calls
// (in the fault class) that take the type of the involved variable as one of
// its parameters and the return type of the method is type compatible with the
// type of the involved variable
// v6 :For each involved variable, whether has methods in scope(method definitions
// or method calls in the faulty class) that return a type which is the same or
// compatible with the typeof the involved variable.
for (CtVariableAccess varAffected : varsAffected) {
boolean v6CurrentVarReturnCompatible = false;
boolean v1CurrentVarCompatibleReturnAndParameterTypes = false;
boolean v16CurrentVarParameterCompatible = false;
if(varAffected.getType()!=null && !varAffected.getType().getQualifiedName().toString().toLowerCase().endsWith("object") &&
varAffected.getType().getQualifiedName().toString().toLowerCase().indexOf("java.lang.object")==-1) {
if (checkMethodDeclarationWithParameterReturnCompatibleType(allMethods, varAffected.getType()) != null
|| checkInvocationWithParameterReturnCompatibleType(invocationsFromClass,
varAffected.getType(), parentclass) != null) {
v1CurrentVarCompatibleReturnAndParameterTypes = true;
}
if (checkMethodDeclarationWithReturnCompatibleType(allMethods, varAffected.getType()) != null
|| checkInvocationWithReturnCompatibleType(invocationsFromClass,
varAffected.getType(), parentclass) != null) {
v6CurrentVarReturnCompatible = true;
}
if (checkMethodDeclarationWithParemetrCompatibleType(allMethods, varAffected.getType()) != null
|| checkInvocationWithParemetrCompatibleType (invocationsFromClass,
varAffected.getType()) != null) {
v16CurrentVarParameterCompatible = true;
}
}
writeGroupedInfo(context, adjustIdentifyInJson(varAffected),
CodeFeatures.V1_IS_TYPE_COMPATIBLE_METHOD_CALL_PARAM_RETURN,
v1CurrentVarCompatibleReturnAndParameterTypes, "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected),
CodeFeatures.V6_IS_METHOD_RETURN_TYPE_VAR,
v6CurrentVarReturnCompatible, "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected),
CodeFeatures.V16_IS_METHOD_PARAMETER_TYPE_VAR,
v16CurrentVarParameterCompatible, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
public CtMethod checkMethodDeclarationWithReturnCompatibleType(List allMethods, CtTypeReference typeToMatch) {
for (Object omethod : allMethods) {
if (!(omethod instanceof CtMethod))
continue;
CtMethod anotherMethodInBuggyClass = (CtMethod) omethod;
if (compareTypes(typeToMatch, anotherMethodInBuggyClass.getType())) {
return anotherMethodInBuggyClass;
}
}
return null;
}
public CtInvocation checkInvocationWithReturnCompatibleType(List invocationsFromClass,
CtTypeReference type, CtClass parentclass) {
List binaryOperatorInClass = parentclass.getElements(e ->
(e instanceof CtBinaryOperator)).stream().map(CtBinaryOperator.class::cast).collect(Collectors.toList());
// For each invocation found in the class
for (CtInvocation anInvocation : invocationsFromClass) {
List inferredpotentionaltypes = new ArrayList();
inferredpotentionaltypes.clear();
CtTypeReference inferredtype = null;
// do simple type inference
if(anInvocation.getType()==null) {
for(CtBinaryOperator certainbinary: binaryOperatorInClass) {
if(certainbinary.getLeftHandOperand() instanceof CtInvocation) {
CtInvocation anotherinvocation=(CtInvocation)certainbinary.getLeftHandOperand();
if(anotherinvocation.getExecutable().getSignature().equals(anInvocation.getExecutable().getSignature())
&& certainbinary.getRightHandOperand().getType()!=null) {
inferredtype=certainbinary.getRightHandOperand().getType();
inferredpotentionaltypes.add(inferredtype);
break;
}
}
if(certainbinary.getRightHandOperand() instanceof CtInvocation) {
CtInvocation anotherinvocation=(CtInvocation)certainbinary.getRightHandOperand();
if(anotherinvocation.getExecutable().getSignature().equals(anInvocation.getExecutable().getSignature())
&& certainbinary.getLeftHandOperand().getType()!=null) {
inferredtype=certainbinary.getLeftHandOperand().getType();
inferredpotentionaltypes.add(inferredtype);
break;
}
}
}
} else inferredtype=anInvocation.getType();
if (compareTypes(type, inferredtype) || compareInferredTypes(type, inferredpotentionaltypes)) {
return anInvocation;
}
}
return null;
}
/**
* For each involved variable, whether has any other variables in scope that are
* similar in identifier name and type compatible
*
* @param varsAffected
* @param varsInScope
* @param element
* @param context
*/
private void analyzeV2_AffectedDistanceVarName(List varsAffected, List varsInScope,
CtElement element, Cntx context) {
try {
for (CtVariableAccess aVarAffected : varsAffected) {
boolean v2VarSimilarNameCompatibleType = false;
boolean v2VarSimilarName = false;
for (CtVariable aVarInScope : varsInScope) {
if (!aVarInScope.getSimpleName().equals(aVarAffected.getVariable().getSimpleName())) {
int dist = StringDistance.calculate(aVarInScope.getSimpleName(),
aVarAffected.getVariable().getSimpleName());
if ((dist > 0 && dist < 3) || nameStartEndWithOther (aVarInScope.getSimpleName(),
aVarAffected.getVariable().getSimpleName())) {
v2VarSimilarName=true;
if (compareTypes(aVarAffected.getType(), aVarInScope.getType())) {
v2VarSimilarNameCompatibleType = true;
break;
}
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(aVarAffected),
CodeFeatures.V2_HAS_VAR_SIM_NAME,
v2VarSimilarName, "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(aVarAffected),
CodeFeatures.V2_HAS_VAR_SIM_NAME_COMP_TYPE,
v2VarSimilarNameCompatibleType, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private boolean nameStartEndWithOther(String name1, String name2) {
if(name1.length()==1 || name2.length()==1)
return false;
else {
if(name1.startsWith(name2) || name1.endsWith(name2) ||
name2.startsWith(name1) || name2.endsWith(name1))
return true;
else return false;
}
}
/**
* For each involved variable, is it constant?–can assume variables whose
* identifier names are majorly capital letters are constant variables
*
* @param varsAffected
* @param element
* @param context
*/
private void analyzeV3_AffectedHasConstant(List varsAffected, CtElement element,
Cntx context) {
try {
for (CtVariableAccess aVarAffected : varsAffected) {
boolean currentIsConstant = false;
if (aVarAffected.getVariable() instanceof CtFieldReference &&
// Check if it's uppercase
aVarAffected.getVariable().getSimpleName().toUpperCase()
.equals(aVarAffected.getVariable().getSimpleName())) {
currentIsConstant = true;
}
writeGroupedInfo(context, adjustIdentifyInJson(aVarAffected),
CodeFeatures.V3_HAS_CONSTANT,
currentIsConstant, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
*
* @param varsAffected
* @param element
* @param context
*/
private void analyzeV4(List varsAffected, CtElement element, Cntx context) {
try {
for (CtVariableAccess varInFaulty : varsAffected) {
CtInvocation parentInvocation = varInFaulty.getParent(CtInvocation.class);
int appearsInParams = 0;
MapCounter parameterFound = new MapCounter<>();
if (parentInvocation != null) {
List arguments = parentInvocation.getArguments();
for (CtElement i_Argument : arguments) {
List varsAccessInParameter = VariableResolver.collectVariableRead(i_Argument);
// .stream().filter(e -> e.getRoleInParent().equals(CtRole.PARAMETER))
// .collect(Collectors.toList());
if (varsAccessInParameter.contains(varInFaulty)) {
appearsInParams++;
if (!parameterFound.containsKey(varInFaulty)) {
writeGroupedInfo(context, adjustIdentifyInJson(varInFaulty),
CodeFeatures.V4_FIRST_TIME_USED_AS_PARAMETER,
true, "FEATURES_VARS");
} else {
writeGroupedInfo(context, adjustIdentifyInJson(varInFaulty),
CodeFeatures.V4_FIRST_TIME_USED_AS_PARAMETER,
false, "FEATURES_VARS");
}
parameterFound.add(varInFaulty);
}
if(appearsInParams > 1)
break;
}
}
writeGroupedInfo(context, adjustIdentifyInJson(varInFaulty),
CodeFeatures.V4B_USED_MULTIPLE_AS_PARAMETER,
(appearsInParams > 1), "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* For each involved variable, is there any other variable in scope that is a
* certain function transformation of the involved variable
*
* @param varsAffected
* @param element
* @param context
*/
@SuppressWarnings("rawtypes")
private void analyzeV5_AffectedVariablesInTransformation(List varsAffected, CtElement element,
Cntx context) {
try {
CtMethod methodParent = element.getParent(CtMethod.class);
List assignments = new ArrayList<>();
CtScanner assignmentScanner = new CtScanner() {
@Override
public void visitCtAssignment(CtAssignment assignement) {
if (assignement.getAssignment() != null)
assignments.add(assignement.getAssignment());
}
@Override
public void visitCtLocalVariable(CtLocalVariable localVariable) {
if (localVariable.getAssignment() != null)
assignments.add(localVariable.getAssignment());
}
};
assignmentScanner.scan(methodParent);
for (CtVariableAccess variableAffected : varsAffected) {
boolean v5_currentVarHasvar = false;
for (CtExpression assignment : assignments) {
if (!isElementBeforeVariable(variableAffected, assignment))
continue;
// let's collect the var access in the right part
List varsInRightPart = VariableResolver.collectVariableRead(assignment); // VariableResolver.collectVariableAccess(assignment);
// if the var access in the right is the same that the affected
for (CtVariableAccess varInAssign : varsInRightPart) {
if (hasSameName(variableAffected, varInAssign)) {
v5_currentVarHasvar = true;
break;
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(variableAffected),
CodeFeatures.V5_HAS_VAR_IN_TRANSFORMATION,
(v5_currentVarHasvar), "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void analyzeV8_TypesVarsAffected(List varsAffected, CtElement element,
Cntx context) {
try {
for (CtVariableAccess aVariableAccess : varsAffected) {
CtVariable ctVariable = aVariableAccess.getVariable().getDeclaration();
boolean isPrimitive = false;
boolean isObject = false;
if (ctVariable != null && ctVariable.getReference() != null
&& ctVariable.getReference().getType() != null) {
if (ctVariable.getReference().getType().isPrimitive() ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("string") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("list") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().indexOf("string")!=-1||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("long") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("boolean") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("double") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("byte")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("short")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("float") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("chart") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("character") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("integer")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("string[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("long[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("boolean[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("double[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("byte[]")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("short[]")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("float[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("chart[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("character[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("integer[]") ||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("java.util.")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("java.nio.")||
ctVariable.getReference().getType().getQualifiedName().toString().toLowerCase().endsWith("java.io.")) {
isPrimitive = true;
}
}
if(isPrimitive)
isObject=false;
else isObject=true;
writeGroupedInfo(context, adjustIdentifyInJson(aVariableAccess),
CodeFeatures.V8_VAR_PRIMITIVE, isPrimitive, "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(aVariableAccess),
CodeFeatures.V8_VAR_OBJECT, isObject, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void analyzeV9_VarSimilarLiteral(CtElement element, Cntx context, CtClass parentClass,
List varsAffected) {
try {
List allliteralsFromClass = new ArrayList();
if(parentClass!=null)
allliteralsFromClass = parentClass.getElements(e -> (e instanceof CtLiteral)).stream()
.map(CtLiteral.class::cast).collect(Collectors.toList());
for (CtVariableAccess varAffected : varsAffected) {
boolean currentVarhasSimilarLiteral = false;
for (CtLiteral literalinclass : allliteralsFromClass) {
String[] anotherLiteralTypeAndValue=getLiteralTypeAndValue(literalinclass);
if(compareVarAccessAndLiteralType(anotherLiteralTypeAndValue[0], varAffected)) {
currentVarhasSimilarLiteral=true;
break;
}
}
writeGroupedInfo(context, adjustIdentifyInJson(varAffected), CodeFeatures.V9_VAR_TYPE_Similar_Literal,
currentVarhasSimilarLiteral, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
public boolean compareVarAccessAndLiteralType(String literaltype, CtVariableAccess varaccess) {
Boolean typecompatiable=false;
if(varaccess.getType()!=null) {
if(varaccess.getType().toString().toLowerCase().endsWith("string")) {
if(literaltype.equals("string"))
typecompatiable=true;
}
else {
if(varaccess.getType().isPrimitive()) {
if(varaccess.getType().toString().toLowerCase().endsWith("char")) {
if(literaltype.equals("char"))
typecompatiable=true;
}
else if(varaccess.getType().toString().toLowerCase().endsWith("boolean")) {
if(literaltype.equals("boolean"))
typecompatiable=true;
}
else {
if(literaltype.equals("numerical"))
typecompatiable=true;
}
}
}
}
return typecompatiable;
}
private void analyzV10_AffectedWithCompatibleTypes(List varsAffected, List varsInScope,
CtElement element, Cntx context) {
try {
for (CtVariableAccess aVariableAccessInStatement : varsAffected) {
boolean currentHasSimType = false;
for (CtVariable aVariableInScope : varsInScope) {
if (!aVariableInScope.getSimpleName().equals(aVariableAccessInStatement.getVariable().getSimpleName())) {
if (compareTypes(aVariableInScope.getType(), aVariableAccessInStatement.getType())) {
currentHasSimType=true;
break;
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(aVariableAccessInStatement),
CodeFeatures.V10_VAR_TYPE_Similar_VAR, currentHasSimType, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void analyzV11_ConditionWithCompatibleTypes (List varsAffected, List varsInScope,
CtElement element, Cntx context) {
try {
for (CtVariableAccess aVariableAccessInStatement : varsAffected) {
boolean currentHasSimType = false;
CtStatement parent = aVariableAccessInStatement.getParent(new LineFilter());
CtElement parentCondition = getPotentionalParentCondition(parent);
CtElement expression = retrieveExpressionToStudy(parentCondition);
List varsInExpression =new ArrayList<>();
if(expression!=null)
varsInExpression = VariableResolver.collectVariableAccess(expression, false);
List localsVariable = new ArrayList<>();
CtScanner scanner = new CtScanner() {
@Override
public void visitCtLocalVariable(CtLocalVariable localVariable) {
localsVariable.add(localVariable);
}
};
scanner.scan(expression);
for (CtVariableAccess aVariableInScope : varsInExpression) {
if (!aVariableInScope.getVariable().getSimpleName().equals(aVariableAccessInStatement.getVariable().getSimpleName())) {
if (compareTypes(aVariableInScope.getType(), aVariableAccessInStatement.getType())) {
currentHasSimType=true;
break;
}
}
}
if(!currentHasSimType) {
for (CtLocalVariable aVariableInScope : localsVariable) {
if (!aVariableInScope.getReference().getSimpleName().equals(aVariableAccessInStatement.getVariable().getSimpleName())) {
if (compareTypes(aVariableInScope.getType(), aVariableAccessInStatement.getType())) {
currentHasSimType=true;
break;
}
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(aVariableAccessInStatement),
CodeFeatures.V11_VAR_COMPATIBLE_TYPE_IN_CONDITION, currentHasSimType, "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private CtElement getPotentionalParentCondition (CtStatement toStudy) {
CtElement parent;
parent=toStudy;
do {
parent= parent.getParent();
} while (!whetherConditionalStat(parent) && parent!=null);
return parent;
}
private boolean whetherConditionalStat(CtElement input) {
if(input instanceof CtIf || input instanceof CtWhile || input instanceof CtFor || input
instanceof CtForEach)
return true;
else return false;
}
public CtElement retrieveExpressionToStudy(CtElement element) {
if (element instanceof CtIf) {
return (((CtIf) element).getCondition());
} else if (element instanceof CtWhile) {
return (((CtWhile) element).getLoopingExpression());
} else if (element instanceof CtFor) {
return (((CtFor) element).getExpression());
} else if (element instanceof CtForEach) {
return (((CtForEach) element).getExpression());
} else
return (element);
}
private void analyzeV1213_ReplaceVarGetAnotherInvocation (List varsAffected, Cntx context,
List invocationsFromClass, List constructorcallsFromClass) {
try {
for (CtVariableAccess varAffected : varsAffected) {
CtInvocation parentInvocation = varAffected.getParent(CtInvocation.class);
boolean v12ReplacewithVarCurrent = false;
boolean v13ReplacewithInvocationCurrent = false;
if (parentInvocation != null) {
List arguments = parentInvocation.getArguments();
for (CtInvocation specificinvocation : invocationsFromClass) {
if(parentInvocation.equals(specificinvocation))
continue;
List specificarguments = specificinvocation.getArguments();
if(parentInvocation.getExecutable().getSimpleName().equals
(specificinvocation.getExecutable().getSimpleName()) &&
arguments.size() == specificarguments.size()) {
int[] comparisionresult= argumentDiff(arguments, specificarguments, varAffected);
if(comparisionresult[0]==1 && comparisionresult[1]==1)
v12ReplacewithVarCurrent =true;
if(comparisionresult[0]==1 && comparisionresult[2]==1)
v13ReplacewithInvocationCurrent =true;
}
if(v12ReplacewithVarCurrent && v13ReplacewithInvocationCurrent)
break;
}
}
if(!v12ReplacewithVarCurrent || !v13ReplacewithInvocationCurrent) {
CtConstructorCall parentConstructorCall = varAffected.getParent(CtConstructorCall.class);
if (parentConstructorCall != null) {
List arguments = parentConstructorCall.getArguments();
for (CtConstructorCall specificonstructorcall : constructorcallsFromClass) {
if(parentConstructorCall.equals(specificonstructorcall))
continue;
List specificarguments = specificonstructorcall.getArguments();
if(getSimplenameForConstructorCall(parentConstructorCall).equals
(getSimplenameForConstructorCall(specificonstructorcall)) &&
arguments.size() == specificarguments.size()) {
int[] comparisionresult= argumentDiff(arguments, specificarguments, varAffected);
if(comparisionresult[0]==1 && comparisionresult[1]==1)
v12ReplacewithVarCurrent =true;
if(comparisionresult[0]==1 && comparisionresult[2]==1)
v13ReplacewithInvocationCurrent =true;
}
if(v12ReplacewithVarCurrent && v13ReplacewithInvocationCurrent)
break;
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(varAffected),
CodeFeatures.V12_VAR_Invocation_VAR_REPLACE_BY_VAR,
(v12ReplacewithVarCurrent), "FEATURES_VARS");
writeGroupedInfo(context, adjustIdentifyInJson(varAffected),
CodeFeatures.V13_VAR_Invocation_VAR_REPLACE_BY_INVOCATION,
(v13ReplacewithInvocationCurrent), "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private int[] argumentDiff(List argumentsoriginal, List argumentsother, CtVariableAccess varaccess) {
int numberdiffargument =0;
int numberdiffvarreplacebyvar =0;
int numberdiffvarreplacebymethod =0;
for(int index=0; index varsAffected, Cntx context,
CtClass parentClass) {
try {
for (CtVariableAccess varAffected : varsAffected) {
boolean v14VarInstanceOfClass= false;
if(varAffected.getType()!=null) {
if(varAffected.getType().toString().equals(parentClass.getQualifiedName()) ||
varAffected.getType().toString().endsWith(parentClass.getQualifiedName()) ||
parentClass.getQualifiedName().endsWith(varAffected.getType().toString()))
v14VarInstanceOfClass=true;
}
writeGroupedInfo(context, adjustIdentifyInJson(varAffected),
CodeFeatures.V14_VAR_INSTANCE_OF_CLASS,
(v14VarInstanceOfClass), "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void analyzeV15_LastthreeVariableIntroduction (List varsAffected, CtElement element,
Cntx context) {
try {
CtExecutable methodParent = element.getParent(CtExecutable.class);
if (methodParent == null)
// the element is not in a method.
return;
List statements=methodParent.getElements(new LineFilter());
// For each variable affected
for (CtVariableAccess variableAffected : varsAffected) {
List statementbefore = new ArrayList<>();
boolean lastthreesametypeloc=false;
for (CtStatement aStatement : statements) {
CtStatement parent = variableAffected.getParent(new LineFilter());
if (!isElementBeforeVariable(variableAffected, aStatement))
continue;
if (isStatementInControl(parent, aStatement) || parent==aStatement)
continue;
if(aStatement instanceof CtIf || aStatement instanceof CtLoop)
continue;
statementbefore.add(aStatement);
}
List statinterest = new ArrayList<>();
if(statementbefore.size()<=4)
statinterest=statementbefore;
else {
statinterest.add(statementbefore.get(statementbefore.size()-1));
statinterest.add(statementbefore.get(statementbefore.size()-2));
statinterest.add(statementbefore.get(statementbefore.size()-3));
statinterest.add(statementbefore.get(statementbefore.size()-4));
}
for (int index=0; index< statinterest.size(); index++) {
if(statinterest.get(index) instanceof CtLocalVariable) {
CtLocalVariable ctLocalVariable=(CtLocalVariable)statinterest.get(index);
if (!ctLocalVariable.getReference().getSimpleName()
.equals(variableAffected.getVariable().getSimpleName())
&& compareTypes(ctLocalVariable.getType(), variableAffected.getType())) {
lastthreesametypeloc = true;
break;
}
}
}
writeGroupedInfo(context, adjustIdentifyInJson(variableAffected),
CodeFeatures.V15_VAR_LAST_THREE_SAME_TYPE_LOC,
(lastthreesametypeloc), "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void analyzeV17_IsEnum (List varsAffected, Cntx context, CtClass parentClass) {
try {
if (parentClass == null)
return;
// Get all enums
List enums = parentClass.getElements(new TypeFilter<>(CtEnum.class));
// For each var access
for (CtVariableAccess varAccess : varsAffected) {
boolean isVarAccessTypeEnum = false;
if (varAccess.getVariable().getType() != null
&& enums.contains(varAccess.getVariable().getType().getDeclaration())) {
isVarAccessTypeEnum = true;
}
writeGroupedInfo(context, adjustIdentifyInJson(varAccess),
CodeFeatures.V17_VAR_IS_ENUMERATION,
(isVarAccessTypeEnum), "FEATURES_VARS");
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}