Skip to content

Commit c1237e7

Browse files
authored
Add referenced libraries as reference container (#113)
1 parent 87e9cf5 commit c1237e7

File tree

1 file changed

+109
-41
lines changed

1 file changed

+109
-41
lines changed

jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java

Lines changed: 109 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ public class PackageCommand {
6767

6868
private static final String DEFAULT_PACKAGE_DISPLAYNAME = "(default package)";
6969

70+
private static final String REFERENCED_LIBRARIES_PATH = "REFERENCED_LIBRARIES_PATH";
71+
72+
private static final String REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries";
73+
74+
private static final ContainerNode REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(REFERENCED_LIBRARIES_CONTAINER_NAME, REFERENCED_LIBRARIES_PATH,
75+
NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);
76+
7077
private static final Gson gson = new GsonBuilder().registerTypeAdapterFactory(new CollectionTypeAdapterFactory())
7178
.registerTypeAdapterFactory(new EnumTypeAdapterFactory()).create();
7279

@@ -97,7 +104,6 @@ public static List<PackageNode> getChildren(List<Object> arguments, IProgressMon
97104
throw new IllegalArgumentException("Should have at least one arugment for getChildren");
98105
}
99106
PackageParams params = gson.fromJson(gson.toJson(arguments.get(0)), PackageParams.class);
100-
101107
BiFunction<PackageParams, IProgressMonitor, List<PackageNode>> loader = commands.get(params.getKind());
102108
if (loader == null) {
103109
throw new CoreException(new Status(IStatus.ERROR, JdtlsExtActivator.PLUGIN_ID, String.format("Unknown classpath item type: %s", params.getKind())));
@@ -144,7 +150,13 @@ public static List<PackageNode> resolvePath(List<Object> arguments, IProgressMon
144150
IPackageFragmentRoot pkgRoot = (IPackageFragmentRoot) packageFragment.getParent();
145151
PackageNode rootNode = null;
146152
if (typeRoot instanceof IClassFile) {
147-
rootNode = new PackageRootNode(pkgRoot.getElementName(), pkgRoot.getPath().toPortableString(), NodeKind.PACKAGEROOT, pkgRoot.getKind());
153+
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
154+
// Process Referenced Variable
155+
if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
156+
rootNode = getNodeFromClasspathVariable(entry);
157+
} else {
158+
rootNode = new PackageRootNode(pkgRoot.getElementName(), pkgRoot.getPath().toPortableString(), NodeKind.PACKAGEROOT, pkgRoot.getKind());
159+
}
148160
} else {
149161
rootNode = new PackageRootNode(ExtUtils.removeProjectSegment(typeRoot.getJavaProject().getElementName(), pkgRoot.getPath()).toPortableString(),
150162
pkgRoot.getPath().toPortableString(), NodeKind.PACKAGEROOT, pkgRoot.getKind());
@@ -154,8 +166,13 @@ public static List<PackageNode> resolvePath(List<Object> arguments, IProgressMon
154166
if (typeRoot instanceof IClassFile) {
155167
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
156168
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), typeRoot.getJavaProject());
157-
PackageNode containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER,
158-
entry.getEntryKind());
169+
PackageNode containerNode = null;
170+
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
171+
containerNode = REFERENCED_LIBRARIES_CONTAINER;
172+
} else {
173+
containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER,
174+
entry.getEntryKind());
175+
}
159176
result.add(containerNode);
160177
}
161178
result.add(rootNode);
@@ -174,36 +191,80 @@ public static List<PackageNode> resolvePath(List<Object> arguments, IProgressMon
174191
*/
175192
private static List<PackageNode> getContainers(PackageParams query, IProgressMonitor pm) {
176193
IJavaProject javaProject = getJavaProject(query.getProjectUri());
177-
178194
if (javaProject != null) {
179195
try {
180196
IClasspathEntry[] references = javaProject.getRawClasspath();
181-
return Arrays.stream(references).map(entry -> {
182-
try {
183-
entry = JavaCore.getResolvedClasspathEntry(entry);
184-
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
185-
// HACK: There is an initialization issue for the first container.
186-
if (container == null) {
187-
container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
188-
}
189-
190-
if (container != null) {
191-
return new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER,
192-
entry.getEntryKind());
193-
}
194-
} catch (CoreException e) {
195-
// Ignore it
196-
}
197-
return null;
198-
}).filter(containerNode -> containerNode != null).collect(Collectors.toList());
197+
List<PackageNode> result = Arrays.stream(references)
198+
.filter(entry -> entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY && entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE)
199+
.map(entry -> getNodeFromClasspathEntry(entry, javaProject, NodeKind.CONTAINER)).filter(containerNode -> containerNode != null)
200+
.collect(Collectors.toList());
201+
boolean isReferencedLibrariesExist = Arrays.stream(references)
202+
.anyMatch(entry -> entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE);
203+
if (isReferencedLibrariesExist) {
204+
result.add(REFERENCED_LIBRARIES_CONTAINER);
205+
}
206+
return result;
199207
} catch (CoreException e) {
200208
JdtlsExtActivator.logException("Problem load project library ", e);
201209
}
202210
}
203211
return Collections.emptyList();
204212
}
205213

