Skip to content

Commit 95ff1ba

Browse files
authored
fix: No context menu when explorer is in hierarchical mode (#435)
1 parent d2f9b37 commit 95ff1ba

File tree

5 files changed

+137
-10
lines changed

5 files changed

+137
-10
lines changed

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

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
import com.microsoft.jdtls.ext.core.model.NodeKind;
6464
import com.microsoft.jdtls.ext.core.model.PackageNode;
6565
import com.microsoft.jdtls.ext.core.model.PackageRootNode;
66+
import com.microsoft.jdtls.ext.core.model.Trie;
67+
import com.microsoft.jdtls.ext.core.model.TrieNode;
6668

6769
public class PackageCommand {
6870

@@ -347,7 +349,7 @@ private static List<PackageNode> getPackages(PackageParams query, IProgressMonit
347349
throw new CoreException(
348350
new Status(IStatus.ERROR, JdtlsExtActivator.PLUGIN_ID, String.format("No package root found for %s", query.getPath())));
349351
}
350-
Object[] result = getPackageFragmentRootContent(packageRoot, pm);
352+
Object[] result = getPackageFragmentRootContent(packageRoot, query.isHierarchicalView(), pm);
351353
return convertToPackageNode(result, packageRoot, pm);
352354
} catch (CoreException e) {
353355
JdtlsExtActivator.logException("Problem load project package ", e);
@@ -461,18 +463,45 @@ private static List<PackageNode> getFolderChildren(PackageParams query, IProgres
461463
return Collections.emptyList();
462464
}
463465

464-
private static Object[] getPackageFragmentRootContent(IPackageFragmentRoot root, IProgressMonitor pm) throws CoreException {
466+
/**
467+
* Return the packages of the package root. Note that when the explorer is in hierarchical mode,
468+
* We also need to return the deepest common parent packages, for example:
469+
* - com.microsoft.example <-- this common parent package should be returned.
470+
* +-- model
471+
* +-- handler
472+
* Here we use a Trie to find all these packages.
473+
*
474+
* @param root the package fragment root
475+
* @param isHierarchicalView whether the explorer is in hierarchical mode or not
476+
* @param pm the progress monitor
477+
*/
478+
private static Object[] getPackageFragmentRootContent(IPackageFragmentRoot root, boolean isHierarchicalView, IProgressMonitor pm) throws CoreException {
465479
ArrayList<Object> result = new ArrayList<>();
466-
for (IJavaElement child : root.getChildren()) {
467-
IPackageFragment fragment = (IPackageFragment) child;
468-
if (fragment.hasChildren()) {
469-
result.add(child);
470-
} else if (fragment.getNonJavaResources().length > 0) { // some package has non-java files
471-
result.add(fragment);
472-
} else if (!fragment.hasSubpackages()) {
473-
result.add(fragment);
480+
if (isHierarchicalView) {
481+
Map<String, IJavaElement> map = new HashMap<>();
482+
for (IJavaElement child : root.getChildren()) {
483+
map.put(child.getElementName(), child);
484+
}
485+
Trie<IJavaElement> trie = new Trie<>(map);
486+
for (TrieNode<IJavaElement> node : trie.getAllNodes()) {
487+
if (node.value == null) {
488+
continue;
489+
}
490+
IPackageFragment fragment = (IPackageFragment) node.value;
491+
if (fragment.hasChildren() || fragment.getNonJavaResources().length > 0
492+
|| !fragment.hasSubpackages() || node.children.size() > 1) {
493+
result.add(fragment);
494+
}
495+
}
496+
} else {
497+
for (IJavaElement child : root.getChildren()) {
498+
IPackageFragment fragment = (IPackageFragment) child;
499+
if (fragment.hasChildren() || fragment.getNonJavaResources().length > 0 || !fragment.hasSubpackages()) {
500+
result.add(fragment);
501+
}
474502
}
475503
}
504+
476505
Object[] nonJavaResources = root.getNonJavaResources();
477506
Collections.addAll(result, nonJavaResources);
478507

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,19 @@ public class PackageParams {
2929

3030
private String rootPath;
3131

32+
private boolean isHierarchicalView;
33+
3234
public PackageParams() {
3335
}
3436

37+
public boolean isHierarchicalView() {
38+
return isHierarchicalView;
39+
}
40+
41+
public void setHierarchicalView(boolean isHierarchicalView) {
42+
this.isHierarchicalView = isHierarchicalView;
43+
}
44+
3545
public PackageParams(NodeKind kind, String projectUri) {
3646
this.kind = kind;
3747
this.projectUri = projectUri;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2021 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.jdtls.ext.core.model;
13+
14+
import java.util.HashSet;
15+
import java.util.Map;
16+
import java.util.Set;
17+
18+
import org.apache.commons.lang3.StringUtils;
19+
20+
public class Trie<T> {
21+
private TrieNode<T> root = new TrieNode<>();
22+
private Set<TrieNode<T>> allNodes = new HashSet<>();
23+
24+
public Trie(Map<String, T> entries) {
25+
for (Map.Entry<String, T> entry : entries.entrySet()) {
26+
insert(entry.getKey(), entry.getValue());
27+
}
28+
}
29+
30+
public Set<TrieNode<T>> getAllNodes() {
31+
return allNodes;
32+
}
33+
34+
public void insert(String name, T value) {
35+
if (StringUtils.isBlank(name)) {
36+
return;
37+
}
38+
39+
String[] names = name.split("\\.");
40+
TrieNode<T> currentNode = this.root;
41+
for (int i = 0; i < names.length; i++) {
42+
TrieNode<T> node;
43+
if (currentNode.children.containsKey(names[i])) {
44+
node = currentNode.children.get(names[i]);
45+
} else {
46+
node = new TrieNode<T>(names[i], null);
47+
currentNode.children.put(names[i], node);
48+
allNodes.add(node);
49+
}
50+
if (i == names.length - 1) {
51+
node.value = value;
52+
}
53+
54+
currentNode = node;
55+
}
56+
}
57+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2021 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.jdtls.ext.core.model;
13+
14+
import java.util.LinkedHashMap;
15+
import java.util.Map;
16+
17+
public class TrieNode<T> {
18+
public String name;
19+
public Map<String, TrieNode<T>> children = new LinkedHashMap<>();
20+
public T value;
21+
22+
public TrieNode() {
23+
}
24+
25+
public TrieNode(String name, T value) {
26+
this.name = name;
27+
this.value = value;
28+
}
29+
}

src/views/packageRootNode.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Explorer } from "../constants";
66
import { Jdtls } from "../java/jdtls";
77
import { INodeData, NodeKind } from "../java/nodeData";
88
import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData";
9+
import { Settings } from "../settings";
910
import { ContainerNode } from "./containerNode";
1011
import { DataNode } from "./dataNode";
1112
import { ExplorerNode } from "./explorerNode";
@@ -27,6 +28,7 @@ export class PackageRootNode extends DataNode {
2728
projectUri: this._project.nodeData.uri,
2829
rootPath: this.nodeData.path,
2930
handlerIdentifier: this.nodeData.handlerIdentifier,
31+
isHierarchicalView: Settings.isHierarchicalView(),
3032
});
3133
}
3234

0 commit comments

Comments
 (0)