Skip to content

Instantly share code, notes, and snippets.

@libetl
Created October 20, 2016 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save libetl/9f2446ecba633bb87f7e0f6829d23a0b to your computer and use it in GitHub Desktop.
Save libetl/9f2446ecba633bb87f7e0f6829d23a0b to your computer and use it in GitHub Desktop.
IsItAltered.java
package org.toilelibre.libe.divedeepanalyzer;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import spoon.Launcher;
import spoon.SpoonAPI;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtParameterReference;
import spoon.reflect.visitor.Filter;
import spoon.reflect.visitor.filter.TypeFilter;
public class IsItAltered {
public static void main (final String [] args) {
System.out.println (IsItAltered.isItAltered ("/home/lionel/Documents/workspace/a/src/", "findlowest.FindByStrategies.findAnExpressionFor", "n"));
}
static class FullNameFilter implements Filter<CtMethod<?>> {
private final String name;
public FullNameFilter (final String name) {
if (name == null) {
throw new IllegalArgumentException ();
}
this.name = name;
}
@Override
public boolean matches (final CtMethod<?> element) {
try {
final String candidateName = element.getDeclaringType ().getQualifiedName () + "." + element.getSimpleName ();
return this.name.equals (candidateName);
} catch (final UnsupportedOperationException e) {
return false;
}
}
@SuppressWarnings ("rawtypes")
public Class<CtMethod> getType () {
return CtMethod.class;
}
}
private static boolean isItAltered (final String srcDir, final String fullMethodName, final String arg) {
final SpoonAPI spoon = new Launcher ();
final File rootDir = new File (srcDir);
IsItAltered.addRecursively (spoon, rootDir);
spoon.run ();
final CtMethod<?> ctMethod = spoon.getModel ().getElements (new FullNameFilter (fullMethodName)).get (0);
CtParameter<?> ctParameter = null;
for (final CtParameter<?> candidateParam : ctMethod.getParameters ()) {
if (candidateParam.getSimpleName ().equals (arg)) {
ctParameter = candidateParam;
}
}
return IsItAltered.isItAltered (ctMethod, Collections.<CtParameter<?>>singletonList (ctParameter), new HashSet<CtExecutable<?>> ());
}
private static boolean isItAltered (final CtExecutable<?> ctExecutable, List<CtParameter<?>> ctParameters, final Set<CtExecutable<?>> alreadySeen) {
if (alreadySeen.contains (ctExecutable)) {
return false;
}
alreadySeen.add (ctExecutable);
final List<CtInvocation<?>> invocations = ctExecutable.getElements (new TypeFilter<CtInvocation<?>> (CtInvocation.class));
boolean result = false;
for (final CtInvocation<?> invocation : invocations) {
if (ctParameters.contains (invocation.getTarget ()) && invocation.getExecutable ().getActualMethod ().getName ().startsWith ("get") && (invocation.getExecutable ().getActualMethod ().getParameterTypes ().length == 0)) {
ctParameters = new ArrayList<> (ctParameters);
ctParameters.add ((CtParameter<?>) invocation.getTarget ());
} else if ((invocation.getTarget () instanceof CtVariableAccess) && (((CtVariableAccess<?>) invocation.getTarget ()).getVariable () instanceof CtParameterReference) && ctParameters.contains (((CtParameterReference<?>) ((CtVariableAccess<?>) invocation.getTarget ()).getVariable ()).getDeclaration ())
&& invocation.getExecutable ().getActualMethod ().getName ().startsWith ("set") && (invocation.getExecutable ().getActualMethod ().getParameterTypes ().length == 1)) {
result = true;
} else if ((invocation.getTarget () instanceof CtVariableAccess) && (((CtVariableAccess<?>) invocation.getTarget ()).getVariable () instanceof CtParameterReference) && ctParameters.contains (((CtParameterReference<?>) ((CtVariableAccess<?>) invocation.getTarget ()).getVariable ()).getDeclaration ())
&& invocation.getExecutable ().getActualMethod ().getName ().equals ("add") && (invocation.getExecutable ().getActualMethod ().getParameterTypes ().length == 1)) {
result = true;
} else if ((invocation.getTarget () instanceof CtVariableAccess) && (((CtVariableAccess<?>) invocation.getTarget ()).getVariable () instanceof CtParameterReference) && ctParameters.contains (((CtParameterReference<?>) ((CtVariableAccess<?>) invocation.getTarget ()).getVariable ()).getDeclaration ())
&& invocation.getExecutable ().getActualMethod ().getName ().equals ("put") && (invocation.getExecutable ().getActualMethod ().getParameterTypes ().length == 1)) {
result = true;
} else {
result |= IsItAltered.isItAltered (((CtExecutableReference<?>) invocation.getExecutable ()).getExecutableDeclaration (), ctParameters, alreadySeen);
}
}
return result;
}
private static void addRecursively (final SpoonAPI spoon, final File dir) {
if (dir.listFiles () == null) {
return;
}
for (final File file : dir.listFiles ()) {
if (file.isDirectory () && !file.equals (dir) && !file.equals (dir.getParentFile ())) {
IsItAltered.addRecursively (spoon, file);
}
if (file.isFile () && file.getName ().endsWith (".java")) {
spoon.addInputResource (file.getAbsolutePath ());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment