/**  
 * 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;  
        }  
    }  
  
}