32
32
import org .eclipse .core .runtime .CoreException ;
33
33
import org .eclipse .core .runtime .IProgressMonitor ;
34
34
import org .eclipse .core .runtime .ProgressMonitorWrapper ;
35
+ import org .eclipse .core .runtime .Status ;
35
36
import org .eclipse .core .runtime .SubMonitor ;
36
37
import org .eclipse .jdt .core .IJavaProject ;
38
+ import org .eclipse .jdt .core .IPackageFragment ;
37
39
import org .eclipse .jdt .core .JavaCore ;
40
+ import org .eclipse .jdt .core .JavaModelException ;
38
41
import org .eclipse .jdt .core .search .IJavaSearchConstants ;
39
42
import org .eclipse .jdt .core .search .IJavaSearchScope ;
40
43
import org .eclipse .jdt .core .search .SearchEngine ;
@@ -144,10 +147,10 @@ public void run(IProgressMonitor monitor) throws InvocationTargetException, Inte
144
147
if (subMonitor .isCanceled ()) {
145
148
return ;
146
149
}
150
+ removeSourceReferences (usedPlugins , usedPackages , subMonitor .split (10 ));
147
151
minimizeDependencies (usedPlugins , usedPackages , subMonitor );
148
152
removeBuddies ();
149
153
removeReexported ();
150
- removeSourceReferences (subMonitor .split (10 ));
151
154
}
152
155
153
156
/**
@@ -158,8 +161,12 @@ public void run(IProgressMonitor monitor) throws InvocationTargetException, Inte
158
161
* warnings. To prevent the user from getting a confusing project
159
162
* error/warnings we retain them here even if not strictly required at
160
163
* runtime.
164
+ *
165
+ * @param usedPackages
166
+ * @param usedPlugins
161
167
*/
162
- private void removeSourceReferences (IProgressMonitor monitor ) {
168
+ private void removeSourceReferences (Map <String , IPluginImport > usedPlugins , List <ImportPackageObject > usedPackages ,
169
+ IProgressMonitor monitor ) {
163
170
if (fList .isEmpty ()) {
164
171
return ;
165
172
}
@@ -168,49 +175,66 @@ private void removeSourceReferences(IProgressMonitor monitor) {
168
175
IJavaProject javaProject = JavaCore .create (project );
169
176
SubMonitor convert = SubMonitor .convert (monitor , "Search Source References for unused requirements" , //$NON-NLS-1$
170
177
fList .size ());
178
+ SearchEngine engine = new SearchEngine ();
179
+ IJavaSearchScope searchScope ;
180
+ try {
181
+ searchScope = PluginJavaSearchUtil .createSeachScope (javaProject );
182
+ } catch (JavaModelException e ) {
183
+ return ;
184
+ }
185
+ Requestor requestor = new Requestor (engine , searchScope );
171
186
for (Iterator <Object > iterator = fList .iterator (); iterator .hasNext ();) {
172
187
Object item = iterator .next ();
173
188
if (item instanceof ImportPackageObject pkg ) {
174
- if (isPackageReferenced (pkg , javaProject , convert .split (1 ))) {
189
+ if (isPackageReferenced (pkg , requestor , convert .split (1 ))) {
190
+ usedPackages .add (pkg );
191
+ iterator .remove ();
192
+ }
193
+ } else if (item instanceof IPluginImport bundle ) {
194
+ IPluginModelBase [] models = PluginJavaSearchUtil .getPluginImports (bundle );
195
+ IPackageFragment [] packageFragments ;
196
+ try {
197
+ packageFragments = PluginJavaSearchUtil .collectPackageFragments (models , javaProject , true );
198
+ } catch (JavaModelException e ) {
199
+ // something is broken, so better assume it is used
200
+ // here.
201
+ iterator .remove ();
202
+ continue ;
203
+ }
204
+ if (isBundleReferenced (packageFragments , requestor , convert .split (1 ))) {
205
+ usedPlugins .put (bundle .getId (), bundle );
175
206
iterator .remove ();
176
207
}
177
208
}
178
209
}
179
210
}
180
211
}
181
212
182
- private boolean isPackageReferenced (ImportPackageObject pkg , IJavaProject javaProject , IProgressMonitor monitor ) {
213
+ private boolean isBundleReferenced (IPackageFragment [] packageFragments , Requestor requestor ,
214
+ IProgressMonitor monitor ) {
183
215
try {
184
- SearchEngine engine = new SearchEngine ();
185
- IJavaSearchScope searchScope = PluginJavaSearchUtil .createSeachScope (javaProject );
186
- Requestor requestor = new Requestor ();
187
- String packageName = pkg .getName ();
188
- SearchPattern pattern = SearchPattern .createPattern (packageName , IJavaSearchConstants .PACKAGE ,
189
- IJavaSearchConstants .REFERENCES , SearchPattern .R_EXACT_MATCH );
190
- if (pattern != null ) {
191
- ProgressMonitorWrapper wrapper = new ProgressMonitorWrapper (monitor ) {
192
-
193
- @ Override
194
- public boolean isCanceled () {
195
- return monitor .isCanceled () || requestor .used ;
196
- }
197
-
198
- @ Override
199
- public void setCanceled (boolean b ) {
200
- }
201
- };
202
- try {
203
- engine .search (pattern , new SearchParticipant [] { SearchEngine .getDefaultSearchParticipant () },
204
- searchScope , requestor , wrapper );
205
- } catch (org .eclipse .core .runtime .OperationCanceledException e ) {
206
- if (monitor .isCanceled ()) {
207
- // the the user really canceled, rethrow it here,
208
- // otherwise we just found a match!
209
- throw e ;
216
+ SubMonitor subMonitor = SubMonitor .convert (monitor , packageFragments .length );
217
+ for (IPackageFragment fragment : packageFragments ) {
218
+ if (fragment .hasChildren () && !fragment .isDefaultPackage ()) {
219
+ SearchPattern pattern = SearchPattern .createPattern (fragment , IJavaSearchConstants .REFERENCES );
220
+ if (requestor .search (pattern , subMonitor .split (1 ))) {
221
+ return true ;
210
222
}
211
223
}
212
- return requestor .used ;
213
224
}
225
+ return false ;
226
+ } catch (CoreException e ) {
227
+ }
228
+ // If we can't be sure better assume it is used!
229
+ return true ;
230
+ }
231
+
232
+ private boolean isPackageReferenced (ImportPackageObject pkg , Requestor requestor , IProgressMonitor monitor ) {
233
+ try {
234
+ String packageName = pkg .getName ();
235
+ SearchPattern pattern = SearchPattern .createPattern (packageName , IJavaSearchConstants .PACKAGE ,
236
+ IJavaSearchConstants .REFERENCES , SearchPattern .R_EXACT_MATCH );
237
+ return requestor .search (pattern , monitor );
214
238
} catch (CoreException e ) {
215
239
}
216
240
// can't tell, so better be safe and assume it is used...
@@ -372,11 +396,50 @@ private void minimizeDependencies(Map<String, IPluginImport> usedPlugins, List<I
372
396
}
373
397
374
398
private static class Requestor extends SearchRequestor {
375
- volatile boolean used ;
399
+ private volatile boolean used ;
400
+ private SearchEngine engine ;
401
+ private IJavaSearchScope searchScope ;
402
+
403
+ public Requestor (SearchEngine engine , IJavaSearchScope searchScope ) {
404
+ this .engine = engine ;
405
+ this .searchScope = searchScope ;
406
+ }
407
+
408
+ public boolean search (SearchPattern pattern , IProgressMonitor monitor ) throws CoreException {
409
+ used = false ;
410
+ if (pattern == null ) {
411
+ throw new CoreException (Status .error ("pattern is null" , new NullPointerException ())); //$NON-NLS-1$
412
+ }
413
+ try {
414
+ engine .search (pattern , new SearchParticipant [] { SearchEngine .getDefaultSearchParticipant () },
415
+ searchScope , this , getMonitor (monitor ));
416
+ } catch (org .eclipse .core .runtime .OperationCanceledException e ) {
417
+ if (monitor .isCanceled ()) {
418
+ // the the user really canceled, rethrow it here,
419
+ // otherwise we just found a match and canceled the search!
420
+ throw e ;
421
+ }
422
+ }
423
+ return used ;
424
+ }
376
425
377
426
@ Override
378
427
public void acceptSearchMatch (SearchMatch match ) {
379
428
used = true ;
380
429
}
430
+
431
+ public IProgressMonitor getMonitor (IProgressMonitor parent ) {
432
+ return new ProgressMonitorWrapper (parent ) {
433
+
434
+ @ Override
435
+ public boolean isCanceled () {
436
+ return parent .isCanceled () || used ;
437
+ }
438
+
439
+ @ Override
440
+ public void setCanceled (boolean b ) {
441
+ }
442
+ };
443
+ }
381
444
}
382
445
}
0 commit comments