Created
October 20, 2016 21:15
-
-
Save libetl/9f2446ecba633bb87f7e0f6829d23a0b to your computer and use it in GitHub Desktop.
IsItAltered.java
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
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