blob: aa3d273099d62911c73df5271f1dd1fc1c1940d7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2016 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
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.jdt.core.search.TypeNameMatch;
import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
import org.eclipse.jdt.debug.ui.console.JavaStackTraceConsoleFactory;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsole;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Action delegate for Open from Clipboard action.
*
* @since 3.7
*/
public class OpenFromClipboardAction implements IWorkbenchWindowActionDelegate {
/**
* Pattern to match a simple name e.g. <code>OpenFromClipboardAction</code>
*/
private static final String SIMPLE_NAME_PATTERN= "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"; //$NON-NLS-1$
/**
* Pattern to match a qualified name e.g.
* <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction</code>, or match a
* simple name e.g. <code>OpenFromClipboardAction</code>.
*/
private static final String QUALIFIED_NAME_PATTERN = "(" + SIMPLE_NAME_PATTERN //$NON-NLS-1$
+ "\\.)*" + SIMPLE_NAME_PATTERN; //$NON-NLS-1$
/**
* Pattern to match a qualified name e.g.
* <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction</code>.
*/
private static final String STRICT_QUALIFIED_NAME_PATTERN = "(" + SIMPLE_NAME_PATTERN //$NON-NLS-1$
+ "\\.)+" + SIMPLE_NAME_PATTERN; //$NON-NLS-1$
/**
* Pattern to match whitespace characters.
*/
private static final String WS = "\\s*"; //$NON-NLS-1$
/**
* Pattern to match a java file name e.g. <code>OpenFromClipboardAction.java</code>
*/
private static final String JAVA_FILE_PATTERN = SIMPLE_NAME_PATTERN + "\\.java"; //$NON-NLS-1$
/**
* Pattern to match a java file name followed by line number e.g.
* <code>OpenFromClipboardAction.java : 21</code>
*/
private static final String JAVA_FILE_LINE_PATTERN = JAVA_FILE_PATTERN + WS + ":" + WS + "\\d+"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Pattern to match a qualified name followed by line number e.g.
* <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction : 21</code>
*/
private static final String TYPE_LINE_PATTERN = QUALIFIED_NAME_PATTERN + WS + ":" + WS + "\\d+"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Pattern to match a line from a stack trace e.g.
* <code>(Assert.java:41)</code>
*/
private static final String STACK_TRACE_PARENTHESIZED_PATTERN = "\\(" + WS + JAVA_FILE_LINE_PATTERN + WS + "\\)"; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Pattern to match a line from a stack trace e.g.
* <code> at org.eclipse.core.runtime.Assert.isLegal(Assert.java:41)</code>
*/
private static final String STACK_TRACE_LINE_PATTERN = "[^()]*?" + STACK_TRACE_PARENTHESIZED_PATTERN; //$NON-NLS-1$
/**
* Pattern to match a line from a stack trace e.g.
* <code> at org.eclipse.core.runtime.Assert.isLegal(Assert.java:41)</code>
*/
private static final String STACK_TRACE_QUALIFIED_LINE_PATTERN = "[^()]*?(" + STRICT_QUALIFIED_NAME_PATTERN + ")" + WS + STACK_TRACE_PARENTHESIZED_PATTERN; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Pattern to match a method e.g.
* <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction.run(IAction)</code> ,
* <code>Worker.run()</code>
*/
private static final String METHOD_PATTERN = QUALIFIED_NAME_PATTERN + "\\(.*\\)"; //$NON-NLS-1$
/**
* Pattern to match a stack element e.g. <code>java.lang.String.valueOf(char) line: 1456</code>
*/
private static final String STACK_PATTERN = METHOD_PATTERN + ".*\\d+"; //$NON-NLS-1$
/**
* Pattern to match a member (field or method) of a type e.g.
* <code>OpenFromClipboardAction#run</code>, <code>Worker#run</code>
*/
private static final String MEMBER_PATTERN = QUALIFIED_NAME_PATTERN + "#" //$NON-NLS-1$
+ SIMPLE_NAME_PATTERN;
/**
* Pattern to match a method e.g. <code>OpenFromClipboardAction#run(IAction)</code>,
* <code>Worker#run()</code>
*/
private static final String METHOD_JAVADOC_REFERENCE_PATTERN = QUALIFIED_NAME_PATTERN + "#" //$NON-NLS-1$
+ SIMPLE_NAME_PATTERN + "\\(.*\\)"; //$NON-NLS-1$
/*
* Constants to indicate the pattern matched
*/
private static final int INVALID = 0;
private static final int QUALIFIED_NAME = 1;
private static final int JAVA_FILE = 2;
private static final int JAVA_FILE_LINE = 3;
private static final int TYPE_LINE = 4;
private static final int STACK_TRACE_LINE = 5;
private static final int METHOD = 6;
private static final int STACK = 7;
private static final int MEMBER = 8;
private static final int METHOD_JAVADOC_REFERENCE = 9;
private static final String TASK_NAME = ActionMessages.OpenFromClipboardAction_OpeningFromClipboard;
/*
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
@Override
public void run(IAction action) {
Clipboard clipboard = new Clipboard(Display.getDefault());
TextTransfer textTransfer = TextTransfer.getInstance();
final String inputText = (String) clipboard.getContents(textTransfer);
if (inputText == null || inputText.length() == 0) {
openInputEditDialog(""); //$NON-NLS-1$
return;
}
String trimmedText = inputText.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
List<Object> matches = new ArrayList<>();
int line = 0;
try {
line = getJavaElementMatches(trimmedText, matches);
}
catch (InterruptedException e) {
matches.clear(); // don't show partial matches
}
if (matches.size() > 0 || isSingleLineInput(inputText)) {
handleMatches(matches, line, trimmedText);
return;
}
handleMultipleLineInput(inputText);
return;
}
private static JavaStackTraceConsole getJavaStackTraceConsole() {
IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
IConsole[] consoles = consoleManager.getConsoles();
for (int i = 0; i < consoles.length; i++) {
if (consoles[i] instanceof JavaStackTraceConsole) {
return (JavaStackTraceConsole) consoles[i];
}
}
return null;
}
private static void handleMultipleLineInput(String inputText) {
// multiple lines - simply paste to the console and open it
IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
JavaStackTraceConsole console = getJavaStackTraceConsole();
if (console != null) {
console.getDocument().set(inputText);
consoleManager.showConsoleView(console);
} else {
JavaStackTraceConsoleFactory javaStackTraceConsoleFactory = new JavaStackTraceConsoleFactory();
javaStackTraceConsoleFactory.openConsole(inputText);
console = getJavaStackTraceConsole();
}
IPreferenceStore preferenceStore = JDIDebugUIPlugin.getDefault().getPreferenceStore();
if (preferenceStore.getBoolean(IJDIPreferencesConstants.PREF_AUTO_FORMAT_JSTCONSOLE)) {
console.format();
}
}
private static boolean isSingleLineInput(String inputText) {
String lineDelimiter = System.lineSeparator();
String s = inputText.trim();
return s.indexOf(lineDelimiter) == -1;
}
private static int getMatchingPattern(String s) {
if (s.matches(JAVA_FILE_LINE_PATTERN)) {
return JAVA_FILE_LINE;
}
if (s.matches(JAVA_FILE_PATTERN)) {
return JAVA_FILE;
}
if (s.matches(TYPE_LINE_PATTERN)) {
return TYPE_LINE;
}
if (s.matches(STACK_TRACE_LINE_PATTERN)) {
return STACK_TRACE_LINE;
}
if (s.matches(METHOD_PATTERN)) {
return METHOD;
}
if (s.matches(STACK_PATTERN)) {
return STACK;
}
if (s.matches(MEMBER_PATTERN)) {
return MEMBER;
}
if (s.matches(METHOD_JAVADOC_REFERENCE_PATTERN)) {
return METHOD_JAVADOC_REFERENCE;
}
if (s.matches(QUALIFIED_NAME_PATTERN)) {
return QUALIFIED_NAME;
}
return INVALID;
}
private static void handleSingleLineInput(String inputText) {
List<Object> matches = new ArrayList<>();
try {
int line= getJavaElementMatches(inputText, matches);
handleMatches(matches, line, inputText);
} catch (InterruptedException ex) {
// Do nothing
}
}
/**
* Parse the input text and search for the corresponding Java elements.
*
* @param inputText the line number
* @param matches matched Java elements
* @return the line number
* @throws InterruptedException if canceled by the user
*/
private static int getJavaElementMatches(String inputText, List<Object> matches) throws InterruptedException {
String s = inputText.trim();
switch (getMatchingPattern(s)) {
case JAVA_FILE_LINE: {
int index = s.indexOf(':');
String typeName = s.substring(0, index);
typeName = s.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$
String lineNumber = s.substring(index + 1, s.length());
lineNumber = lineNumber.trim();
int line = (Integer.valueOf(lineNumber)).intValue();
getTypeMatches(typeName, matches);
return line;
}
case JAVA_FILE: {
String typeName = s.substring(0, s.indexOf(".java")); //$NON-NLS-1$
getTypeMatches(typeName, matches);
return -1;
}
case TYPE_LINE: {
int index = s.indexOf(':');
String typeName = s.substring(0, index);
typeName = typeName.trim();
String lineNumber = s.substring(index + 1, s.length());
lineNumber = lineNumber.trim();
int line = (Integer.valueOf(lineNumber)).intValue();
getTypeMatches(typeName, matches);
return line;
}
case STACK_TRACE_LINE: {
int index1 = s.lastIndexOf('(');
int index2 = s.lastIndexOf(')');
String typeLine = s.substring(index1 + 1, index2).trim();
int index = typeLine.indexOf(':');
String lineNumber = typeLine.substring(index + 1, typeLine.length()).trim();
int line = (Integer.valueOf(lineNumber)).intValue();
Pattern pattern = Pattern.compile(STACK_TRACE_QUALIFIED_LINE_PATTERN);
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
String qualifiedName = matcher.group(1);
index = qualifiedName.lastIndexOf('.');
qualifiedName = qualifiedName.substring(0, index);
getTypeMatches(qualifiedName, matches);
} else {
String typeName = typeLine.substring(0, index);
typeName = typeLine.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$
getTypeMatches(typeName, matches);
}
return line;
}
case METHOD: {
getMethodMatches(s, matches);
return -1;
}
case STACK: {
int index = s.indexOf(')');
String method = s.substring(0, index + 1);
index = s.indexOf(':');
String lineNumber = s.substring(index + 1).trim();
int line = (Integer.valueOf(lineNumber)).intValue();
getMethodMatches(method, matches);
return line;
}
case MEMBER:
getMemberMatches(s.replace('#', '.'), matches);
return -1;
case METHOD_JAVADOC_REFERENCE:
getMethodMatches(s.replace('#', '.'), matches);
return -1;
case QUALIFIED_NAME:
getNameMatches(s, matches);
return -1;
default:
return -1;
}
}
/**
* Perform a Java search for the type and return the corresponding Java elements.
*
* @param typeName the Type name
* @param matches matched Java elements
* @throws InterruptedException if canceled by the user
*/
private static void getTypeMatches(final String typeName, final List<Object> matches) throws InterruptedException {
executeRunnable(new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
doTypeSearch(typeName, matches, monitor);
}
});
}
/**
* Perform a Java search for methods and constructors and return the corresponding Java
* elements.
*
* @param s the method pattern
* @param matches matched Java elements
* @throws InterruptedException if canceled by the user
*/
private static void getMethodMatches(final String s, final List<Object> matches) throws InterruptedException {
executeRunnable(new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
doMemberSearch(s, matches, true, true, false, monitor, 100);
}
});
}
/**
* Perform a Java search for fields, methods and constructors and return the corresponding Java
* elements.
*
* @param s the member pattern
* @param matches matched Java elements
* @throws InterruptedException if canceled by the user
*/
private static void getMemberMatches(final String s, final List<Object> matches) throws InterruptedException {
executeRunnable(new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
doMemberSearch(s, matches, true, true, true, monitor, 100);
}
});
}
/**
* Perform a Java search for types, fields and methods and return the corresponding Java
* elements.
*
* @param s the qualified name pattern
* @param matches matched Java elements
* @throws InterruptedException if canceled by the user
*/
private static void getNameMatches(final String s, final List<Object> matches) throws InterruptedException {
executeRunnable(new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
SubMonitor progress = SubMonitor.convert(monitor, 100);
progress.beginTask(TASK_NAME, 100);
doTypeSearch(s, matches, progress.newChild(34));
doMemberSearch(s, matches, true, false, true, progress.newChild(34), 66);
}
});
}
private static void executeRunnable(IRunnableWithProgress runnableWithProgress) throws InterruptedException {
try {
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnableWithProgress);
} catch (InvocationTargetException e) {
JDIDebugUIPlugin.log(e);
}
}
/**
* Handles the given matches.
*
* @param matches matched Java elements
* @param line the line number
* @param inputText the input text
* @throws InterruptedException if canceled by the user
*/
private static void handleMatches(List<Object> matches, int line, String inputText) {
if (matches.size() > 1) {
int flags = JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT;
IWorkbenchWindow window = JDIDebugUIPlugin.getActiveWorkbenchWindow();
ElementListSelectionDialog dialog = new ElementListSelectionDialog(window.getShell(), new JavaElementLabelProvider(flags)) {
/*
* @see org.eclipse.ui.dialogs.SelectionDialog#getDialogBoundsSettings()
* @since 4.3
*/
@Override
protected IDialogSettings getDialogBoundsSettings() {
IDialogSettings settings = JDIDebugUIPlugin.getDefault().getDialogSettings();
return DialogSettings.getOrCreateSection(settings, "OpenFromClipboardAction_dialogBounds"); //$NON-NLS-1$
}
};
dialog.setTitle(ActionMessages.OpenFromClipboardAction_OpenFromClipboard);
dialog.setMessage(ActionMessages.OpenFromClipboardAction_SelectOrEnterTheElementToOpen);
dialog.setElements(matches.toArray());
dialog.setMultipleSelection(true);
int result = dialog.open();
if (result != IDialogConstants.OK_ID) {
return;
}
Object[] elements = dialog.getResult();
if (elements != null && elements.length > 0) {
openJavaElements(elements, line);
}
} else if (matches.size() == 1) {
openJavaElements(matches.toArray(), line);
} else if (matches.isEmpty()) {
openInputEditDialog(inputText);
}
}
/**
* Opens each specified Java element in a Java editor and navigates to the specified line
* number.
*
* @param elements
* the Java elements
* @param line
* the line number
*/
private static void openJavaElements(Object[] elements, int line) {
for (int i = 0; i < elements.length; i++) {
Object ob = elements[i];
if (ob instanceof IJavaElement) {
IJavaElement element = (IJavaElement) ob;
try {
IEditorPart editorPart = JavaUI.openInEditor(element);
gotoLine(editorPart, line, element);
} catch (PartInitException e) {
JDIDebugUIPlugin.log(e);
} catch (JavaModelException e) {
JDIDebugUIPlugin.log(e);
}
}
}
}
/**
* Jumps to the given line in the editor if the line number lies within the given Java element.
*
* @param editorPart the Editor part
* @param line the line to jump to
* @param element the Java Element
* @throws JavaModelException if fetching the Java element's source range fails
*/
private static void gotoLine(IEditorPart editorPart, int line, IJavaElement element) throws JavaModelException {
if (line <= 0) {
return;
}
ITextEditor editor = (ITextEditor) editorPart;
IDocumentProvider provider = editor.getDocumentProvider();
IDocument document = provider.getDocument(editor.getEditorInput());
try {
if (element instanceof IMethod) {
ISourceRange sourceRange = ((IMethod) element).getSourceRange();
int start = sourceRange.getOffset();
int end = start + sourceRange.getLength();
start = document.getLineOfOffset(start);
end = document.getLineOfOffset(end);
if (start > line || end < line) {
return;
}
}
int start = document.getLineOffset(line - 1);
editor.selectAndReveal(start, 0);
IWorkbenchPage page = editor.getSite().getPage();
page.activate(editor);
} catch (BadLocationException e) {
// ignore
}
}
/**
* Opens an text input dialog to let the user refine the input text.
*
* @param inputText the input text
*/
private static void openInputEditDialog(String inputText) {
IWorkbenchWindow window = JDIDebugUIPlugin.getActiveWorkbenchWindow();
IInputValidator validator = new IInputValidator() {
@Override
public String isValid(String newText) {
return newText.length() == 0 ? "" : null; //$NON-NLS-1$
}
};
InputDialog dialog = new InputDialog(window.getShell(), ActionMessages.OpenFromClipboardAction_OpenFromClipboard, ActionMessages.OpenFromClipboardAction_ElementToOpen, inputText, validator);
int result = dialog.open();
if (result != IDialogConstants.OK_ID) {
return;
}
inputText = dialog.getValue();
handleSingleLineInput(inputText);
}
private static SearchPattern createSearchPattern(String s, int searchFor) {
return SearchPattern.createPattern(s, searchFor, IJavaSearchConstants.DECLARATIONS, getSearchFlags());
}
private static int getSearchFlags() {
return SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH;
}
private static SearchRequestor createSearchRequestor(final List<Object> matches) {
return new SearchRequestor() {
@Override
public void acceptSearchMatch(SearchMatch match) {
if (match.getAccuracy() == SearchMatch.A_ACCURATE) {
matches.add(match.getElement());
}
}
};
}
private static SearchParticipant[] createSearchParticipant() {
return new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
}
/**
* Perform a Java search for the type and return the corresponding Java elements.
*
* <p>
* TODO: Because of faster performance SearchEngine.searchAllTypeNames(...) is used to do the
* Java Search, instead of the usual SearchEngine.search(...) API. This logic should be moved to
* JDT/Core.
* </p>
*
* @param typeName
* the Type Name
* @param matches
* matched Java Elements
* @param monitor
* the Progress Monitor
*/
private static void doTypeSearch(String typeName, final List<Object> matches, IProgressMonitor monitor) {
IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
SearchEngine searchEngine = new SearchEngine();
String packageName = null;
int index = typeName.lastIndexOf('.');
if (index != -1) {
packageName = typeName.substring(0, index);
typeName = typeName.substring(index + 1);
}
try {
searchEngine.searchAllTypeNames(packageName == null ? null : packageName.toCharArray(), packageName == null ? SearchPattern.R_EXACT_MATCH : getSearchFlags(), typeName.toCharArray(),
getSearchFlags(), IJavaSearchConstants.TYPE, scope, new TypeNameMatchRequestor() {
@Override
public void acceptTypeNameMatch(TypeNameMatch match) {
matches.add(match.getType());
}
}, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor);
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
}
/**
* Perform a Java search for one or more of fields, methods and constructors and return the
* corresponding Java elements.
*
* <p>
* TODO: Because of faster performance, if the type name is available
* SearchEngine.searchAllTypeNames(...) is used to narrow the scope of Java Search. This logic
* should be moved to JDT/Core.
* </p>
*
* @param memberName
* the Member Name
* @param matches
* matched Java Elements
* @param searchForMethods
* if <code>true</code>, a method search is performed
* @param searchForConstructors
* if <code>true</code>, a constructor search is performed
* @param searchForFields
* if <code>true</code>, a field search is performed
* @param monitor
* the Progress Monitor
* @param work
* the remaining Work
*/
private static void doMemberSearch(String memberName, final List<Object> matches, boolean searchForMethods, boolean searchForConstructors, boolean searchForFields, IProgressMonitor monitor, int work) {
int noOfSearches = 0;
noOfSearches = searchForMethods ? noOfSearches + 1 : noOfSearches;
noOfSearches = searchForConstructors ? noOfSearches + 1 : noOfSearches;
noOfSearches = searchForFields ? noOfSearches + 1 : noOfSearches;
if (noOfSearches == 0) {
return;
}
SubMonitor progress = SubMonitor.convert(monitor);
progress.beginTask(TASK_NAME, work);
IJavaSearchScope scope = null;
SearchRequestor requestor = createSearchRequestor(matches);
SearchEngine searchEngine = new SearchEngine();
String typeName = null;
int index = memberName.lastIndexOf('.');
if (index != -1) {
typeName = memberName.substring(0, index);
memberName = memberName.substring(index + 1);
final List<Object> typeMatches = new ArrayList<>();
noOfSearches++;
doTypeSearch(typeName, typeMatches, progress.newChild(work / noOfSearches));
IType[] types = new IType[typeMatches.size()];
for (int i = 0; i < typeMatches.size(); i++) {
types[i] = (IType) typeMatches.get(i);
}
scope = SearchEngine.createJavaSearchScope(types);
} else {
scope = SearchEngine.createWorkspaceScope();
}
try {
int workPerSearch = work / noOfSearches;
if (searchForMethods) {
doMemberSearch(searchEngine, memberName, IJavaSearchConstants.METHOD, scope, requestor, progress.newChild(workPerSearch));
}
if (searchForConstructors) {
doMemberSearch(searchEngine, memberName, IJavaSearchConstants.CONSTRUCTOR, scope, requestor, progress.newChild(workPerSearch));
}
if (searchForFields) {
doMemberSearch(searchEngine, memberName, IJavaSearchConstants.FIELD, scope, requestor, progress.newChild(workPerSearch));
}
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
}
private static void doMemberSearch(SearchEngine searchEngine, String memberName, int searchFor, IJavaSearchScope scope, SearchRequestor requestor, SubMonitor progressMonitor) throws CoreException {
SearchPattern pattern = createSearchPattern(memberName, searchFor);
if (pattern != null) {
searchEngine.search(pattern, createSearchParticipant(), scope, requestor, progressMonitor);
}
}
/*
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action .IAction,
* org.eclipse.jface.viewers.ISelection)
*/
@Override
public void selectionChanged(IAction action, ISelection selection) {
}
/*
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
*/
@Override
public void dispose() {
}
/*
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui. IWorkbenchWindow)
*/
@Override
public void init(IWorkbenchWindow window) {
}
}