Skip to content

Commit a648bbe

Browse files
committed
Avoid blocking the UI when using SearchTools and IndexManager is working
1 parent 082db77 commit a648bbe

File tree

11 files changed

+222
-178
lines changed

11 files changed

+222
-178
lines changed

org.moreunit.core.test/.classpath

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
<classpath>
33
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
44
<attributes>
5+
<attribute name="module" value="true"/>
56
<attribute name="maven.pomderived" value="true"/>
67
</attributes>
78
</classpathentry>
89
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
910
<classpathentry kind="src" output="classes" path="test">
1011
<attributes>
12+
<attribute name="test" value="true"/>
1113
<attribute name="optional" value="true"/>
1214
<attribute name="maven.pomderived" value="true"/>
1315
</attributes>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.moreunit.core.util;
2+
3+
import java.util.function.Consumer;
4+
import java.util.function.Supplier;
5+
6+
import org.eclipse.core.runtime.IProgressMonitor;
7+
import org.eclipse.core.runtime.IStatus;
8+
import org.eclipse.core.runtime.Status;
9+
import org.eclipse.core.runtime.jobs.Job;
10+
import org.eclipse.swt.widgets.Display;
11+
12+
/**
13+
* Utility class for {@link Job}.
14+
*/
15+
public class Jobs
16+
{
17+
18+
private Jobs()
19+
{
20+
}
21+
22+
public static <T> void executeAndRunInUI(String jobName, Supplier<T> backgroundJob, Consumer<T> uiJob)
23+
{
24+
Job job = new Job(jobName)
25+
{
26+
27+
@Override
28+
protected IStatus run(IProgressMonitor progressmonitor)
29+
{
30+
T result = backgroundJob.get();
31+
if(progressmonitor.isCanceled())
32+
{
33+
return Status.CANCEL_STATUS;
34+
}
35+
if(result != null)
36+
{
37+
Display.getDefault().syncExec(() -> uiJob.accept(result));
38+
}
39+
return progressmonitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
40+
}
41+
};
42+
job.schedule();
43+
}
44+
}

org.moreunit.plugin/src/org/moreunit/actions/CreateTestMethodHierarchyAction.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.eclipse.jface.viewers.IStructuredSelection;
1010
import org.eclipse.ui.IObjectActionDelegate;
1111
import org.eclipse.ui.IWorkbenchPart;
12-
import org.moreunit.elements.MethodCreationResult;
12+
import org.moreunit.core.util.Jobs;
1313
import org.moreunit.elements.TestCaseTypeFacade;
1414
import org.moreunit.elements.TestmethodCreator;
1515
import org.moreunit.elements.TestmethodCreator.TestMethodCreationSettings;
@@ -59,22 +59,22 @@ public void run(final IAction action)
5959
private void createTestMethod(IMethod method)
6060
{
6161
ICompilationUnit cu = method.getCompilationUnit();
62-
ProjectPreferences prefs = preferencesFor(cu);
63-
if(prefs == null)
64-
return;
65-
66-
TestmethodCreator testmethodCreator = new TestmethodCreator(new TestMethodCreationSettings()
67-
.compilationUnit(cu)
68-
.testType(prefs.getTestType())
69-
.generateComments(prefs.shouldGenerateCommentsForTestMethod())
70-
.defaultTestMethodContent(prefs.getTestMethodDefaultContent()));
71-
72-
MethodCreationResult result = testmethodCreator.createTestMethod(method);
73-
74-
if(result.methodCreated())
75-
{
76-
editorUI.open(result.getMethod());
77-
}
62+
Jobs.executeAndRunInUI("Create test method ... ", () -> {
63+
ProjectPreferences prefs = preferencesFor(cu);
64+
if(prefs != null)
65+
{
66+
67+
TestmethodCreator testmethodCreator = new TestmethodCreator(new TestMethodCreationSettings().compilationUnit(cu).testType(prefs.getTestType()).generateComments(prefs.shouldGenerateCommentsForTestMethod()).defaultTestMethodContent(prefs.getTestMethodDefaultContent()));
68+
69+
return testmethodCreator.createTestMethod(method);
70+
}
71+
return null;
72+
}, creationResult -> {
73+
if(creationResult.methodCreated())
74+
{
75+
editorUI.open(creationResult.getMethod());
76+
}
77+
});
7878
}
7979

