Skip to content

Commit 02fa168

Browse files
Copilotlaeubi
authored andcommitted
Use JDT API to discover package names in ProjectTypeContainer
This change addresses issue #801 by using JDT's IPackageFragmentRoot API to discover package names instead of relying on filesystem traversal. Fix #801
1 parent f2cc40b commit 02fa168

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/ProjectComponent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ private static IApiTypeContainer getApiTypeContainer(String location, ProjectCom
395395
IPath location2 = res.getLocation();
396396
IApiTypeContainer cfc = outputLocationToContainer.get(location2);
397397
if (cfc == null) {
398-
cfc = new ProjectTypeContainer(component, (IContainer) res);
398+
cfc = new ProjectTypeContainer(component, (IContainer) res, root);
399399
outputLocationToContainer.put(location2, cfc);
400400
}
401401
return cfc;
@@ -416,7 +416,7 @@ private static IApiTypeContainer getApiTypeContainer(String location, ProjectCom
416416
} else {
417417
container = project.getProject().getWorkspace().getRoot().getFolder(outputLocation);
418418
}
419-
cfc = new ProjectTypeContainer(component, container);
419+
cfc = new ProjectTypeContainer(component, container, root);
420420
outputLocationToContainer.put(outputLocation, cfc);
421421
}
422422
return cfc;

apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/model/ProjectTypeContainer.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import java.util.ArrayList;
1717
import java.util.List;
18+
import java.util.Objects;
1819
import java.util.Set;
1920
import java.util.SortedSet;
2021
import java.util.TreeSet;
@@ -25,6 +26,9 @@
2526
import org.eclipse.core.resources.IResource;
2627
import org.eclipse.core.runtime.CoreException;
2728
import org.eclipse.core.runtime.IPath;
29+
import org.eclipse.jdt.core.IJavaElement;
30+
import org.eclipse.jdt.core.IPackageFragment;
31+
import org.eclipse.jdt.core.IPackageFragmentRoot;
2832
import org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor;
2933
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
3034
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
@@ -43,17 +47,27 @@ public class ProjectTypeContainer extends ApiElement implements IApiTypeContaine
4347
* Root directory of the {@link IApiTypeContainer}
4448
*/
4549
private final IContainer fRoot;
46-
private String[] fPackageNames = null;
50+
private String[] fPackageNames;
4751

4852
/**
49-
* Constructs an {@link IApiTypeContainer} rooted at the location.
53+
* Optional package fragment root for JDT-based package discovery
54+
*/
55+
private final IPackageFragmentRoot fPackageFragmentRoot;
56+
57+
/**
58+
* Constructs an {@link IApiTypeContainer} rooted at the location with an
59+
* optional package fragment root for package discovery.
5060
*
5161
* @param parent the {@link IApiElement} parent for this container
5262
* @param container folder in the workspace
63+
* @param packageFragmentRoot optional package fragment root for JDT-based
64+
* package discovery, may be <code>null</code>
65+
* @since 1.3.300
5366
*/
54-
public ProjectTypeContainer(IApiElement parent, IContainer container) {
67+
public ProjectTypeContainer(IApiElement parent, IContainer container, IPackageFragmentRoot packageFragmentRoot) {
5568
super(parent, IApiElement.API_TYPE_CONTAINER, container.getName());
5669
this.fRoot = container;
70+
this.fPackageFragmentRoot = Objects.requireNonNull(packageFragmentRoot);
5771
}
5872

5973
@Override
@@ -145,28 +159,34 @@ public IApiTypeRoot findTypeRoot(String qualifiedName) throws CoreException {
145159
public String[] getPackageNames() throws CoreException {
146160
if (fPackageNames == null) {
147161
SortedSet<String> names = new TreeSet<>();
148-
collectPackageNames(names, fRoot);
162+
if (fPackageFragmentRoot.exists()) {
163+
collectPackageNames(names, fPackageFragmentRoot);
164+
}
149165
fPackageNames = names.toArray(String[]::new);
150166
}
151167
return fPackageNames;
152168
}
153169

154170
/**
155-
* Traverses a directory to determine if it has {@link IApiTypeRoot}s and then
156-
* visits sub-directories.
171+
* Collects package names using JDT's package fragment root API.
157172
*
158-
* @param dir directory being visited
173+
* @param collector set to collect package names
174+
* @param root package fragment root to traverse
175+
* @throws CoreException if unable to traverse the package fragment root
159176
*/
160-
private static void collectPackageNames(Set<String> collector, IContainer dir) throws CoreException {
161-
int segmentCount = dir.getFullPath().segmentCount();
162-
dir.accept(proxy -> {
163-
if (proxy.getType() == IResource.FOLDER) {
164-
IPath relativePath = proxy.requestFullPath().removeFirstSegments(segmentCount);
165-
String packageName = relativePath.toString().replace(IPath.SEPARATOR, '.');
166-
return collector.add(packageName);
177+
private static void collectPackageNames(Set<String> collector, IPackageFragmentRoot root) throws CoreException {
178+
IJavaElement[] children = root.getChildren();
179+
if (children != null) {
180+
for (IJavaElement element : children) {
181+
if (element instanceof IPackageFragment fragment) {
182+
String name = fragment.getElementName();
183+
if (name.length() == 0) {
184+
name = Util.DEFAULT_PACKAGE_NAME;
185+
}
186+
collector.add(name);
187+
}
167188
}
168-
return false;
169-
}, IResource.NONE);
189+
}
170190
}
171191

172192
@Override

0 commit comments

Comments
 (0)