mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Add main class selection in the settings of a project
This commit is contained in:
parent
8351c48e25
commit
8202faca69
|
@ -54,3 +54,4 @@ Bundle-ClassPath: .,
|
|||
lib/websocket-server-9.2.1.v20140609.jar,
|
||||
lib/websocket-servlet-9.2.1.v20140609.jar
|
||||
Export-Package: org.teavm.eclipse.debugger
|
||||
Bundle-ActivationPolicy: lazy
|
||||
|
|
|
@ -52,9 +52,13 @@
|
|||
</runtime>
|
||||
</extension>
|
||||
<extension point="org.eclipse.ui.propertyPages">
|
||||
<page id="org.teavm.eclipse.projectProperties" name="TeaVM"
|
||||
objectClass="org.eclipse.core.resources.IProject"
|
||||
class="org.teavm.eclipse.ui.TeaVMProjectPropertyPage">
|
||||
<page id="org.teavm.eclipse.projectProperties" name="TeaVM" class="org.teavm.eclipse.ui.TeaVMProjectPropertyPage">
|
||||
<enabledWhen>
|
||||
<or>
|
||||
<instanceof value="org.eclipse.core.resources.IProject"/>
|
||||
<instanceof value="org.eclipse.jdt.core.IJavaProject"/>
|
||||
</or>
|
||||
</enabledWhen>
|
||||
</page>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -15,22 +15,20 @@
|
|||
*/
|
||||
package org.teavm.eclipse;
|
||||
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class TeaVMEclipsePlugin extends Plugin {
|
||||
public class TeaVMEclipsePlugin extends AbstractUIPlugin {
|
||||
public static final String ID = "org.teavm.eclipse";
|
||||
|
||||
public static final String NATURE_ID = "org.teavm.eclipse.nature";
|
||||
|
||||
public static final String NATURE_ID = ID + ".nature";
|
||||
public static final String MAIN_METHOD_DIALOG_ID = ID + ".dialogs.mainMethod";
|
||||
private static TeaVMEclipsePlugin defaultInstance;
|
||||
|
||||
static {
|
||||
}
|
||||
|
||||
public TeaVMEclipsePlugin() {
|
||||
defaultInstance = this;
|
||||
}
|
||||
|
@ -38,4 +36,12 @@ public class TeaVMEclipsePlugin extends Plugin {
|
|||
public static TeaVMEclipsePlugin getDefault() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public static IStatus makeError(Throwable e) {
|
||||
return new Status(IStatus.ERROR, ID, "Error occured", e);
|
||||
}
|
||||
|
||||
public static void logError(Throwable e) {
|
||||
getDefault().getLog().log(makeError(e));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
package org.teavm.eclipse.ui;
|
||||
|
||||
import static org.teavm.eclipse.TeaVMEclipsePlugin.MAIN_METHOD_DIALOG_ID;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.eclipse.core.runtime.*;
|
||||
import org.eclipse.jdt.core.*;
|
||||
import org.eclipse.jdt.core.search.*;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||
import org.eclipse.jface.viewers.LabelProvider;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
|
||||
import org.teavm.eclipse.TeaVMEclipsePlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class MainClassSelectionDialog extends FilteredItemsSelectionDialog {
|
||||
private IJavaProject javaProject;
|
||||
|
||||
public MainClassSelectionDialog(Shell shell, IJavaProject javaProject) {
|
||||
super(shell, false);
|
||||
this.javaProject = javaProject;
|
||||
setTitle("Searching main class");
|
||||
LabelProvider labelProvider = new LabelProvider() {
|
||||
@Override public String getText(Object element) {
|
||||
return getElementName(element);
|
||||
}
|
||||
};
|
||||
setListLabelProvider(labelProvider);
|
||||
setDetailsLabelProvider(labelProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Control createExtendedContentArea(Composite parent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemsFilter createFilter() {
|
||||
return new ItemsFilter() {
|
||||
@Override public boolean matchItem(Object item) {
|
||||
IType type = (IType)item;
|
||||
return type.getTypeQualifiedName().toLowerCase().contains(getPattern().toLowerCase());
|
||||
}
|
||||
@Override public boolean isConsistentItem(Object item) {
|
||||
return item instanceof IType;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillContentProvider(AbstractContentProvider contentProvider, ItemsFilter filter,
|
||||
IProgressMonitor progressMonitor) throws CoreException {
|
||||
IType[] mainTypes = findMainTypes(progressMonitor);
|
||||
for (IType type : mainTypes) {
|
||||
contentProvider.add(type, filter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IDialogSettings getDialogSettings() {
|
||||
IDialogSettings settings = TeaVMEclipsePlugin.getDefault().getDialogSettings();
|
||||
IDialogSettings section = settings.getSection(MAIN_METHOD_DIALOG_ID);
|
||||
if (section == null) {
|
||||
section = settings.addNewSection(MAIN_METHOD_DIALOG_ID);
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName(Object element) {
|
||||
IType type = (IType)element;
|
||||
return getTypeName(type);
|
||||
}
|
||||
|
||||
private String getTypeName(IType type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(type.getTypeQualifiedName());
|
||||
if (type.getPackageFragment() != null) {
|
||||
sb.append(" in ").append(type.getPackageFragment().getElementName());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Comparator<?> getItemsComparator() {
|
||||
return new Comparator<IType>() {
|
||||
@Override public int compare(IType o1, IType o2) {
|
||||
return getTypeName(o1).compareTo(getTypeName(o2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus validateItem(Object item) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
private IType[] findMainTypes(IProgressMonitor progressMonitor) {
|
||||
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] { javaProject },
|
||||
IJavaSearchScope.SOURCES | IJavaSearchScope.REFERENCED_PROJECTS |
|
||||
IJavaSearchScope.APPLICATION_LIBRARIES);
|
||||
SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD,
|
||||
IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
|
||||
SearchParticipant[] participants = new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
|
||||
MainClassCollector collector = new MainClassCollector();
|
||||
try {
|
||||
new SearchEngine().search(pattern, participants, scope, collector, progressMonitor);
|
||||
} catch (CoreException e) {
|
||||
logError(e);
|
||||
return new IType[0];
|
||||
}
|
||||
IType[] foundTypes = collector.getTypes().toArray(new IType[collector.getTypes().size()]);
|
||||
return foundTypes;
|
||||
}
|
||||
|
||||
private void logError(Throwable e) {
|
||||
IStatus status = TeaVMEclipsePlugin.makeError(e);
|
||||
TeaVMEclipsePlugin.getDefault().getLog().log(status);
|
||||
ErrorDialog.openError(getShell(), "Error", "Error", status);
|
||||
}
|
||||
|
||||
private static class MainClassCollector extends SearchRequestor {
|
||||
private Set<IType> types = new HashSet<>();
|
||||
|
||||
public Set<IType> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptSearchMatch(SearchMatch match) throws CoreException {
|
||||
IMethod method = (IMethod)match.getElement();
|
||||
if ((method.getFlags() & Flags.AccStatic) != 0) {
|
||||
types.add(method.getDeclaringType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,15 @@
|
|||
package org.teavm.eclipse.ui;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.ui.IWorkbenchPropertyPage;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.dialogs.PropertyPage;
|
||||
import org.teavm.eclipse.TeaVMEclipsePlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -16,7 +21,17 @@ public class TeaVMProjectPropertyPage extends PropertyPage implements IWorkbench
|
|||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
widget = new TeaVMProjectPropertyWidget(parent);
|
||||
widget.load((IProject)getElement().getAdapter(IProject.class));
|
||||
widget.setRunnableContext(PlatformUI.getWorkbench().getProgressService());
|
||||
IProject project = (IProject)getElement().getAdapter(IProject.class);
|
||||
try {
|
||||
if (project.hasNature(JavaCore.NATURE_ID)) {
|
||||
IJavaProject javaProject = JavaCore.create(project);
|
||||
widget.setJavaProject(javaProject);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
TeaVMEclipsePlugin.logError(e);
|
||||
}
|
||||
widget.load(project);
|
||||
return widget;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,16 +4,27 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.util.Arrays;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IProjectDescription;
|
||||
import org.eclipse.core.resources.ProjectScope;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.eclipse.jdt.core.IJavaProject;
|
||||
import org.eclipse.jdt.core.IType;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
|
||||
import org.eclipse.jface.operation.IRunnableContext;
|
||||
import org.eclipse.jface.operation.IRunnableWithProgress;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.layout.RowData;
|
||||
import org.eclipse.swt.layout.RowLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.osgi.service.prefs.BackingStoreException;
|
||||
import org.teavm.eclipse.TeaVMEclipsePlugin;
|
||||
|
||||
/**
|
||||
|
@ -22,6 +33,10 @@ import org.teavm.eclipse.TeaVMEclipsePlugin;
|
|||
*/
|
||||
public class TeaVMProjectPropertyWidget extends Composite {
|
||||
private Button natureButton;
|
||||
private Text mainClassField;
|
||||
private Button mainClassChooseButton;
|
||||
private IJavaProject javaProject;
|
||||
private IRunnableContext runnableContext;
|
||||
|
||||
public TeaVMProjectPropertyWidget(Composite parent) {
|
||||
super(parent, SWT.NONE);
|
||||
|
@ -31,22 +46,84 @@ public class TeaVMProjectPropertyWidget extends Composite {
|
|||
setLayout(layout);
|
||||
natureButton = new Button(this, SWT.CHECK);
|
||||
natureButton.setText("TeaVM build enabled");
|
||||
createOptionsContainer();
|
||||
|
||||
natureButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
updateEnabled(natureButton.getSelection());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateEnabled(boolean enabled) {
|
||||
mainClassField.setEnabled(enabled);
|
||||
mainClassChooseButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
private void createOptionsContainer() {
|
||||
Composite container = new Composite(this, SWT.NONE);
|
||||
GridLayout layout = new GridLayout();
|
||||
layout.numColumns = 2;
|
||||
layout.verticalSpacing = 6;
|
||||
layout.horizontalSpacing = 6;
|
||||
container.setLayout(layout);
|
||||
createMainClassField(container);
|
||||
}
|
||||
|
||||
private void createMainClassField(Composite container) {
|
||||
Label label = new Label(container, SWT.NONE);
|
||||
label.setText("Main class:");
|
||||
Composite row = new Composite(container, SWT.NONE);
|
||||
RowLayout rowLayout = new RowLayout();
|
||||
row.setLayout(rowLayout);
|
||||
rowLayout.type = SWT.HORIZONTAL;
|
||||
rowLayout.spacing = 3;
|
||||
mainClassField = new Text(row, SWT.SINGLE | SWT.BORDER);
|
||||
RowData rowData = new RowData();
|
||||
rowData.width = 300;
|
||||
mainClassField.setLayoutData(rowData);
|
||||
mainClassChooseButton = new Button(row, SWT.PUSH);
|
||||
mainClassChooseButton.setText("Choose...");
|
||||
mainClassChooseButton.addSelectionListener(new SelectionAdapter() {
|
||||
@Override public void widgetSelected(SelectionEvent e) {
|
||||
chooseMainClass();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void chooseMainClass() {
|
||||
MainClassSelectionDialog selectionDialog = new MainClassSelectionDialog(getShell(), javaProject);
|
||||
if (selectionDialog.open() == MainClassSelectionDialog.OK) {
|
||||
Object[] result = selectionDialog.getResult();
|
||||
if (result.length > 0) {
|
||||
IType type = (IType)result[0];
|
||||
mainClassField.setText(type.getFullyQualifiedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setJavaProject(IJavaProject javaProject) {
|
||||
this.javaProject = javaProject;
|
||||
}
|
||||
|
||||
public void setRunnableContext(IRunnableContext runnableContext) {
|
||||
this.runnableContext = runnableContext;
|
||||
}
|
||||
|
||||
public void load(IProject project) {
|
||||
try {
|
||||
natureButton.setSelection(project.hasNature(TeaVMEclipsePlugin.NATURE_ID));
|
||||
} catch (CoreException e) {
|
||||
ProjectScope scope = new ProjectScope(project);
|
||||
IEclipsePreferences preferences = scope.getNode(TeaVMEclipsePlugin.ID);
|
||||
preferences.sync();
|
||||
mainClassField.setText(preferences.get("mainClass", ""));
|
||||
updateEnabled(natureButton.getSelection());
|
||||
} catch (CoreException | BackingStoreException e) {
|
||||
reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportError(Throwable e) {
|
||||
e.printStackTrace();
|
||||
Status status = new Status(Status.ERROR, TeaVMEclipsePlugin.ID, getToolTipText(), e);
|
||||
ErrorDialog.openError(getShell(), "Error occured", "Error occured", status);
|
||||
}
|
||||
|
||||
public boolean save(IProject project) {
|
||||
try {
|
||||
if (natureButton.getSelection()) {
|
||||
|
@ -58,17 +135,20 @@ public class TeaVMProjectPropertyWidget extends Composite {
|
|||
removeNature(project);
|
||||
}
|
||||
}
|
||||
ProjectScope scope = new ProjectScope(project);
|
||||
IEclipsePreferences preferences = scope.getNode(TeaVMEclipsePlugin.ID);
|
||||
preferences.put("mainClass", mainClassField.getText().trim());
|
||||
preferences.flush();
|
||||
return true;
|
||||
} catch (CoreException e) {
|
||||
} catch (CoreException | BackingStoreException e) {
|
||||
reportError(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void addNature(final IProject project) {
|
||||
ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(getShell());
|
||||
try {
|
||||
progressDialog.run(false, true, new IRunnableWithProgress() {
|
||||
runnableContext.run(false, true, new IRunnableWithProgress() {
|
||||
@Override
|
||||
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
|
||||
try {
|
||||
|
@ -86,24 +166,25 @@ public class TeaVMProjectPropertyWidget extends Composite {
|
|||
} catch (InterruptedException e) {
|
||||
reportError(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
reportError(e.getTargetException());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNature(final IProject project) {
|
||||
ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(getShell());
|
||||
try {
|
||||
progressDialog.run(false, true, new IRunnableWithProgress() {
|
||||
runnableContext.run(false, true, new IRunnableWithProgress() {
|
||||
@Override
|
||||
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
|
||||
try {
|
||||
String[] natureIds = project.getDescription().getNatureIds();
|
||||
IProjectDescription projectDescription = project.getDescription();
|
||||
String[] natureIds = projectDescription.getNatureIds();
|
||||
String[] newNatureIds = new String[natureIds.length - 1];
|
||||
for (int i = 0; i < natureIds.length; ++i) {
|
||||
if (natureIds.equals(TeaVMEclipsePlugin.NATURE_ID)) {
|
||||
System.arraycopy(natureIds, 0, newNatureIds, 0, i - 1);
|
||||
if (natureIds[i].equals(TeaVMEclipsePlugin.NATURE_ID)) {
|
||||
System.arraycopy(natureIds, 0, newNatureIds, 0, i);
|
||||
System.arraycopy(natureIds, i + 1, newNatureIds, i, newNatureIds.length - i);
|
||||
project.getDescription().setNatureIds(newNatureIds);
|
||||
projectDescription.setNatureIds(newNatureIds);
|
||||
project.setDescription(projectDescription, monitor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +196,13 @@ public class TeaVMProjectPropertyWidget extends Composite {
|
|||
} catch (InterruptedException e) {
|
||||
reportError(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
reportError(e.getTargetException());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void reportError(Throwable e) {
|
||||
IStatus status = TeaVMEclipsePlugin.makeError(e);
|
||||
TeaVMEclipsePlugin.getDefault().getLog().log(status);
|
||||
ErrorDialog.openError(getShell(), "Error occured", "Error occured", status);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user