Eclipse的JDT编译器提供了一个接口INameEnvironment,它定义了方法findType(…),使您能够进行级联编译.好奇地,我想知道是否有办法使用标准的JDK编译器工具包?
请注意,该方案是一个模板引擎,用于内存编译,用于具有相互依赖关系的模板文件生成的类,并且它不能预测您遇到的模板文件的顺序,因此Foo可能需要先编译,然后才能编译它的父栏因此,您需要一个机制来执行级联编译,这意味着在编译Foo期间,您需要生成另一个源代码栏并首先编译它以继续Foo的编译:一些代码如下所示:
private NameEnvironmentAnswer findType(final String name) { try { if (!name.contains(TemplateClass.CN_SUFFIX)) { return findStandType(name); } char[] fileName = name.tocharArray(); TemplateClass templateClass = classCache.getByClassName(name); // TemplateClass exists if (templateClass != null) { if (templateClass.javaByteCode != null) { ClassFileReader classFileReader = new ClassFileReader(templateClass.javaByteCode,fileName,true); return new NameEnvironmentAnswer(classFileReader,null); } // Cascade compilation ICompilationUnit compilationUnit = new CompilationUnit(name); return new NameEnvironmentAnswer(compilationUnit,null); } // So it's a standard class return findStandType(name); } catch (ClassFormatException e) { // Something very very bad throw new RuntimeException(e); } }
解决方法
基于我们的评论对话,我认为答案是清楚的:不,你不能用JDK编译器来做.当它请求包时,它会给你一个钩子,而不是特定的类依赖.
关于尽可能靠近,我知道的是:
Here’s a nice article与代码,虽然它需要适应处理内存类.具体来说,您所描述的问题由JavaFileManager.list(…)方法处理.您必须在这里返回您已在内存中缓存的JavaFileObjects.您很可能需要创建一个ForwardingJavaFileManager的子类,如本文所述 – 尽管通过修改来处理您正在使用的缓存类.
你可以用它来编写一些东西.如果它返回错误,请使用正则表达式来查找丢失的内容.在为缺少的东西生成/编译代码之后,重试编译原始代码.
注意:它在某些时候要求依赖类的FQN作为ForwardingFileManager.list(…)中的packageName参数.那时我没有试图返回班级.它可能不起作用,因为包将不匹配,但也许会这样.