214+
/**
215+
* Get the correspond node of classpath, it may be container or a package root
216+
*
217+
* @param classpathEntry
218+
* classpath entry
219+
* @param javaProject
220+
* correspond java project
221+
* @param nodeKind
222+
* could be CONTAINER or PACKAGEROOT(for referenced libraries)
223+
* @return correspond PackageNode of classpath entry
224+
*/
225+
private static PackageNode getNodeFromClasspathEntry(IClasspathEntry classpathEntry, IJavaProject javaProject, NodeKind nodeKind) {
226+
try {
227+
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
228+
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
229+
// HACK: There is an initialization issue for the first container.
230+
if (container == null) {
231+
container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
232+
}
233+
if (container != null) {
234+
switch (nodeKind) {
235+
case CONTAINER:
236+
return new ContainerNode(container.getDescription(), container.getPath().toPortableString(), nodeKind, entry.getEntryKind());
237+
case PACKAGEROOT:
238+
// Use package name as package root name
239+
String[] pathSegments = container.getPath().segments();
240+
return new PackageRootNode(pathSegments[pathSegments.length - 1], container.getPath().toPortableString(), nodeKind,
241+
IPackageFragmentRoot.K_BINARY);
242+
default:
243+
return null;
244+
}
245+
}
246+
} catch (CoreException e) {
247+
JdtlsExtActivator.logException("Problems when convert classpath entry to package node ", e);
248+
}
249+
return null;
250+
}
251+
252+
/**
253+
* Get correspond node of referenced variable
254+
*
255+
* @param classpathEntry
256+
* referenced cariable's classpath entry
257+
* @return correspond package node
258+
*/
259+
private static PackageNode getNodeFromClasspathVariable(IClasspathEntry classpathEntry) {
260+
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
261+
String name = classpathEntry.getPath().toPortableString();
262+
String path = entry.getPath().toPortableString();
263+
return new PackageRootNode(name, path, NodeKind.PACKAGEROOT, IPackageFragmentRoot.K_BINARY);
264+
}
265+
206266
private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IProgressMonitor pm) {
267+
ArrayList<PackageNode> children = new ArrayList<>();
207268
IJavaProject javaProject = getJavaProject(query.getProjectUri());
208269

209270
if (javaProject != null) {
@@ -217,7 +278,6 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP
217278
}
218279
}
219280
if (containerEntry != null) {
220-
ArrayList<PackageNode> children = new ArrayList<>();
221281
IPackageFragmentRoot[] packageFragmentRoots = javaProject.findPackageFragmentRoots(containerEntry);
222282
for (IPackageFragmentRoot fragmentRoot : packageFragmentRoots) {
223283
String displayName = fragmentRoot.getElementName();
@@ -232,6 +292,16 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP
232292
}
233293
}
234294
return children;
295+
} else if (query.getPath().equals(REFERENCED_LIBRARIES_PATH)) {
296+
// Process referenced libraries
297+
List<PackageNode> referLibs = Arrays.stream(references).filter(entry -> entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY)
298+
.map(classpath -> getNodeFromClasspathEntry(classpath, javaProject, NodeKind.PACKAGEROOT)).filter(entry -> entry != null)
299+
.collect(Collectors.toList());
300+
List<PackageNode> referVariables = Arrays.stream(references).filter(entry -> entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE)
301+
.map(classpath -> getNodeFromClasspathVariable(classpath)).filter(entry -> entry != null).collect(Collectors.toList());
302+
children.addAll(referLibs);
303+
children.addAll(referVariables);
304+
return children;
235305
}
236306
} catch (CoreException e) {
237307
JdtlsExtActivator.logException("Problem load project JAR entries ", e);
@@ -243,9 +313,7 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP
243313

244314
private static List<PackageNode> getPackages(PackageParams query, IProgressMonitor pm) {
245315
IJavaProject javaProject = getJavaProject(query.getProjectUri());
246-
247316
if (javaProject != null) {
248-
249317
try {
250318
IPackageFragmentRoot packageRoot = javaProject.findPackageFragmentRoot(Path.fromPortableString(query.getRootPath()));
251319
if (packageRoot == null) {
@@ -274,7 +342,7 @@ private static List<PackageNode> getRootTypes(PackageParams query, IProgressMoni
274342
if (packageFragment != null) {
275343
IJavaElement[] types = packageFragment.getChildren();
276344
Object[] nonJavaResources = packageFragment.getNonJavaResources();
277-
List<PackageNode> rootTypeNodes = Arrays.stream(types).filter(typeRoot -> !typeRoot.getElementName().contains("$")).map(typeRoot -> {
345+
List<PackageNode> rootTypeNodes = Arrays.stream(types).filter(typeRoot -> !typeRoot.getElementName().contains("$")).map(typeRoot -> {
278346
PackageNode item = new TypeRootNode(typeRoot.getElementName(), typeRoot.getPath().toPortableString(), NodeKind.TYPEROOT,
279347
typeRoot instanceof IClassFile ? TypeRootNode.K_BINARY : TypeRootNode.K_SOURCE);
280348
if (typeRoot instanceof ICompilationUnit) {
@@ -289,20 +357,20 @@ private static List<PackageNode> getRootTypes(PackageParams query, IProgressMoni
289357
}
290358
// when .java files and other .properties files are mixed up
291359
rootTypeNodes.addAll(
292-
Arrays.stream(nonJavaResources).filter(resource -> resource instanceof IFile || resource instanceof JarEntryFile).map(resource -> {
293-
if (resource instanceof IFile) {
294-
IFile file = (IFile) resource;
295-
PackageNode item = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
296-
item.setUri(JDTUtils.getFileURI(file));
297-
return item;
298-
} else {
299-
JarEntryFile file = (JarEntryFile) resource;
300-
PackageNode entry = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
301-
entry.setUri(ExtUtils.toUri((JarEntryFile) resource));
302-
return entry;
303-
}
304-
305-
}).collect(Collectors.toList()));
360+
Arrays.stream(nonJavaResources).filter(resource -> resource instanceof IFile || resource instanceof JarEntryFile).map(resource -> {
361+
if (resource instanceof IFile) {
362+
IFile file = (IFile) resource;
363+
PackageNode item = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
364+
item.setUri(JDTUtils.getFileURI(file));
365+
return item;
366+
} else {
367+
JarEntryFile file = (JarEntryFile) resource;
368+
PackageNode entry = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
369+
entry.setUri(ExtUtils.toUri((JarEntryFile) resource));
370+
return entry;
371+
}
372+
373+
}).collect(Collectors.toList()));
306374
return rootTypeNodes;
307375
}
308376
} catch (CoreException e) {

0 commit comments

Comments
 (0)