Skip to content

Commit 822d38b

Browse files
committed
Search required bundles for references in sources
Similar to package-imports we need to search for referenced packages from source-only types in case of require bundle. This also improves how searching is done in general by only create some objects once and have a more uniform handling through the Requestor class to avoid code duplication.
1 parent 2aea21c commit 822d38b

File tree

1 file changed

+95
-32
lines changed

1 file changed

+95
-32
lines changed

ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/dependencies/GatherUnusedDependenciesOperation.java

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
import org.eclipse.core.runtime.CoreException;
3333
import org.eclipse.core.runtime.IProgressMonitor;
3434
import org.eclipse.core.runtime.ProgressMonitorWrapper;
35+
import org.eclipse.core.runtime.Status;
3536
import org.eclipse.core.runtime.SubMonitor;
3637
import org.eclipse.jdt.core.IJavaProject;
38+
import org.eclipse.jdt.core.IPackageFragment;
3739
import org.eclipse.jdt.core.JavaCore;
40+
import org.eclipse.jdt.core.JavaModelException;
3841
import org.eclipse.jdt.core.search.IJavaSearchConstants;
3942
import org.eclipse.jdt.core.search.IJavaSearchScope;
4043
import org.eclipse.jdt.core.search.SearchEngine;
@@ -144,10 +147,10 @@ public void run(IProgressMonitor monitor) throws InvocationTargetException, Inte
144147
if (subMonitor.isCanceled()) {
145148
return;
146149
}
150+
removeSourceReferences(usedPlugins, usedPackages, subMonitor.split(10));
147151
minimizeDependencies(usedPlugins, usedPackages, subMonitor);
148152
removeBuddies();
149153
removeReexported();
150-
removeSourceReferences(subMonitor.split(10));
151154
}
152155

153156
/**
@@ -158,8 +161,12 @@ public void run(IProgressMonitor monitor) throws InvocationTargetException, Inte
158161
* warnings. To prevent the user from getting a confusing project
159162
* error/warnings we retain them here even if not strictly required at
160163
* runtime.
164+
*
165+
* @param usedPackages
166+
* @param usedPlugins
161167
*/
162-
private void removeSourceReferences(IProgressMonitor monitor) {
168+
private void removeSourceReferences(Map<String, IPluginImport> usedPlugins, List<ImportPackageObject> usedPackages,
169+
IProgressMonitor monitor) {
163170
if (fList.isEmpty()) {
164171
return;
165172
}
@@ -168,49 +175,66 @@ private void removeSourceReferences(IProgressMonitor monitor) {
168175
IJavaProject javaProject = JavaCore.create(project);
169176
SubMonitor convert = SubMonitor.convert(monitor, "Search Source References for unused requirements", //$NON-NLS-1$
170177
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);
171186
for (Iterator<Object> iterator = fList.iterator(); iterator.hasNext();) {
172187
Object item = iterator.next();
173188
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);
175206
iterator.remove();
176207
}
177208
}
178209
}
179210
}
180211
}
181212

182-
private boolean isPackageReferenced(ImportPackageObject pkg, IJavaProject javaProject, IProgressMonitor monitor) {
213+
private boolean isBundleReferenced(IPackageFragment[] packageFragments, Requestor requestor,
214+
IProgressMonitor monitor) {
183215
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;
210222
}
211223
}
212-
return requestor.used;
213224
}
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);
214238
} catch (CoreException e) {
215239
}
216240
// 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
372396
}
373397

374398
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+
}
376425

377426
@Override
378427
public void acceptSearchMatch(SearchMatch match) {
379428
used = true;
380429
}
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+
}
381444
}
382445
}

0 commit comments

Comments
 (0)