From bceb459c59967384a7fa081ab998f9ee2946572d Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Wed, 16 Oct 2024 10:59:37 +0200 Subject: [PATCH 01/16] ux - display maven and gradle dependencies with pattern 'groupId:artifactId:version ' --- src/views/containerNode.ts | 37 ++++++++++++++++++++++++----- src/views/dataNode.ts | 10 +++++++- src/views/dependencyDataProvider.ts | 10 +++++++- src/views/documentSymbolNode.ts | 6 ++++- src/views/explorerNode.ts | 2 ++ 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/views/containerNode.ts b/src/views/containerNode.ts index 0245514c..8117dce4 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -15,23 +15,48 @@ export class ContainerNode extends DataNode { super(nodeData, parent); } + private _containerType: ContainerType; + public get projectBasePath() { return this._project.uri && Uri.parse(this._project.uri).fsPath; } - public getContainerType(): string { + public getContainerType(): ContainerType { + if (this._containerType) { + return this._containerType; + } + const containerPath: string = this._nodeData.path || ""; if (containerPath.startsWith(ContainerPath.JRE)) { - return ContainerType.JRE; + this._containerType = ContainerType.JRE; } else if (containerPath.startsWith(ContainerPath.Maven)) { - return ContainerType.Maven; + this._containerType = ContainerType.Maven; } else if (containerPath.startsWith(ContainerPath.Gradle)) { - return ContainerType.Gradle; + this._containerType = ContainerType.Gradle; } else if (containerPath.startsWith(ContainerPath.ReferencedLibrary) && this._project.isUnmanagedFolder()) { // currently, we only support editing referenced libraries in unmanaged folders - return ContainerType.ReferencedLibrary; + this._containerType = ContainerType.ReferencedLibrary; + } else { + this._containerType = ContainerType.Unknown; } - return ContainerType.Unknown; + + return this._containerType; + } + + public getLabel(): string { + if (this._nodeData.metaData?.['maven.groupId']) { + return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; + } else { + return this._nodeData.displayName ?? this._nodeData.name; + } + } + + public isMavenType(): boolean { + return this.getContainerType() == ContainerType.Maven; + } + + public isGradleType(): boolean { + return this.getContainerType() == ContainerType.Gradle; } protected async loadData(): Promise { diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index 21be07a7..870ccab2 100644 --- a/src/views/dataNode.ts +++ b/src/views/dataNode.ts @@ -17,7 +17,7 @@ export abstract class DataNode extends ExplorerNode { public getTreeItem(): TreeItem | Promise { const item = new TreeItem( - this._nodeData.displayName || this._nodeData.name, + this.getLabel(), this.hasChildren() ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None, ); item.description = this.description; @@ -42,6 +42,14 @@ export abstract class DataNode extends ExplorerNode { return item; } + public getLabel(): string { + if (this._nodeData.metaData?.['maven.groupId']) { + return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; + } else { + return this._nodeData.displayName ?? this._nodeData.name; + } + } + public get nodeData(): INodeData { return this._nodeData; } diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index dd0bd05b..21802b8c 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -7,7 +7,7 @@ import { RelativePattern, TreeDataProvider, TreeItem, Uri, window, workspace, } from "vscode"; import { instrumentOperationAsVsCodeCommand, sendError } from "vscode-extension-telemetry-wrapper"; -import { contextManager } from "../../extension.bundle"; +import { contextManager, ContainerNode } from "../../extension.bundle"; import { Commands } from "../commands"; import { Context } from "../constants"; import { appendOutput, executeExportJarTask } from "../tasks/buildArtifact/BuildArtifactTaskProvider"; @@ -124,6 +124,14 @@ export class DependencyDataProvider implements TreeDataProvider { const children = (!this._rootItems || !element) ? await this.getRootNodes() : await element.getChildren(); + if (children && element instanceof ContainerNode) { + if (element.isMavenType() || element.isGradleType()) { + children.sort((a, b) => { + return a.getLabel().localeCompare(b.getLabel()); + }); + } + } + explorerNodeCache.saveNodes(children || []); return children; } diff --git a/src/views/documentSymbolNode.ts b/src/views/documentSymbolNode.ts index a6ead753..3ad00e3a 100644 --- a/src/views/documentSymbolNode.ts +++ b/src/views/documentSymbolNode.ts @@ -28,6 +28,10 @@ export class DocumentSymbolNode extends ExplorerNode { super(parent); } + public getLabel(): string { + return this.symbolInfo.name; + } + public getChildren(): ExplorerNode[] | Promise { const res: ExplorerNode[] = []; if (this.symbolInfo?.children?.length) { @@ -39,7 +43,7 @@ export class DocumentSymbolNode extends ExplorerNode { } public getTreeItem(): TreeItem | Promise { - const item = new TreeItem(this.symbolInfo.name, + const item = new TreeItem(this.getLabel(), this.symbolInfo?.children?.length ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None); item.iconPath = this.iconPath; diff --git a/src/views/explorerNode.ts b/src/views/explorerNode.ts index c5c29092..5b271531 100644 --- a/src/views/explorerNode.ts +++ b/src/views/explorerNode.ts @@ -33,4 +33,6 @@ export abstract class ExplorerNode { public abstract getTreeItem(): TreeItem | Promise; public abstract computeContextValue(): string | undefined; + + public abstract getLabel(): string; } From 002adf6da5e926df3af9bf856404e0e10ab2c03e Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Wed, 16 Oct 2024 11:00:07 +0200 Subject: [PATCH 02/16] add contibuting file --- CONTRIBUTING.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..5409280a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# How to Contribute + +We greatly appreciate contributions to the vscode-java-dependency project. Your efforts help us maintain and improve this extension. To ensure a smooth contribution process, please follow these guidelines. + +## Setup Guide + +To set up the vscode-java-dependency project, follow these steps: + +1. **Build the Server JAR**: + - The server JAR (Java application) is located in the [jdtls.ext](./jdtls.ext) directory. + - Run the following command to build the server: + ```shell + npm run build-server + ``` + +2. **Install Dependencies**: + - Execute the following command to install the necessary dependencies: + ```shell + npm install + ``` + +3. **Run the Extension**: + - Open the "Run and Debug" view in Visual Studio Code. + - Run the "Run Extension" task. + +4. **Attach to Plugin**: + - Open the "Run and Debug" view in Visual Studio Code. + - Run the "Attach to Plugin" task. + - Note: This task is required only if you want to debug Java code [jdtls.ext](./jdtls.ext). It requires the [vscode-pde](https://marketplace.visualstudio.com/items?itemName=yaozheng.vscode-pde) extension to be installed. + +Thank you for your contributions and support! \ No newline at end of file From 2da4296183e7c12637a8e0575f8bf8e62ef9fd76 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Wed, 16 Oct 2024 11:00:48 +0200 Subject: [PATCH 03/16] launch: add projectName to Attach To Plugin task --- .vscode/launch.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 57261f9f..7e154613 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,6 +18,7 @@ { "type": "java", "name": "Attach to Plugin", + "projectName": "com.microsoft.jdtls.ext.core", "request": "attach", "hostName": "localhost", "port": 1044 From e64ac43de5e45d0723a8d5acda65cca3acc0411b Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Wed, 16 Oct 2024 11:01:37 +0200 Subject: [PATCH 04/16] refactor: use EnumMap instead of HasMap due to performance improvement --- .../src/com/microsoft/jdtls/ext/core/PackageCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java index 1bb2e99b..cada8754 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.EnumMap; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -78,7 +79,7 @@ public class PackageCommand { private static final Map>> commands; static { - commands = new HashMap<>(); + commands = new EnumMap<>(NodeKind.class); commands.put(NodeKind.PROJECT, PackageCommand::getProjectChildren); commands.put(NodeKind.CONTAINER, PackageCommand::getContainerChildren); commands.put(NodeKind.PACKAGEROOT, PackageCommand::getPackageRootChildren); From 3db2c0ea5b5994fc06c31081b52200807416263d Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Fri, 18 Oct 2024 13:32:24 +0200 Subject: [PATCH 05/16] refactor: print label for maven packages only --- src/views/PrimaryTypeNode.ts | 4 ++++ src/views/containerNode.ts | 6 +----- src/views/dataNode.ts | 8 -------- src/views/dependencyDataProvider.ts | 2 +- src/views/fileNode.ts | 4 ++++ src/views/folderNode.ts | 4 ++++ src/views/packageNode.ts | 4 ++++ src/views/packageRootNode.ts | 12 +++++++++++- src/views/projectNode.ts | 4 ++++ src/views/workspaceNode.ts | 4 ++++ 10 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/views/PrimaryTypeNode.ts b/src/views/PrimaryTypeNode.ts index 8ee95223..0d80bf8b 100644 --- a/src/views/PrimaryTypeNode.ts +++ b/src/views/PrimaryTypeNode.ts @@ -34,6 +34,10 @@ export class PrimaryTypeNode extends DataNode { return ""; } + public getLabel(): string { + return this._nodeData.displayName ?? this._nodeData.name; + } + protected async loadData(): Promise { if (!this.hasChildren() || !this.nodeData.uri) { return undefined; diff --git a/src/views/containerNode.ts b/src/views/containerNode.ts index 8117dce4..06bc9930 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -44,11 +44,7 @@ export class ContainerNode extends DataNode { } public getLabel(): string { - if (this._nodeData.metaData?.['maven.groupId']) { - return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; - } else { - return this._nodeData.displayName ?? this._nodeData.name; - } + return this._nodeData.displayName ?? this._nodeData.name; } public isMavenType(): boolean { diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index 870ccab2..e0292a0e 100644 --- a/src/views/dataNode.ts +++ b/src/views/dataNode.ts @@ -42,14 +42,6 @@ export abstract class DataNode extends ExplorerNode { return item; } - public getLabel(): string { - if (this._nodeData.metaData?.['maven.groupId']) { - return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; - } else { - return this._nodeData.displayName ?? this._nodeData.name; - } - } - public get nodeData(): INodeData { return this._nodeData; } diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index 21802b8c..ba42d3fe 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -125,7 +125,7 @@ export class DependencyDataProvider implements TreeDataProvider { await this.getRootNodes() : await element.getChildren(); if (children && element instanceof ContainerNode) { - if (element.isMavenType() || element.isGradleType()) { + if (element.isMavenType()) { children.sort((a, b) => { return a.getLabel().localeCompare(b.getLabel()); }); diff --git a/src/views/fileNode.ts b/src/views/fileNode.ts index 851afafa..e593f10c 100644 --- a/src/views/fileNode.ts +++ b/src/views/fileNode.ts @@ -13,6 +13,10 @@ export class FileNode extends DataNode { super(nodeData, parent); } + public getLabel(): string { + return this._nodeData.displayName ?? this._nodeData.name; + } + protected hasChildren(): boolean { return false; } diff --git a/src/views/folderNode.ts b/src/views/folderNode.ts index 609b799b..45529b31 100644 --- a/src/views/folderNode.ts +++ b/src/views/folderNode.ts @@ -15,6 +15,10 @@ export class FolderNode extends DataNode { super(nodeData, parent); } + public getLabel(): string { + return this._nodeData.displayName ?? this._nodeData.name; + } + protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Folder, diff --git a/src/views/packageNode.ts b/src/views/packageNode.ts index a6151435..83f7589c 100644 --- a/src/views/packageNode.ts +++ b/src/views/packageNode.ts @@ -22,6 +22,10 @@ export class PackageNode extends DataNode { return parentData.entryKind === PackageRootKind.K_SOURCE || parentData.kind === NodeKind.Project; } + public getLabel(): string { + return this._nodeData.displayName ?? this._nodeData.name; + } + protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Package, diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index 63de2c65..e64252d7 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -8,7 +8,7 @@ import { INodeData, NodeKind } from "../java/nodeData"; import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData"; import { Settings } from "../settings"; import { isTest } from "../utility"; -import { ContainerNode } from "./containerNode"; +import { ContainerNode, ContainerType } from "./containerNode"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { ProjectNode } from "./projectNode"; @@ -20,6 +20,16 @@ export class PackageRootNode extends DataNode { super(nodeData, parent); } + public getLabel(): string { + if (this.getParent() instanceof ContainerNode) { + const parent = this.getParent() as ContainerNode; + if (parent.getContainerType() == ContainerType.Maven) { + return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; + } + } + return this._nodeData.displayName ?? this._nodeData.name; + } + public isSourceRoot(): boolean { return (this.nodeData).entryKind === PackageRootKind.K_SOURCE; } diff --git a/src/views/projectNode.ts b/src/views/projectNode.ts index f48ef75a..2bd341c4 100644 --- a/src/views/projectNode.ts +++ b/src/views/projectNode.ts @@ -54,6 +54,10 @@ export class ProjectNode extends DataNode { return false; } + public getLabel(): string { + return this._nodeData.displayName ?? this._nodeData.name; + } + protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Project, projectUri: this.nodeData.uri }); } diff --git a/src/views/workspaceNode.ts b/src/views/workspaceNode.ts index 4cb8331f..6cbd1913 100644 --- a/src/views/workspaceNode.ts +++ b/src/views/workspaceNode.ts @@ -14,6 +14,10 @@ export class WorkspaceNode extends DataNode { super(nodeData, parent); } + public getLabel(): string { + return this._nodeData.displayName ?? this._nodeData.name; + } + protected async loadData(): Promise { if (!this.nodeData.uri) { return undefined; From 39b10c782860ef3e5631283d5b01900c56c9faaf Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Fri, 18 Oct 2024 13:32:41 +0200 Subject: [PATCH 06/16] refactor: update CONTRIBUTING.md --- CONTRIBUTING.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5409280a..9917e21e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,12 @@ We greatly appreciate contributions to the vscode-java-dependency project. Your efforts help us maintain and improve this extension. To ensure a smooth contribution process, please follow these guidelines. -## Setup Guide +## Prerequisites +- [JDK](https://www.oracle.com/java/technologies/downloads/?er=221886) +- [Node.JS](https://nodejs.org/en/) +- [VSCode](https://code.visualstudio.com/) + +## Build and Run To set up the vscode-java-dependency project, follow these steps: @@ -19,11 +24,12 @@ To set up the vscode-java-dependency project, follow these steps: npm install ``` -3. **Run the Extension**: +3. **Run/Debug the Extension**: - Open the "Run and Debug" view in Visual Studio Code. - Run the "Run Extension" task. -4. **Attach to Plugin**: +4. **Attach to Plugin[Debug Java]**: + - Prerequisite: Ensure that the extension is activated, meaning the Java process is already launched. This is required for the task to run properly. - Open the "Run and Debug" view in Visual Studio Code. - Run the "Attach to Plugin" task. - Note: This task is required only if you want to debug Java code [jdtls.ext](./jdtls.ext). It requires the [vscode-pde](https://marketplace.visualstudio.com/items?itemName=yaozheng.vscode-pde) extension to be installed. From f4b44d91a176824baa8a526a5984ebf1568a9c6b Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Mon, 21 Oct 2024 13:19:30 +0200 Subject: [PATCH 07/16] refactor: simplify getLabel logic in PackageRootNode --- src/views/packageRootNode.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index e64252d7..15581c86 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -21,11 +21,8 @@ export class PackageRootNode extends DataNode { } public getLabel(): string { - if (this.getParent() instanceof ContainerNode) { - const parent = this.getParent() as ContainerNode; - if (parent.getContainerType() == ContainerType.Maven) { - return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; - } + if (this._nodeData.metaData?.['maven.groupId']) { + return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; } return this._nodeData.displayName ?? this._nodeData.name; } From 4530ccd43cf7a60dd7647b2729536d75ff1b16b2 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Tue, 22 Oct 2024 07:26:32 +0200 Subject: [PATCH 08/16] refactor: sort children by label --- src/views/dependencyDataProvider.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index ba42d3fe..d9c71eda 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -124,12 +124,10 @@ export class DependencyDataProvider implements TreeDataProvider { const children = (!this._rootItems || !element) ? await this.getRootNodes() : await element.getChildren(); - if (children && element instanceof ContainerNode) { - if (element.isMavenType()) { - children.sort((a, b) => { - return a.getLabel().localeCompare(b.getLabel()); - }); - } + if (children) { + children.sort((a, b) => { + return a.getLabel().localeCompare(b.getLabel()); + }); } explorerNodeCache.saveNodes(children || []); From 79a1cf949589bd84b487e924260f8c9196b82822 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Tue, 22 Oct 2024 15:41:41 +0200 Subject: [PATCH 09/16] refactor: remove unused import in dependencyDataProvider.ts --- src/views/dependencyDataProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index d9c71eda..9cfe445d 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -7,7 +7,7 @@ import { RelativePattern, TreeDataProvider, TreeItem, Uri, window, workspace, } from "vscode"; import { instrumentOperationAsVsCodeCommand, sendError } from "vscode-extension-telemetry-wrapper"; -import { contextManager, ContainerNode } from "../../extension.bundle"; +import { contextManager } from "../../extension.bundle"; import { Commands } from "../commands"; import { Context } from "../constants"; import { appendOutput, executeExportJarTask } from "../tasks/buildArtifact/BuildArtifactTaskProvider"; From 18527a1dc57ce57c360d677302c66597bdc1d789 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Tue, 22 Oct 2024 20:48:52 +0200 Subject: [PATCH 10/16] refactor: remove unused methods in ContainerNode --- src/views/containerNode.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/views/containerNode.ts b/src/views/containerNode.ts index 06bc9930..71284039 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -47,14 +47,6 @@ export class ContainerNode extends DataNode { return this._nodeData.displayName ?? this._nodeData.name; } - public isMavenType(): boolean { - return this.getContainerType() == ContainerType.Maven; - } - - public isGradleType(): boolean { - return this.getContainerType() == ContainerType.Gradle; - } - protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Container, projectUri: this._project.uri, path: this.path }); } From ecced17cf0429a327d6c66fccd8bdf645fb7c4e8 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Sun, 27 Oct 2024 12:59:17 +0100 Subject: [PATCH 11/16] refactor: set display name on java server side --- .../jdtls/ext/core/model/PackageNode.java | 22 +++++++++++++++++++ src/views/containerNode.ts | 4 ++-- src/views/dataNode.ts | 6 ++++- src/views/dependencyDataProvider.ts | 4 ++-- src/views/documentSymbolNode.ts | 4 ++-- src/views/explorerNode.ts | 2 +- src/views/fileNode.ts | 4 ---- src/views/folderNode.ts | 4 ---- src/views/packageNode.ts | 4 ---- src/views/packageRootNode.ts | 9 +------- src/views/projectNode.ts | 4 ---- src/views/workspaceNode.ts | 4 ---- 12 files changed, 35 insertions(+), 36 deletions(-) diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/model/PackageNode.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/model/PackageNode.java index 7f146d8d..92fa4cf7 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/model/PackageNode.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/model/PackageNode.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Objects; +import org.apache.commons.lang3.StringUtils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -273,11 +274,32 @@ public static PackageRootNode createNodeForPackageFragmentRoot(IPackageFragmentR for (IClasspathAttribute attribute : resolvedClasspathEntry.getExtraAttributes()) { node.setMetaDataValue(attribute.getName(), attribute.getValue()); } + + String computedDisplayName = computeDisplayName(node); + if (StringUtils.isNotBlank(computedDisplayName)) { + node.setDisplayName(computedDisplayName); + } } return node; } + private static String computeDisplayName(PackageRootNode node) { + if (node.getMetaData() == null || node.getMetaData().isEmpty()) { + return node.getName(); + } + + String version = (String) node.getMetaData().get("maven.version"); + String groupId = (String) node.getMetaData().get("maven.groupId"); + String artifactId = (String) node.getMetaData().get("maven.artifactId"); + + if (StringUtils.isBlank(version) || StringUtils.isBlank(groupId) || StringUtils.isBlank(artifactId)) { + return node.getName(); + } + + return groupId + ":" + artifactId + ":" + version; + } + /** * Get the correspond node of classpath, it may be container or a package root. * diff --git a/src/views/containerNode.ts b/src/views/containerNode.ts index 71284039..479afd53 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -43,8 +43,8 @@ export class ContainerNode extends DataNode { return this._containerType; } - public getLabel(): string { - return this._nodeData.displayName ?? this._nodeData.name; + public isMavenType(): boolean { + return this._containerType == ContainerType.Maven; } protected async loadData(): Promise { diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index e0292a0e..200abf13 100644 --- a/src/views/dataNode.ts +++ b/src/views/dataNode.ts @@ -17,7 +17,7 @@ export abstract class DataNode extends ExplorerNode { public getTreeItem(): TreeItem | Promise { const item = new TreeItem( - this.getLabel(), + this._nodeData.displayName || this._nodeData.name, this.hasChildren() ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None, ); item.description = this.description; @@ -42,6 +42,10 @@ export abstract class DataNode extends ExplorerNode { return item; } + public getDisplayName(): string { + return this._nodeData.displayName || this._nodeData.name; + } + public get nodeData(): INodeData { return this._nodeData; } diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index 9cfe445d..295cc208 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -7,7 +7,7 @@ import { RelativePattern, TreeDataProvider, TreeItem, Uri, window, workspace, } from "vscode"; import { instrumentOperationAsVsCodeCommand, sendError } from "vscode-extension-telemetry-wrapper"; -import { contextManager } from "../../extension.bundle"; +import { ContainerNode, contextManager } from "../../extension.bundle"; import { Commands } from "../commands"; import { Context } from "../constants"; import { appendOutput, executeExportJarTask } from "../tasks/buildArtifact/BuildArtifactTaskProvider"; @@ -126,7 +126,7 @@ export class DependencyDataProvider implements TreeDataProvider { if (children) { children.sort((a, b) => { - return a.getLabel().localeCompare(b.getLabel()); + return a.getDisplayName().localeCompare(b.getDisplayName()); }); } diff --git a/src/views/documentSymbolNode.ts b/src/views/documentSymbolNode.ts index 3ad00e3a..7552116e 100644 --- a/src/views/documentSymbolNode.ts +++ b/src/views/documentSymbolNode.ts @@ -28,7 +28,7 @@ export class DocumentSymbolNode extends ExplorerNode { super(parent); } - public getLabel(): string { + public getDisplayName(): string { return this.symbolInfo.name; } @@ -43,7 +43,7 @@ export class DocumentSymbolNode extends ExplorerNode { } public getTreeItem(): TreeItem | Promise { - const item = new TreeItem(this.getLabel(), + const item = new TreeItem(this.getDisplayName(), this.symbolInfo?.children?.length ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None); item.iconPath = this.iconPath; diff --git a/src/views/explorerNode.ts b/src/views/explorerNode.ts index 5b271531..1dcac373 100644 --- a/src/views/explorerNode.ts +++ b/src/views/explorerNode.ts @@ -34,5 +34,5 @@ export abstract class ExplorerNode { public abstract computeContextValue(): string | undefined; - public abstract getLabel(): string; + public abstract getDisplayName(): string; } diff --git a/src/views/fileNode.ts b/src/views/fileNode.ts index e593f10c..851afafa 100644 --- a/src/views/fileNode.ts +++ b/src/views/fileNode.ts @@ -13,10 +13,6 @@ export class FileNode extends DataNode { super(nodeData, parent); } - public getLabel(): string { - return this._nodeData.displayName ?? this._nodeData.name; - } - protected hasChildren(): boolean { return false; } diff --git a/src/views/folderNode.ts b/src/views/folderNode.ts index 45529b31..609b799b 100644 --- a/src/views/folderNode.ts +++ b/src/views/folderNode.ts @@ -15,10 +15,6 @@ export class FolderNode extends DataNode { super(nodeData, parent); } - public getLabel(): string { - return this._nodeData.displayName ?? this._nodeData.name; - } - protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Folder, diff --git a/src/views/packageNode.ts b/src/views/packageNode.ts index 83f7589c..a6151435 100644 --- a/src/views/packageNode.ts +++ b/src/views/packageNode.ts @@ -22,10 +22,6 @@ export class PackageNode extends DataNode { return parentData.entryKind === PackageRootKind.K_SOURCE || parentData.kind === NodeKind.Project; } - public getLabel(): string { - return this._nodeData.displayName ?? this._nodeData.name; - } - protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Package, diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index 15581c86..63de2c65 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -8,7 +8,7 @@ import { INodeData, NodeKind } from "../java/nodeData"; import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData"; import { Settings } from "../settings"; import { isTest } from "../utility"; -import { ContainerNode, ContainerType } from "./containerNode"; +import { ContainerNode } from "./containerNode"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { ProjectNode } from "./projectNode"; @@ -20,13 +20,6 @@ export class PackageRootNode extends DataNode { super(nodeData, parent); } - public getLabel(): string { - if (this._nodeData.metaData?.['maven.groupId']) { - return `${this._nodeData.metaData?.['maven.groupId']}:${this._nodeData.metaData?.['maven.artifactId']}:${this._nodeData.metaData?.['maven.version']}`; - } - return this._nodeData.displayName ?? this._nodeData.name; - } - public isSourceRoot(): boolean { return (this.nodeData).entryKind === PackageRootKind.K_SOURCE; } diff --git a/src/views/projectNode.ts b/src/views/projectNode.ts index 2bd341c4..f48ef75a 100644 --- a/src/views/projectNode.ts +++ b/src/views/projectNode.ts @@ -54,10 +54,6 @@ export class ProjectNode extends DataNode { return false; } - public getLabel(): string { - return this._nodeData.displayName ?? this._nodeData.name; - } - protected async loadData(): Promise { return Jdtls.getPackageData({ kind: NodeKind.Project, projectUri: this.nodeData.uri }); } diff --git a/src/views/workspaceNode.ts b/src/views/workspaceNode.ts index 6cbd1913..4cb8331f 100644 --- a/src/views/workspaceNode.ts +++ b/src/views/workspaceNode.ts @@ -14,10 +14,6 @@ export class WorkspaceNode extends DataNode { super(nodeData, parent); } - public getLabel(): string { - return this._nodeData.displayName ?? this._nodeData.name; - } - protected async loadData(): Promise { if (!this.nodeData.uri) { return undefined; From 234105e293ff38fbbdc52130991e128598e7c939 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Mon, 28 Oct 2024 07:32:43 +0100 Subject: [PATCH 12/16] refactor: fix dependencyDataProvider --- src/views/dependencyDataProvider.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index 295cc208..12001be2 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -124,10 +124,12 @@ export class DependencyDataProvider implements TreeDataProvider { const children = (!this._rootItems || !element) ? await this.getRootNodes() : await element.getChildren(); - if (children) { - children.sort((a, b) => { - return a.getDisplayName().localeCompare(b.getDisplayName()); - }); + if (children && element instanceof ContainerNode) { + if (element.isMavenType()) { + children.sort((a, b) => { + return a.getDisplayName().localeCompare(b.getDisplayName()); + }); + } } explorerNodeCache.saveNodes(children || []); From 0c1a8d32880a5fbb8a13d5a822c795c2f008f055 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Tue, 29 Oct 2024 06:55:43 +0100 Subject: [PATCH 13/16] Refactor: fix comparison operator --- src/views/containerNode.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/containerNode.ts b/src/views/containerNode.ts index 479afd53..a8cbd6c7 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -44,7 +44,7 @@ export class ContainerNode extends DataNode { } public isMavenType(): boolean { - return this._containerType == ContainerType.Maven; + return this._containerType === ContainerType.Maven; } protected async loadData(): Promise { From 9bb8490aa7882bfa33b47896d02205bf764fb809 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Tue, 29 Oct 2024 16:38:00 +0100 Subject: [PATCH 14/16] test: add test for displaying Maven dependency nodes in correct format --- test/maven-suite/projectView.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/maven-suite/projectView.test.ts b/test/maven-suite/projectView.test.ts index f6863758..a8cf68b0 100644 --- a/test/maven-suite/projectView.test.ts +++ b/test/maven-suite/projectView.test.ts @@ -253,6 +253,19 @@ suite("Maven Project View Tests", () => { assert.equal(projectChildren.length, 4); }); + test("Can maven dependency nodes display in correct groupId:artifactId:version format", async function() { + const explorer = DependencyExplorer.getInstance(contextManager.context); + + const roots = await explorer.dataProvider.getChildren(); + const projectNode = roots![0] as ProjectNode; + const projectChildren = await projectNode.getChildren(); + const mavenDependency = projectChildren[3] as ContainerNode; + const mavenChildren = await mavenDependency.getChildren(); + + assert.equal(mavenChildren[0].getDisplayName(), "org.hamcrest:hamcrest-core:1.3") + assert.equal(mavenChildren[1].getDisplayName(), "junit:junit:4.13.1") + }); + teardown(async () => { // Restore default settings. Some tests might alter them and others depend on a specific setting. // Not resetting to the default settings will also show the file as changed in the source control view. From fe0e1940e8ae1e9256bcc54c0fed49d9017ea2b2 Mon Sep 17 00:00:00 2001 From: Marko Milic Date: Wed, 30 Oct 2024 08:30:58 +0100 Subject: [PATCH 15/16] fix: lint issues --- test/maven-suite/projectView.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/maven-suite/projectView.test.ts b/test/maven-suite/projectView.test.ts index a8cf68b0..b338f209 100644 --- a/test/maven-suite/projectView.test.ts +++ b/test/maven-suite/projectView.test.ts @@ -262,8 +262,8 @@ suite("Maven Project View Tests", () => { const mavenDependency = projectChildren[3] as ContainerNode; const mavenChildren = await mavenDependency.getChildren(); - assert.equal(mavenChildren[0].getDisplayName(), "org.hamcrest:hamcrest-core:1.3") - assert.equal(mavenChildren[1].getDisplayName(), "junit:junit:4.13.1") + assert.equal(mavenChildren[0].getDisplayName(), "org.hamcrest:hamcrest-core:1.3"); + assert.equal(mavenChildren[1].getDisplayName(), "junit:junit:4.13.1"); }); teardown(async () => { From 0cb8e490811ea64b9d0f148d38bfede54cf3d517 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Thu, 31 Oct 2024 14:53:09 +0800 Subject: [PATCH 16/16] Wait more time --- test/gradle-suite/projectView.test.ts | 6 +++++- test/invisible-suite/projectView.test.ts | 14 +++++--------- test/maven-suite/projectView.test.ts | 7 +++++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/test/gradle-suite/projectView.test.ts b/test/gradle-suite/projectView.test.ts index ec5a045d..4a4e6776 100644 --- a/test/gradle-suite/projectView.test.ts +++ b/test/gradle-suite/projectView.test.ts @@ -3,13 +3,17 @@ import * as assert from "assert"; import { ContainerNode, contextManager, DataNode, DependencyExplorer, + languageServerApiManager, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle"; import { fsPath, setupTestEnv, Uris } from "../shared"; // tslint:disable: only-arrow-functions suite("Gradle Project View Tests", () => { - suiteSetup(setupTestEnv); + suiteSetup(async () => { + await setupTestEnv(); + await languageServerApiManager.ready(); + }); test("Can node render correctly", async function() { const explorer = DependencyExplorer.getInstance(contextManager.context); diff --git a/test/invisible-suite/projectView.test.ts b/test/invisible-suite/projectView.test.ts index c1488ce7..61e91d01 100644 --- a/test/invisible-suite/projectView.test.ts +++ b/test/invisible-suite/projectView.test.ts @@ -3,22 +3,21 @@ import * as assert from "assert"; import * as fse from "fs-extra"; -import { platform } from "os"; import * as path from "path"; import * as vscode from "vscode"; -import { Commands, contextManager, DependencyExplorer, PackageNode, PackageRootNode, ProjectNode } from "../../extension.bundle"; +import { Commands, contextManager, DependencyExplorer, languageServerApiManager, PackageNode, PackageRootNode, ProjectNode } from "../../extension.bundle"; import { setupTestEnv } from "../shared"; import { sleep } from "../util"; // tslint:disable: only-arrow-functions suite("Invisible Project View Tests", () => { - suiteSetup(setupTestEnv); + suiteSetup(async () => { + await setupTestEnv(); + await languageServerApiManager.ready(); + }); test("Can execute command java.project.refreshLibraries correctly", async function() { - if (platform() === "darwin") { - this.skip(); - } const explorer = DependencyExplorer.getInstance(contextManager.context); let projectNode = (await explorer.dataProvider.getChildren())![0] as ProjectNode; @@ -37,9 +36,6 @@ suite("Invisible Project View Tests", () => { }); test("Can execute command java.project.removeLibrary correctly", async function() { - if (platform() === "darwin") { - this.skip(); - } const explorer = DependencyExplorer.getInstance(contextManager.context); let projectNode = (await explorer.dataProvider.getChildren())![0] as ProjectNode; diff --git a/test/maven-suite/projectView.test.ts b/test/maven-suite/projectView.test.ts index b338f209..ec305edd 100644 --- a/test/maven-suite/projectView.test.ts +++ b/test/maven-suite/projectView.test.ts @@ -4,13 +4,16 @@ import * as assert from "assert"; import * as vscode from "vscode"; import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode, - INodeData, Jdtls, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle"; + INodeData, Jdtls, languageServerApiManager, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle"; import { fsPath, printNodes, setupTestEnv, Uris } from "../shared"; // tslint:disable: only-arrow-functions suite("Maven Project View Tests", () => { - suiteSetup(setupTestEnv); + suiteSetup(async () => { + await setupTestEnv(); + await languageServerApiManager.ready(); + }); test("Can node render correctly in hierarchical view", async function() { await vscode.workspace.getConfiguration("java.dependency").update("packagePresentation", "hierarchical");