private void expectDiagnostic( Kind kind, String message, @Nullable String source, long start, long end, long col) throws IOException { expect(diagnostic.getKind()).andReturn(kind); expect(diagnostic.getMessage(EasyMock.<Locale>notNull())).andReturn(message); expect(diagnostic.getSource()).andReturn(file).anyTimes(); expect(diagnostic.getStartPosition()).andReturn(start).anyTimes(); expect(diagnostic.getEndPosition()).andReturn(end).anyTimes(); expect(diagnostic.getColumnNumber()).andReturn(col).anyTimes(); expect(file.getCharContent(anyBoolean())).andReturn(source).anyTimes(); }
public void report(Diagnostic<? extends S> diagnostic) { String out = String.format( "Kind: %1$-6s\r\nLine: %2$-6s\r\nColumn: %3$-6s\r\nMessage: %4$-6s\r\nCode:\r\n%5$-6s\r\n", diagnostic.getKind(), diagnostic.getLineNumber(), diagnostic.getColumnNumber(), diagnostic.getMessage(Locale.CHINA), ((JITCompiler.JavaSourceForString) diagnostic.getSource()).getCode()); System.out.println(out); }
public void report(Diagnostic<? extends JavaFileObject> diagnostic) { final CompilerMessage.Kind kind; switch (diagnostic.getKind()) { case ERROR: kind = BuildMessage.Kind.ERROR; myErrorCount++; break; case MANDATORY_WARNING: case WARNING: case NOTE: kind = BuildMessage.Kind.WARNING; myWarningCount++; break; default: kind = BuildMessage.Kind.INFO; } File sourceFile = null; try { // for eclipse compiler just an attempt to call getSource() may lead to an NPE, // so calling this method under try/catch to avoid induced compiler errors final JavaFileObject source = diagnostic.getSource(); sourceFile = source != null ? Utils.convertToFile(source.toUri()) : null; } catch (Exception e) { LOG.info(e); } final String srcPath = sourceFile != null ? FileUtil.toSystemIndependentName(sourceFile.getPath()) : null; String message = diagnostic.getMessage(Locale.US); if (Utils.IS_TEST_MODE) { LOG.info(message); } myContext.processMessage( new CompilerMessage( BUILDER_NAME, kind, message, srcPath, diagnostic.getStartPosition(), diagnostic.getEndPosition(), diagnostic.getPosition(), diagnostic.getLineNumber(), diagnostic.getColumnNumber())); }
@NotNull private static String errorsToString( @NotNull DiagnosticCollector<JavaFileObject> diagnosticCollector, boolean humanReadable) { StringBuilder builder = new StringBuilder(); for (javax.tools.Diagnostic<? extends JavaFileObject> diagnostic : diagnosticCollector.getDiagnostics()) { if (diagnostic.getKind() != javax.tools.Diagnostic.Kind.ERROR) continue; if (humanReadable) { builder.append(diagnostic).append("\n"); } else { builder .append(diagnostic.getSource().getName()) .append(":") .append(diagnostic.getLineNumber()) .append(":") .append(diagnostic.getColumnNumber()) .append(":") .append(diagnostic.getCode()) .append("\n"); } } return builder.toString(); }
/** Compiles a single Java project. */ private static void performCompilation( final ResourceHandle sourceFolder, final ResourceHandle binaryFolder) { // delete binary files from previous builds binaryFolder.delete(); // obtain the standard file manager so we can include the boot classpath final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); final DiagnosticCollector<JavaFileObject> diagnosticListener = new DiagnosticCollector<JavaFileObject>(); final Locale locale = null; final StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(diagnosticListener, locale, Charset.forName("utf-8")); final PlatformClasspathShieldFileManager wrappedStandardFileManager = new PlatformClasspathShieldFileManager(standardFileManager); // create library file managers JavaFileManager fileManager = wrappedStandardFileManager; try { if (Configuration.isDeployedFolderLayout()) { fileManager = new JarFileManager(new JarFile("jars/wicket-util-6.4.0.jar"), fileManager); fileManager = new JarFileManager(new JarFile("jars/wicket-core-6.4.0.jar"), fileManager); fileManager = new JarFileManager(new JarFile("jars/wicket-request-6.4.0.jar"), fileManager); fileManager = new JarFileManager(new JarFile("jars/wicket-extensions-6.4.0.jar"), fileManager); fileManager = new ClassFolderLibraryFileManager(new File("."), fileManager); } else { fileManager = new JarFileManager( new JarFile("../webapp.wicket/lib/java/wicket-util-6.4.0.jar"), fileManager); fileManager = new JarFileManager( new JarFile("../webapp.wicket/lib/java/wicket-core-6.4.0.jar"), fileManager); fileManager = new JarFileManager( new JarFile("../webapp.wicket/lib/java/wicket-request-6.4.0.jar"), fileManager); fileManager = new JarFileManager( new JarFile("../webapp.wicket/lib/java/wicket-extensions-6.4.0.jar"), fileManager); fileManager = new ClassFolderLibraryFileManager(new File("bin"), fileManager); fileManager = new ClassFolderLibraryFileManager(new File("../webapp.wicket/bin"), fileManager); fileManager = new ClassFolderLibraryFileManager(new File("../webapp.common/bin"), fileManager); } } catch (final IOException e) { throw new RuntimeException(e); } // fetch and wrap source code files as JavaFileObjects final MemoryFileManager memoryFileManager = new MemoryFileManager(fileManager); final List<JavaFileObject> javaFiles = new ArrayList<JavaFileObject>(); try { new RecursiveResourceOperation() { @Override protected void handleFile(ResourceHandle resourceHandle) { if ("java".equals(resourceHandle.getExtension())) { ResourcePath path = resourceHandle.getPath(); final String key = path.removeFirstSegments(sourceFolder.getPath().getSegmentCount(), true).toString(); final IMemoryJavaFileObject fileObject = new MemoryJavaFileObject(key, resourceHandle.readBinaryFile(true)); javaFiles.add(fileObject); memoryFileManager.getInputFiles().put(key, fileObject); } } }.handle(sourceFolder); } catch (final WorkspaceResourceNotFoundException e) { // src folder doesn't exist try { memoryFileManager.close(); } catch (final IOException e2) { } return; } // run the java compiler final CompilationTask task = compiler.getTask(null, memoryFileManager, diagnosticListener, null, null, javaFiles); /* final boolean success = */ task.call(); // save the class files for (final IMemoryFileObject fileObject : memoryFileManager.getOutputFiles().values()) { final ResourcePath path = new ResourcePath(binaryFolder.getPath().toString() + fileObject.getName()); final ResourceHandle handle = new ResourceHandle(binaryFolder.getWorkspaceId(), path); handle.writeFile(fileObject.getBinaryContent(), true, true); } // dispose of the file manager try { memoryFileManager.close(); } catch (final IOException e) { } // collect diagnostic messages per source file final List<Diagnostic<? extends JavaFileObject>> diagnostics = diagnosticListener.getDiagnostics(); final Map<JavaFileObject, List<Diagnostic<? extends JavaFileObject>>> sourceFileToDiagnostics = new HashMap<JavaFileObject, List<Diagnostic<? extends JavaFileObject>>>(); for (final Diagnostic<? extends JavaFileObject> diagnostic : diagnostics) { final JavaFileObject currentFile = diagnostic.getSource(); List<Diagnostic<? extends JavaFileObject>> currentFileDiagnostics = sourceFileToDiagnostics.get(currentFile); if (currentFileDiagnostics == null) { currentFileDiagnostics = new ArrayList<Diagnostic<? extends JavaFileObject>>(); sourceFileToDiagnostics.put(currentFile, currentFileDiagnostics); } currentFileDiagnostics.add(diagnostic); } // these warnings will be ignored because they're nonsense final Set<String> ignoredWarnings = new HashSet<String>(); ignoredWarnings.add( "warning: [package-info] a package-info.java file has already been seen for package unnamed package"); ignoredWarnings.add( "[package-info] a package-info.java file has already been seen for package unnamed package"); // generate markers for the diagnostic messages sourceFolder.deleteMarkersRecursively(MarkerOrigin.JAVAC); for (final Map.Entry<JavaFileObject, List<Diagnostic<? extends JavaFileObject>>> fileEntry : sourceFileToDiagnostics.entrySet()) { ResourcePath filePath = new ResourcePath(fileEntry.getKey().getName()); ResourceHandle fileHandle = sourceFolder.get(filePath.withLeadingSeparator(false)); for (final Diagnostic<? extends JavaFileObject> diagnostic : fileEntry.getValue()) { // convert the diagnostic kind to a marker meaning (skip this diagnostic if the kind is // unknown) final Kind diagnosticKind = diagnostic.getKind(); MarkerMeaning meaning; if (diagnosticKind == Kind.ERROR) { meaning = MarkerMeaning.ERROR; } else if (diagnosticKind == Kind.WARNING || diagnosticKind == Kind.MANDATORY_WARNING) { meaning = MarkerMeaning.WARNING; } else { continue; } // skip erroneous markers final String messageText = diagnostic.getMessage(null); if (meaning == MarkerMeaning.WARNING && ignoredWarnings.contains(messageText)) { continue; } // create the marker final long line = diagnostic.getLineNumber(); final long column = diagnostic.getColumnNumber(); fileHandle.createMarker(MarkerOrigin.JAVAC, meaning, line, column, messageText); } } // copy non-Java files over to the output folder new RecursiveResourceOperation() { @Override protected void handleFile(ResourceHandle sourceFile) { if (!"java".equals(sourceFile.getExtension())) { ResourcePath relativePath = sourceFile .getPath() .removeFirstSegments(sourceFolder.getPath().getSegmentCount(), false); sourceFile.copyFileTo(binaryFolder.get(relativePath), true); } } }.handle(sourceFolder); }
public static void main(String[] args) throws Throwable { StringBuilder sb = new StringBuilder(64); sb.append("package tools.test.compile;\n"); sb.append("public class HelloWorld implements tools.test.InlineCompiler.DoStuff {\n"); sb.append(" public void doStuff() {\n"); sb.append( " System.out.println(\"print:\" + tools.Convert.toString(\"Hello world\"));\n"); sb.append(" }\n"); sb.append("}\n"); File helloWorldJava = new File("./tools/test/compile/HelloWorld.java"); // 注意这里的路径,和包名对应 2014-11-21 by 六三 if (helloWorldJava.getParentFile().exists() || helloWorldJava.getParentFile().mkdirs()) { // 写文件 Writer writer = null; try { writer = new FileWriter(helloWorldJava); writer.write(sb.toString()); writer.flush(); } finally { try { writer.close(); } catch (Exception e) {; } } } /** * Compilation Requirements * ******************************************************************************************** */ DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); // This sets up the class path that the compiler will use. // I've added the .jar file that contains the DoStuff interface within in it... List<String> optionList = new ArrayList<String>(); optionList.add("-classpath"); optionList.add(System.getProperty("java.class.path") + ";"); Iterable<? extends JavaFileObject> compilationUnit = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(helloWorldJava)); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionList, null, compilationUnit); /** Compilation Requirements * */ if (task.call()) { /** Load and execute * */ System.out.println("Yipe"); // Create a new custom class loader, pointing to the directory that contains the compiled // classes, this should point to the top of the package structure! URLClassLoader classLoader = new URLClassLoader(new URL[] {new File("./").toURI().toURL()}); // Load the class from the classloader by name.... Class<?> loadedClass = classLoader.loadClass("tools.test.compile.HelloWorld"); // Create a new instance... Object obj = loadedClass.newInstance(); // Santity check if (obj instanceof DoStuff) { // Cast to the DoStuff interface DoStuff stuffToDo = (DoStuff) obj; // Run it baby stuffToDo.doStuff(); } /** Load and execute * */ } else { for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { System.out.format( "Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource().toUri()); } } fileManager.close(); }
private void markError( DiagnosticCollector<JavaFileObject> diagnosticsCollector, boolean markerCreation) { for (Diagnostic diagnostic : diagnosticsCollector.getDiagnostics()) { System.out.format("Error on line %d" + " -> ", diagnostic.getLineNumber(), diagnostic); System.out.println(diagnostic.getMessage(null) + "\n"); System.err.println("*** " + diagnostic.toString() + " *** " + diagnostic.getCode()); JavaFileObject source = (JavaFileObject) diagnostic.getSource(); String longFileName = source == null ? null : source.toUri().getPath(); // String shortFileName = source == null ? null : source.getName(); // System.out.println("Error in: " + longFileName); // Path path = new Path(longFileName); // IFile ifile = // ResourcesPlugin.getWorkspace().getRoot().getFile(path); if (diagnostic.getLineNumber() > -1) { File fileToOpen = new File(longFileName); if (fileToOpen.exists() && fileToOpen.isFile()) { final IFileStore fileStore = EFS.getLocalFileSystem().getStore(fileToOpen.toURI()); Display display = PlatformUI.getWorkbench().getDisplay(); display.syncExec( new Runnable() { public void run() { try { IEditorPart part = IDE.openEditorOnFileStore(pag, fileStore); if (part != null) { IEditorInput input = part.getEditorInput(); ifile = ((IFileEditorInput) input).getFile(); // ... use activeProjectName } } catch (PartInitException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } else { // Do something if the file does not exist } } // System.out.format("Error on line %d in %s"+"\n", // diagnostic.getLineNumber(), diagnostic); if (markerCreation == true) { int lnr = (int) diagnostic.getLineNumber(); int startPos = (int) diagnostic.getStartPosition(); int stopPos = (int) diagnostic.getEndPosition(); if (ifile != null) { IMarker marker; try { marker = ifile.createMarker(IMarker.PROBLEM); marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); marker.setAttribute(IMarker.MESSAGE, diagnostic.getMessage(null)); marker.setAttribute(IMarker.LINE_NUMBER, lnr); // if (pos.offset != 0) { // System.out.println(startPos); // System.out.println(stopPos); marker.setAttribute(IMarker.CHAR_START, startPos); marker.setAttribute(IMarker.CHAR_END, stopPos - 1); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
/** * Compile the given files. * * @param files Source files to compile. * @param classPath Support jars or directories that should be on the classpath. If @code{null}, * the default is used. * @param sourcePath Location of additional sources to be compiled on-demand. If @code{null}, the * default is used. * @param destination Location (directory) for compiled classes. If @code{null}, the default * in-place location is used. * @param bootClassPath The bootclasspath (contains Java API jars or directories); should be * consistent with @code{sourceVersion} If @code{null}, the default is used. * @param sourceVersion The language version of the sources. Should be consistent * with @code{bootClassPath}. If @code{null}, the default is used. * @param showWarnings Whether compiler warnings should be shown or ignored. * @return Errors that occurred. If no errors, should be zero length (not null). */ public List<? extends DJError> compile( List<? extends File> files, List<? extends File> classPath, List<? extends File> sourcePath, File destination, List<? extends File> bootClassPath, String sourceVersion, boolean showWarnings) { debug.logStart("compile()"); debug.logValues( new String[] { "this", "files", "classPath", "sourcePath", "destination", "bootClassPath", "sourceVersion", "showWarnings" }, this, files, classPath, sourcePath, destination, bootClassPath, sourceVersion, showWarnings); Iterable<String> options = _createOptions( classPath, sourcePath, destination, bootClassPath, sourceVersion, showWarnings); LinkedList<DJError> errors = new LinkedList<DJError>(); // This is the class that javax.tools.ToolProvider.getSystemJavaCompiler() uses. // We create an instance of that class directly, bypassing ToolProvider, because ToolProvider // returns null // if DrJava is started with just the JRE, instead of with the JDK, even if tools.jar is later // made available // to the class loader. JavaCompiler compiler = null; try { compiler = (JavaCompiler) (Class.forName("com.sun.tools.javac.api.JavacTool").newInstance()); } catch (ClassNotFoundException e) { errors.addFirst(new DJError("Compile exception: " + e, false)); error.log(e); return errors; } catch (InstantiationException e) { errors.addFirst(new DJError("Compile exception: " + e, false)); error.log(e); return errors; } catch (IllegalAccessException e) { errors.addFirst(new DJError("Compile exception: " + e, false)); error.log(e); return errors; } /** Default FileManager provided by Context class */ DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjectsFromFiles(files); try { System.err.println("Calling '" + compiler + "' with options " + options); compiler.getTask(null, fileManager, diagnostics, options, null, fileObjects).call(); for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics()) { Diagnostic.Kind dt = d.getKind(); boolean isWarning = false; // init required by javac switch (dt) { case OTHER: continue; // skip, do not record case NOTE: continue; // skip, do not record case MANDATORY_WARNING: isWarning = true; break; case WARNING: isWarning = true; break; case ERROR: isWarning = false; break; } /* The new Java 6.0 Diagnostic interface appears to be broken. The expression d.getSource().getName() returns a * non-existent path--the name of the test file (allocated as a TEMP file) appended to the source root for * DrJava--in GlobalModelCompileErrorsTest.testCompileFailsCorrectLineNumbers(). The expression * d.getSource().toUri().getPath() returns the correct result as does ((JCDiagnostic) d).getSourceName(). */ if (d.getSource() != null) { errors.add( new DJError( new File(d.getSource().toUri().getPath()), // d.getSource().getName() fails! ((int) d.getLineNumber()) - 1, // javac starts counting at 1 ((int) d.getColumnNumber()) - 1, d.getMessage(null), // null is the locale isWarning)); } else { errors.add(new DJError(d.getMessage(null), isWarning)); } } fileManager.close(); } catch (Throwable t) { // compiler threw an exception/error (typically out of memory error) errors.addFirst(new DJError("Compile exception: " + t, false)); error.log(t); } debug.logEnd("compile()"); return errors; }