@SuppressWarnings("deprecation") public boolean compile(CompilerOptions options, CompilationListener listener) { CeyloncTool compiler = new CeyloncTool(); com.redhat.ceylon.compiler.java.runtime.tools.impl.JavaCompilerImpl.CompilationListenerAdapter diagnosticListener = new com.redhat.ceylon.compiler.java.runtime.tools.impl.JavaCompilerImpl .CompilationListenerAdapter(listener); Writer writer = null; // FIXME: allow the user to capture stdout if (!options.isVerbose()) { // make the tool shut the hell up writer = new NullWriter(); } JavacFileManager fileManager = compiler.getStandardFileManager(writer, diagnosticListener, null, null); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(options.getFiles()); CeyloncTaskImpl compilerTask = compiler.getTask( null, fileManager, diagnosticListener, translateOptions(options), options.getModules(), compilationUnits); compilerTask.setTaskListener(diagnosticListener); ExitState state = compilerTask.call2(); // print any helpful info if required if (options.isVerbose() && state.abortingException != null) state.abortingException.printStackTrace(); return state.ceylonState == CeylonState.OK; }
/** * Programmatic interface for main function. * * @param args The command line parameters. */ public int compile(String[] args) { Context context = new Context(); JavacFileManager.preRegister(context); // can't create it until Log has been set up int result = compile(args, context); if (fileManager instanceof JavacFileManager) { // A fresh context was created above, so jfm must be a JavacFileManager ((JavacFileManager) fileManager).close(); } return result; }
private boolean isResource(JavaFileObject fo) { JavacFileManager dfm = (JavacFileManager) fileManager; for (File dir : dfm.getLocation(CeylonLocation.RESOURCE_PATH)) { String prefix = dir.getPath(); if (fo.getName().startsWith(prefix)) { return true; } String absPrefix = dir.getAbsolutePath(); if (fo.getName().startsWith(absPrefix)) { return true; } } return false; }
// This is a bit of a hack, but if we got passed a list of resources // without any accompaning source files we'll not be able to determine // the module to which the resource files belong. So to try to fix that // we see if a module file exists in the source folders and add it to // the list of source files private List<JavaFileObject> addModuleDescriptors( List<JavaFileObject> sourceFiles, List<JavaFileObject> resourceFiles) { List<JavaFileObject> result = sourceFiles; JavacFileManager dfm = (JavacFileManager) fileManager; for (JavaFileObject fo : resourceFiles) { String resName = JarUtils.toPlatformIndependentPath( dfm.getLocation(CeylonLocation.RESOURCE_PATH), fo.getName()); JavaFileObject moduleFile = findModuleDescriptorForFile(new File(resName)); if (moduleFile != null && !result.contains(moduleFile)) { result = result.append(moduleFile); } } return result; }
private static Context preRegister(Context context) { Bark.preRegister(context); if (context.get(JavaFileManager.class) == null) JavacFileManager.preRegister(context); return context; }
private JavaFileObject findModuleDescriptorForFile(File file) { JavacFileManager dfm = (JavacFileManager) fileManager; File dir = file.getParentFile(); while (dir != null) { try { String name = dir.getPath() + "/module"; JavaFileObject fo = dfm.getJavaFileForInput(StandardLocation.SOURCE_PATH, name, Kind.SOURCE); if (fo != null) { return fo; } } catch (IOException e) { // Ignore } dir = dir.getParentFile(); } return null; }
private Context prepareContext(Context baseContext, JCCompilationUnit compilationUnit) { Context context = new SubContext(baseContext); if (context.get(JavaFileManager.class) == null) { JavacFileManager.preRegister(context); } context.put(JCCompilationUnit.class, compilationUnit); context.put(PackageSymbol.class, compilationUnit.packge); context.put(RULE_TYPE_VARS, typeVariables()); return context; }
/** * Programmatic interface for main function. * * @param args The command line parameters. */ public int compile( String[] args, Context context, List<JavaFileObject> fileObjects, Iterable<? extends Processor> processors) { if (options == null) options = Options.instance(context); // creates a new one filenames = new ListBuffer<File>(); classnames = new ListBuffer<String>(); JavaCompiler comp = null; /* * TODO: Logic below about what is an acceptable command line * should be updated to take annotation processing semantics * into account. */ try { if (args.length == 0 && fileObjects.isEmpty()) { help(); return EXIT_CMDERR; } List<File> files; try { files = processArgs(CommandLine.parse(args)); if (files == null) { // null signals an error in options, abort return EXIT_CMDERR; } else if (files.isEmpty() && fileObjects.isEmpty() && classnames.isEmpty()) { // it is allowed to compile nothing if just asking for help or version info if (options.get("-help") != null || options.get("-X") != null || options.get("-version") != null || options.get("-fullversion") != null) return EXIT_OK; error("err.no.source.files"); return EXIT_CMDERR; } } catch (java.io.FileNotFoundException e) { Log.printLines( out, ownName + ": " + getLocalizedString("err.file.not.found", e.getMessage())); return EXIT_SYSERR; } boolean forceStdOut = options.get("stdout") != null; if (forceStdOut) { out.flush(); out = new PrintWriter(System.out, true); } context.put(Log.outKey, out); // allow System property in following line as a Mustang legacy boolean batchMode = (options.get("nonBatchMode") == null && System.getProperty("nonBatchMode") == null); if (batchMode) CacheFSInfo.preRegister(context); fileManager = context.get(JavaFileManager.class); comp = JavaCompiler.instance(context); if (comp == null) return EXIT_SYSERR; if (!files.isEmpty()) { // add filenames to fileObjects comp = JavaCompiler.instance(context); List<JavaFileObject> otherFiles = List.nil(); JavacFileManager dfm = (JavacFileManager) fileManager; for (JavaFileObject fo : dfm.getJavaFileObjectsFromFiles(files)) otherFiles = otherFiles.prepend(fo); for (JavaFileObject fo : otherFiles) fileObjects = fileObjects.prepend(fo); } comp.compile(fileObjects, classnames.toList(), processors); if (comp.errorCount() != 0) return EXIT_ERROR; } catch (IOException ex) { ioMessage(ex); return EXIT_SYSERR; } catch (OutOfMemoryError ex) { resourceMessage(ex); return EXIT_SYSERR; } catch (StackOverflowError ex) { resourceMessage(ex); return EXIT_SYSERR; } catch (FatalError ex) { feMessage(ex); return EXIT_SYSERR; } catch (AnnotationProcessingError ex) { apMessage(ex); return EXIT_SYSERR; } catch (ClientCodeException ex) { // as specified by javax.tools.JavaCompiler#getTask // and javax.tools.JavaCompiler.CompilationTask#call throw new RuntimeException(ex.getCause()); } catch (PropagatedException ex) { throw ex.getCause(); } catch (Throwable ex) { // Nasty. If we've already reported an error, compensate // for buggy compiler error recovery by swallowing thrown // exceptions. if (comp == null || comp.errorCount() == 0 || options == null || options.get("dev") != null) bugMessage(ex); return EXIT_ABNORMAL; } finally { if (comp != null) comp.close(); filenames = null; options = null; } return EXIT_OK; }
public static void main(String... args) throws IOException, URISyntaxException { if (args.length != 1) throw new IllegalStateException("Must provide class name!"); String testContent = null; List<File> sourcePath = new ArrayList<>(); for (String sourcePaths : System.getProperty("test.src.path").split(":")) { sourcePath.add(new File(sourcePaths)); } JavacFileManager fm = JavacTool.create().getStandardFileManager(null, null, null); for (File sp : sourcePath) { File inp = new File(sp, args[0]); if (inp.canRead()) { testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString(); } } if (testContent == null) throw new IllegalStateException(); final List<Diagnostic<?>> diagnostics = new ArrayList<>(); DiagnosticListener<JavaFileObject> collectDiagnostics = new DiagnosticListener<JavaFileObject>() { @Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) { diagnostics.add(diagnostic); } }; JavaFileObject testFile = new TestFO(new URI("mem://" + args[0]), testContent); JavacTask task = JavacTool.create() .getTask( null, new TestFM(fm), collectDiagnostics, STANDARD_PARAMS, null, Arrays.asList(testFile)); final Trees trees = Trees.instance(task); final CompilationUnitTree cut = task.parse().iterator().next(); task.analyze(); final List<int[]> declarationSpans = new ArrayList<>(); new TreeScanner<Void, Void>() { @Override public Void visitClass(ClassTree node, Void p) { handleDeclaration(node); return super.visitClass(node, p); } @Override public Void visitMethod(MethodTree node, Void p) { handleDeclaration(node); return super.visitMethod(node, p); } @Override public Void visitVariable(VariableTree node, Void p) { handleDeclaration(node); return super.visitVariable(node, p); } @Override public Void visitNewClass(NewClassTree node, Void p) { if (node.getClassBody() != null) { scan(node.getClassBody().getMembers(), null); } return null; } private void handleDeclaration(Tree node) { int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node); if (endPos == (-1)) { if (node.getKind() == Tree.Kind.METHOD && (((JCMethodDecl) node).getModifiers().flags & Flags.GENERATEDCONSTR) != 0) { return; } throw new IllegalStateException(); } declarationSpans.add( new int[] {(int) trees.getSourcePositions().getStartPosition(cut, node), endPos}); } }.scan(cut, null); for (final int[] declarationSpan : declarationSpans) { final String suppressWarnings = "@SuppressWarnings({\"deprecation\", \"unchecked\", \"serial\", \"divzero\"})"; final String updatedContent = testContent.substring(0, declarationSpan[0]) + suppressWarnings + testContent.substring(declarationSpan[0]); final List<Diagnostic<?>> foundErrors = new ArrayList<>(diagnostics); DiagnosticListener<JavaFileObject> verifyDiagnostics = new DiagnosticListener<JavaFileObject>() { @Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) { long adjustedPos = diagnostic.getPosition(); if (adjustedPos >= declarationSpan[0]) adjustedPos -= suppressWarnings.length(); if (declarationSpan[0] <= adjustedPos && adjustedPos <= declarationSpan[1]) { throw new IllegalStateException("unsuppressed: " + diagnostic.getMessage(null)); } boolean found = false; for (Iterator<Diagnostic<?>> it = foundErrors.iterator(); it.hasNext(); ) { Diagnostic<?> d = it.next(); if (d.getPosition() == adjustedPos && d.getCode().equals(diagnostic.getCode())) { it.remove(); found = true; break; } } if (!found) { throw new IllegalStateException( "diagnostic not originally reported: " + diagnostic.getMessage(null)); } } }; JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]), updatedContent); JavacTask testTask = JavacTool.create() .getTask( null, new TestFM(fm), verifyDiagnostics, STANDARD_PARAMS, null, Arrays.asList(updatedFile)); testTask.analyze(); for (Diagnostic<?> d : foundErrors) { if (d.getPosition() < declarationSpan[0] || declarationSpan[1] < d.getPosition()) { throw new IllegalStateException("missing: " + d.getMessage(null)); } } } }
/** * Main method: compile a list of files, return all compiled classes * * @param filenames The names of all files to be compiled. */ public List<ClassSymbol> compile( List<String> filenames, Map<String, String> origOptions, ClassLoader aptCL, AnnotationProcessorFactory providedFactory, java.util.Set<Class<? extends AnnotationProcessorFactory>> productiveFactories, java.util.Set<java.io.File> aggregateGenFiles) throws Throwable { // as a JavaCompiler can only be used once, throw an exception if // it has been used before. assert !hasBeenUsed : "attempt to reuse JavaCompiler"; hasBeenUsed = true; this.aggregateGenFiles = aggregateGenFiles; long msec = System.currentTimeMillis(); ListBuffer<ClassSymbol> classes = new ListBuffer<ClassSymbol>(); try { JavacFileManager fm = (JavacFileManager) fileManager; // parse all files ListBuffer<JCCompilationUnit> trees = new ListBuffer<JCCompilationUnit>(); for (List<String> l = filenames; l.nonEmpty(); l = l.tail) { if (classesAsDecls) { if (!l.head.endsWith(".java")) { // process as class file ClassSymbol cs = reader.enterClass(names.fromString(l.head)); try { cs.complete(); } catch (Symbol.CompletionFailure cf) { bark.aptError("CantFindClass", l); continue; } classes.append(cs); // add to list of classes continue; } } JavaFileObject fo = fm.getJavaFileObjectsFromStrings(List.of(l.head)).iterator().next(); trees.append(parse(fo)); } // enter symbols for all files List<JCCompilationUnit> roots = trees.toList(); if (errorCount() == 0) { boolean prev = bark.setDiagnosticsIgnored(true); try { enter.main(roots); } finally { bark.setDiagnosticsIgnored(prev); } } if (errorCount() == 0) { apt.main(roots, classes, origOptions, aptCL, providedFactory, productiveFactories); genSourceFileNames.addAll(apt.getSourceFileNames()); genClassFileNames.addAll(apt.getClassFileNames()); } } catch (Abort ex) { } if (verbose) log.printVerbose("total", Long.toString(System.currentTimeMillis() - msec)); chk.reportDeferredDiagnostics(); printCount("error", errorCount()); printCount("warn", warningCount()); return classes.toList(); }
/** * Get the context for the next round of processing. Important values are propogated from round * to round; other values are implicitly reset. */ private Context nextContext() { Context next = new Context(context); Options options = Options.instance(context); Assert.checkNonNull(options); next.put(Options.optionsKey, options); PrintWriter out = context.get(Log.outKey); Assert.checkNonNull(out); next.put(Log.outKey, out); Locale locale = context.get(Locale.class); if (locale != null) next.put(Locale.class, locale); Assert.checkNonNull(messages); next.put(JavacMessages.messagesKey, messages); final boolean shareNames = true; if (shareNames) { Names names = Names.instance(context); Assert.checkNonNull(names); next.put(Names.namesKey, names); } DiagnosticListener<?> dl = context.get(DiagnosticListener.class); if (dl != null) next.put(DiagnosticListener.class, dl); TaskListener tl = context.get(TaskListener.class); if (tl != null) next.put(TaskListener.class, tl); FSInfo fsInfo = context.get(FSInfo.class); if (fsInfo != null) next.put(FSInfo.class, fsInfo); JavaFileManager jfm = context.get(JavaFileManager.class); Assert.checkNonNull(jfm); next.put(JavaFileManager.class, jfm); if (jfm instanceof JavacFileManager) { ((JavacFileManager) jfm).setContext(next); } Names names = Names.instance(context); Assert.checkNonNull(names); next.put(Names.namesKey, names); Keywords keywords = Keywords.instance(context); Assert.checkNonNull(keywords); next.put(Keywords.keywordsKey, keywords); JavaCompiler oldCompiler = JavaCompiler.instance(context); JavaCompiler nextCompiler = JavaCompiler.instance(next); nextCompiler.initRound(oldCompiler); filer.newRound(next); messager.newRound(next); elementUtils.setContext(next); typeUtils.setContext(next); JavacTaskImpl task = context.get(JavacTaskImpl.class); if (task != null) { next.put(JavacTaskImpl.class, task); task.updateContext(next); } JavacTrees trees = context.get(JavacTrees.class); if (trees != null) { next.put(JavacTrees.class, trees); trees.updateContext(next); } context.clear(); return next; }