summaryrefslogtreecommitdiffstats
path: root/jack
diff options
context:
space:
mode:
authorYohann Roussel <yroussel@google.com>2014-04-08 14:42:53 +0200
committerYohann Roussel <yroussel@google.com>2014-04-09 17:28:52 +0200
commit87cbd3bed3d88619e567fad5002d627329429353 (patch)
tree0541aa0ccfc7f85c82b99fc18c1fccd7fe015bfc /jack
parent56d348b1e3997cf4c9788ef7e0fa1069f7309e88 (diff)
downloadtoolchain_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.java43
-rw-r--r--jack/src/com/android/jack/frontend/java/JAstBuilder.java59
-rw-r--r--jack/src/com/android/jack/frontend/java/JackBatchCompiler.java44
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) {