diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java index d7c10b33c..1214d52a9 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyStack.java @@ -15,6 +15,7 @@ */ package org.teavm.dependency; +import org.teavm.model.InstructionLocation; import org.teavm.model.MethodReference; /** @@ -25,6 +26,7 @@ public class DependencyStack { public static final DependencyStack ROOT = new DependencyStack(); private MethodReference method; private DependencyStack cause; + private InstructionLocation location; private DependencyStack() { } @@ -33,11 +35,20 @@ public class DependencyStack { this(method, ROOT); } + public DependencyStack(MethodReference method, InstructionLocation location) { + this(method, location, ROOT); + } + public DependencyStack(MethodReference method, DependencyStack cause) { + this(method, null, cause); + } + + public DependencyStack(MethodReference method, InstructionLocation location, DependencyStack cause) { if (method == null || cause == null) { throw new IllegalArgumentException("Arguments must not be null"); } this.method = method; + this.location = location; this.cause = cause; } @@ -49,6 +60,10 @@ public class DependencyStack { return cause; } + public InstructionLocation getLocation() { + return location; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java index 6c867d8f4..3780bb586 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java @@ -254,8 +254,6 @@ public class TeaVMTestTool { fileNames.get(method)); } catch (IOException e) { log.error("Error generating JavaScript", e); - } catch (InterruptedException e) { - log.error("Error generating JavaScript", e); } } }); @@ -320,7 +318,7 @@ public class TeaVMTestTool { } private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource, - MethodReference methodRef, String targetName) throws IOException, InterruptedException { + MethodReference methodRef, String targetName) throws IOException { TeaVM vm = new TeaVMBuilder() .setClassLoader(classLoader) .setClassSource(classSource) diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java index 6441f29a0..09090cdcb 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -59,6 +59,8 @@ public class TeaVMTool { private DiskRegularMethodNodeCache astCache; private FileSymbolTable symbolTable; private FileSymbolTable fileTable; + private boolean cancelled; + private TeaVMProgressListener progressListener; public File getTargetDirectory() { return targetDirectory; @@ -180,8 +182,17 @@ public class TeaVMTool { this.classLoader = classLoader; } - public void generate() throws TeaVMToolException, InterruptedException { + public void setProgressListener(TeaVMProgressListener progressListener) { + this.progressListener = progressListener; + } + + public boolean wasCancelled() { + return cancelled; + } + + public void generate() throws TeaVMToolException { try { + cancelled = false; log.info("Building JavaScript file"); TeaVMBuilder vmBuilder = new TeaVMBuilder(); if (incremental) { @@ -205,6 +216,9 @@ public class TeaVMTool { vmBuilder.setClassLoader(classLoader).setClassSource(new ClasspathClassHolderSource(classLoader)); } TeaVM vm = vmBuilder.build(); + if (progressListener != null) { + vm.setProgressListener(progressListener); + } vm.setMinifying(minifying); vm.setBytecodeLogging(bytecodeLogging); vm.setProperties(properties); @@ -221,8 +235,7 @@ public class TeaVMTool { vm.add(transformer); } if (mainClass != null) { - MethodDescriptor mainMethodDesc = new MethodDescriptor("main", ValueType.arrayOf( - ValueType.object("java.lang.String")), ValueType.VOID); + MethodDescriptor mainMethodDesc = new MethodDescriptor("main", String[].class, void.class); vm.entryPoint("main", new MethodReference(mainClass, mainMethodDesc)) .withValue(1, "java.lang.String"); } @@ -253,6 +266,11 @@ public class TeaVMTool { vm.add(runtimeInjector); } vm.build(writer, new DirectoryBuildTarget(targetDirectory)); + if (vm.wasCancelled()) { + log.info("Build cancelled"); + cancelled = true; + return; + } vm.checkForMissingItems(); log.info("JavaScript file successfully built"); if (debugInformationGenerated) { diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 511c90f87..1ac48a857 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -83,14 +83,19 @@ public class TeaVM implements TeaVMHost, ServiceRepository { private RegularMethodNodeCache astCache = new EmptyRegularMethodNodeCache(); private boolean incremental; private TeaVMProgressListener progressListener; + private boolean cancelled; TeaVM(ClassReaderSource classSource, ClassLoader classLoader) { this.classSource = classSource; this.classLoader = classLoader; dependencyChecker = new DependencyChecker(this.classSource, classLoader, this); progressListener = new TeaVMProgressListener() { - @Override public void progressReached(int progress) throws InterruptedException { } - @Override public void phaseStarted(TeaVMPhase phase, int count) throws InterruptedException { } + @Override public TeaVMProgressFeedback progressReached(int progress) { + return TeaVMProgressFeedback.CONTINUE; + } + @Override public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) { + return TeaVMProgressFeedback.CONTINUE; + } }; } @@ -201,6 +206,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository { this.progressListener = progressListener; } + public boolean wasCancelled() { + return cancelled; + } + /** *

Adds an entry point. TeaVM guarantees, that all methods that are required by the entry point * will be available at run-time in browser. Also you need to specify for each parameter of entry point @@ -323,9 +332,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository { * @param target where to generate additional resources. Can be null, but if there are * plugins or inteceptors that generate additional resources, the build process will fail. */ - public void build(Appendable writer, BuildTarget target) throws RenderingException, InterruptedException { + public void build(Appendable writer, BuildTarget target) throws RenderingException { // Check dependencies - progressListener.phaseStarted(TeaVMPhase.DEPENDENCY_CHECKING, 1); + reportPhase(TeaVMPhase.DEPENDENCY_CHECKING, 1); + if (wasCancelled()) { + return; + } AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider(); dependencyChecker.linkMethod(new MethodReference("java.lang.Class", "createNew", ValueType.object("java.lang.Class")), DependencyStack.ROOT).use(); @@ -343,26 +355,38 @@ public class TeaVM implements TeaVMHost, ServiceRepository { dependencyChecker.linkMethod(new MethodReference("java.lang.Object", new MethodDescriptor("clone", ValueType.object("java.lang.Object"))), DependencyStack.ROOT).use(); dependencyChecker.processDependencies(); - progressListener.progressReached(1); - if (hasMissingItems()) { + reportProgress(1); + if (wasCancelled() || hasMissingItems()) { return; } // Link - progressListener.phaseStarted(TeaVMPhase.LINKING, 1); + reportPhase(TeaVMPhase.LINKING, 1); + if (wasCancelled()) { + return; + } Linker linker = new Linker(); ListableClassHolderSource classSet = linker.link(dependencyChecker); - progressListener.progressReached(1); + reportProgress(1); + if (wasCancelled()) { + return; + } // Optimize and allocate registers if (!incremental) { devirtualize(classSet, dependencyChecker); + if (wasCancelled()) { + return; + } } List clsNodes = modelToAst(classSet); // Render - progressListener.phaseStarted(TeaVMPhase.RENDERING, classSet.getClassNames().size()); + reportPhase(TeaVMPhase.RENDERING, classSet.getClassNames().size()); + if (wasCancelled()) { + return; + } DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, dependencyChecker.getClassSource()); naming.setMinifying(minifying); SourceWriterBuilder builder = new SourceWriterBuilder(naming); @@ -378,7 +402,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository { emitCFG(debugEmitter, method.getProgram()); } } - progressListener.progressReached(++classIndex); + reportProgress(++classIndex); + if (wasCancelled()) { + return; + } } renderer.setDebugEmitter(debugEmitter); } @@ -418,6 +445,18 @@ public class TeaVM implements TeaVMHost, ServiceRepository { } } + private void reportPhase(TeaVMPhase phase, int progressLimit) { + if (progressListener.phaseStarted(phase, progressLimit) == TeaVMProgressFeedback.CANCEL) { + cancelled = true; + } + } + + private void reportProgress(int progress) { + if (progressListener.progressReached(progress) == TeaVMProgressFeedback.CANCEL) { + cancelled = true; + } + } + private void emitCFG(DebugInformationEmitter emitter, Program program) { Map cfg = ProgramUtils.getLocationCFG(program); for (Map.Entry entry : cfg.entrySet()) { @@ -437,9 +476,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository { return new SourceLocation(location.getFileName(), location.getLine()); } - private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) - throws InterruptedException { - progressListener.phaseStarted(TeaVMPhase.DEVIRTUALIZATION, classes.getClassNames().size()); + private void devirtualize(ListableClassHolderSource classes, DependencyInfo dependency) { + reportPhase(TeaVMPhase.DEVIRTUALIZATION, classes.getClassNames().size()); + if (wasCancelled()) { + return; + } final Devirtualization devirtualization = new Devirtualization(dependency, classes); int index = 0; for (String className : classes.getClassNames()) { @@ -449,11 +490,14 @@ public class TeaVM implements TeaVMHost, ServiceRepository { devirtualization.apply(method); } } - progressListener.progressReached(++index); + reportProgress(++index); + if (wasCancelled()) { + return; + } } } - private List modelToAst(ListableClassHolderSource classes) throws InterruptedException { + private List modelToAst(ListableClassHolderSource classes) { progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size()); Decompiler decompiler = new Decompiler(classes, classLoader); decompiler.setRegularMethodCache(incremental ? astCache : null); @@ -606,7 +650,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { } } - public void build(File dir, String fileName) throws RenderingException, InterruptedException { + public void build(File dir, String fileName) throws RenderingException { try (Writer writer = new OutputStreamWriter(new FileOutputStream(new File(dir, fileName)), "UTF-8")) { build(writer, new DirectoryBuildTarget(dir)); } catch (UnsupportedEncodingException e) { diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressFeedback.java b/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressFeedback.java new file mode 100644 index 000000000..54d7470ea --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressFeedback.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 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.vm; + +/** + * + * @author Alexey Andreev + */ +public enum TeaVMProgressFeedback { + CONTINUE, + CANCEL +} diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java b/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java index ea6c720ef..8286dbf75 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java @@ -20,7 +20,7 @@ package org.teavm.vm; * @author Alexey Andreev */ public interface TeaVMProgressListener { - void phaseStarted(TeaVMPhase phase, int count) throws InterruptedException; + TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count); - void progressReached(int progress) throws InterruptedException; + TeaVMProgressFeedback progressReached(int progress); } diff --git a/teavm-eclipse/teavm-eclipse-plugin/.classpath b/teavm-eclipse/teavm-eclipse-plugin/.classpath index b1eb14910..ba5006521 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/.classpath +++ b/teavm-eclipse/teavm-eclipse-plugin/.classpath @@ -1,6 +1,9 @@ + + + diff --git a/teavm-eclipse/teavm-eclipse-plugin/META-INF/MANIFEST.MF b/teavm-eclipse/teavm-eclipse-plugin/META-INF/MANIFEST.MF index f2b6ec6b9..4616fadfd 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/META-INF/MANIFEST.MF +++ b/teavm-eclipse/teavm-eclipse-plugin/META-INF/MANIFEST.MF @@ -53,6 +53,9 @@ Bundle-ClassPath: ., lib/websocket-client-9.2.1.v20140609.jar, lib/websocket-common-9.2.1.v20140609.jar, lib/websocket-server-9.2.1.v20140609.jar, - lib/websocket-servlet-9.2.1.v20140609.jar + lib/websocket-servlet-9.2.1.v20140609.jar, + lib/gson-2.2.4.jar, + lib/teavm-classlib-0.2-SNAPSHOT.jar, + lib/teavm-platform-0.2-SNAPSHOT.jar Export-Package: org.teavm.eclipse.debugger Bundle-ActivationPolicy: lazy diff --git a/teavm-eclipse/teavm-eclipse-plugin/build.properties b/teavm-eclipse/teavm-eclipse-plugin/build.properties index c73e6cfde..336d59585 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/build.properties +++ b/teavm-eclipse/teavm-eclipse-plugin/build.properties @@ -37,7 +37,10 @@ bin.includes = plugin.xml,\ lib/websocket-client-9.2.1.v20140609.jar,\ lib/websocket-common-9.2.1.v20140609.jar,\ lib/websocket-server-9.2.1.v20140609.jar,\ - lib/websocket-servlet-9.2.1.v20140609.jar + lib/websocket-servlet-9.2.1.v20140609.jar,\ + lib/gson-2.2.4.jar,\ + lib/teavm-classlib-0.2-SNAPSHOT.jar,\ + lib/teavm-platform-0.2-SNAPSHOT.jar jars.compile.order = . jars.extra.classpath = logback.xml,\ lib/asm-5.0.1.jar,\ @@ -72,4 +75,7 @@ jars.extra.classpath = logback.xml,\ lib/websocket-client-9.2.1.v20140609.jar,\ lib/websocket-common-9.2.1.v20140609.jar,\ lib/websocket-server-9.2.1.v20140609.jar,\ - lib/websocket-servlet-9.2.1.v20140609.jar + lib/websocket-servlet-9.2.1.v20140609.jar,\ + lib/gson-2.2.4.jar,\ + lib/teavm-classlib-0.2-SNAPSHOT.jar,\ + lib/teavm-platform-0.2-SNAPSHOT.jar diff --git a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml index 1d25682f8..d32f9e4f1 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml +++ b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml @@ -50,6 +50,7 @@ + @@ -61,4 +62,9 @@ + + + + + diff --git a/teavm-eclipse/teavm-eclipse-plugin/pom.xml b/teavm-eclipse/teavm-eclipse-plugin/pom.xml index 693d3687f..e13e481bb 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/pom.xml +++ b/teavm-eclipse/teavm-eclipse-plugin/pom.xml @@ -17,6 +17,11 @@ teavm-core ${project.version} + + org.teavm + teavm-classlib + ${project.version} + org.teavm teavm-chrome-rdp diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java index d2dec4bde..0f44cd2db 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMBuilder.java @@ -4,14 +4,10 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.resources.ResourcesPlugin; +import java.util.*; +import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.jdt.core.IClasspathEntry; @@ -19,6 +15,7 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.teavm.tooling.RuntimeCopyOperation; import org.teavm.tooling.TeaVMTool; +import org.teavm.tooling.TeaVMToolException; /** * @@ -39,7 +36,12 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { tool.setRuntime(RuntimeCopyOperation.SEPARATE); tool.setMinifying(false); tool.setMainClass(projectSettings.getMainClass()); - + tool.setProgressListener(new TeaVMEclipseProgressListener(monitor)); + try { + tool.generate(); + } catch (TeaVMToolException e) { + throw new CoreException(TeaVMEclipsePlugin.makeError(e)); + } return null; } @@ -57,9 +59,10 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { return new URL[0]; } IJavaProject javaProject = JavaCore.create(project); - List urls = new ArrayList<>(); + PathCollector collector = new PathCollector(); + IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); try { - urls.add(javaProject.getOutputLocation().toFile().toURI().toURL()); + collector.addPath(workspaceRoot.findMember(javaProject.getOutputLocation()).getLocation()); } catch (MalformedURLException e) { TeaVMEclipsePlugin.logError(e); } @@ -68,7 +71,7 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { switch (entry.getEntryKind()) { case IClasspathEntry.CPE_LIBRARY: try { - urls.add(entry.getPath().toFile().toURI().toURL()); + collector.addPath(entry.getPath()); } catch (MalformedURLException e) { TeaVMEclipsePlugin.logError(e); } @@ -76,7 +79,7 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { case IClasspathEntry.CPE_SOURCE: if (entry.getOutputLocation() != null) { try { - urls.add(entry.getOutputLocation().toFile().toURI().toURL()); + collector.addPath(workspaceRoot.findMember(entry.getOutputLocation()).getLocation()); } catch (MalformedURLException e) { TeaVMEclipsePlugin.logError(e); } @@ -91,7 +94,8 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { IJavaProject depJavaProject = JavaCore.create(depProject); if (depJavaProject.getOutputLocation() != null) { try { - urls.add(depJavaProject.getOutputLocation().toFile().toURI().toURL()); + collector.addPath(workspaceRoot.findMember(depJavaProject.getOutputLocation()) + .getLocation()); } catch (MalformedURLException e) { TeaVMEclipsePlugin.logError(e); } @@ -100,6 +104,31 @@ public class TeaVMBuilder extends IncrementalProjectBuilder { } } } - return urls.toArray(new URL[urls.size()]); + return collector.getUrls(); + } + + static class PathCollector { + private Set urlSet = new HashSet<>(); + private List urls = new ArrayList<>(); + + public void addPath(IPath path) throws MalformedURLException { + File file = path.toFile(); + if (!file.exists()) { + return; + } + if (file.isDirectory()) { + file = new File(file.getAbsolutePath() + "/"); + } else { + file = new File(file.getAbsolutePath()); + } + URL url = file.toURI().toURL(); + if (urlSet.add(url)) { + urls.add(url); + } + } + + public URL[] getUrls() { + return urls.toArray(new URL[urls.size()]); + } } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java index c7a3fbc94..784d9ed61 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java @@ -36,6 +36,7 @@ import org.eclipse.ui.plugin.AbstractUIPlugin; public class TeaVMEclipsePlugin extends AbstractUIPlugin { public static final String ID = "org.teavm.eclipse"; public static final String NATURE_ID = ID + ".nature"; + public static final String BUILDER_ID = ID + ".builder"; public static final String MAIN_METHOD_DIALOG_ID = ID + ".dialogs.mainMethod"; private static TeaVMEclipsePlugin defaultInstance; private ConcurrentMap settingsMap = new ConcurrentHashMap<>(); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipseProgressListener.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipseProgressListener.java new file mode 100644 index 000000000..57808acac --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipseProgressListener.java @@ -0,0 +1,48 @@ +package org.teavm.eclipse; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.teavm.vm.TeaVMPhase; +import org.teavm.vm.TeaVMProgressFeedback; +import org.teavm.vm.TeaVMProgressListener; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMEclipseProgressListener implements TeaVMProgressListener { + private IProgressMonitor progressMonitor; + + public TeaVMEclipseProgressListener(IProgressMonitor progressMonitor) { + this.progressMonitor = progressMonitor; + } + + @Override + public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) { + String taskName = "Building"; + switch (phase) { + case DECOMPILATION: + taskName = "Decompiling"; + break; + case DEPENDENCY_CHECKING: + taskName = "Dependency checking"; + break; + case DEVIRTUALIZATION: + taskName = "Applying devirtualization"; + break; + case LINKING: + taskName = "Linking"; + break; + case RENDERING: + taskName = "Rendering"; + break; + } + progressMonitor.beginTask(taskName, count); + return progressMonitor.isCanceled() ? TeaVMProgressFeedback.CANCEL : TeaVMProgressFeedback.CONTINUE; + } + + @Override + public TeaVMProgressFeedback progressReached(int progress) { + progressMonitor.worked(progress); + return progressMonitor.isCanceled() ? TeaVMProgressFeedback.CANCEL : TeaVMProgressFeedback.CONTINUE; + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java index 49fa6b52a..8f018a968 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java @@ -1,8 +1,12 @@ package org.teavm.eclipse; +import java.util.Arrays; +import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; /** * @@ -11,12 +15,50 @@ import org.eclipse.core.runtime.CoreException; public class TeaVMProjectNature implements IProjectNature { private IProject project; + private boolean hasBuilder() throws CoreException { + IProjectDescription description = project.getDescription(); + ICommand[] buildCommands = description.getBuildSpec(); + for (ICommand command : buildCommands) { + if (command.getBuilderName().equals(TeaVMEclipsePlugin.BUILDER_ID)) { + return true; + } + } + return false; + } + @Override public void configure() throws CoreException { + if (!hasBuilder()) { + IProjectDescription description = project.getDescription(); + ICommand[] buildCommands = description.getBuildSpec(); + buildCommands = Arrays.copyOf(buildCommands, buildCommands.length + 1); + ICommand teaVMCommand = description.newCommand(); + teaVMCommand.setBuilderName(TeaVMEclipsePlugin.BUILDER_ID); + buildCommands[buildCommands.length - 1] = teaVMCommand; + description.setBuildSpec(buildCommands); + project.setDescription(description, new NullProgressMonitor()); + } } @Override public void deconfigure() throws CoreException { + if (hasBuilder()) { + IProjectDescription description = project.getDescription(); + ICommand[] buildCommands = description.getBuildSpec(); + int index = -1; + for (int i = 0; i < buildCommands.length; ++i) { + ICommand command = buildCommands[i]; + if (command.getBuilderName().equals(TeaVMEclipsePlugin.BUILDER_ID)) { + index = i; + break; + } + } + ICommand[] newBuildCommands = new ICommand[buildCommands.length - 1]; + System.arraycopy(buildCommands, 0, newBuildCommands, 0, index); + System.arraycopy(buildCommands, index + 1, newBuildCommands, index, newBuildCommands.length - index); + description.setBuildSpec(newBuildCommands); + project.setDescription(description, new NullProgressMonitor()); + } } @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java index a8e3239e1..ad19fb8ad 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java @@ -63,7 +63,7 @@ public class TeaVMSourcePathComputerDelegate implements ISourcePathComputerDeleg case IClasspathEntry.CPE_CONTAINER: sourceContainers.add(new ClasspathContainerSourceContainer(entry.getPath())); break; - case IClasspathEntry.CPE_LIBRARY:; + case IClasspathEntry.CPE_LIBRARY: sourceContainers.add(new ExternalArchiveSourceContainer(entry.getPath().toString(), true)); if (entry.getSourceAttachmentPath() != null) { System.out.println(entry.getSourceAttachmentPath()); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java index 666b1783b..4055b8411 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java @@ -26,7 +26,7 @@ public class MainClassSelectionDialog extends FilteredItemsSelectionDialog { public MainClassSelectionDialog(Shell shell, IJavaProject javaProject) { super(shell, false); this.javaProject = javaProject; - setTitle("Searching main class"); + setTitle("Selecting main class"); LabelProvider labelProvider = new LabelProvider() { @Override public String getText(Object element) { return getElementName(element); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyWidget.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyWidget.java index fb87cb3c4..374c67687 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyWidget.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyWidget.java @@ -167,7 +167,7 @@ public class TeaVMProjectPropertyWidget extends Composite { private void chooseFileSystemTargetDirectory() { String filePath = targetDirectoryField.getText(); - FileDialog dialog = new FileDialog(getShell(), SWT.SAVE); + DirectoryDialog dialog = new DirectoryDialog(getShell()); filePath = dialog.open(); if (filePath != null) { targetDirectoryField.setText(filePath); diff --git a/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java b/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java index 52aea38c1..3a7d431e2 100644 --- a/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java +++ b/teavm-maven-plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java @@ -214,8 +214,6 @@ public class BuildJavascriptMojo extends AbstractMojo { throw new MojoExecutionException("Unexpected error occured", e); } catch (TeaVMToolException e) { throw new MojoExecutionException("IO error occured", e); - } catch (InterruptedException e) { - throw new MojoExecutionException("Build was interrupted", e); } }