-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cross-validation + training for feature envy
- Loading branch information
1 parent
ba5a222
commit 218be1b
Showing
243 changed files
with
43,860 additions
and
1,415 deletions.
There are no files selected for viewing
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
File renamed without changes.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.HashSet; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
import org.apache.commons.io.FileUtils; | ||
import org.apache.commons.io.FilenameUtils; | ||
import org.eclipse.jdt.core.JavaCore; | ||
import org.eclipse.jdt.core.dom.AST; | ||
import org.eclipse.jdt.core.dom.ASTParser; | ||
import org.eclipse.jdt.core.dom.CompilationUnit; | ||
|
||
public class ASTReader { | ||
private List<String> types = new ArrayList<String>(); | ||
private Set<String> staticEntities = new HashSet<String>(); | ||
private Map<String, String> accessorToAccessedFieldMap = new LinkedHashMap<String,String>(); | ||
private Map<String, Set<String>> classToEntitySetMap = new LinkedHashMap<String,Set<String>>(); | ||
private Map<String, Set<String>> methodToEntitySetMap = new LinkedHashMap<String,Set<String>>(); | ||
private Map<String, Set<String>> methodToTargetClassSetMap = new LinkedHashMap<String,Set<String>>(); | ||
|
||
public ASTReader(String[] sourcePaths) { | ||
int nbProcessedFiles = 0; | ||
for (int i=0;i<sourcePaths.length;i++) { | ||
Collection<File> filesInDirectory = FileUtils.listFiles(new File(sourcePaths[i]), new String[]{"java"}, true); | ||
for (File file : filesInDirectory) { | ||
String fileName = FilenameUtils.normalize(file.getAbsolutePath(), true).substring(sourcePaths[i].length()); | ||
try { | ||
parseAST(file, fileName, sourcePaths); | ||
} | ||
catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
nbProcessedFiles++; | ||
if ((nbProcessedFiles % 500) == 0) { | ||
System.out.println(nbProcessedFiles + " files have been processed."); | ||
} | ||
} | ||
} | ||
|
||
replaceAccessorsByAccessedFields(methodToEntitySetMap); | ||
|
||
removeSystemMemberAccesses(classToEntitySetMap); | ||
removeSystemMemberAccesses(methodToEntitySetMap); | ||
|
||
removeStaticEntities(methodToEntitySetMap); | ||
} | ||
|
||
private void parseAST(File file, String fileName, String[] sourcePaths) throws IOException { | ||
String fileString = FileUtils.readFileToString(file, "UTF-8"); | ||
|
||
ASTParser parser = ASTParser.newParser(AST.JLS8); | ||
parser.setKind(ASTParser.K_COMPILATION_UNIT); | ||
parser.setResolveBindings(true); | ||
parser.setBindingsRecovery(true); | ||
parser.setCompilerOptions(JavaCore.getOptions()); | ||
parser.setUnitName(fileName); | ||
|
||
parser.setEnvironment(null, sourcePaths, null, true); | ||
parser.setSource(fileString.toCharArray()); | ||
|
||
CompilationUnit cu = (CompilationUnit) parser.createAST(null); | ||
|
||
FileVisitor visitor = new FileVisitor(); | ||
cu.accept(visitor); | ||
|
||
types.addAll(visitor.getTypes()); | ||
staticEntities.addAll(visitor.getStaticEntities()); | ||
accessorToAccessedFieldMap.putAll(visitor.getaccessorToAccessedFieldMap()); | ||
classToEntitySetMap.putAll(visitor.getClassToEntitySetMap()); | ||
methodToEntitySetMap.putAll(visitor.getMethodToEntitySetMap()); | ||
methodToTargetClassSetMap.putAll(visitor.getMethodToTargetClassSetMap()); | ||
} | ||
|
||
public Map<String, Set<String>> getClassToEntitySetMap() { | ||
return this.classToEntitySetMap; | ||
} | ||
|
||
public Map<String, Set<String>> getMethodToEntitySetMap() { | ||
return this.methodToEntitySetMap; | ||
} | ||
|
||
public Map<String, Set<String>> getMethodToTargetClassSetMap() { | ||
return this.methodToTargetClassSetMap; | ||
} | ||
|
||
private void replaceAccessorsByAccessedFields(Map<String, Set<String>> map) { | ||
for(Map.Entry<String, Set<String>> entry : map.entrySet()) { | ||
List<String> entitiesToRemove = new ArrayList<String>(); | ||
List<String> entitiesToAdd = new ArrayList<String>(); | ||
for(String entity :entry.getValue()) { | ||
if (accessorToAccessedFieldMap.containsKey(entity)) { | ||
entitiesToRemove.add(entity); | ||
entitiesToAdd.add(accessorToAccessedFieldMap.get(entity)); | ||
} | ||
} | ||
map.get(entry.getKey()).removeAll(entitiesToRemove); | ||
map.get(entry.getKey()).addAll(entitiesToAdd); | ||
} | ||
} | ||
|
||
private void removeSystemMemberAccesses(Map<String, Set<String>> map) { | ||
Pattern p = Pattern.compile(".+:(.+)"); | ||
|
||
for(Map.Entry<String, Set<String>> entry : map.entrySet()) { | ||
List<String> entitiesToRemove = new ArrayList<String>(); | ||
for(String entity :entry.getValue()) { | ||
Matcher m = p.matcher(entity); | ||
if (m.matches()) | ||
if(types.contains(m.group(1))) | ||
entitiesToRemove.add(entity); | ||
} | ||
map.get(entry.getKey()).removeAll(entitiesToRemove); | ||
} | ||
} | ||
|
||
private void removeStaticEntities(Map<String, Set<String>> map) { | ||
for(Map.Entry<String, Set<String>> entry : map.entrySet()) { | ||
List<String> entitiesToRemove = new ArrayList<String>(); | ||
for(String entity :entry.getValue()) { | ||
if (staticEntities.contains(entity)) | ||
entitiesToRemove.add(entity); | ||
} | ||
map.get(entry.getKey()).removeAll(entitiesToRemove); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import org.eclipse.jdt.core.dom.ASTNode; | ||
import org.eclipse.jdt.core.dom.ASTVisitor; | ||
import org.eclipse.jdt.core.dom.Assignment; | ||
import org.eclipse.jdt.core.dom.ExpressionStatement; | ||
import org.eclipse.jdt.core.dom.FieldAccess; | ||
import org.eclipse.jdt.core.dom.FieldDeclaration; | ||
import org.eclipse.jdt.core.dom.ITypeBinding; | ||
import org.eclipse.jdt.core.dom.IVariableBinding; | ||
import org.eclipse.jdt.core.dom.MethodDeclaration; | ||
import org.eclipse.jdt.core.dom.ReturnStatement; | ||
import org.eclipse.jdt.core.dom.SimpleName; | ||
import org.eclipse.jdt.core.dom.SingleVariableDeclaration; | ||
import org.eclipse.jdt.core.dom.VariableDeclarationFragment; | ||
|
||
|
||
public class ClassVisitor extends ASTVisitor { | ||
private Set<String> staticEntities = new HashSet<String>(); | ||
private Set<String> entitySet = new HashSet<String>(); | ||
private Map<String, String> accessorToAccessedFieldMap = new LinkedHashMap<String,String>(); | ||
private Map<String,Set<String>> methodToEntitySetMap = new LinkedHashMap<String,Set<String>>(); | ||
private Map<String,Set<String>> methodToTargetClassSetMap = new LinkedHashMap<String,Set<String>>(); | ||
private String className; | ||
|
||
public ClassVisitor(String className) { | ||
this.className = className; | ||
} | ||
|
||
public Set<String> getStaticEntities() { | ||
return this.staticEntities; | ||
} | ||
|
||
public Set<String> getEntitySet() { | ||
return this.entitySet; | ||
} | ||
|
||
public Map<String,Set<String>> getMethodToEntitySetMap() { | ||
return this.methodToEntitySetMap; | ||
} | ||
|
||
public Map<String,Set<String>> getMethodToTargetClassSetMap() { | ||
return this.methodToTargetClassSetMap; | ||
} | ||
|
||
public Map<String, String> getaccessorToAccessedFieldMap() { | ||
return this.accessorToAccessedFieldMap; | ||
} | ||
|
||
@Override | ||
public boolean visit(FieldDeclaration node) { | ||
ITypeBinding bind = node.getType().resolveBinding(); | ||
if (bind == null) { | ||
return true; | ||
} | ||
|
||
Set<String> attributes = new HashSet<String>(); | ||
String type = bind.getQualifiedName(); | ||
for (VariableDeclarationFragment vdf : (List<VariableDeclarationFragment>) node.fragments()) { | ||
String attributeName = className + '.' + vdf.getName().getIdentifier() + ':' + type; | ||
|
||
attributes.add(attributeName); | ||
} | ||
|
||
for (Object modifier : node.modifiers()) { | ||
if(modifier.toString().equals("static")) { | ||
staticEntities.addAll(attributes); | ||
return true; | ||
} | ||
} | ||
|
||
entitySet.addAll(attributes); | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean visit(MethodDeclaration node) { | ||
if (node.isConstructor() || node.getBody() == null) { | ||
return true; | ||
} | ||
|
||
// Construct the method's name. | ||
List<String> params = new ArrayList<>(); | ||
for (SingleVariableDeclaration var : (List<SingleVariableDeclaration>) node.parameters()) { | ||
IVariableBinding varBind = var.resolveBinding(); | ||
if (varBind == null) { | ||
params.add(var.toString().split("\\s+")[0]); | ||
}else { | ||
params.add(varBind.getType().getQualifiedName()); | ||
} | ||
} | ||
Collections.sort(params, String.CASE_INSENSITIVE_ORDER); | ||
|
||
StringBuffer buffer = new StringBuffer(); | ||
buffer.append(node.getName().getIdentifier()); | ||
buffer.append("("); | ||
buffer.append(String.join(", ", params)); | ||
buffer.append(")"); | ||
|
||
String methodName = className + '.' + buffer.toString(); | ||
|
||
for (Object modifier : node.modifiers()) { | ||
if(modifier.toString().equals("static")) { | ||
staticEntities.add(methodName); | ||
return true; | ||
} | ||
} | ||
|
||
|
||
// Visit the body of the method. | ||
MethodVisitor visitor = new MethodVisitor(); | ||
node.getBody().accept(visitor); | ||
|
||
|
||
// Check if the method is an accessor | ||
if (isSetter(visitor) != null && params.size() == 1) { | ||
accessorToAccessedFieldMap.put(methodName, isSetter(visitor)); | ||
return true; | ||
} | ||
|
||
if (isGetter(visitor) != null && params.size() == 0) { | ||
accessorToAccessedFieldMap.put(methodName, isGetter(visitor)); | ||
return true; | ||
} | ||
|
||
|
||
entitySet.add(methodName); | ||
methodToEntitySetMap.put(methodName, visitor.getEntitySet()); | ||
methodToTargetClassSetMap.put(methodName, visitor.getTargetClassSet()); | ||
|
||
return true; | ||
} | ||
|
||
public String isGetter(MethodVisitor visitor) { | ||
List<ASTNode> abstractStatements = visitor.getAbstractSatements(); | ||
if(abstractStatements.size() == 1) { | ||
ASTNode node = abstractStatements.get(0); | ||
if(node instanceof ReturnStatement) { | ||
ReturnStatement returnStatement = (ReturnStatement) node; | ||
if((returnStatement.getExpression() instanceof SimpleName || returnStatement.getExpression() instanceof FieldAccess) && visitor.getFieldInstructions().size() == 1 && visitor.getMethodInvocations().size() == 0 && | ||
visitor.getLocalVariableDeclarations().size() == 0 && visitor.getLocalVariableInstructions().size() == 0) { | ||
return visitor.getFieldInstructions().iterator().next(); | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public String isSetter(MethodVisitor visitor) { | ||
List<ASTNode> abstractStatements = visitor.getAbstractSatements(); | ||
if(abstractStatements.size() == 1) { | ||
ASTNode node = abstractStatements.get(0); | ||
if(node instanceof ExpressionStatement) { | ||
ExpressionStatement expressionStatement = (ExpressionStatement)node; | ||
if(expressionStatement.getExpression() instanceof Assignment && visitor.getFieldInstructions().size() == 1 && visitor.getMethodInvocations().size() == 0 && | ||
visitor.getLocalVariableDeclarations().size() == 0 && visitor.getLocalVariableInstructions().size() == 1) { | ||
Assignment assignment = (Assignment)expressionStatement.getExpression(); | ||
if((assignment.getLeftHandSide() instanceof SimpleName || assignment.getLeftHandSide() instanceof FieldAccess) && assignment.getRightHandSide() instanceof SimpleName) | ||
return visitor.getFieldInstructions().iterator().next(); | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
} |
Oops, something went wrong.