8080
private ProjectPreferences preferencesFor(ICompilationUnit cu)

org.moreunit.plugin/src/org/moreunit/codemining/JumpCodeMining.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.eclipse.jface.text.codemining.LineEndCodeMining;
2222
import org.eclipse.swt.events.MouseEvent;
2323
import org.eclipse.ui.IEditorPart;
24+
import org.moreunit.core.util.Jobs;
2425
import org.moreunit.elements.ClassTypeFacade;
2526
import org.moreunit.elements.CorrespondingMemberRequest;
2627
import org.moreunit.elements.CorrespondingMemberRequest.MemberType;
@@ -117,6 +118,7 @@ else if(typeFacade instanceof TestCaseTypeFacade)
117118
public Consumer<MouseEvent> getAction()
118119
{
119120
return e -> {
121+
Jobs.executeAndRunInUI("Jump to ... ", () -> {
120122
MethodSearchMode searchMode = Preferences.getInstance().getMethodSearchMode(element.getJavaProject());
121123

122124
TypeFacade typeFacade = TypeFacade.createFacade(((IMember) element).getCompilationUnit());
@@ -129,11 +131,8 @@ public Consumer<MouseEvent> getAction()
129131
.promptText(" Jump to " + testOrTested + " class...")
130132
.build();
131133

132-
IMember memberToJump = typeFacade.getOneCorrespondingMember(request);
133-
if(memberToJump != null)
134-
{
135-
jumpToMember(memberToJump);
136-
}
134+
return typeFacade.getOneCorrespondingMember(request);
135+
}, this::jumpToMember);
137136
};
138137
}
139138

org.moreunit.plugin/src/org/moreunit/elements/ClassTypeFacade.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.eclipse.jdt.core.IMethod;
1212
import org.eclipse.jdt.core.IType;
1313
import org.eclipse.jdt.core.JavaModelException;
14+
import org.eclipse.swt.widgets.Display;
1415
import org.eclipse.ui.IEditorPart;
1516
import org.moreunit.log.LogHandler;
1617
import org.moreunit.preferences.Preferences.MethodSearchMode;
@@ -61,12 +62,12 @@ else if(testcases.size() > 1)
6162
CreateNewTestCaseAction newTestCaseAction = new CreateNewTestCaseAction(getType());
6263
MemberContentProvider contentProvider = new MemberContentProvider(testcases, null).withAction(newTestCaseAction);
6364

64-
IType testCase = new ChooseDialog<IType>(promptText, contentProvider).getChoice();
65+
IType testCase = Display.getDefault().syncCall(() -> new ChooseDialog<IType>(promptText, contentProvider).getChoice());
6566
return new CorrespondingTestCase(testCase, newTestCaseAction.testCaseCreated);
6667
}
6768
else if(createIfNecessary)
6869
{
69-
IType testcaseToJump = new NewTestCaseWizard(getType()).open();
70+
IType testcaseToJump = Display.getDefault().syncCall(() -> new NewTestCaseWizard(getType()).open());
7071
return new CorrespondingTestCase(testcaseToJump, testcaseToJump != null);
7172
}
7273

@@ -92,7 +93,7 @@ public List<IMethod> getCorrespondingTestMethodsByName(IMethod method)
9293

