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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..9917e21e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,37 @@ +# 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. + +## 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: + +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/Debug the Extension**: + - Open the "Run and Debug" view in Visual Studio Code. + - Run the "Run Extension" task. + +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. + +Thank you for your contributions and support! \ No newline at end of file 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); 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 0245514c..71284039 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -15,23 +15,36 @@ 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 { + return this._nodeData.displayName ?? this._nodeData.name; } protected async loadData(): Promise { diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index 21be07a7..e0292a0e 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; diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index dd0bd05b..9cfe445d 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -124,6 +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.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; } 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..15581c86 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,13 @@ 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 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;