/** * created by Harrison on 2020/09/22 **/ public static class MethodCollector { private static JavacFileManager fileManager = new JavacFileManager(new Context(), true, Charsets.UTF_8); private static JavacTool javacTool = new JavacTool(); public static Map<String, byte[]> collect(String code) { Map<String, byte[]> methods = Maps.newHashMap(); SourceVisitor visitor = new SourceVisitor(methods); JavaContentObject object = new JavaContentObject("anonymous", code); Iterable<? extends JavaFileObject> files = Lists.newArrayList(object); ** scanJavaCode(visitor, files); return visitor.getMethods(); } private static void scanJavaCode(SourceVisitor visitor, Iterable<? extends JavaFileObject> files) { JavacTask javacTask = javacTool.getTask(null, fileManager, null, null, null, files); try { Iterable<? extends CompilationUnitTree> result = javacTask.parse(); for (CompilationUnitTree tree : result) { tree.accept(visitor, null); } } catch (IOException e) { e.printStackTrace(); } } static class SourceVisitor extends TreeScanner<Void, Void> { private boolean innerClass = false; private final Map<String, byte[]> methods; public SourceVisitor(Map<String, byte[]> methods) { this.methods = methods; } @Override public Void visitClass(ClassTree node, Void unused) { //先过滤匿名类 if (innerClass) { return null; } innerClass = true; return super.visitClass(node, unused); } @Override public Void visitMethod(MethodTree node, Void unused) { String methodName = formatMethodName(node.getName().toString(), node.getParameters()); BlockTree body = node.getBody(); if (body == null) { return null; } methods.put(methodName, (body.toString().getBytes())); return super.visitMethod(node, unused); } private String formatMethodName(String name, Iterable<? extends VariableTree> params) { StringBuilder sb = new StringBuilder(); sb.append(name) .append("("); for (VariableTree param : params) { String type = param.getType().toString(); //过滤掉范型 String filterGeneric = type.replaceAll("<.*?>", StringUtils.EMPTY); sb.append(filterGeneric).append(";"); } sb.append(")"); return sb.toString(); } public Map<String, byte[]> getMethods() { return methods; } } private static class JavaContentObject extends SimpleJavaFileObject { private final String code; private JavaContentObject(String name, String code) { super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); this.code = code; } public CharSequence getCharContent(boolean ignoreEncodingErrors) { return code; } } }