diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java index ad31ae35a..771debee6 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java @@ -26,6 +26,7 @@ public class PreferencesBasedTeaVMProjectSettings implements TeaVMProjectSetting public static final String SOURCE_MAPS = "sourceMaps"; public static final String DEBUG_INFORMATION = "debugInformation"; public static final String PROPERTIES = "properties"; + public static final String CLASSES = "classes"; public static final String TRANSFORMERS = "transformers"; private static final String NEW_PROFILE_NAME = "New profile"; @@ -144,6 +145,7 @@ public class PreferencesBasedTeaVMProjectSettings implements TeaVMProjectSetting private boolean debugInformationGenerated; private Properties properties = new Properties(); private String[] transformers = new String[0]; + private Map classeAliases = new HashMap<>(); @Override public String getName() { @@ -274,6 +276,16 @@ public class PreferencesBasedTeaVMProjectSettings implements TeaVMProjectSetting this.properties.putAll(properties); } + @Override + public Map getClassAliases() { + return new HashMap<>(classeAliases); + } + + @Override + public void setClassAliases(Map classAliases) { + this.classeAliases = new HashMap<>(classAliases); + } + @Override public String[] getTransformers() { return transformers.clone(); @@ -305,6 +317,11 @@ public class PreferencesBasedTeaVMProjectSettings implements TeaVMProjectSetting Preferences transformersPrefs = preferences.node(TRANSFORMERS); transformersPrefs.sync(); transformers = transformersPrefs.keys(); + Preferences classesPrefs = preferences.node(CLASSES); + classesPrefs.sync(); + for (String key : classesPrefs.keys()) { + classeAliases.put(key, classesPrefs.get(key, "_")); + } } public void save() throws BackingStoreException { @@ -331,6 +348,12 @@ public class PreferencesBasedTeaVMProjectSettings implements TeaVMProjectSetting transformersPrefs.put(transformer, ""); } transformersPrefs.flush(); + Preferences classesPrefs = preferences.node(CLASSES); + classesPrefs.clear(); + for (String key : classeAliases.keySet()) { + classesPrefs.put(key, classeAliases.get(key)); + } + classesPrefs.flush(); preferences.flush(); } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProfile.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProfile.java index 14de2461f..222b1fdc5 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProfile.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProfile.java @@ -1,5 +1,6 @@ package org.teavm.eclipse; +import java.util.Map; import java.util.Properties; /** @@ -58,4 +59,8 @@ public interface TeaVMProfile { String[] getTransformers(); void setTransformers(String[] transformers); + + Map getClassAliases(); + + void setClassAliases(Map classAliases); } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java index d52caffe3..30999c5b1 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java @@ -19,6 +19,7 @@ import org.teavm.model.ClassHolderTransformer; import org.teavm.model.InstructionLocation; import org.teavm.model.MethodReference; import org.teavm.model.ValueType; +import org.teavm.tooling.ClassAlias; import org.teavm.tooling.RuntimeCopyOperation; import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMToolException; @@ -38,10 +39,12 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder { @Override protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { TeaVMProjectSettings projectSettings = getProjectSettings(); + projectSettings.load(); TeaVMProfile profiles[] = getEnabledProfiles(projectSettings); monitor.beginTask("Running TeaVM", profiles.length * TICKS_PER_PROFILE); try { prepareClassPath(); + removeMarkers(); ClassLoader classLoader = new URLClassLoader(classPath, TeaVMProjectBuilder.class.getClassLoader()); for (TeaVMProfile profile : profiles) { SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, TICKS_PER_PROFILE); @@ -75,7 +78,6 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder { if ((kind == AUTO_BUILD || kind == INCREMENTAL_BUILD) && !shouldBuild(profile)) { return; } - getProject().deleteMarkers(TeaVMEclipsePlugin.CONFIG_MARKER_ID, true, IResource.DEPTH_INFINITE); IStringVariableManager varManager = VariablesPlugin.getDefault().getStringVariableManager(); TeaVMTool tool = new TeaVMTool(); tool.setClassLoader(classLoader); @@ -94,11 +96,16 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder { for (ClassHolderTransformer transformer : instantiateTransformers(profile, classLoader)) { tool.getTransformers().add(transformer); } + for (Map.Entry entry : profile.getClassAliases().entrySet()) { + ClassAlias classAlias = new ClassAlias(); + classAlias.setClassName(entry.getKey()); + classAlias.setAlias(entry.getValue()); + tool.getClassAliases().add(classAlias); + } tool.setProgressListener(new TeaVMEclipseProgressListener(this, monitor, TICKS_PER_PROFILE)); try { monitor.beginTask("Running TeaVM", 10000); tool.generate(); - removeMarkers(); if (tool.getDependencyViolations().hasMissingItems()) { putMarkers(tool.getDependencyViolations()); } else if (!tool.wasCancelled()) { @@ -177,6 +184,7 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder { private void removeMarkers() throws CoreException { getProject().deleteMarkers(TeaVMEclipsePlugin.DEPENDENCY_MARKER_ID, true, IResource.DEPTH_INFINITE); + getProject().deleteMarkers(TeaVMEclipsePlugin.CONFIG_MARKER_ID, true, IResource.DEPTH_INFINITE); } private void putMarkers(DependencyViolations violations) throws CoreException { @@ -375,6 +383,7 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder { IMarker marker = getProject().createMarker(TeaVMEclipsePlugin.CONFIG_MARKER_ID); marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); marker.setAttribute(IMarker.MESSAGE, message); + marker.setAttribute(IMarker.LOCATION, getProject().getName() + " project"); } private void prepareClassPath() throws CoreException { diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/AnyClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/AnyClassSelectionDialog.java new file mode 100644 index 000000000..f013ade50 --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/AnyClassSelectionDialog.java @@ -0,0 +1,30 @@ +package org.teavm.eclipse.ui; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.swt.widgets.Shell; + +/** + * + * @author Alexey Andreev + */ +public class AnyClassSelectionDialog extends ClassSelectionDialog { + public AnyClassSelectionDialog(Shell shell, IJavaProject javaProject) { + super(shell, javaProject); + } + + @Override + protected SearchPattern createSearchPattern(String text) { + return SearchPattern.createPattern("*" + text + "*", IJavaSearchConstants.CLASS, + IJavaSearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH); + } + + @Override + protected IType acceptMatch(SearchMatch match) throws CoreException { + return (IType)match.getElement(); + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java index 0283d433c..b7b621179 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java @@ -118,7 +118,7 @@ public abstract class ClassSelectionDialog extends FilteredItemsSelectionDialog private IType[] findTypes(String patternText, IProgressMonitor progressMonitor) { IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] { javaProject }, - IJavaSearchScope.SOURCES | IJavaSearchScope.REFERENCED_PROJECTS | + IJavaSearchScope.SOURCES | IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SYSTEM_LIBRARIES | IJavaSearchScope.APPLICATION_LIBRARIES); SearchPattern pattern = createSearchPattern(patternText); SearchParticipant[] participants = new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java index 2273ee7ea..fea403080 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java @@ -1,8 +1,7 @@ package org.teavm.eclipse.ui; -import java.util.Arrays; +import java.util.*; import java.util.List; -import java.util.Properties; import org.eclipse.core.databinding.observable.list.WritableList; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -16,13 +15,7 @@ import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ColumnViewer; -import org.eclipse.jface.viewers.EditingSupport; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.*; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.SelectionAdapter; @@ -64,7 +57,11 @@ public class TeaVMProfileDialog extends Dialog { private Button addPropertyButton; private Button deletePropertyButton; private WritableList propertyList = new WritableList(); - private org.eclipse.swt.widgets.List transormersList; + private TableViewer classAliasesTableViewer; + private Button addClassAliasButton; + private Button removeClassAliasButton; + private WritableList classAliases = new WritableList(); + private org.eclipse.swt.widgets.List transformersList; private Button addTransformerButton; private Button removeTransformerButton; private IJavaProject javaProject; @@ -131,6 +128,7 @@ public class TeaVMProfileDialog extends Dialog { layout.marginHeight = 8; layout.verticalSpacing = 10; container.setLayout(layout); + createClassesGroup(container); createTransformersGroup(container); return container; } @@ -276,10 +274,73 @@ public class TeaVMProfileDialog extends Dialog { String value = ""; } + private void createClassesGroup(Composite parent) { + Group group = createGroup(parent, "Class aliases", 2, true); + classAliasesTableViewer = new TableViewer(group, SWT.BORDER | SWT.V_SCROLL); + classAliasesTableViewer.getTable().setLinesVisible(true); + classAliasesTableViewer.getTable().setHeaderVisible(true); + classAliasesTableViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 3)); + classAliasesTableViewer.setContentProvider(new ObservableListContentProvider()); + classAliasesTableViewer.setInput(classAliases); + + TableViewerColumn classNameColumn = new TableViewerColumn(classAliasesTableViewer, SWT.LEFT); + classNameColumn.getColumn().setWidth(200); + classNameColumn.getColumn().setText("Class"); + classNameColumn.setLabelProvider(new ColumnLabelProvider() { + @Override public String getText(Object element) { + ClassAliasRow item = (ClassAliasRow)element; + return item.className; + } + }); + + TableViewerColumn valueColumn = new TableViewerColumn(classAliasesTableViewer, SWT.LEFT); + valueColumn.getColumn().setWidth(200); + valueColumn.getColumn().setText("Alias"); + valueColumn.setLabelProvider(new ColumnLabelProvider() { + @Override public String getText(Object element) { + ClassAliasRow item = (ClassAliasRow)element; + return item.alias; + } + }); + valueColumn.setEditingSupport(new EditingSupport(valueColumn.getViewer()) { + private TextCellEditor editor = new TextCellEditor(classAliasesTableViewer.getTable()); + @Override protected Object getValue(Object element) { + ClassAliasRow item = (ClassAliasRow)element; + return item.alias; + } + @Override protected void setValue(Object element, Object value) { + ClassAliasRow item = (ClassAliasRow)element; + item.alias = (String)value; + getViewer().update(element, null); + } + @Override protected boolean canEdit(Object element) { return true; } + @Override protected CellEditor getCellEditor(Object element) { return editor; } + }); + + addClassAliasButton = new Button(group, SWT.PUSH); + addClassAliasButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); + addClassAliasButton.setText("Add..."); + addClassAliasButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { addClass(); } + }); + + removeClassAliasButton = new Button(group, SWT.PUSH); + removeClassAliasButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); + removeClassAliasButton.setText("Remove"); + removeClassAliasButton.addSelectionListener(new SelectionAdapter() { + @Override public void widgetSelected(SelectionEvent e) { removeClass(); } + }); + } + + static class ClassAliasRow { + String className; + String alias; + } + private void createTransformersGroup(Composite parent) { Group group = createGroup(parent, "TeaVM bytecode transformers", 2, true); - transormersList = new org.eclipse.swt.widgets.List(group, SWT.SINGLE | SWT.BORDER); - transormersList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 3)); + transformersList = new org.eclipse.swt.widgets.List(group, SWT.SINGLE | SWT.BORDER); + transformersList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 3)); addTransformerButton = new Button(group, SWT.PUSH); addTransformerButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); @@ -491,30 +552,63 @@ public class TeaVMProfileDialog extends Dialog { } private void addTransformer() { - TransformerClassSelectionDialog selectionDialog = new TransformerClassSelectionDialog(getParentShell(), + TransformerClassSelectionDialog selectionDialog = new TransformerClassSelectionDialog(getShell(), javaProject); - if (selectionDialog.open() == MainClassSelectionDialog.OK) { + if (selectionDialog.open() == ClassSelectionDialog.OK) { Object[] result = selectionDialog.getResult(); if (result.length > 0) { IType type = (IType)result[0]; - List existingTypes = Arrays.asList(transormersList.getItems()); + List existingTypes = Arrays.asList(transformersList.getItems()); if (!existingTypes.contains(type.getFullyQualifiedName())) { - transormersList.add(type.getFullyQualifiedName()); + transformersList.add(type.getFullyQualifiedName()); } } } } private void removeTransformer() { - if (transormersList.getSelectionCount() != 1) { + if (transformersList.getSelectionCount() != 1) { return; } boolean confirmed = MessageDialog.openConfirm(getShell(), "Removal confirmation", - "Are you sure to delete the " + transormersList.getSelection()[0] + " transformer?"); + "Are you sure to delete the " + transformersList.getSelection()[0] + " transformer?"); if (!confirmed) { return; } - transormersList.remove(transormersList.getSelectionIndex()); + transformersList.remove(transformersList.getSelectionIndex()); + } + + private void addClass() { + AnyClassSelectionDialog selectionDialog = new AnyClassSelectionDialog(getShell(), javaProject); + if (selectionDialog.open() == ClassSelectionDialog.OK) { + Object[] result = selectionDialog.getResult(); + if (result.length > 0) { + IType type = (IType)result[0]; + for (int i = 0; i < classAliases.size(); ++i) { + ClassAliasRow row = (ClassAliasRow)classAliases.get(i); + if (row.className.equals(type.getFullyQualifiedName())) { + return; + } + } + ClassAliasRow row = new ClassAliasRow(); + row.alias = "_"; + row.className = type.getFullyQualifiedName(); + classAliases.add(row); + } + } + } + + private void removeClass() { + Table table = classAliasesTableViewer.getTable(); + if (table.getSelectionCount() != 1) { + return; + } + boolean confirmed = MessageDialog.openConfirm(getShell(), "Removal confirmation", + "Are you sure to delete the " + table.getSelection()[0].getText(0) + " class?"); + if (!confirmed) { + return; + } + classAliases.remove(table.getSelectionIndex()); } @Override @@ -555,7 +649,13 @@ public class TeaVMProfileDialog extends Dialog { propertyList.add(property); } updateCacheFieldsEnabled(); - transormersList.setItems(profile.getTransformers()); + transformersList.setItems(profile.getTransformers()); + for (Map.Entry entry : profile.getClassAliases().entrySet()) { + ClassAliasRow row = new ClassAliasRow(); + row.className = entry.getKey(); + row.alias = entry.getValue(); + classAliases.add(row); + } } private boolean save() { @@ -581,7 +681,13 @@ public class TeaVMProfileDialog extends Dialog { properties.setProperty(property.key, property.value); } profile.setProperties(properties); - profile.setTransformers(transormersList.getItems()); + profile.setTransformers(transformersList.getItems()); + Map classAliasMap = new HashMap<>(); + for (int i = 0; i < classAliases.size(); ++i) { + ClassAliasRow row = (ClassAliasRow)classAliases.get(i); + classAliasMap.put(row.className, row.alias); + } + profile.setClassAliases(classAliasMap); return true; } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java index a52e963cf..f4d60899a 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java @@ -1,6 +1,7 @@ package org.teavm.eclipse.ui; import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.search.IJavaSearchConstants; @@ -27,6 +28,10 @@ public class TransformerClassSelectionDialog extends ClassSelectionDialog { @Override protected IType acceptMatch(SearchMatch match) throws CoreException { - return (IType)match.getElement(); + IType type = (IType)match.getElement(); + if ((type.getFlags() & Flags.AccPublic) != 0) { + return type; + } + return null; } }