9394
private List<IMethod> getTestMethodsForTestCases(IMethod method, Collection<IType> testCases)
9495
{
95-
List<IMethod> result = new ArrayList<IMethod>();
96+
List<IMethod> result = new ArrayList<>();
9697

9798
for (IType testCaseType : testCases)
9899
{
@@ -104,7 +105,7 @@ private List<IMethod> getTestMethodsForTestCases(IMethod method, Collection<ITyp
104105

105106
private List<IMethod> getTestMethodsForTestCase(IMethod method, IType testCaseType)
106107
{
107-
List<IMethod> result = new ArrayList<IMethod>();
108+
List<IMethod> result = new ArrayList<>();
108109

109110
if(testCaseType == null)
110111
{
@@ -134,7 +135,7 @@ private List<IMethod> getTestMethodsForTestCase(IMethod method, IType testCaseTy
134135

135136
public Set<IMethod> getCorrespondingTestMethods(IMethod method, MethodSearchMode searchMethod)
136137
{
137-
final Set<IMethod> correspondingTestMethods = new HashSet<IMethod>();
138+
final Set<IMethod> correspondingTestMethods = new HashSet<>();
138139
if(searchMethod.searchByCall)
139140
{
140141
Collection<IType> correspondingClasses = getCorrespondingTestCases();

org.moreunit.plugin/src/org/moreunit/elements/TypeFacade.java

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.eclipse.jdt.core.IMethod;
1212
import org.eclipse.jdt.core.IType;
1313
import org.eclipse.jdt.core.JavaCore;
14+
import org.eclipse.swt.widgets.Display;
1415
import org.eclipse.ui.IEditorPart;
1516
import org.moreunit.core.util.StringConstants;
1617
import org.moreunit.elements.CorrespondingMemberRequest.MemberType;
@@ -81,7 +82,7 @@ private TypeFacade(IFile file)
8182

8283
protected TypeFacade(IEditorPart editorPart)
8384
{
84-
this((IFile) editorPart.getEditorInput().getAdapter(IFile.class));
85+
this(editorPart.getEditorInput().getAdapter(IFile.class));
8586
}
8687

8788
public IType getType()
@@ -103,7 +104,7 @@ public ICompilationUnit getCompilationUnit()
103104
* to make a choice via a dialog. If no member is found <tt>null</tt> is
104105
* returned, or a wizard opens to create a new type if
105106
* <tt>createIfNecessary</tt> is true.
106-
*
107+
*
107108
* @param request the details of the request for corresponding member.
108109
* @return one corresponding member or <code>null</code>
109110
* @see CorrespondingMemberRequest
@@ -165,7 +166,7 @@ else if(request.shouldCreateClassIfNoResult())
165166

166167
private Collection<IMethod> findCorrespondingMethodsInClasses(CorrespondingMemberRequest request, Collection<IType> classes)
167168
{
168-
Collection<IMethod> proposedMethods = new LinkedHashSet<IMethod>();
169+
Collection<IMethod> proposedMethods = new LinkedHashSet<>();
169170

170171
if(request.shouldReturn(MemberType.TYPE_OR_METHOD))
171172
{
@@ -200,40 +201,16 @@ else if(request.shouldCreateClassIfNoResult())
200201
return null;
201202
}
202203

203-
abstract protected Collection<IMethod> getCorrespondingMethodsInClasses(IMethod method, Collection<IType> classes);
204+
protected abstract Collection<IMethod> getCorrespondingMethodsInClasses(IMethod method, Collection<IType> classes);
204205

205206
public final Collection<IType> getCorrespondingClasses(boolean alsoIncludeLikelyMatches)
206207
{
207208
return getCorrespondingTypeSearcher().getMatches(alsoIncludeLikelyMatches);
208209
}
209210

210-
abstract protected MethodCallFinder getCallRelationshipFinder(IMethod method, Collection<IType> searchScope);
211+
protected abstract MethodCallFinder getCallRelationshipFinder(IMethod method, Collection<IType> searchScope);
211212

212-
abstract protected NewClassyWizard newCorrespondingClassWizard(IType fromType);
213-
214-
private IMember openDialog(CorrespondingMemberRequest request, Collection<IType> proposedClasses, Collection<IMethod> proposedMethods, boolean perfectMatches)
215-
{
216-
String promptText = request.getPromptText();
217-
String infoText = null;
218-
if(! perfectMatches)
219-
{
220-
promptText = String.format("%s %s%s", promptText, StringConstants.NEWLINE, "We could find the following classes, but their packages do not match:");
221-
infoText = "Please note that theses classes will not be considered for other MoreUnit features such as test launching or refactoring.";
222-
}
223-
224-
IMember startMember = request.getCurrentMethod() != null ? request.getCurrentMethod() : getType();
225-
IMember defaultSelection = getDefaultSelection(proposedClasses, proposedMethods, startMember);
226-
MemberContentProvider contentProvider = new MemberContentProvider(proposedClasses, proposedMethods, defaultSelection).withAction(new CreateNewClassAction()
227-
{
228-
@Override
229-
public IType execute()
230-
{
231-
return newCorrespondingClassWizard(getType()).open();
232-
}
233-
});
234-
235-
return new ChooseDialog<IMember>(promptText, infoText, contentProvider).getChoice();
236-
}
213+
protected abstract NewClassyWizard newCorrespondingClassWizard(IType fromType);
237214

238215
private IMember getDefaultSelection(Collection<IType> proposedClasses, Collection<IMethod> proposedMethods, IMember startMember)
239216
{
@@ -311,13 +288,39 @@ public IMember getCorrespondingMember()
311288
{
312289
return openDialog(request, proposedClasses, proposedMethods, perfectMatches);
313290
}
291+
292+
private IMember openDialog(CorrespondingMemberRequest request, Collection<IType> proposedClasses, Collection<IMethod> proposedMethods, boolean perfectMatches)
293+
{
294+
String promptText = request.getPromptText();
295+
String infoText = null;
296+
if(! perfectMatches)
297+
{
298+
promptText = String.format("%s %s%s", promptText, StringConstants.NEWLINE, "We could find the following classes, but their packages do not match:");
299+
infoText = "Please note that theses classes will not be considered for other MoreUnit features such as test launching or refactoring.";
300+
}
301+
302+
IMember startMember = request.getCurrentMethod() != null ? request.getCurrentMethod() : getType();
303+
IMember defaultSelection = getDefaultSelection(proposedClasses, proposedMethods, startMember);
304+
MemberContentProvider contentProvider = new MemberContentProvider(proposedClasses, proposedMethods, defaultSelection).withAction(new CreateNewClassAction()
305+
{
306+
@Override
307+
public IType execute()
308+
{
309+
return newCorrespondingClassWizard(getType()).open();
310+
}
311+
});
312+
313+
String finalPromptTest = promptText;
314+
String finalInfoText = infoText;
315+
return Display.getDefault().syncCall(() -> new ChooseDialog<IMember>(finalPromptTest, finalInfoText, contentProvider).getChoice());
316+
}
314317
}
315318

316319
private class OpenNewClassWizard implements OneCorrespondingMemberAction
317320
{
318321
public IMember getCorrespondingMember()
319322
{
320-
return newCorrespondingClassWizard(getType()).open();
323+
return Display.getDefault().syncCall(() -> newCorrespondingClassWizard(getType()).open());
321324
}
322325
}
323326
}

org.moreunit.plugin/src/org/moreunit/handler/CreateTestMethodActionExecutor.java

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
import org.moreunit.actions.CreateTestMethodEditorAction;
2424
import org.moreunit.actions.CreateTestMethodHierarchyAction;
2525
import org.moreunit.annotation.MoreUnitAnnotationModel;
26+
import org.moreunit.core.util.Jobs;
2627
import org.moreunit.elements.ClassTypeFacade;
2728
import org.moreunit.elements.ClassTypeFacade.CorrespondingTestCase;
2829
import org.moreunit.elements.EditorPartFacade;
29-
import org.moreunit.elements.MethodCreationResult;
3030
import org.moreunit.elements.TestmethodCreator;
3131
import org.moreunit.elements.TestmethodCreator.TestMethodCreationSettings;
3232
import org.moreunit.elements.TypeFacade;
@@ -89,43 +89,43 @@ public void executeCreateTestMethodAction(IEditorPart editorPart)
8989
EditorPartFacade editorPartFacade = new EditorPartFacade(editorPart);
9090
ICompilationUnit compilationUnit = editorPartFacade.getCompilationUnit();
9191
IMethod originalMethod = editorPartFacade.getFirstNonAnonymousMethodSurroundingCursorPosition();
92+
Jobs.executeAndRunInUI("Create test method ... ", () -> {
93+
// Creates an intermediate object to clarify code that follows
94+
CreationContext context = createContext(compilationUnit);
95+
if(context != null)
96+
{
97+
// Creates test method template
98+
ProjectPreferences prefs = preferences.getProjectView(editorPartFacade.getJavaProject());
99+
TestmethodCreator creator = new TestmethodCreator(new TestMethodCreationSettings().compilationUnit(compilationUnit, context.testCaseUnit).testCaseJustCreated(context.newTestClassCreated).testType(prefs.getTestType()).generateComments(prefs.shouldGenerateCommentsForTestMethod()).defaultTestMethodContent(prefs.getTestMethodDefaultContent()));
92100

93-
// Creates an intermediate object to clarify code that follows
94-
CreationContext context = createContext(compilationUnit, originalMethod);
95-
96-
// Creates test method template
97-
ProjectPreferences prefs = preferences.getProjectView(editorPartFacade.getJavaProject());
98-
TestmethodCreator creator = new TestmethodCreator(new TestMethodCreationSettings()
99-
.compilationUnit(compilationUnit, context.testCaseUnit)
100-
.testCaseJustCreated(context.newTestClassCreated)
101-
.testType(prefs.getTestType())
102-
.generateComments(prefs.shouldGenerateCommentsForTestMethod())
103-
.defaultTestMethodContent(prefs.getTestMethodDefaultContent()));
104-
MethodCreationResult creationResult = creator.createTestMethod(originalMethod);
105-
106-
if(creationResult.methodAlreadyExists())
107-
{
108-
editorUI.open(creationResult.getMethod());
109-
}
110-
else if(creationResult.methodCreated())
111-
{
112-
IMethod createdMethod = creationResult.getMethod();
113-
114-
editorUI.open(createdMethod);
115-
116-
if(createdMethod.getElementName().endsWith(MoreUnitContants.SUFFIX_NAME))
101+
return creator.createTestMethod(originalMethod);
102+
}
103+
return null;
104+
}, creationResult -> {
105+
if(creationResult.methodAlreadyExists())
117106
{
118-
markMethodSuffix(editorPartFacade, createdMethod);
107+
editorUI.open(creationResult.getMethod());
119108
}
120-
121-
if(editorPart instanceof ITextEditor)
109+
else if(creationResult.methodCreated())
122110
{
123-
MoreUnitAnnotationModel.updateAnnotations((ITextEditor) editorPart);
111+
IMethod createdMethod = creationResult.getMethod();
112+
113+
editorUI.open(createdMethod);
114+
115+
if(createdMethod.getElementName().endsWith(MoreUnitContants.SUFFIX_NAME))
116+
{
117+
markMethodSuffix(editorPartFacade, createdMethod);
118+
}
119+
120+
if(editorPart instanceof ITextEditor textEditor)
121+
{
122+
MoreUnitAnnotationModel.updateAnnotations(textEditor);
123+
}
124124
}
125-
}
125+
});
126126
}
127127

128-
private CreationContext createContext(ICompilationUnit currentlyEditedUnit, IMethod currentlyEditedMethod)
128+
private CreationContext createContext(ICompilationUnit currentlyEditedUnit)
129129
{
130130
if(TypeFacade.isTestCase(currentlyEditedUnit.findPrimaryType()))
131131
{

0 commit comments

Comments
 (0)