From 91a7f69bee108330dbbd28fcd80352d4044ad99d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 6 Jun 2017 23:08:31 +0300 Subject: [PATCH] Report error in JPS when TeaVM build crashes --- .../idea/jps/model/TeaVMBuildResult.java | 2 ++ .../jps/remote/TeaVMRemoteBuildResponse.java | 1 + .../teavm/idea/jps/util/ExceptionUtil.java | 32 +++++++++++++++++++ .../idea/jps/InProcessBuildStrategy.java | 17 ++++++++-- .../teavm/idea/jps/RemoteBuildStrategy.java | 5 +++ .../java/org/teavm/idea/jps/TeaVMBuild.java | 12 +++++-- .../teavm/idea/daemon/TeaVMBuildDaemon.java | 5 ++- 7 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 tools/idea/jps-common/src/main/java/org/teavm/idea/jps/util/ExceptionUtil.java diff --git a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMBuildResult.java b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMBuildResult.java index e0a291f82..ffca62f2b 100644 --- a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMBuildResult.java +++ b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMBuildResult.java @@ -24,6 +24,8 @@ public interface TeaVMBuildResult { boolean isErrorOccurred(); + String getStackTrace(); + ProblemProvider getProblems(); Collection getUsedResources(); diff --git a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/remote/TeaVMRemoteBuildResponse.java b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/remote/TeaVMRemoteBuildResponse.java index 0fddf69a5..6364a5e4b 100644 --- a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/remote/TeaVMRemoteBuildResponse.java +++ b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/remote/TeaVMRemoteBuildResponse.java @@ -31,4 +31,5 @@ public class TeaVMRemoteBuildResponse implements Serializable { public final Set usedResources = new HashSet<>(); public final Set classes = new HashSet<>(); public final Set generatedFiles = new HashSet<>(); + public String stackTrace; } diff --git a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/util/ExceptionUtil.java b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/util/ExceptionUtil.java new file mode 100644 index 000000000..f6921ca59 --- /dev/null +++ b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/util/ExceptionUtil.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.idea.jps.util; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public final class ExceptionUtil { + private ExceptionUtil() { + } + + public static String exceptionToString(Throwable e) { + StringWriter writer = new StringWriter(); + PrintWriter output = new PrintWriter(writer); + e.printStackTrace(output); + output.close(); + return writer.toString(); + } +} diff --git a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/InProcessBuildStrategy.java b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/InProcessBuildStrategy.java index 7c316b397..eb76477d7 100644 --- a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/InProcessBuildStrategy.java +++ b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/InProcessBuildStrategy.java @@ -29,6 +29,7 @@ import org.teavm.callgraph.CallGraph; import org.teavm.diagnostics.ProblemProvider; import org.teavm.idea.jps.model.TeaVMBuildResult; import org.teavm.idea.jps.model.TeaVMBuildStrategy; +import org.teavm.idea.jps.util.ExceptionUtil; import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTool; @@ -135,10 +136,12 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy { } boolean errorOccurred = false; + String stackTrace = null; try { tool.generate(); } catch (TeaVMToolException | RuntimeException | Error e) { e.printStackTrace(System.err); + stackTrace = ExceptionUtil.exceptionToString(e); context.processMessage(new CompilerMessage("TeaVM", e)); errorOccurred = true; } @@ -147,7 +150,7 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy { .map(File::getAbsolutePath) .collect(Collectors.toSet()); - return new InProcessBuildResult(tool.getDependencyInfo().getCallGraph(), errorOccurred, + return new InProcessBuildResult(tool.getDependencyInfo().getCallGraph(), errorOccurred, stackTrace, tool.getProblemProvider(), tool.getClasses(), tool.getUsedResources(), generatedFiles); } @@ -168,15 +171,18 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy { static class InProcessBuildResult implements TeaVMBuildResult { private CallGraph callGraph; private boolean errorOccurred; + private String stackTrace; private ProblemProvider problemProvider; private Collection classes; private Collection usedResources; private Collection generatedFiles; - InProcessBuildResult(CallGraph callGraph, boolean errorOccurred, ProblemProvider problemProvider, - Collection classes, Collection usedResources, Collection generatedFiles) { + InProcessBuildResult(CallGraph callGraph, boolean errorOccurred, String stackTrace, + ProblemProvider problemProvider, Collection classes, Collection usedResources, + Collection generatedFiles) { this.callGraph = callGraph; this.errorOccurred = errorOccurred; + this.stackTrace = stackTrace; this.problemProvider = problemProvider; this.classes = classes; this.usedResources = usedResources; @@ -193,6 +199,11 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy { return errorOccurred; } + @Override + public String getStackTrace() { + return stackTrace; + } + @Override public ProblemProvider getProblems() { return problemProvider; diff --git a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/RemoteBuildStrategy.java b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/RemoteBuildStrategy.java index 25d77c619..de887b208 100644 --- a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/RemoteBuildStrategy.java +++ b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/RemoteBuildStrategy.java @@ -133,6 +133,11 @@ public class RemoteBuildStrategy implements TeaVMBuildStrategy { return response.errorOccurred; } + @Override + public String getStackTrace() { + return response.stackTrace; + } + @Override public ProblemProvider getProblems() { return problems; diff --git a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java index f7ad86cf3..04bdd2d91 100644 --- a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java +++ b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java @@ -122,8 +122,16 @@ class TeaVMBuild { reportProblems(buildResult.getProblems(), buildResult.getCallGraph()); - for (String fileName : buildResult.getGeneratedFiles()) { - outputConsumer.registerOutputFile(new File(fileName), Collections.emptyList()); + if (!buildResult.isErrorOccurred()) { + for (String fileName : buildResult.getGeneratedFiles()) { + outputConsumer.registerOutputFile(new File(fileName), Collections.emptyList()); + } + } + + if (buildResult.getStackTrace() != null) { + context.processMessage(new CompilerMessage("TeaVM", BuildMessage.Kind.ERROR, + "Compiler crashed:\n" + buildResult.getStackTrace(), "", + -1, -1, -1, -1, -1)); } return true; diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/daemon/TeaVMBuildDaemon.java b/tools/idea/plugin/src/main/java/org/teavm/idea/daemon/TeaVMBuildDaemon.java index 7bab510ed..798f01740 100644 --- a/tools/idea/plugin/src/main/java/org/teavm/idea/daemon/TeaVMBuildDaemon.java +++ b/tools/idea/plugin/src/main/java/org/teavm/idea/daemon/TeaVMBuildDaemon.java @@ -47,6 +47,7 @@ import org.teavm.idea.jps.remote.TeaVMRemoteBuildCallback; import org.teavm.idea.jps.remote.TeaVMRemoteBuildRequest; import org.teavm.idea.jps.remote.TeaVMRemoteBuildResponse; import org.teavm.idea.jps.remote.TeaVMRemoteBuildService; +import org.teavm.idea.jps.util.ExceptionUtil; import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMToolException; @@ -191,16 +192,18 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote } boolean errorOccurred = false; + String stackTrace = null; try { tool.generate(); System.out.println("Build complete"); } catch (TeaVMToolException | RuntimeException | Error e) { - e.printStackTrace(System.err); + stackTrace = ExceptionUtil.exceptionToString(e); errorOccurred = true; } TeaVMRemoteBuildResponse response = new TeaVMRemoteBuildResponse(); response.errorOccurred = errorOccurred; + response.stackTrace = stackTrace; response.callGraph = tool.getDependencyInfo().getCallGraph(); response.problems.addAll(tool.getProblemProvider().getProblems()); response.severeProblems.addAll(tool.getProblemProvider().getSevereProblems());