diff options
author | Yohann Roussel <yroussel@google.com> | 2014-04-08 14:42:53 +0200 |
---|---|---|
committer | Yohann Roussel <yroussel@google.com> | 2014-04-09 17:28:52 +0200 |
commit | 87cbd3bed3d88619e567fad5002d627329429353 (patch) | |
tree | 0541aa0ccfc7f85c82b99fc18c1fccd7fe015bfc /jack | |
parent | 56d348b1e3997cf4c9788ef7e0fa1069f7309e88 (diff) | |
download | toolchain_jack-87cbd3bed3d88619e567fad5002d627329429353.zip toolchain_jack-87cbd3bed3d88619e567fad5002d627329429353.tar.gz toolchain_jack-87cbd3bed3d88619e567fad5002d627329429353.tar.bz2 |
Improve error reporting when exception comes through ecj.
Change-Id: I192b64a547942fbe7fa51a20f1c4fdaaeb7c1b8b
Diffstat (limited to 'jack')
-rw-r--r-- | jack/src/com/android/jack/CommandLine.java | 43 | ||||
-rw-r--r-- | jack/src/com/android/jack/frontend/java/JAstBuilder.java | 59 | ||||
-rw-r--r-- | jack/src/com/android/jack/frontend/java/JackBatchCompiler.java | 44 |
3 files changed, 109 insertions, 37 deletions
diff --git a/jack/src/com/android/jack/CommandLine.java b/jack/src/com/android/jack/CommandLine.java index 8cead0f..8045b4e 100644 --- a/jack/src/com/android/jack/CommandLine.java +++ b/jack/src/com/android/jack/CommandLine.java @@ -43,6 +43,10 @@ import javax.annotation.Nonnull; public abstract class CommandLine { @Nonnull + private static final String INTERRUPTED_COMPILATION_WARNING = + "Warning: This may have produced partial or corrupted output."; + + @Nonnull private static Logger logger = LoggerFactory.getLogger(); protected static void runJackAndExitOnError(@Nonnull Options options) { @@ -69,26 +73,33 @@ public abstract class CommandLine { System.exit(ExitStatus.FAILURE_COMPILATION); } catch (JackUserException e) { System.err.println(e.getMessage()); - logger.log(Level.INFO, "Jack user exception:", e); + logger.log(Level.FINE, "Jack user exception:", e); System.exit(ExitStatus.FAILURE_COMPILATION); + } catch (OutOfMemoryError e) { + printExceptionMessage(e, "Out of memory error."); + System.err.println("Try increasing heap size with java option '-Xmx<size>'"); + System.err.println(INTERRUPTED_COMPILATION_WARNING); + logger.log(Level.FINE, "Out of memory error:", e); + System.exit(ExitStatus.FAILURE_VM); + } catch (StackOverflowError e) { + printExceptionMessage(e, "Stack overflow error."); + System.err.println("Try increasing stack size with java option '-Xss<size>'"); + System.err.println(INTERRUPTED_COMPILATION_WARNING); + logger.log(Level.FINE, "Stack overflow error:", e); + System.exit(ExitStatus.FAILURE_VM); } catch (VirtualMachineError e) { - System.err.println(e.getMessage()); - if (e instanceof OutOfMemoryError) { - System.err.println("Try increasing heap size with java option '-Xmx<size>'"); - } else if (e instanceof StackOverflowError) { - System.err.println("Try increasing stack size with java option '-Xss<size>'"); - } - System.err.println("Warning: This may have produced partial or corrupted output."); - logger.log(Level.CONFIG, "Virtual machine error:", e); + printExceptionMessage(e, "Virtual machine error: " + e.getClass() + "."); + System.err.println(INTERRUPTED_COMPILATION_WARNING); + logger.log(Level.FINE, "Virtual machine error:", e); System.exit(ExitStatus.FAILURE_VM); } catch (UnrecoverableException e) { System.err.println("Unrecoverable error: " + e.getMessage()); - System.err.println("Warning: This may have produced partial or corrupted output."); + System.err.println(INTERRUPTED_COMPILATION_WARNING); logger.log(Level.FINE, "Unrecoverable exception:", e); System.exit(ExitStatus.FAILURE_UNRECOVERABLE); } catch (Throwable e) { - System.err.println("Internal compiler error (see log)"); - System.err.println("Warning: This may have produced partial or corrupted output."); + System.err.println("Internal compiler error."); + System.err.println(INTERRUPTED_COMPILATION_WARNING); logger.log(Level.SEVERE, "Internal compiler error:", e); System.exit(ExitStatus.FAILURE_INTERNAL); @@ -158,4 +169,12 @@ public abstract class CommandLine { System.out.println(sb); } } + + private static void printExceptionMessage(@Nonnull Throwable t, @Nonnull String defaultMessage) { + String exceptionMessage = t.getMessage(); + if (exceptionMessage == null) { + exceptionMessage = defaultMessage; + } + System.err.println(exceptionMessage); + } } diff --git a/jack/src/com/android/jack/frontend/java/JAstBuilder.java b/jack/src/com/android/jack/frontend/java/JAstBuilder.java index c3f3ed9..f4b93f0 100644 --- a/jack/src/com/android/jack/frontend/java/JAstBuilder.java +++ b/jack/src/com/android/jack/frontend/java/JAstBuilder.java @@ -31,6 +31,7 @@ import com.android.sched.util.log.Tracer; import com.android.sched.util.log.TracerFactory; import org.eclipse.jdt.core.compiler.CompilationProgress; +import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.ICompilerRequestor; import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; import org.eclipse.jdt.internal.compiler.IProblemFactory; @@ -111,34 +112,42 @@ class JAstBuilder extends JavaParser { */ @Override public void process(CompilationUnitDeclaration unit, int i) { - Event jastEvent = tracer.start(JackEventType.J_AST_BUILDER); try { - super.process(unit, i); + Event jastEvent = tracer.start(JackEventType.J_AST_BUILDER); + try { + super.process(unit, i); - loadLocalClasses(unit); + loadLocalClasses(unit); - if (unit.hasErrors()) { - // An error has already been detected, don't even try to handle the unit. - return; - } + if (unit.hasErrors()) { + // An error has already been detected, don't even try to handle the unit. + return; + } - // Generate GWT IR after each compilation of CompilationUnitDeclaration. - // It could not be done at the end of compile(ICompilationUnit[] sourceUnits) method since - // reset method of ecj was called by super.compile(sourceUnits) and after the lookup - // environment is no longer usable. - Event gwtEvent = tracer.start(JackEventType.GWT_AST_BUILDER); - List<JDefinedClassOrInterface> types; - try { - types = astBuilder.process(unit); - } finally { - gwtEvent.end(); - } + // Generate GWT IR after each compilation of CompilationUnitDeclaration. + // It could not be done at the end of compile(ICompilationUnit[] sourceUnits) method since + // reset method of ecj was called by super.compile(sourceUnits) and after the lookup + // environment is no longer usable. + Event gwtEvent = tracer.start(JackEventType.GWT_AST_BUILDER); + List<JDefinedClassOrInterface> types; + try { + types = astBuilder.process(unit); + } finally { + gwtEvent.end(); + } - for (JDefinedClassOrInterface type : types) { - session.addTypeToEmit(type); + for (JDefinedClassOrInterface type : types) { + session.addTypeToEmit(type); + } + } finally { + jastEvent.end(); } - } finally { - jastEvent.end(); + } catch (IllegalArgumentException e) { + // This is a workaround to reduce bad handling of IllegalArgumentException in + // JackBatchCompiler. + AssertionError error = new AssertionError(); + error.initCause(e); + throw error; } } @@ -198,4 +207,10 @@ class JAstBuilder extends JavaParser { } } } + + @Override + protected void handleInternalException(@Nonnull Throwable internalException, + @CheckForNull CompilationUnitDeclaration unit, @CheckForNull CompilationResult result) { + // do nothing here, let JackBatchCompiler do the appropriate handling + } } diff --git a/jack/src/com/android/jack/frontend/java/JackBatchCompiler.java b/jack/src/com/android/jack/frontend/java/JackBatchCompiler.java index c2657b5..3bd3ea6 100644 --- a/jack/src/com/android/jack/frontend/java/JackBatchCompiler.java +++ b/jack/src/com/android/jack/frontend/java/JackBatchCompiler.java @@ -16,6 +16,7 @@ package com.android.jack.frontend.java; +import com.android.jack.JackUserException; import com.android.jack.backend.jayce.JayceFileImporter; import com.android.jack.ecj.loader.jast.JAstClasspath; import com.android.jack.ir.ast.JSession; @@ -40,6 +41,24 @@ import javax.annotation.Nonnull; * Entry-point to call JDT compiler. */ public class JackBatchCompiler extends Main { + /** + * Error used to transport runtime exception through ecj catch. + */ + private static class TransportExceptionAroundEcjError extends Error { + + private static final long serialVersionUID = 1L; + + public TransportExceptionAroundEcjError(@Nonnull RuntimeException cause) { + super(cause); + } + + @Nonnull + @Override + public RuntimeException getCause() { + return (RuntimeException) super.getCause(); + } + + } @Nonnull public static final String JACK_LOGICAL_PATH_ENTRY = "<jack-logical-entry>"; @@ -132,7 +151,17 @@ public class JackBatchCompiler extends Main { } @Override - public void performCompilation() { + public boolean compile(String[] argv) { + try { + return super.compile(argv); + } catch (TransportExceptionAroundEcjError e) { + throw e.getCause(); + } + } + + @Override + public void performCompilation() throws JackUserException, + TransportExceptionAroundEcjError { startTime = System.currentTimeMillis(); compilerOptions = new CompilerOptions(options); @@ -157,8 +186,17 @@ public class JackBatchCompiler extends Main { // Compiles every compilation units with logging support. logger.startLoggingSources(); - batchCompiler.compile(getCompilationUnits()); - logger.endLoggingSources(); + try { + batchCompiler.compile(getCompilationUnits()); + } catch (IllegalArgumentException e) { + // ecj is throwing this one for missing source files, let them be reported correctly + // most other IllegalArgumentException are wrapped by JAstBuilder + throw new JackUserException(e.getMessage(), e); + } catch (RuntimeException e) { + throw new TransportExceptionAroundEcjError(e); + } finally { + logger.endLoggingSources(); + } // Update compiler statistics and log them. if (compilerStats != null && compilerStats.length > currentRepetition) { |