Created
June 9, 2016 17:20
-
-
Save edwardmp/aa11989194a85cdb0dd9febe91ecda1f to your computer and use it in GitHub Desktop.
Example Eclipse JDT AST visitation
This file contains hidden or 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 eu.sig.aevas; | |
import eu.sig.aevas.dependencymanager.maven.MavenDependency; | |
import org.apache.commons.io.FileUtils; | |
import org.apache.commons.lang3.StringUtils; | |
import org.apache.log4j.Logger; | |
import org.eclipse.jdt.core.JavaCore; | |
import org.eclipse.jdt.core.dom.*; | |
import java.io.File; | |
import java.util.*; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
/** | |
* Created by Edward Poot on 02/06/16. | |
*/ | |
public class InvokedLibraryMethods { | |
private static final Logger log = Logger.getLogger(InvokedLibraryMethods.class); | |
private Set<String> allDependencyPackageNames = new HashSet<>(); | |
private Set<String> invokedMethods = new HashSet<>(); | |
private String[] dependencyJarPaths; | |
protected Set<String> obtainMethods(String systemPath, Set<MavenDependency> mavenDependencies) { | |
dependencyJarPaths = mavenDependencies.stream().map(dependency -> dependency.pathToJar()).toArray(String[]::new); | |
mavenDependencies.stream().forEach(mavenDependency -> allDependencyPackageNames.addAll(mavenDependency.getPackageNames())); | |
parseSourceCode(systemPath); | |
return invokedMethods; | |
} | |
protected void parseSourceCode(String systemPath) { | |
File srcDir = new File(systemPath); | |
String[] sourceFiles = FileUtils.listFiles(srcDir, new String[]{"java"}, true).stream().map(srcFile -> srcFile.getAbsolutePath()).toArray(String[]::new); | |
final ASTParser parser = ASTParser.newParser(AST.JLS8); | |
parser.setResolveBindings(true); | |
//parser.setBindingsRecovery(true); | |
parser.setKind(ASTParser.K_COMPILATION_UNIT); | |
parser.setEnvironment(dependencyJarPaths, null, null, false); | |
Map options = JavaCore.getOptions(); | |
options.put(JavaCore.COMPILER_SOURCE, "1.8"); | |
parser.setCompilerOptions(options); | |
parser.createASTs(sourceFiles, null, new String[0], new FileRequestor(), null); | |
log.info(String.format("Found %d directly invoked library methods", invokedMethods.size())); | |
} | |
class FileRequestor extends FileASTRequestor { | |
@Override | |
public void acceptAST(String source, CompilationUnit ast) { | |
ast.accept(new TypeFinderVisitor()); | |
} | |
} | |
class TypeFinderVisitor extends ASTVisitor { | |
protected boolean isAnyNeededElementNull(MethodInvocation node) { | |
IMethodBinding binding = node.resolveMethodBinding(); | |
if (binding == null) { | |
return true; | |
} | |
Expression expression = node.getExpression(); | |
if (expression == null) { | |
return true; | |
} | |
ITypeBinding typeBinding = expression.resolveTypeBinding(); | |
if (typeBinding == null) { | |
return true; | |
} | |
if (typeBinding.getPackage() == null) { | |
return true; | |
} | |
return false; | |
} | |
@Override | |
public boolean visit(MethodInvocation node) { | |
if (isAnyNeededElementNull(node)) { | |
return false; | |
} | |
IMethodBinding binding = node.resolveMethodBinding(); | |
Expression expression = node.getExpression(); | |
ITypeBinding typeBinding = expression.resolveTypeBinding(); | |
String methodName = String.format("%s:%s", typeBinding.getQualifiedName(), node.getName().getIdentifier()); | |
String packageName = typeBinding.getPackage().getName(); | |
if (StringUtils.isEmpty(packageName)) { | |
return false; | |
} | |
if (allDependencyPackageNames.contains(packageName)) { | |
Stream<ITypeBinding> parameterStream = Arrays.stream(binding.getParameterTypes()); | |
List<String> parameterTypes = parameterStream.map(parameterTypeBinding -> parameterTypeBinding.getQualifiedName()).collect(Collectors.toList()); | |
parameterStream.close(); | |
String returnType = binding.getReturnType().getQualifiedName(); | |
returnType = returnType.equals("void") ? "V" : returnType; | |
String methodSignature = String.format("%s(%s)%s", methodName, StringUtils.join(parameterTypes, ", "), returnType); | |
invokedMethods.add(methodSignature); | |
log.debug(String.format("Found invoked library method %s", methodSignature)); | |
} | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment