Java : parse java source code, extract methods

I wish to parse java source code files, and extract the methods source code.

I would need a method like this :

/** Returns a map with key = method name ; value = method source code */ Map<String,String> getMethods(File javaFile); 

Is there a simple way to achieve this, a library to help me build my method, etc. ?

2

2 Answers

Download the java parser from

You'll have to write some code. This code will invoke the parser... it will return you a CompilationUnit:

 InputStream in = null; CompilationUnit cu = null; try { in = new SEDInputStream(filename); cu = JavaParser.parse(in); } catch(ParseException x) { // handle parse exceptions here. } finally { in.close(); } return cu; 

Note: SEDInputStream is a subclass of input stream. You can use a FileInputStream if you want.


You'll have to create a visitor. Your visitor will be easy because you're only interested in methods:

 public class MethodVisitor extends VoidVisitorAdapter { public void visit(MethodDeclaration n, Object arg) { // extract method information here. // put in to hashmap } } 

To invoke the visitor, do this:

 MethodVisitor visitor = new MethodVisitor(); visitor.visit(cu, null); 
10

I implemented lee's suggestion, there is no need of third party libraries to achieve that, the following example prints the names of the methods (tested with Java 17 but should work with Java 1.6 with minor changes):

import com.sun.source.util.JavacTask; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class Main { public static void main(final String[] args) throws Exception { final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); try (final StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, StandardCharsets.UTF_8)) { final Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(new File(args[0]))); final JavacTask javacTask = (JavacTask) compiler.getTask(null, fileManager, null, null, null, compilationUnits); final Iterable<? extends CompilationUnitTree> compilationUnitTrees = javacTask.parse(); final ClassTree classTree = (ClassTree) compilationUnitTrees.iterator().next().getTypeDecls().get(0); final List<? extends Tree> classMemberList = classTree.getMembers(); final List<MethodTree> classMethodMemberList = classMemberList.stream() .filter(MethodTree.class::isInstance) .map(MethodTree.class::cast) .collect(Collectors.toList()); // just prints the names of the methods classMethodMemberList.stream().map(MethodTree::getName) .forEachOrdered(System.out::println); } } } 

Note that other solutions except ANTLR don't support very latest versions of Java, javaparser doesn't fully support 19 currently (January 2023), JavaCC doesn't seem to support Java >= 9 according to its public documentation.

Federico Tomassetti wrote in 2016 that there was no parsing functionality as part of the JDK, I replied that he was wrong. I have nothing against third party libraries but providing false information to developers in order to promote her/his stuff is not honest and is not the kind of behavior I expect on StackOverflow. I use some classes and APIs available in Java since Java 1.6 released in December 2006.

4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like