Add a minimal TeaVM builder that simply works

This commit is contained in:
konsoletyper 2014-09-15 12:13:27 +04:00
parent 80899af284
commit d9ea3764f8
19 changed files with 287 additions and 46 deletions

View File

@ -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();

View File

@ -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)

View File

@ -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) {

View File

@ -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;
}
/**
* <p>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<ClassNode> 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<InstructionLocation, InstructionLocation[]> cfg = ProgramUtils.getLocationCFG(program);
for (Map.Entry<InstructionLocation, InstructionLocation[]> 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<ClassNode> modelToAst(ListableClassHolderSource classes) throws InterruptedException {
private List<ClassNode> 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) {

View File

@ -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
}

View File

@ -20,7 +20,7 @@ package org.teavm.vm;
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
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);
}

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry exported="true" kind="lib" path="lib/gson-2.2.4.jar"/>
<classpathentry exported="true" kind="lib" path="lib/teavm-classlib-0.2-SNAPSHOT.jar"/>
<classpathentry exported="true" kind="lib" path="lib/teavm-platform-0.2-SNAPSHOT.jar"/>
<classpathentry exported="true" kind="lib" path="lib/asm-5.0.1.jar"/>
<classpathentry exported="true" kind="lib" path="lib/asm-commons-5.0.1.jar"/>
<classpathentry exported="true" kind="lib" path="lib/asm-debug-all-4.2.jar"/>

View File

@ -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

View File

@ -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

View File

@ -50,6 +50,7 @@
<runtime>
<run class="org.teavm.eclipse.TeaVMProjectNature"/>
</runtime>
<builder id="org.teavm.eclipse.builder"/>
</extension>
<extension point="org.eclipse.ui.propertyPages">
<page id="org.teavm.eclipse.projectProperties" name="TeaVM" class="org.teavm.eclipse.ui.TeaVMProjectPropertyPage">
@ -61,4 +62,9 @@
</enabledWhen>
</page>
</extension>
<extension point="org.eclipse.core.resources.builders" id="builder" name="TeaVM builder">
<builder hasNature="true">
<run class="org.teavm.eclipse.TeaVMBuilder"/>
</builder>
</extension>
</plugin>

View File

@ -17,6 +17,11 @@
<artifactId>teavm-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-classlib</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-chrome-rdp</artifactId>

View File

@ -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<URL> 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 collector.getUrls();
}
static class PathCollector {
private Set<URL> urlSet = new HashSet<>();
private List<URL> 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()]);
}
}
}

View File

@ -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<IProject, TeaVMProjectSettings> settingsMap = new ConcurrentHashMap<>();

View File

@ -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;
}
}

View File

@ -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

View File

@ -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());

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}