| // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| package com.android.tools.r8.utils; |
| |
| import com.android.tools.r8.CompilationException; |
| import com.android.tools.r8.CompilationFailedException; |
| import com.android.tools.r8.DiagnosticsHandler; |
| import com.android.tools.r8.ResourceException; |
| import com.android.tools.r8.StringConsumer; |
| import com.android.tools.r8.errors.CompilationError; |
| import java.io.IOException; |
| import java.util.function.Consumer; |
| |
| public abstract class ExceptionUtils { |
| |
| public static final int STATUS_ERROR = 1; |
| |
| public static void withConsumeResourceHandler( |
| Reporter reporter, StringConsumer consumer, String data) { |
| withConsumeResourceHandler(reporter, handler -> consumer.accept(data, handler)); |
| } |
| |
| public static void withConsumeResourceHandler( |
| Reporter reporter, Consumer<DiagnosticsHandler> consumer) { |
| // Unchecked exceptions simply propagate out, aborting the compilation forcefully. |
| consumer.accept(reporter); |
| // Fail fast for now. We might consider delaying failure since consumer failure does not affect |
| // the compilation. We might need to be careful to correctly identify errors so as to exit |
| // compilation with an error code. |
| reporter.failIfPendingErrors(); |
| } |
| |
| public interface CompileAction { |
| void run() throws IOException, CompilationException, CompilationError, ResourceException; |
| } |
| |
| private enum Compiler { |
| D8, |
| R8; |
| } |
| |
| public static void withD8CompilationHandler(Reporter reporter, CompileAction action) |
| throws CompilationFailedException { |
| withCompilationHandler(reporter, action, Compiler.D8); |
| } |
| |
| public static void withR8CompilationHandler(Reporter reporter, CompileAction action) |
| throws CompilationFailedException { |
| withCompilationHandler(reporter, action, Compiler.R8); |
| } |
| |
| public static void withCompilationHandler( |
| Reporter reporter, CompileAction action, Compiler compiler) |
| throws CompilationFailedException { |
| try { |
| try { |
| action.run(); |
| } catch (IOException e) { |
| throw reporter.fatalError(new IOExceptionDiagnostic(e)); |
| } catch (CompilationException e) { |
| throw reporter.fatalError( |
| new StringDiagnostic( |
| compiler == Compiler.D8 ? e.getMessageForD8() : e.getMessageForR8()), |
| e); |
| } catch (CompilationError e) { |
| throw reporter.fatalError(e); |
| } catch (ResourceException e) { |
| throw reporter.fatalError( |
| e.getCause() instanceof IOException |
| ? new IOExceptionDiagnostic((IOException) e.getCause(), e.getOrigin()) |
| : new StringDiagnostic(e.getMessage(), e.getOrigin())); |
| } |
| reporter.failIfPendingErrors(); |
| } catch (AbortException e) { |
| throw new CompilationFailedException(e); |
| } |
| } |
| |
| public interface MainAction { |
| void run() throws CompilationFailedException; |
| } |
| |
| public static void withMainProgramHandler(MainAction action) { |
| try { |
| action.run(); |
| } catch (CompilationFailedException | AbortException e) { |
| // Detail of the errors were already reported |
| System.err.println("Compilation failed"); |
| System.exit(STATUS_ERROR); |
| } catch (RuntimeException e) { |
| System.err.println("Compilation failed with an internal error."); |
| Throwable cause = e.getCause() == null ? e : e.getCause(); |
| cause.printStackTrace(); |
| System.exit(STATUS_ERROR); |
| } |
| |
| } |
| } |