diff --git a/teavm-eclipse/teavm-eclipse-plugin/.settings/org.eclipse.jdt.ui.prefs b/teavm-eclipse/teavm-eclipse-plugin/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..6592633f4
--- /dev/null
+++ b/teavm-eclipse/teavm-eclipse-plugin/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.ondemandthreshold=90
+org.eclipse.jdt.ui.staticondemandthreshold=3
diff --git a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml
index d09cc3412..c4f24e6c7 100644
--- a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml
+++ b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml
@@ -70,9 +70,15 @@
-
+
-
+
+
+
+
+
+
+
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 2540bb92d..bef957d2a 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
@@ -37,8 +37,9 @@ 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";
+ public static final String CLASS_DIALOG_ID = ID + ".dialogs.classSelection";
public static final String DEPENDENCY_MARKER_ID = ID + ".dependencyMarker";
+ public static final String CONFIG_MARKER_ID = ID + ".configMarker";
private static TeaVMEclipsePlugin defaultInstance;
private ConcurrentMap settingsMap = new ConcurrentHashMap<>();
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 a9c5530db..d52caffe3 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
@@ -1,6 +1,8 @@
package org.teavm.eclipse;
import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@@ -13,6 +15,7 @@ import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.teavm.dependency.*;
+import org.teavm.model.ClassHolderTransformer;
import org.teavm.model.InstructionLocation;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
@@ -72,6 +75,7 @@ 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);
@@ -87,6 +91,9 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
tool.setIncremental(profile.isIncremental());
String cacheDir = profile.getCacheDirectory();
tool.setCacheDirectory(!cacheDir.isEmpty() ? new File(varManager.performStringSubstitution(cacheDir)) : null);
+ for (ClassHolderTransformer transformer : instantiateTransformers(profile, classLoader)) {
+ tool.getTransformers().add(transformer);
+ }
tool.setProgressListener(new TeaVMEclipseProgressListener(this, monitor, TICKS_PER_PROFILE));
try {
monitor.beginTask("Running TeaVM", 10000);
@@ -328,6 +335,48 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
return projects;
}
+ private List instantiateTransformers(TeaVMProfile profile, ClassLoader classLoader)
+ throws CoreException{
+ List transformerInstances = new ArrayList<>();
+ for (String transformerName : profile.getTransformers()) {
+ Class> transformerRawType;
+ try {
+ transformerRawType = Class.forName(transformerName, true, classLoader);
+ } catch (ClassNotFoundException e) {
+ putConfigMarker("Transformer not found: " + transformerName);
+ continue;
+ }
+ if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
+ putConfigMarker("Transformer " + transformerName + " is not a subtype of " +
+ ClassHolderTransformer.class.getName());
+ continue;
+ }
+ Class extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
+ ClassHolderTransformer.class);
+ Constructor extends ClassHolderTransformer> ctor;
+ try {
+ ctor = transformerType.getConstructor();
+ } catch (NoSuchMethodException e) {
+ putConfigMarker("Transformer " + transformerName + " has no default constructor");
+ continue;
+ }
+ try {
+ ClassHolderTransformer transformer = ctor.newInstance();
+ transformerInstances.add(transformer);
+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+ putConfigMarker("Error instantiating transformer " + transformerName);
+ continue;
+ }
+ }
+ return transformerInstances;
+ }
+
+ private void putConfigMarker(String message) throws CoreException {
+ IMarker marker = getProject().createMarker(TeaVMEclipsePlugin.CONFIG_MARKER_ID);
+ marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+ marker.setAttribute(IMarker.MESSAGE, message);
+ }
+
private void prepareClassPath() throws CoreException {
classPath = new URL[0];
sourceContainers = new IContainer[0];
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
new file mode 100644
index 000000000..0283d433c
--- /dev/null
+++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java
@@ -0,0 +1,161 @@
+package org.teavm.eclipse.ui;
+
+import static org.teavm.eclipse.TeaVMEclipsePlugin.CLASS_DIALOG_ID;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.SearchRequestor;
+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
+ */
+public abstract class ClassSelectionDialog extends FilteredItemsSelectionDialog {
+ private IJavaProject javaProject;
+
+ public ClassSelectionDialog(Shell shell, IJavaProject javaProject) {
+ super(shell, false);
+ this.javaProject = javaProject;
+ LabelProvider labelProvider = new LabelProvider() {
+ @Override public String getText(Object element) {
+ return getElementName(element);
+ }
+ };
+ setListLabelProvider(labelProvider);
+ setDetailsLabelProvider(labelProvider);
+ }
+
+ @Override
+ protected String getInitialPattern() {
+ return "";
+ }
+
+ @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.getFullyQualifiedName().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 = findTypes(filter.getPattern(), progressMonitor);
+ for (IType type : mainTypes) {
+ contentProvider.add(type, filter);
+ }
+ }
+
+ @Override
+ protected IDialogSettings getDialogSettings() {
+ IDialogSettings settings = TeaVMEclipsePlugin.getDefault().getDialogSettings();
+ IDialogSettings section = settings.getSection(CLASS_DIALOG_ID);
+ if (section == null) {
+ section = settings.addNewSection(CLASS_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() {
+ @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[] findTypes(String patternText, IProgressMonitor progressMonitor) {
+ IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[] { javaProject },
+ IJavaSearchScope.SOURCES | IJavaSearchScope.REFERENCED_PROJECTS |
+ IJavaSearchScope.APPLICATION_LIBRARIES);
+ SearchPattern pattern = createSearchPattern(patternText);
+ SearchParticipant[] participants = new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
+ ClassCollector collector = new ClassCollector();
+ 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 class ClassCollector extends SearchRequestor {
+ private Set types = new HashSet<>();
+
+ public Set getTypes() {
+ return types;
+ }
+
+ @Override
+ public void acceptSearchMatch(SearchMatch match) throws CoreException {
+ IType type = acceptMatch(match);
+ if (type != null) {
+ types.add(type);
+ }
+ }
+ }
+
+ protected abstract SearchPattern createSearchPattern(String text);
+
+ protected abstract IType acceptMatch(SearchMatch match) throws CoreException;
+}
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 4055b8411..5b323b4ac 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
@@ -1,146 +1,37 @@
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.core.runtime.CoreException;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+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;
-import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
-import org.teavm.eclipse.TeaVMEclipsePlugin;
/**
*
* @author Alexey Andreev
*/
-public class MainClassSelectionDialog extends FilteredItemsSelectionDialog {
- private IJavaProject javaProject;
-
+public class MainClassSelectionDialog extends ClassSelectionDialog {
public MainClassSelectionDialog(Shell shell, IJavaProject javaProject) {
- super(shell, false);
- this.javaProject = javaProject;
+ super(shell, javaProject);
setTitle("Selecting 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) {
+ protected SearchPattern createSearchPattern(String text) {
+ return SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD,
+ IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
+ }
+
+ @Override
+ protected IType acceptMatch(SearchMatch match) throws CoreException {
+ IMethod method = (IMethod)match.getElement();
+ if ((method.getFlags() & Flags.AccStatic) != 0) {
+ return method.getDeclaringType();
+ }
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() {
- @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 types = new HashSet<>();
-
- public Set 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());
- }
- }
- }
}
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 73d668a9c..2273ee7ea 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
@@ -284,10 +284,20 @@ public class TeaVMProfileDialog extends Dialog {
addTransformerButton = new Button(group, SWT.PUSH);
addTransformerButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
addTransformerButton.setText("Add...");
+ addTransformerButton.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ addTransformer();
+ }
+ });
removeTransformerButton = new Button(group, SWT.PUSH);
removeTransformerButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
removeTransformerButton.setText("Remove");
+ removeTransformerButton.addSelectionListener(new SelectionAdapter() {
+ @Override public void widgetSelected(SelectionEvent e) {
+ removeTransformer();
+ }
+ });
}
private Group createGroup(Composite parent, String title, int columns, boolean fillVert) {
@@ -480,6 +490,33 @@ public class TeaVMProfileDialog extends Dialog {
return filePath;
}
+ private void addTransformer() {
+ TransformerClassSelectionDialog selectionDialog = new TransformerClassSelectionDialog(getParentShell(),
+ javaProject);
+ if (selectionDialog.open() == MainClassSelectionDialog.OK) {
+ Object[] result = selectionDialog.getResult();
+ if (result.length > 0) {
+ IType type = (IType)result[0];
+ List existingTypes = Arrays.asList(transormersList.getItems());
+ if (!existingTypes.contains(type.getFullyQualifiedName())) {
+ transormersList.add(type.getFullyQualifiedName());
+ }
+ }
+ }
+ }
+
+ private void removeTransformer() {
+ if (transormersList.getSelectionCount() != 1) {
+ return;
+ }
+ boolean confirmed = MessageDialog.openConfirm(getShell(), "Removal confirmation",
+ "Are you sure to delete the " + transormersList.getSelection()[0] + " transformer?");
+ if (!confirmed) {
+ return;
+ }
+ transormersList.remove(transormersList.getSelectionIndex());
+ }
+
@Override
protected void okPressed() {
if (save()) {
@@ -518,6 +555,7 @@ public class TeaVMProfileDialog extends Dialog {
propertyList.add(property);
}
updateCacheFieldsEnabled();
+ transormersList.setItems(profile.getTransformers());
}
private boolean save() {
@@ -543,6 +581,7 @@ public class TeaVMProfileDialog extends Dialog {
properties.setProperty(property.key, property.value);
}
profile.setProperties(properties);
+ profile.setTransformers(transormersList.getItems());
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
new file mode 100644
index 000000000..a52e963cf
--- /dev/null
+++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java
@@ -0,0 +1,32 @@
+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;
+import org.teavm.model.ClassHolderTransformer;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class TransformerClassSelectionDialog extends ClassSelectionDialog {
+ public TransformerClassSelectionDialog(Shell shell, IJavaProject javaProject) {
+ super(shell, javaProject);
+ setTitle("Selecting TeaVM transformer");
+ }
+
+ @Override
+ protected SearchPattern createSearchPattern(String text) {
+ return SearchPattern.createPattern(ClassHolderTransformer.class.getName(), IJavaSearchConstants.CLASS,
+ IJavaSearchConstants.IMPLEMENTORS, SearchPattern.R_EXACT_MATCH);
+ }
+
+ @Override
+ protected IType acceptMatch(SearchMatch match) throws CoreException {
+ return (IType)match.getElement();
+ }
+}