From 95bf714147d903e690606df759e93922cd585274 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Fri, 30 Nov 2018 16:49:38 +0800 Subject: [PATCH 01/12] Add hierarchical package view, for issue #57 --- package.json | 5 ++ src/settings.ts | 4 + src/views/dependencyExplorer.ts | 21 ++++- src/views/packageRootNode.ts | 149 +++++++++++++++++++++++++++++++- 4 files changed, 173 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e109e650..f72bdfda 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,11 @@ "type": "boolean", "description": "Synchronize dependency viewer selection with folder explorer", "default": true + }, + "java.dependency.isHierarchicalView": { + "type": "boolean", + "description": "Switch whether package shows in hierarchical view", + "default": false } } }, diff --git a/src/settings.ts b/src/settings.ts index 361e3ee6..c370ae8e 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -28,5 +28,9 @@ export class Settings { return this._depdendencyConfig.get("syncWithFolderExplorer"); } + public static isHierarchicalView(): boolean { + return this._depdendencyConfig.get("isHierarchicalView"); + } + private static _depdendencyConfig: WorkspaceConfiguration = workspace.getConfiguration("java.dependency"); } diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 4c80ee89..711327a1 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -9,6 +9,7 @@ import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { DependencyDataProvider } from "./dependencyDataProvider"; import { ExplorerNode } from "./explorerNode"; +import { PackageRootNode } from "./packageRootNode"; export class DependencyExplorer { @@ -49,7 +50,6 @@ export class DependencyExplorer { if (!current) { return; } - const res = current.getChildren(); if (Utility.isThenable(res)) { res.then((children: DataNode[]) => { @@ -71,8 +71,23 @@ export class DependencyExplorer { this._selectionWhenHidden = c; } } else { - paths.shift(); - this.revealPath(c, paths); + // Resove Hierarchical packages + const node = paths.shift(); + if (Settings.isHierarchicalView() && c instanceof PackageRootNode) { + const packageNode = paths.shift(); + const res = c.getChildren(); + if (Utility.isThenable(res)) { + res.then(() => { + const correspondPackageNode = c.getPackageNodeFromNodeData(packageNode); + this.revealPath(correspondPackageNode, paths); + }); + } else { + const correspondPackageNode = c.getPackageNodeFromNodeData(packageNode); + this.revealPath(correspondPackageNode, paths); + } + } else { + this.revealPath(c, paths); + } } break; } diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index be1e712a..71a645fa 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -4,6 +4,8 @@ import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData"; +import { Settings } from "../settings"; +import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { FileNode } from "./fileNode"; @@ -14,15 +16,45 @@ import { TypeRootNode } from "./typeRootNode"; export class PackageRootNode extends DataNode { - constructor(nodeData: INodeData, parent: DataNode, private _project: ProjectNode) { + private packageTree: PackageTreeNode; + + constructor(nodeData: INodeData, parent: DataNode, private _project: ProjectNode, packageTree: PackageTreeNode = null) { super(nodeData, parent); + this.packageTree = packageTree; + } + + // Get correspond packageRootNode when revealPath + public getPackageNodeFromNodeData(classPackage: INodeData): PackageRootNode { + // tslint:disable-next-line:no-this-assignment + let packageRootNode: PackageRootNode = this; + while (packageRootNode.packageTree === null || packageRootNode.packageTree.fullName !== classPackage.name) { + let noMatchPackage: boolean = true; + packageRootNode.createChildNodeList().forEach((child) => { + if (child instanceof PackageRootNode && classPackage.name.startsWith(child.packageTree.fullName)) { + packageRootNode = child; + noMatchPackage = false; + } + }); + if (noMatchPackage) { + return null; + } + } + return packageRootNode; } protected loadData(): Thenable { - return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); + if (this.packageTree && this.packageTree.isPackage) { + // load package data + return Jdtls.getPackageData({ + kind: NodeKind.Package, projectUri: this._project.nodeData.uri, path: this.packageTree.fullName, rootPath: this.nodeData.path, + }); + } else { + return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); + } + } - protected createChildNodeList(): ExplorerNode[] { + protected createFlatChildNodeList(): ExplorerNode[] { const result = []; if (this.nodeData.children && this.nodeData.children.length) { this.sort(); @@ -41,7 +73,67 @@ export class PackageRootNode extends DataNode { return result; } + protected createHierarchicalChildNodeList(): ExplorerNode[] { + const result = []; + if (this.nodeData.children && this.nodeData.children.length) { + this.nodeData.children.forEach((data) => { + if (data.kind === NodeKind.File) { + result.push(new FileNode(data, this)); + } else if (data.kind === NodeKind.Folder) { + result.push(new FolderNode(data, this, this._project, this)); + } else if (data.kind === NodeKind.TypeRoot) { + result.push(new TypeRootNode(data, this)); + } + }); + } + this.getHierarchicalPackageNodes().forEach((node) => result.push(node)); + result.sort(); + return result; + } + + protected createChildNodeList(): ExplorerNode[] { + if (Settings.isHierarchicalView()) { + return this.createHierarchicalChildNodeList(); + } else { + return this.createFlatChildNodeList(); + } + } + + protected getHierarchicalPackageNodes(): ExplorerNode[] { + const result = []; + const packageTree = this.packageTree ? this.packageTree : this.getPackageTree(); + packageTree.childs.forEach((childNode) => { + const childNodeData: INodeData = { + name: childNode.name, + moduleName: this.nodeData.moduleName, + path: this.nodeData.path, + uri: null, + kind: NodeKind.PackageRoot, + children: null, + }; + result.push(new PackageRootNode(childNodeData, this, this._project, childNode)); + }); + return result; + } + + // Generage tree for packages, use for Hierarchical view + protected getPackageTree(): PackageTreeNode { + const result: PackageTreeNode = new PackageTreeNode("", ""); + if (this.nodeData.children && this.nodeData.children.length) { + this.nodeData.children.forEach((child) => { + if (child.kind === NodeKind.Package) { + result.addPackage(child.name); + } + }); + } + result.compressTree(); + return result; + } + protected get iconPath(): { light: string; dark: string } { + if (this.packageTree !== null) { + return ExplorerNode.resolveIconPath("package"); + } const data = this.nodeData; if (data.entryKind === PackageRootKind.K_BINARY) { return ExplorerNode.resolveIconPath("jar"); @@ -50,3 +142,54 @@ export class PackageRootNode extends DataNode { } } } + +class PackageTreeNode { + public name: string; + public fullName: string; + public childs: PackageTreeNode[] = []; + public isPackage: boolean = false; + + constructor(packageName: string, parentName: string) { + const splitPackageName = packageName.split("."); + this.name = splitPackageName[0]; + this.fullName = parentName === "" ? this.name : parentName + "." + this.name; + if (splitPackageName.length > 1) { + this.childs.push(new PackageTreeNode(packageName.substring(this.name.length + 1), this.fullName)); + } else { + this.isPackage = true; + } + } + + public addPackage(packageName: string): void { + const splitPackageName = packageName.split("."); + const firstSubName = splitPackageName[0]; + const restname = packageName.substring(firstSubName.length + 1); + + let contains: boolean = false; + this.childs.forEach((child) => { + if (child.name === firstSubName) { + if (restname === "") { + child.isPackage = true; + } else { + child.addPackage(restname); + } + contains = true; + } + }); + if (!contains) { + this.childs.push(new PackageTreeNode(packageName, this.fullName)); + } + } + + public compressTree(): void { + // Don't compress the root node + while (this.name !== "" && this.childs.length === 1 && !this.isPackage) { + const child = this.childs[0]; + this.fullName = this.fullName + "." + child.name; + this.name = this.name + "." + child.name; + this.childs = child.childs; + this.isPackage = child.isPackage; + } + this.childs.forEach((child) => child.compressTree()); + } +} From 6c8fad44df9150b0d1c1d98547d89768780fd77a Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Mon, 3 Dec 2018 11:12:55 +0800 Subject: [PATCH 02/12] Update vscode to 1.1.22 to fix vulnerability issue of event-stream; Refactor get node function of package root --- package-lock.json | 401 +++++++++++--------------------- package.json | 2 +- src/views/dependencyExplorer.ts | 14 +- src/views/packageRootNode.ts | 17 +- 4 files changed, 152 insertions(+), 282 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d2e2806..67547da0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,15 +48,15 @@ } }, "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz", + "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ansi-colors": { @@ -1185,12 +1185,6 @@ } } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -1405,7 +1399,7 @@ }, "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { @@ -1444,7 +1438,7 @@ }, "deep-assign": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", "dev": true, "requires": { @@ -1576,7 +1570,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -1748,19 +1742,26 @@ "dev": true }, "event-stream": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz", - "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==", + "version": "3.3.4", + "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { - "duplexer": "^0.1.1", - "flatmap-stream": "^0.1.0", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + }, + "dependencies": { + "map-stream": { + "version": "0.1.0", + "resolved": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + } } }, "expand-brackets": { @@ -1774,7 +1775,7 @@ }, "expand-range": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { @@ -1848,9 +1849,9 @@ } }, "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, "fast-json-stable-stringify": { @@ -2273,12 +2274,6 @@ "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", "dev": true }, - "flatmap-stream": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.1.tgz", - "integrity": "sha512-lAq4tLbm3sidmdCN8G3ExaxH7cUCtP5mgDvrYowsx84dcYkJJ4I28N7gkxA6+YlSXzaGLJYIDEi9WGfXzMiXdw==", - "dev": true - }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -2349,25 +2344,14 @@ "dev": true }, "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "1.0.6", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" - }, - "dependencies": { - "combined-stream": { - "version": "1.0.6", - "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - } } }, "fragment-cache": { @@ -4055,7 +4039,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -4073,7 +4057,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -4084,12 +4068,12 @@ } }, "gulp-remote-src-vscode": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/gulp-remote-src-vscode/-/gulp-remote-src-vscode-0.5.0.tgz", - "integrity": "sha512-/9vtSk9eI9DEWCqzGieglPqmx0WUQ9pwPHyHFpKmfxqdgqGJC2l0vFMdYs54hLdDsMDEZFLDL2J4ikjc4hQ5HQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/gulp-remote-src-vscode/-/gulp-remote-src-vscode-0.5.1.tgz", + "integrity": "sha512-mw4OGjtC/jlCWJFhbcAlel4YPvccChlpsl3JceNiB/DLJi24/UPxXt53/N26lgI3dknEqd4ErfdHrO8sJ5bATQ==", "dev": true, "requires": { - "event-stream": "^3.3.4", + "event-stream": "3.3.4", "node.extend": "^1.1.2", "request": "^2.79.0", "through2": "^2.0.3", @@ -4163,12 +4147,12 @@ } }, "gulp-symdest": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gulp-symdest/-/gulp-symdest-1.1.0.tgz", - "integrity": "sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/gulp-symdest/-/gulp-symdest-1.1.1.tgz", + "integrity": "sha512-UHd3MokfIN7SrFdsbV5uZTwzBpL0ZSTu7iq98fuDqBGZ0dlHxgbQBJwfd6qjCW83snkQ3Hz9IY4sMRMz2iTq7w==", "dev": true, "requires": { - "event-stream": "^3.3.1", + "event-stream": "3.3.4", "mkdirp": "^0.5.1", "queue": "^3.1.0", "vinyl-fs": "^2.4.3" @@ -4211,7 +4195,7 @@ "dependencies": { "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -4223,7 +4207,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -4391,16 +4375,16 @@ } }, "gulp-vinyl-zip": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.0.tgz", - "integrity": "sha1-JOQGhdwFtxSZlSRQmeBZAmO+ja0=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.2.tgz", + "integrity": "sha512-wJn09jsb8PyvUeyFF7y7ImEJqJwYy40BqL9GKfJs6UGpaGW9A+N68Q+ajsIpb9AeR6lAdjMbIdDPclIGo1/b7Q==", "dev": true, "requires": { - "event-stream": "^3.3.1", + "event-stream": "3.3.4", "queue": "^4.2.1", "through2": "^2.0.3", "vinyl": "^2.0.2", - "vinyl-fs": "^2.0.0", + "vinyl-fs": "^3.0.3", "yauzl": "^2.2.1", "yazl": "^2.2.1" }, @@ -4417,90 +4401,15 @@ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-stream": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", - "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^5.0.3", - "glob-parent": "^3.0.0", - "micromatch": "^2.3.7", - "ordered-read-streams": "^0.3.0", - "through2": "^0.6.0", - "to-absolute-glob": "^0.1.1", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "ordered-read-streams": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", - "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", - "dev": true, - "requires": { - "is-stream": "^1.0.1", - "readable-stream": "^2.0.1" - } - }, "queue": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/queue/-/queue-4.5.0.tgz", - "integrity": "sha512-DwxpAnqJuoQa+wyDgQuwkSshkhlqIlWEvwvdAY27fDPunZ2cVJzXU4JyjY+5l7zs7oGLaYAQm4MbLOVFAHFBzA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/queue/-/queue-4.5.1.tgz", + "integrity": "sha512-AMD7w5hRXcFSb8s9u38acBZ+309u6GsiibP4/0YacJeaurRshogB7v/ZcVPxP5gD5+zIw6ixRHdutiYUJfwKHw==", "dev": true, "requires": { "inherits": "~2.0.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, "vinyl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", @@ -4514,62 +4423,6 @@ "remove-trailing-separator": "^1.0.1", "replace-ext": "^1.0.0" } - }, - "vinyl-fs": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", - "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", - "dev": true, - "requires": { - "duplexify": "^3.2.0", - "glob-stream": "^5.3.2", - "graceful-fs": "^4.0.0", - "gulp-sourcemaps": "1.6.0", - "is-valid-glob": "^0.3.0", - "lazystream": "^1.0.0", - "lodash.isequal": "^4.0.0", - "merge-stream": "^1.0.0", - "mkdirp": "^0.5.0", - "object-assign": "^4.0.0", - "readable-stream": "^2.0.4", - "strip-bom": "^2.0.0", - "strip-bom-stream": "^1.0.0", - "through2": "^2.0.0", - "through2-filter": "^2.0.0", - "vali-date": "^1.0.0", - "vinyl": "^1.0.0" - }, - "dependencies": { - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } } } }, @@ -4589,15 +4442,24 @@ "dev": true }, "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "^5.3.0", + "ajv": "^6.5.5", "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -4890,7 +4752,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, @@ -5027,9 +4889,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify": { @@ -5713,18 +5575,18 @@ } }, "mime-db": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", - "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", "dev": true }, "mime-types": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", - "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "dev": true, "requires": { - "mime-db": "~1.36.0" + "mime-db": "~1.37.0" } }, "minimatch": { @@ -5759,7 +5621,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -5945,7 +5807,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, @@ -5956,12 +5818,13 @@ "dev": true }, "node.extend": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", - "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz", + "integrity": "sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==", "dev": true, "requires": { - "is": "^3.1.0" + "has": "^1.0.3", + "is": "^3.2.1" } }, "normalize-package-data": { @@ -6310,7 +6173,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -6362,7 +6225,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -6383,7 +6246,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -6447,7 +6310,7 @@ }, "pretty-hrtime": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, @@ -6507,9 +6370,9 @@ } }, "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "qs": { @@ -6534,9 +6397,9 @@ } }, "randomatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz", - "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", "dev": true, "requires": { "is-number": "^4.0.0", @@ -7210,7 +7073,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -7491,9 +7354,9 @@ "dev": true }, "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "version": "0.3.3", + "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { "through": "2" @@ -7536,9 +7399,9 @@ "dev": true }, "sshpk": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz", - "integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -7586,13 +7449,12 @@ } }, "stream-combiner": { - "version": "0.2.2", - "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "version": "0.0.4", + "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" + "duplexer": "~0.1.1" } }, "stream-exhaust": { @@ -7644,7 +7506,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -7691,7 +7553,7 @@ }, "tar": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { @@ -7702,7 +7564,7 @@ }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -7864,6 +7726,14 @@ "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } } }, "tslib": { @@ -8079,6 +7949,15 @@ "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", "dev": true }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -8086,9 +7965,9 @@ "dev": true }, "url-parse": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", - "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", "dev": true, "requires": { "querystringify": "^2.0.0", @@ -8331,19 +8210,19 @@ } }, "vscode": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.21.tgz", - "integrity": "sha512-tJl9eL15ZMm6vzCYYeQ26sSYRuXGMGPsaeIAmG2rOOYRn01jdaDg6I4b9G5Ed6FISdmn6egpKThk4o4om8Ax/A==", + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.22.tgz", + "integrity": "sha512-G/zu7PRAN1yF80wg+l6ebIexDflU3uXXeabacJuLearTIfObKw4JaI8aeHwDEmpnCkc3MkIr3Bclkju2gtEz6A==", "dev": true, "requires": { "glob": "^7.1.2", "gulp-chmod": "^2.0.0", "gulp-filter": "^5.0.1", "gulp-gunzip": "1.0.0", - "gulp-remote-src-vscode": "^0.5.0", - "gulp-symdest": "^1.1.0", + "gulp-remote-src-vscode": "^0.5.1", + "gulp-symdest": "^1.1.1", "gulp-untar": "^0.0.7", - "gulp-vinyl-zip": "^2.1.0", + "gulp-vinyl-zip": "^2.1.2", "mocha": "^4.0.1", "request": "^2.83.0", "semver": "^5.4.1", @@ -8501,7 +8380,7 @@ }, "xmlbuilder": { "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xtend": { @@ -8557,9 +8436,9 @@ } }, "yazl": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.3.tgz", - "integrity": "sha1-7CblzIfVYBud+EMtvdPNLlFzoHE=", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", "dev": true, "requires": { "buffer-crc32": "~0.2.3" diff --git a/package.json b/package.json index f72bdfda..c899964c 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "shelljs": "^0.8.3", "tslint": "^5.11.0", "typescript": "^3.1.6", - "vscode": "^1.1.21" + "vscode": "^1.1.22" }, "dependencies": { "find-java-home": "^0.2.0", diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 711327a1..346f7880 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -74,17 +74,9 @@ export class DependencyExplorer { // Resove Hierarchical packages const node = paths.shift(); if (Settings.isHierarchicalView() && c instanceof PackageRootNode) { - const packageNode = paths.shift(); - const res = c.getChildren(); - if (Utility.isThenable(res)) { - res.then(() => { - const correspondPackageNode = c.getPackageNodeFromNodeData(packageNode); - this.revealPath(correspondPackageNode, paths); - }); - } else { - const correspondPackageNode = c.getPackageNodeFromNodeData(packageNode); - this.revealPath(correspondPackageNode, paths); - } + const packageNodeData = paths.shift(); + c.getPackageNodeFromNodeData(packageNodeData) + .then((correspondPackageNode) => { this.revealPath(correspondPackageNode, paths); }); } else { this.revealPath(c, paths); } diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index 71a645fa..a09f1408 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -24,22 +24,22 @@ export class PackageRootNode extends DataNode { } // Get correspond packageRootNode when revealPath - public getPackageNodeFromNodeData(classPackage: INodeData): PackageRootNode { + public async getPackageNodeFromNodeData(classPackage: INodeData): Promise { + await this.getChildren(); // tslint:disable-next-line:no-this-assignment let packageRootNode: PackageRootNode = this; - while (packageRootNode.packageTree === null || packageRootNode.packageTree.fullName !== classPackage.name) { - let noMatchPackage: boolean = true; + let existCorrespondPackageNode: boolean = false; + while (packageRootNode.packageTree === null || + (packageRootNode.packageTree.fullName !== classPackage.name && existCorrespondPackageNode)) { + existCorrespondPackageNode = false; packageRootNode.createChildNodeList().forEach((child) => { if (child instanceof PackageRootNode && classPackage.name.startsWith(child.packageTree.fullName)) { packageRootNode = child; - noMatchPackage = false; + existCorrespondPackageNode = true; } }); - if (noMatchPackage) { - return null; - } } - return packageRootNode; + return existCorrespondPackageNode ? packageRootNode : null; } protected loadData(): Thenable { @@ -51,7 +51,6 @@ export class PackageRootNode extends DataNode { } else { return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); } - } protected createFlatChildNodeList(): ExplorerNode[] { From 11269cd6adcde0d52d24e33aff2141503e8bf53e Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Mon, 3 Dec 2018 16:59:31 +0800 Subject: [PATCH 03/12] Resolve comments --- package.json | 9 +- src/settings.ts | 4 +- src/views/dependencyExplorer.ts | 11 +- src/views/hierachicalPackageRootSubNode.ts | 66 +++++++++ src/views/hierarchicalNode.ts | 18 +++ src/views/packageRootNode.ts | 155 ++++++--------------- src/views/packageTreeNode.ts | 63 +++++++++ 7 files changed, 198 insertions(+), 128 deletions(-) create mode 100644 src/views/hierachicalPackageRootSubNode.ts create mode 100644 src/views/hierarchicalNode.ts create mode 100644 src/views/packageTreeNode.ts diff --git a/package.json b/package.json index c899964c..ecb9de96 100644 --- a/package.json +++ b/package.json @@ -63,10 +63,11 @@ "description": "Synchronize dependency viewer selection with folder explorer", "default": true }, - "java.dependency.isHierarchicalView": { - "type": "boolean", - "description": "Switch whether package shows in hierarchical view", - "default": false + "java.dependency.packagePresentation": { + "type": "string", + "enum":["flat","hierarchical"], + "description": "Set the presentation model of packages", + "default": "flat" } } }, diff --git a/src/settings.ts b/src/settings.ts index c370ae8e..7ff72047 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -28,8 +28,8 @@ export class Settings { return this._depdendencyConfig.get("syncWithFolderExplorer"); } - public static isHierarchicalView(): boolean { - return this._depdendencyConfig.get("isHierarchicalView"); + public static getPackagePresentation(): string { + return this._depdendencyConfig.get("packagePresentation"); } private static _depdendencyConfig: WorkspaceConfiguration = workspace.getConfiguration("java.dependency"); diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 346f7880..0f441fb1 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -9,7 +9,7 @@ import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { DependencyDataProvider } from "./dependencyDataProvider"; import { ExplorerNode } from "./explorerNode"; -import { PackageRootNode } from "./packageRootNode"; +import { HierarchicalNode } from "./hierarchicalNode"; export class DependencyExplorer { @@ -72,12 +72,11 @@ export class DependencyExplorer { } } else { // Resove Hierarchical packages - const node = paths.shift(); - if (Settings.isHierarchicalView() && c instanceof PackageRootNode) { - const packageNodeData = paths.shift(); - c.getPackageNodeFromNodeData(packageNodeData) - .then((correspondPackageNode) => { this.revealPath(correspondPackageNode, paths); }); + if (c instanceof HierarchicalNode && c.isHierarchicalView()) { + c.revealPath(paths) + .then((revealResult) => { this.revealPath(revealResult[0], revealResult[1]); }); } else { + paths.shift(); this.revealPath(c, paths); } } diff --git a/src/views/hierachicalPackageRootSubNode.ts b/src/views/hierachicalPackageRootSubNode.ts new file mode 100644 index 00000000..64789e8d --- /dev/null +++ b/src/views/hierachicalPackageRootSubNode.ts @@ -0,0 +1,66 @@ +import { Jdtls } from "../java/jdtls"; +import { INodeData, NodeKind } from "../java/nodeData"; +import { DataNode } from "./dataNode"; +import { ExplorerNode } from "./explorerNode"; +import { FileNode } from "./fileNode"; +import { FolderNode } from "./folderNode"; +import { PackageTreeNode } from "./packageTreeNode"; +import { ProjectNode } from "./projectNode"; +import { TypeRootNode } from "./typeRootNode"; + +export class HierachicalPackageRootSubNode extends DataNode { + + public packageTree: PackageTreeNode; + + constructor(nodeData: INodeData, parent: DataNode, private _project: ProjectNode, packageTree: PackageTreeNode = null) { + super(nodeData, parent); + this.packageTree = packageTree; + } + + protected loadData(): Thenable { + return Jdtls.getPackageData({ + kind: NodeKind.Package, + projectUri: this._project.nodeData.uri, + path: this.packageTree.fullName, + rootPath: this.nodeData.path, + }); + } + + protected get iconPath(): { light: string; dark: string } { + return ExplorerNode.resolveIconPath("package"); + } + + protected createChildNodeList(): ExplorerNode[] { + const result = []; + if (this.nodeData.children && this.nodeData.children.length) { + this.nodeData.children.forEach((data) => { + if (data.kind === NodeKind.File) { + result.push(new FileNode(data, this)); + } else if (data.kind === NodeKind.Folder) { + result.push(new FolderNode(data, this, this._project, this)); + } else if (data.kind === NodeKind.TypeRoot) { + result.push(new TypeRootNode(data, this)); + } + }); + } + this.getHierarchicalPackageNodes().forEach((node) => result.push(node)); + result.sort(); + return result; + } + + protected getHierarchicalPackageNodes(): ExplorerNode[] { + const result = []; + this.packageTree.childs.forEach((childNode) => { + const childNodeData: INodeData = { + name: childNode.name, + moduleName: this.nodeData.moduleName, + path: this.nodeData.path, + uri: null, + kind: NodeKind.PackageRoot, + children: null, + }; + result.push(new HierachicalPackageRootSubNode(childNodeData, this, this._project, childNode)); + }); + return result; + } +} diff --git a/src/views/hierarchicalNode.ts b/src/views/hierarchicalNode.ts new file mode 100644 index 00000000..bfbb2530 --- /dev/null +++ b/src/views/hierarchicalNode.ts @@ -0,0 +1,18 @@ +import { INodeData } from "../java/nodeData"; +import { DataNode } from "./dataNode"; +import { ExplorerNode } from "./explorerNode"; + +export abstract class HierarchicalNode extends DataNode { + public abstract createFlatChildNodeList(): ExplorerNode[]; + public abstract createHierarchicalChildNodeList(): ExplorerNode[]; + public abstract isHierarchicalView(): boolean; + public abstract revealPath(paths: INodeData[]): Promise<[ExplorerNode, INodeData[]]>; + + protected createChildNodeList(): ExplorerNode[] { + if (this.isHierarchicalView()) { + return this.createHierarchicalChildNodeList(); + } else { + return this.createFlatChildNodeList(); + } + } +} diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index a09f1408..75004b58 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -5,55 +5,28 @@ import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData"; import { Settings } from "../settings"; -import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { FileNode } from "./fileNode"; import { FolderNode } from "./folderNode"; +import { HierachicalPackageRootSubNode } from "./hierachicalPackageRootSubNode"; +import { HierarchicalNode } from "./hierarchicalNode"; import { PackageNode } from "./packageNode"; +import { PackageTreeNode } from "./packageTreeNode"; import { ProjectNode } from "./projectNode"; import { TypeRootNode } from "./typeRootNode"; -export class PackageRootNode extends DataNode { +export class PackageRootNode extends HierarchicalNode { - private packageTree: PackageTreeNode; - - constructor(nodeData: INodeData, parent: DataNode, private _project: ProjectNode, packageTree: PackageTreeNode = null) { + constructor(nodeData: INodeData, parent: DataNode, protected _project: ProjectNode) { super(nodeData, parent); - this.packageTree = packageTree; - } - - // Get correspond packageRootNode when revealPath - public async getPackageNodeFromNodeData(classPackage: INodeData): Promise { - await this.getChildren(); - // tslint:disable-next-line:no-this-assignment - let packageRootNode: PackageRootNode = this; - let existCorrespondPackageNode: boolean = false; - while (packageRootNode.packageTree === null || - (packageRootNode.packageTree.fullName !== classPackage.name && existCorrespondPackageNode)) { - existCorrespondPackageNode = false; - packageRootNode.createChildNodeList().forEach((child) => { - if (child instanceof PackageRootNode && classPackage.name.startsWith(child.packageTree.fullName)) { - packageRootNode = child; - existCorrespondPackageNode = true; - } - }); - } - return existCorrespondPackageNode ? packageRootNode : null; } - protected loadData(): Thenable { - if (this.packageTree && this.packageTree.isPackage) { - // load package data - return Jdtls.getPackageData({ - kind: NodeKind.Package, projectUri: this._project.nodeData.uri, path: this.packageTree.fullName, rootPath: this.nodeData.path, - }); - } else { - return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); - } + public isHierarchicalView(): boolean { + return Settings.getPackagePresentation() === "hierarchical"; } - protected createFlatChildNodeList(): ExplorerNode[] { + public createFlatChildNodeList(): ExplorerNode[] { const result = []; if (this.nodeData.children && this.nodeData.children.length) { this.sort(); @@ -71,8 +44,7 @@ export class PackageRootNode extends DataNode { } return result; } - - protected createHierarchicalChildNodeList(): ExplorerNode[] { + public createHierarchicalChildNodeList(): ExplorerNode[] { const result = []; if (this.nodeData.children && this.nodeData.children.length) { this.nodeData.children.forEach((data) => { @@ -90,33 +62,47 @@ export class PackageRootNode extends DataNode { return result; } - protected createChildNodeList(): ExplorerNode[] { - if (Settings.isHierarchicalView()) { - return this.createHierarchicalChildNodeList(); + public async revealPath(paths: INodeData[]): Promise<[ExplorerNode, INodeData[]]> { + await this.getChildren(); + const packageRootNodeData = paths.shift(); + const packageNodeData = paths.shift(); + let packageTreeNode: PackageTreeNode = this.getPackageTree(); + // tslint:disable-next-line:no-this-assignment + let result: DataNode = this; + while (packageTreeNode.childs.length && packageTreeNode.fullName !== packageNodeData.name) { + packageTreeNode.childs.forEach((child) => { + if (packageNodeData.name.startsWith(child.fullName)) { + result = new HierachicalPackageRootSubNode(child.getNodeDataFromPackageTreeNode(this.nodeData), result, this._project, child); + packageTreeNode = child; + } + }); + } + return [result, paths]; + } + + protected get iconPath(): { light: string; dark: string } { + const data = this.nodeData; + if (data.entryKind === PackageRootKind.K_BINARY) { + return ExplorerNode.resolveIconPath("jar"); } else { - return this.createFlatChildNodeList(); + return ExplorerNode.resolveIconPath("packagefolder"); } } protected getHierarchicalPackageNodes(): ExplorerNode[] { const result = []; - const packageTree = this.packageTree ? this.packageTree : this.getPackageTree(); + const packageTree = this.getPackageTree(); packageTree.childs.forEach((childNode) => { - const childNodeData: INodeData = { - name: childNode.name, - moduleName: this.nodeData.moduleName, - path: this.nodeData.path, - uri: null, - kind: NodeKind.PackageRoot, - children: null, - }; - result.push(new PackageRootNode(childNodeData, this, this._project, childNode)); + result.push(new HierachicalPackageRootSubNode(childNode.getNodeDataFromPackageTreeNode(this.nodeData), this, this._project, childNode)); }); return result; } - // Generage tree for packages, use for Hierarchical view - protected getPackageTree(): PackageTreeNode { + protected loadData(): Thenable { + return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); + } + + private getPackageTree(): PackageTreeNode { const result: PackageTreeNode = new PackageTreeNode("", ""); if (this.nodeData.children && this.nodeData.children.length) { this.nodeData.children.forEach((child) => { @@ -128,67 +114,4 @@ export class PackageRootNode extends DataNode { result.compressTree(); return result; } - - protected get iconPath(): { light: string; dark: string } { - if (this.packageTree !== null) { - return ExplorerNode.resolveIconPath("package"); - } - const data = this.nodeData; - if (data.entryKind === PackageRootKind.K_BINARY) { - return ExplorerNode.resolveIconPath("jar"); - } else { - return ExplorerNode.resolveIconPath("packagefolder"); - } - } -} - -class PackageTreeNode { - public name: string; - public fullName: string; - public childs: PackageTreeNode[] = []; - public isPackage: boolean = false; - - constructor(packageName: string, parentName: string) { - const splitPackageName = packageName.split("."); - this.name = splitPackageName[0]; - this.fullName = parentName === "" ? this.name : parentName + "." + this.name; - if (splitPackageName.length > 1) { - this.childs.push(new PackageTreeNode(packageName.substring(this.name.length + 1), this.fullName)); - } else { - this.isPackage = true; - } - } - - public addPackage(packageName: string): void { - const splitPackageName = packageName.split("."); - const firstSubName = splitPackageName[0]; - const restname = packageName.substring(firstSubName.length + 1); - - let contains: boolean = false; - this.childs.forEach((child) => { - if (child.name === firstSubName) { - if (restname === "") { - child.isPackage = true; - } else { - child.addPackage(restname); - } - contains = true; - } - }); - if (!contains) { - this.childs.push(new PackageTreeNode(packageName, this.fullName)); - } - } - - public compressTree(): void { - // Don't compress the root node - while (this.name !== "" && this.childs.length === 1 && !this.isPackage) { - const child = this.childs[0]; - this.fullName = this.fullName + "." + child.name; - this.name = this.name + "." + child.name; - this.childs = child.childs; - this.isPackage = child.isPackage; - } - this.childs.forEach((child) => child.compressTree()); - } } diff --git a/src/views/packageTreeNode.ts b/src/views/packageTreeNode.ts new file mode 100644 index 00000000..7825c8cd --- /dev/null +++ b/src/views/packageTreeNode.ts @@ -0,0 +1,63 @@ +import { INodeData, NodeKind } from "../java/nodeData"; + +export class PackageTreeNode { + public name: string; + public fullName: string; + public childs: PackageTreeNode[] = []; + public isPackage: boolean = false; + + constructor(packageName: string, parentName: string) { + const splitPackageName = packageName.split("."); + this.name = splitPackageName[0]; + this.fullName = parentName === "" ? this.name : parentName + "." + this.name; + if (splitPackageName.length > 1) { + this.childs.push(new PackageTreeNode(packageName.substring(this.name.length + 1), this.fullName)); + } else { + this.isPackage = true; + } + } + + public addPackage(packageName: string): void { + const splitPackageName = packageName.split("."); + const firstSubName = splitPackageName[0]; + const restname = packageName.substring(firstSubName.length + 1); + + let contains: boolean = false; + this.childs.forEach((child) => { + if (child.name === firstSubName) { + if (restname === "") { + child.isPackage = true; + } else { + child.addPackage(restname); + } + contains = true; + } + }); + if (!contains) { + this.childs.push(new PackageTreeNode(packageName, this.fullName)); + } + } + + public compressTree(): void { + // Don't compress the root node + while (this.name !== "" && this.childs.length === 1 && !this.isPackage) { + const child = this.childs[0]; + this.fullName = this.fullName + "." + child.name; + this.name = this.name + "." + child.name; + this.childs = child.childs; + this.isPackage = child.isPackage; + } + this.childs.forEach((child) => child.compressTree()); + } + + public getNodeDataFromPackageTreeNode(nodeData: INodeData): INodeData { + return { + name: this.name, + moduleName: nodeData.moduleName, + path: nodeData.path, + uri: null, + kind: NodeKind.PackageRoot, + children: null, + }; + } +} From 19e1c0bc14a52c044a7f1dd06ee45a5033f5ca74 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Tue, 4 Dec 2018 09:46:44 +0800 Subject: [PATCH 04/12] Simple codes by comments --- src/views/hierarchicalNode.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/views/hierarchicalNode.ts b/src/views/hierarchicalNode.ts index bfbb2530..e47c09d8 100644 --- a/src/views/hierarchicalNode.ts +++ b/src/views/hierarchicalNode.ts @@ -9,10 +9,6 @@ export abstract class HierarchicalNode extends DataNode { public abstract revealPath(paths: INodeData[]): Promise<[ExplorerNode, INodeData[]]>; protected createChildNodeList(): ExplorerNode[] { - if (this.isHierarchicalView()) { - return this.createHierarchicalChildNodeList(); - } else { - return this.createFlatChildNodeList(); - } + return this.isHierarchicalView() ? this.createHierarchicalChildNodeList() : this.createFlatChildNodeList(); } } From 8b29ec19de84bf491382c07e12c970a95f3d2b08 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Wed, 5 Dec 2018 12:59:59 +0800 Subject: [PATCH 05/12] Refactor hierachical package node structure --- src/{views => java}/packageTreeNode.ts | 5 +- src/views/containerNode.ts | 4 +- src/views/dependencyExplorer.ts | 22 ++--- src/views/hierachicalPackageRootNode.ts | 104 +++++++++++++++++++++ src/views/hierachicalPackageRootSubNode.ts | 26 ++---- src/views/hierarchicalNode.ts | 14 --- src/views/nodeFactory.ts | 15 +++ src/views/packageRootNode.ts | 73 +-------------- src/views/projectNode.ts | 4 +- 9 files changed, 150 insertions(+), 117 deletions(-) rename src/{views => java}/packageTreeNode.ts (93%) create mode 100644 src/views/hierachicalPackageRootNode.ts delete mode 100644 src/views/hierarchicalNode.ts create mode 100644 src/views/nodeFactory.ts diff --git a/src/views/packageTreeNode.ts b/src/java/packageTreeNode.ts similarity index 93% rename from src/views/packageTreeNode.ts rename to src/java/packageTreeNode.ts index 7825c8cd..8894c641 100644 --- a/src/views/packageTreeNode.ts +++ b/src/java/packageTreeNode.ts @@ -1,4 +1,7 @@ -import { INodeData, NodeKind } from "../java/nodeData"; +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import { INodeData, NodeKind } from "./nodeData"; export class PackageTreeNode { public name: string; diff --git a/src/views/containerNode.ts b/src/views/containerNode.ts index 6ac7c002..5cc1ffd5 100644 --- a/src/views/containerNode.ts +++ b/src/views/containerNode.ts @@ -5,7 +5,7 @@ import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; -import { PackageRootNode } from "./packageRootNode"; +import { NodeFactory } from "./nodeFactory"; import { ProjectNode } from "./projectNode"; export class ContainerNode extends DataNode { @@ -21,7 +21,7 @@ export class ContainerNode extends DataNode { if (this.nodeData.children && this.nodeData.children.length) { this.sort(); this.nodeData.children.forEach((classpathNode) => { - result.push(new PackageRootNode(classpathNode, this, this._project)); + result.push(NodeFactory.createPackageRootNode(classpathNode, this, this._project)); }); } return result; diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 0f441fb1..0bed4287 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -9,7 +9,7 @@ import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { DependencyDataProvider } from "./dependencyDataProvider"; import { ExplorerNode } from "./explorerNode"; -import { HierarchicalNode } from "./hierarchicalNode"; +import { HierachicalPackageRootNode } from "./hierachicalPackageRootNode"; export class DependencyExplorer { @@ -41,9 +41,13 @@ export class DependencyExplorer { } public reveal(uri: Uri): void { - Jdtls.resolvePath(uri.toString()).then((paths: INodeData[]) => { - this.revealPath(this._dataProvider, paths); - }); + Jdtls.resolvePath(uri.toString()) + .then((paths: INodeData[]) => this.processPaths(paths)) + .then((paths: INodeData[]) => this.revealPath(this._dataProvider, paths)); + } + + private processPaths(paths: INodeData[]): Promise { + return HierachicalPackageRootNode.convertPaths(paths); } private revealPath(current: { getChildren: (element?: ExplorerNode) => ProviderResult }, paths: INodeData[]) { @@ -71,14 +75,8 @@ export class DependencyExplorer { this._selectionWhenHidden = c; } } else { - // Resove Hierarchical packages - if (c instanceof HierarchicalNode && c.isHierarchicalView()) { - c.revealPath(paths) - .then((revealResult) => { this.revealPath(revealResult[0], revealResult[1]); }); - } else { - paths.shift(); - this.revealPath(c, paths); - } + paths.shift(); + this.revealPath(c, paths); } break; } diff --git a/src/views/hierachicalPackageRootNode.ts b/src/views/hierachicalPackageRootNode.ts new file mode 100644 index 00000000..5b326f8d --- /dev/null +++ b/src/views/hierachicalPackageRootNode.ts @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import { INodeData, NodeKind } from "../java/nodeData"; +import { PackageTreeNode } from "../java/packageTreeNode"; +import { Settings } from "../settings"; +import { DataNode } from "./dataNode"; +import { ExplorerNode } from "./explorerNode"; +import { FileNode } from "./fileNode"; +import { FolderNode } from "./folderNode"; +import { HierachicalPackageRootSubNode } from "./hierachicalPackageRootSubNode"; +import { PackageRootNode } from "./packageRootNode"; +import { ProjectNode } from "./projectNode"; +import { TypeRootNode } from "./typeRootNode"; + +export class HierachicalPackageRootNode extends PackageRootNode { + + public static isHierarchicalView(): boolean { + return Settings.getPackagePresentation() === "hierarchical"; + } + + public static async convertPaths(paths: INodeData[]): Promise { + if (!HierachicalPackageRootNode.isHierarchicalView()) { + return paths; + } + const index = paths.findIndex((nodeData) => nodeData.kind === NodeKind.PackageRoot); + const projectNodeData = paths.find((nodeData) => nodeData.kind === NodeKind.Project); + const packageRootNodeData = paths[index]; + const packageNodeData = paths[index + 1]; + const packageRootNode = new HierachicalPackageRootNode(packageRootNodeData, null, new ProjectNode(projectNodeData, null)); + + const correspondDataNodes: INodeData[] = []; + let correspondNode = await packageRootNode.revealPath(packageNodeData); + while (correspondNode instanceof HierachicalPackageRootSubNode) { + correspondDataNodes.push({ + name: correspondNode.nodeData.name, + moduleName: null, + path: correspondNode.nodeData.path, + uri: null, + kind: NodeKind.PackageRoot, + children: null, + }); + correspondNode = correspondNode.getParent(); + } + const result = paths.slice(null, index + 1).concat(correspondDataNodes.reverse(), paths.slice(index + 2)); + return result; + } + + constructor(nodeData: INodeData, parent: DataNode, _project: ProjectNode) { + super(nodeData, parent, _project); + } + + public async revealPath(packageNodeData: INodeData): Promise { + await this.getChildren(); + let packageTreeNode: PackageTreeNode = this.getPackageTree(); + let result: DataNode = null; + while (packageTreeNode && packageTreeNode.fullName !== packageNodeData.name) { + packageTreeNode = packageTreeNode.childs.find((child) => packageNodeData.name.startsWith(child.fullName)); + result = packageTreeNode ? new HierachicalPackageRootSubNode(packageTreeNode.getNodeDataFromPackageTreeNode(this.nodeData), + result, this._project, packageTreeNode) : null; + } + return result; + } + + protected createChildNodeList(): ExplorerNode[] { + const result = []; + if (this.nodeData.children && this.nodeData.children.length) { + this.sort(); + this.nodeData.children.forEach((data) => { + if (data.kind === NodeKind.File) { + result.push(new FileNode(data, this)); + } else if (data.kind === NodeKind.Folder) { + result.push(new FolderNode(data, this, this._project, this)); + } else if (data.kind === NodeKind.TypeRoot) { + result.push(new TypeRootNode(data, this)); + } + }); + } + const packageNodeList = this.getHierarchicalPackageNodes(); + return packageNodeList.concat(result); + } + + protected getHierarchicalPackageNodes(): ExplorerNode[] { + const result = []; + const packageTree = this.getPackageTree(); + packageTree.childs.forEach((childNode) => { + result.push(new HierachicalPackageRootSubNode(childNode.getNodeDataFromPackageTreeNode(this.nodeData), this, this._project, childNode)); + }); + return result; + } + + private getPackageTree(): PackageTreeNode { + const result: PackageTreeNode = new PackageTreeNode("", ""); + if (this.nodeData.children && this.nodeData.children.length) { + this.nodeData.children.forEach((child) => { + if (child.kind === NodeKind.Package) { + result.addPackage(child.name); + } + }); + } + result.compressTree(); + return result; + } +} diff --git a/src/views/hierachicalPackageRootSubNode.ts b/src/views/hierachicalPackageRootSubNode.ts index 64789e8d..7a8c6190 100644 --- a/src/views/hierachicalPackageRootSubNode.ts +++ b/src/views/hierachicalPackageRootSubNode.ts @@ -1,10 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; +import { PackageTreeNode } from "../java/packageTreeNode"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { FileNode } from "./fileNode"; import { FolderNode } from "./folderNode"; -import { PackageTreeNode } from "./packageTreeNode"; import { ProjectNode } from "./projectNode"; import { TypeRootNode } from "./typeRootNode"; @@ -19,10 +22,7 @@ export class HierachicalPackageRootSubNode extends DataNode { protected loadData(): Thenable { return Jdtls.getPackageData({ - kind: NodeKind.Package, - projectUri: this._project.nodeData.uri, - path: this.packageTree.fullName, - rootPath: this.nodeData.path, + kind: NodeKind.Package, projectUri: this._project.nodeData.uri, path: this.packageTree.fullName, rootPath: this.nodeData.path, }); } @@ -33,6 +33,7 @@ export class HierachicalPackageRootSubNode extends DataNode { protected createChildNodeList(): ExplorerNode[] { const result = []; if (this.nodeData.children && this.nodeData.children.length) { + this.sort(); this.nodeData.children.forEach((data) => { if (data.kind === NodeKind.File) { result.push(new FileNode(data, this)); @@ -43,23 +44,14 @@ export class HierachicalPackageRootSubNode extends DataNode { } }); } - this.getHierarchicalPackageNodes().forEach((node) => result.push(node)); - result.sort(); - return result; + const packageNodeList = this.getHierarchicalPackageNodes(); + return packageNodeList.concat(result); } protected getHierarchicalPackageNodes(): ExplorerNode[] { const result = []; this.packageTree.childs.forEach((childNode) => { - const childNodeData: INodeData = { - name: childNode.name, - moduleName: this.nodeData.moduleName, - path: this.nodeData.path, - uri: null, - kind: NodeKind.PackageRoot, - children: null, - }; - result.push(new HierachicalPackageRootSubNode(childNodeData, this, this._project, childNode)); + result.push(new HierachicalPackageRootSubNode(childNode.getNodeDataFromPackageTreeNode(this.nodeData), this, this._project, childNode)); }); return result; } diff --git a/src/views/hierarchicalNode.ts b/src/views/hierarchicalNode.ts deleted file mode 100644 index e47c09d8..00000000 --- a/src/views/hierarchicalNode.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { INodeData } from "../java/nodeData"; -import { DataNode } from "./dataNode"; -import { ExplorerNode } from "./explorerNode"; - -export abstract class HierarchicalNode extends DataNode { - public abstract createFlatChildNodeList(): ExplorerNode[]; - public abstract createHierarchicalChildNodeList(): ExplorerNode[]; - public abstract isHierarchicalView(): boolean; - public abstract revealPath(paths: INodeData[]): Promise<[ExplorerNode, INodeData[]]>; - - protected createChildNodeList(): ExplorerNode[] { - return this.isHierarchicalView() ? this.createHierarchicalChildNodeList() : this.createFlatChildNodeList(); - } -} diff --git a/src/views/nodeFactory.ts b/src/views/nodeFactory.ts new file mode 100644 index 00000000..69adccf7 --- /dev/null +++ b/src/views/nodeFactory.ts @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import { INodeData } from "../java/nodeData"; +import { DataNode } from "./dataNode"; +import { HierachicalPackageRootNode } from "./hierachicalPackageRootNode"; +import { PackageRootNode } from "./packageRootNode"; +import { ProjectNode } from "./projectNode"; + +export class NodeFactory { + public static createPackageRootNode(nodeData: INodeData, parent: DataNode, project: ProjectNode): PackageRootNode { + return HierachicalPackageRootNode.isHierarchicalView() ? + new HierachicalPackageRootNode(nodeData, parent, project) : new PackageRootNode(nodeData, parent, project); + } +} diff --git a/src/views/packageRootNode.ts b/src/views/packageRootNode.ts index 75004b58..0f7e9c2e 100644 --- a/src/views/packageRootNode.ts +++ b/src/views/packageRootNode.ts @@ -4,29 +4,25 @@ import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { IPackageRootNodeData, PackageRootKind } from "../java/packageRootNodeData"; -import { Settings } from "../settings"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { FileNode } from "./fileNode"; import { FolderNode } from "./folderNode"; -import { HierachicalPackageRootSubNode } from "./hierachicalPackageRootSubNode"; -import { HierarchicalNode } from "./hierarchicalNode"; import { PackageNode } from "./packageNode"; -import { PackageTreeNode } from "./packageTreeNode"; import { ProjectNode } from "./projectNode"; import { TypeRootNode } from "./typeRootNode"; -export class PackageRootNode extends HierarchicalNode { +export class PackageRootNode extends DataNode { constructor(nodeData: INodeData, parent: DataNode, protected _project: ProjectNode) { super(nodeData, parent); } - public isHierarchicalView(): boolean { - return Settings.getPackagePresentation() === "hierarchical"; + protected loadData(): Thenable { + return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); } - public createFlatChildNodeList(): ExplorerNode[] { + protected createChildNodeList(): ExplorerNode[] { const result = []; if (this.nodeData.children && this.nodeData.children.length) { this.sort(); @@ -44,41 +40,6 @@ export class PackageRootNode extends HierarchicalNode { } return result; } - public createHierarchicalChildNodeList(): ExplorerNode[] { - const result = []; - if (this.nodeData.children && this.nodeData.children.length) { - this.nodeData.children.forEach((data) => { - if (data.kind === NodeKind.File) { - result.push(new FileNode(data, this)); - } else if (data.kind === NodeKind.Folder) { - result.push(new FolderNode(data, this, this._project, this)); - } else if (data.kind === NodeKind.TypeRoot) { - result.push(new TypeRootNode(data, this)); - } - }); - } - this.getHierarchicalPackageNodes().forEach((node) => result.push(node)); - result.sort(); - return result; - } - - public async revealPath(paths: INodeData[]): Promise<[ExplorerNode, INodeData[]]> { - await this.getChildren(); - const packageRootNodeData = paths.shift(); - const packageNodeData = paths.shift(); - let packageTreeNode: PackageTreeNode = this.getPackageTree(); - // tslint:disable-next-line:no-this-assignment - let result: DataNode = this; - while (packageTreeNode.childs.length && packageTreeNode.fullName !== packageNodeData.name) { - packageTreeNode.childs.forEach((child) => { - if (packageNodeData.name.startsWith(child.fullName)) { - result = new HierachicalPackageRootSubNode(child.getNodeDataFromPackageTreeNode(this.nodeData), result, this._project, child); - packageTreeNode = child; - } - }); - } - return [result, paths]; - } protected get iconPath(): { light: string; dark: string } { const data = this.nodeData; @@ -88,30 +49,4 @@ export class PackageRootNode extends HierarchicalNode { return ExplorerNode.resolveIconPath("packagefolder"); } } - - protected getHierarchicalPackageNodes(): ExplorerNode[] { - const result = []; - const packageTree = this.getPackageTree(); - packageTree.childs.forEach((childNode) => { - result.push(new HierachicalPackageRootSubNode(childNode.getNodeDataFromPackageTreeNode(this.nodeData), this, this._project, childNode)); - }); - return result; - } - - protected loadData(): Thenable { - return Jdtls.getPackageData({ kind: NodeKind.PackageRoot, projectUri: this._project.nodeData.uri, rootPath: this.nodeData.path }); - } - - private getPackageTree(): PackageTreeNode { - const result: PackageTreeNode = new PackageTreeNode("", ""); - if (this.nodeData.children && this.nodeData.children.length) { - this.nodeData.children.forEach((child) => { - if (child.kind === NodeKind.Package) { - result.addPackage(child.name); - } - }); - } - result.compressTree(); - return result; - } } diff --git a/src/views/projectNode.ts b/src/views/projectNode.ts index 49346377..29f345d7 100644 --- a/src/views/projectNode.ts +++ b/src/views/projectNode.ts @@ -8,7 +8,7 @@ import { Telemetry } from "../telemetry"; import { ContainerNode } from "./containerNode"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; -import { PackageRootNode } from "./packageRootNode"; +import { NodeFactory } from "./nodeFactory"; export class ProjectNode extends DataNode { @@ -54,7 +54,7 @@ export class ProjectNode extends DataNode { if (data.kind === NodeKind.Container) { result.push(new ContainerNode(data, this, this)); } else if (data.kind === NodeKind.PackageRoot) { - result.push(new PackageRootNode(data, this, this)); + result.push(NodeFactory.createPackageRootNode(data, this, this)); } }); } From 053c4636e869170872d91a0e0a3c8035dd3df654 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Wed, 5 Dec 2018 14:40:50 +0800 Subject: [PATCH 06/12] Move path process to PathProcesser --- src/settings.ts | 4 ++-- src/views/dependencyExplorer.ts | 11 ++--------- src/views/hierachicalPackageRootNode.ts | 7 ------- src/views/nodeFactory.ts | 3 ++- src/views/pathProcesser.ts | 23 +++++++++++++++++++++++ 5 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 src/views/pathProcesser.ts diff --git a/src/settings.ts b/src/settings.ts index 7ff72047..a1cbc35a 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -28,8 +28,8 @@ export class Settings { return this._depdendencyConfig.get("syncWithFolderExplorer"); } - public static getPackagePresentation(): string { - return this._depdendencyConfig.get("packagePresentation"); + public static isHierarchicalView(): boolean { + return this._depdendencyConfig.get("packagePresentation") === "hierarchical"; } private static _depdendencyConfig: WorkspaceConfiguration = workspace.getConfiguration("java.dependency"); diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 0bed4287..41dd508c 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -2,14 +2,13 @@ // Licensed under the MIT license. import { ExtensionContext, ProviderResult, TextEditor, TreeView, TreeViewVisibilityChangeEvent, Uri, window } from "vscode"; -import { Jdtls } from "../java/jdtls"; import { INodeData } from "../java/nodeData"; import { Settings } from "../settings"; import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { DependencyDataProvider } from "./dependencyDataProvider"; import { ExplorerNode } from "./explorerNode"; -import { HierachicalPackageRootNode } from "./hierachicalPackageRootNode"; +import { PathProcesser } from "./pathProcesser"; export class DependencyExplorer { @@ -41,13 +40,7 @@ export class DependencyExplorer { } public reveal(uri: Uri): void { - Jdtls.resolvePath(uri.toString()) - .then((paths: INodeData[]) => this.processPaths(paths)) - .then((paths: INodeData[]) => this.revealPath(this._dataProvider, paths)); - } - - private processPaths(paths: INodeData[]): Promise { - return HierachicalPackageRootNode.convertPaths(paths); + PathProcesser.resolvePath(uri).then((paths: INodeData[]) => this.revealPath(this._dataProvider, paths)); } private revealPath(current: { getChildren: (element?: ExplorerNode) => ProviderResult }, paths: INodeData[]) { diff --git a/src/views/hierachicalPackageRootNode.ts b/src/views/hierachicalPackageRootNode.ts index 5b326f8d..0172d2ee 100644 --- a/src/views/hierachicalPackageRootNode.ts +++ b/src/views/hierachicalPackageRootNode.ts @@ -15,14 +15,7 @@ import { TypeRootNode } from "./typeRootNode"; export class HierachicalPackageRootNode extends PackageRootNode { - public static isHierarchicalView(): boolean { - return Settings.getPackagePresentation() === "hierarchical"; - } - public static async convertPaths(paths: INodeData[]): Promise { - if (!HierachicalPackageRootNode.isHierarchicalView()) { - return paths; - } const index = paths.findIndex((nodeData) => nodeData.kind === NodeKind.PackageRoot); const projectNodeData = paths.find((nodeData) => nodeData.kind === NodeKind.Project); const packageRootNodeData = paths[index]; diff --git a/src/views/nodeFactory.ts b/src/views/nodeFactory.ts index 69adccf7..ad5ae537 100644 --- a/src/views/nodeFactory.ts +++ b/src/views/nodeFactory.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import { INodeData } from "../java/nodeData"; +import { Settings } from "../settings"; import { DataNode } from "./dataNode"; import { HierachicalPackageRootNode } from "./hierachicalPackageRootNode"; import { PackageRootNode } from "./packageRootNode"; @@ -9,7 +10,7 @@ import { ProjectNode } from "./projectNode"; export class NodeFactory { public static createPackageRootNode(nodeData: INodeData, parent: DataNode, project: ProjectNode): PackageRootNode { - return HierachicalPackageRootNode.isHierarchicalView() ? + return Settings.isHierarchicalView() ? new HierachicalPackageRootNode(nodeData, parent, project) : new PackageRootNode(nodeData, parent, project); } } diff --git a/src/views/pathProcesser.ts b/src/views/pathProcesser.ts new file mode 100644 index 00000000..adc6256b --- /dev/null +++ b/src/views/pathProcesser.ts @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import { Uri } from "vscode"; +import { Jdtls } from "../java/jdtls"; +import { INodeData } from "../java/nodeData"; +import { Settings } from "../settings"; +import { HierachicalPackageRootNode } from "./hierachicalPackageRootNode"; + +export class PathProcesser { + + public static async resolvePath(uri: Uri): Promise { + return Jdtls.resolvePath(uri.toString()) + .then((paths: INodeData[]) => PathProcesser.processPaths(paths)); + } + + private static async processPaths(paths: INodeData[]): Promise { + let result = paths; + result = Settings.isHierarchicalView() ? await HierachicalPackageRootNode.convertPaths(result) : result; + return result; + } + +} From cc21dcd7473bdeaf7e7289999ecb2ed6d532c514 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Wed, 5 Dec 2018 20:18:45 +0800 Subject: [PATCH 07/12] Refactor reveal paths, fix bug to work in workspace --- src/views/dataNode.ts | 5 +++ src/views/dependencyDataProvider.ts | 32 +++++++++++++++ src/views/dependencyExplorer.ts | 47 +++++----------------- src/views/hierachicalPackageRootNode.ts | 40 ++++-------------- src/views/hierachicalPackageRootSubNode.ts | 9 ++++- src/views/pathProcesser.ts | 23 ----------- 6 files changed, 62 insertions(+), 94 deletions(-) delete mode 100644 src/views/pathProcesser.ts diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index ac43cac1..ef05eaa2 100644 --- a/src/views/dataNode.ts +++ b/src/views/dataNode.ts @@ -32,6 +32,11 @@ export abstract class DataNode extends ExplorerNode { return this._nodeData.path; } + public async getCorrespondChildNodeWithNodeData(nodeData: INodeData): Promise { + const childs: ExplorerNode[] = await this.getChildren(); + return childs.find((child: DataNode) => child.nodeData.name === nodeData.name && child.path === nodeData.path); + } + public getChildren(): ProviderResult { if (!this._nodeData.children) { return this.loadData().then((res) => { diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index 2a955e77..a69a0122 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -10,6 +10,7 @@ import { Commands } from "../commands"; import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { Telemetry } from "../telemetry"; +import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { ProjectNode } from "./projectNode"; import { WorkspaceNode } from "./workspaceNode"; @@ -67,6 +68,37 @@ export class DependencyDataProvider implements TreeDataProvider { return element.getParent(); } + public async getRootNodeByData(nodeData: INodeData): Promise { + // Server only return project nodes, so use get root projects function + const rootNodes: ExplorerNode[] = await this.getRootProjects(); + return rootNodes.find((node: DataNode) => node.path === nodeData.path && node.nodeData.name === nodeData.name); + } + + private async getRootProjects(): Promise { + let result = new Array(); + const folders = workspace.workspaceFolders; + if (folders && folders.length) { + if (folders.length > 1) { + const workspaces = folders.map((folder) => new WorkspaceNode({ + name: folder.name, + uri: folder.uri.toString(), + kind: NodeKind.Workspace, + }, null)); + // return projects of all workspaces + for (const singleworkspace of workspaces) { + const projects = await singleworkspace.getChildren(); + result = result.concat(projects); + } + } else { + const projectsNodeData = await Jdtls.getProjects(folders[0].uri.toString()); + projectsNodeData.forEach((project) => { + result.push(new ProjectNode(project, null)); + }); + } + } + return result; + } + private getRootNodes(): Thenable { return new Promise((resolve, reject) => { this._rootItems = new Array(); diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 41dd508c..896f14dc 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -1,14 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -import { ExtensionContext, ProviderResult, TextEditor, TreeView, TreeViewVisibilityChangeEvent, Uri, window } from "vscode"; +import { ExtensionContext, TextEditor, TreeView, TreeViewVisibilityChangeEvent, Uri, window } from "vscode"; +import { Jdtls } from "../java/jdtls"; import { INodeData } from "../java/nodeData"; import { Settings } from "../settings"; -import { Utility } from "../utility"; import { DataNode } from "./dataNode"; import { DependencyDataProvider } from "./dependencyDataProvider"; import { ExplorerNode } from "./explorerNode"; -import { PathProcesser } from "./pathProcesser"; export class DependencyExplorer { @@ -39,41 +38,17 @@ export class DependencyExplorer { public dispose(): void { } - public reveal(uri: Uri): void { - PathProcesser.resolvePath(uri).then((paths: INodeData[]) => this.revealPath(this._dataProvider, paths)); - } - - private revealPath(current: { getChildren: (element?: ExplorerNode) => ProviderResult }, paths: INodeData[]) { - if (!current) { - return; + public async reveal(uri: Uri): Promise { + const paths: INodeData[] = await Jdtls.resolvePath(uri.toString()); + // Get correspond project node from dataProvider + let node = await this._dataProvider.getRootNodeByData(paths.shift()); + while (paths.length && node) { + node = await node.getCorrespondChildNodeWithNodeData(paths.shift()); } - const res = current.getChildren(); - if (Utility.isThenable(res)) { - res.then((children: DataNode[]) => { - this.visitChildren(children, paths); - }); + if (this._dependencyViewer.visible) { + this._dependencyViewer.reveal(node); } else { - this.visitChildren(res, paths); - } - } - - private visitChildren(children: DataNode[], paths: INodeData[]): void { - if (children && paths) { - for (const c of children) { - if (paths[0] && c.path === paths[0].path && c.nodeData.name === paths[0].name) { - if (paths.length === 1) { - if (this._dependencyViewer.visible) { - this._dependencyViewer.reveal(c); - } else { - this._selectionWhenHidden = c; - } - } else { - paths.shift(); - this.revealPath(c, paths); - } - break; - } - } + this._selectionWhenHidden = node; } } } diff --git a/src/views/hierachicalPackageRootNode.ts b/src/views/hierachicalPackageRootNode.ts index 0172d2ee..39077e18 100644 --- a/src/views/hierachicalPackageRootNode.ts +++ b/src/views/hierachicalPackageRootNode.ts @@ -15,43 +15,17 @@ import { TypeRootNode } from "./typeRootNode"; export class HierachicalPackageRootNode extends PackageRootNode { - public static async convertPaths(paths: INodeData[]): Promise { - const index = paths.findIndex((nodeData) => nodeData.kind === NodeKind.PackageRoot); - const projectNodeData = paths.find((nodeData) => nodeData.kind === NodeKind.Project); - const packageRootNodeData = paths[index]; - const packageNodeData = paths[index + 1]; - const packageRootNode = new HierachicalPackageRootNode(packageRootNodeData, null, new ProjectNode(projectNodeData, null)); - - const correspondDataNodes: INodeData[] = []; - let correspondNode = await packageRootNode.revealPath(packageNodeData); - while (correspondNode instanceof HierachicalPackageRootSubNode) { - correspondDataNodes.push({ - name: correspondNode.nodeData.name, - moduleName: null, - path: correspondNode.nodeData.path, - uri: null, - kind: NodeKind.PackageRoot, - children: null, - }); - correspondNode = correspondNode.getParent(); - } - const result = paths.slice(null, index + 1).concat(correspondDataNodes.reverse(), paths.slice(index + 2)); - return result; - } - constructor(nodeData: INodeData, parent: DataNode, _project: ProjectNode) { super(nodeData, parent, _project); } - public async revealPath(packageNodeData: INodeData): Promise { - await this.getChildren(); - let packageTreeNode: PackageTreeNode = this.getPackageTree(); - let result: DataNode = null; - while (packageTreeNode && packageTreeNode.fullName !== packageNodeData.name) { - packageTreeNode = packageTreeNode.childs.find((child) => packageNodeData.name.startsWith(child.fullName)); - result = packageTreeNode ? new HierachicalPackageRootSubNode(packageTreeNode.getNodeDataFromPackageTreeNode(this.nodeData), - result, this._project, packageTreeNode) : null; - } + public async getCorrespondChildNodeWithNodeData(nodeData: INodeData): Promise { + let result: HierachicalPackageRootSubNode = null; + do { + const child: ExplorerNode[] = result ? await result.getChildren() : await this.getChildren(); + result = child.find((node) => node instanceof HierachicalPackageRootSubNode + && nodeData.name.startsWith(node.fullName)); + } while (result && result.fullName !== nodeData.name); return result; } diff --git a/src/views/hierachicalPackageRootSubNode.ts b/src/views/hierachicalPackageRootSubNode.ts index 7a8c6190..23a4a9fb 100644 --- a/src/views/hierachicalPackageRootSubNode.ts +++ b/src/views/hierachicalPackageRootSubNode.ts @@ -20,10 +20,15 @@ export class HierachicalPackageRootSubNode extends DataNode { this.packageTree = packageTree; } + public get fullName() { + return this.packageTree.fullName; + } + protected loadData(): Thenable { - return Jdtls.getPackageData({ + // Load data only when current node is a package + return this.packageTree.isPackage ? Jdtls.getPackageData({ kind: NodeKind.Package, projectUri: this._project.nodeData.uri, path: this.packageTree.fullName, rootPath: this.nodeData.path, - }); + }) : Promise.resolve([]); } protected get iconPath(): { light: string; dark: string } { diff --git a/src/views/pathProcesser.ts b/src/views/pathProcesser.ts deleted file mode 100644 index adc6256b..00000000 --- a/src/views/pathProcesser.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -import { Uri } from "vscode"; -import { Jdtls } from "../java/jdtls"; -import { INodeData } from "../java/nodeData"; -import { Settings } from "../settings"; -import { HierachicalPackageRootNode } from "./hierachicalPackageRootNode"; - -export class PathProcesser { - - public static async resolvePath(uri: Uri): Promise { - return Jdtls.resolvePath(uri.toString()) - .then((paths: INodeData[]) => PathProcesser.processPaths(paths)); - } - - private static async processPaths(paths: INodeData[]): Promise { - let result = paths; - result = Settings.isHierarchicalView() ? await HierachicalPackageRootNode.convertPaths(result) : result; - return result; - } - -} From bfd578b2bddd8cf81fd91a2f500d42a5f803ad9f Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Thu, 6 Dec 2018 10:43:20 +0800 Subject: [PATCH 08/12] Refactor package tree node --- src/java/packageTreeNode.ts | 53 ++++++++++++------------- src/views/hierachicalPackageRootNode.ts | 2 +- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/java/packageTreeNode.ts b/src/java/packageTreeNode.ts index 8894c641..9a4f3974 100644 --- a/src/java/packageTreeNode.ts +++ b/src/java/packageTreeNode.ts @@ -4,41 +4,24 @@ import { INodeData, NodeKind } from "./nodeData"; export class PackageTreeNode { + + public static createEmptyRootNode(): PackageTreeNode { + return new PackageTreeNode("", ""); + } + public name: string; public fullName: string; public childs: PackageTreeNode[] = []; public isPackage: boolean = false; - constructor(packageName: string, parentName: string) { - const splitPackageName = packageName.split("."); - this.name = splitPackageName[0]; - this.fullName = parentName === "" ? this.name : parentName + "." + this.name; - if (splitPackageName.length > 1) { - this.childs.push(new PackageTreeNode(packageName.substring(this.name.length + 1), this.fullName)); - } else { - this.isPackage = true; - } + private constructor(name: string, parentFullName: string) { + this.name = name; + this.fullName = parentFullName === "" ? name : parentFullName + "." + name; } public addPackage(packageName: string): void { - const splitPackageName = packageName.split("."); - const firstSubName = splitPackageName[0]; - const restname = packageName.substring(firstSubName.length + 1); - - let contains: boolean = false; - this.childs.forEach((child) => { - if (child.name === firstSubName) { - if (restname === "") { - child.isPackage = true; - } else { - child.addPackage(restname); - } - contains = true; - } - }); - if (!contains) { - this.childs.push(new PackageTreeNode(packageName, this.fullName)); - } + const packages = packageName.split("."); + this.addSubPackage(packages); } public compressTree(): void { @@ -63,4 +46,20 @@ export class PackageTreeNode { children: null, }; } + + private addSubPackage(packages: string[]): void { + if (!packages.length) { + this.isPackage = true; + return; + } + const subPackageName = packages.shift(); + const childNode = this.childs.find((child) => child.name === subPackageName); + if (childNode) { + childNode.addSubPackage(packages); + } else { + const newNode = new PackageTreeNode(subPackageName, this.fullName); + newNode.addSubPackage(packages); + this.childs.push(newNode); + } + } } diff --git a/src/views/hierachicalPackageRootNode.ts b/src/views/hierachicalPackageRootNode.ts index 39077e18..95558fdb 100644 --- a/src/views/hierachicalPackageRootNode.ts +++ b/src/views/hierachicalPackageRootNode.ts @@ -57,7 +57,7 @@ export class HierachicalPackageRootNode extends PackageRootNode { } private getPackageTree(): PackageTreeNode { - const result: PackageTreeNode = new PackageTreeNode("", ""); + const result: PackageTreeNode = PackageTreeNode.createEmptyRootNode(); if (this.nodeData.children && this.nodeData.children.length) { this.nodeData.children.forEach((child) => { if (child.kind === NodeKind.Package) { From 4e75cad4f2bce0231c8cbc10dd97c83cd57dc18a Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Thu, 6 Dec 2018 10:53:31 +0800 Subject: [PATCH 09/12] update hierachical settings --- package.json | 2 +- src/settings.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ecb9de96..0b0b7140 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "java.dependency.packagePresentation": { "type": "string", "enum":["flat","hierarchical"], - "description": "Set the presentation model of packages", + "description": "Package presentation mode: flat or hierarchical", "default": "flat" } } diff --git a/src/settings.ts b/src/settings.ts index a1cbc35a..c3e484e3 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -12,7 +12,8 @@ export class Settings { return; } const updatedConfig = workspace.getConfiguration("java.dependency"); - if (updatedConfig.showOutline !== this._depdendencyConfig.showOutline) { + if (updatedConfig.showOutline !== this._depdendencyConfig.showOutline + || updatedConfig.packagePresentation !== this._depdendencyConfig.packagePresentation) { commands.executeCommand(Commands.VIEW_PACKAGE_REFRESH); } this._depdendencyConfig = updatedConfig; From fdc2cb7712ff813a3b9ff43f513b3cc90e679ed1 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Fri, 7 Dec 2018 15:56:44 +0800 Subject: [PATCH 10/12] Add node to change representation, refactor code. --- package.json | 19 ++++- src/commands.ts | 2 + src/settings.ts | 16 ++++- src/views/dataNode.ts | 8 ++- src/views/dependencyDataProvider.ts | 42 +++++------ src/views/dependencyExplorer.ts | 7 +- src/views/hierachicalPackageNode.ts | 83 ++++++++++++++++++++++ src/views/hierachicalPackageRootNode.ts | 46 +++++------- src/views/hierachicalPackageRootSubNode.ts | 63 ---------------- src/views/packageNode.ts | 2 +- 10 files changed, 161 insertions(+), 127 deletions(-) create mode 100644 src/views/hierachicalPackageNode.ts delete mode 100644 src/views/hierachicalPackageRootSubNode.ts diff --git a/package.json b/package.json index 0b0b7140..a3acc90d 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,15 @@ "dark": "images/dark/icon-refresh.svg", "light": "images/light/icon-refresh.svg" } + }, + { + "command": "java.view.package.changeRepresentation", + "title": "Change package representation", + "category": "Java", + "icon": { + "dark": "images/dark/package.svg", + "light": "images/light/package.svg" + } } ], "configuration": { @@ -65,7 +74,10 @@ }, "java.dependency.packagePresentation": { "type": "string", - "enum":["flat","hierarchical"], + "enum": [ + "flat", + "hierarchical" + ], "description": "Package presentation mode: flat or hierarchical", "default": "flat" } @@ -76,6 +88,11 @@ { "command": "java.view.package.refresh", "when": "view == javaDependencyExplorer", + "group": "navigation@1" + }, + { + "command": "java.view.package.changeRepresentation", + "when": "view == javaDependencyExplorer", "group": "navigation@0" } ] diff --git a/src/commands.ts b/src/commands.ts index 64feac68..7f981852 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -10,6 +10,8 @@ export namespace Commands { */ export const EXECUTE_WORKSPACE_COMMAND = "java.execute.workspaceCommand"; + export const VIEW_PACKAGE_CHANGEREPRESENTATION = "java.view.package.changeRepresentation"; + export const VIEW_PACKAGE_REFRESH = "java.view.package.refresh"; export const VIEW_PACKAGE_OPEN_FILE = "java.view.package.openFile"; diff --git a/src/settings.ts b/src/settings.ts index c3e484e3..520c0fd0 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import { commands, ConfigurationChangeEvent, ExtensionContext, workspace, WorkspaceConfiguration } from "vscode"; +import { instrumentOperation } from "vscode-extension-telemetry-wrapper"; import { Commands } from "./commands"; export class Settings { @@ -19,6 +20,14 @@ export class Settings { this._depdendencyConfig = updatedConfig; })); + + const instrumented = instrumentOperation(Commands.VIEW_PACKAGE_CHANGEREPRESENTATION, Settings.changePackageRepresentation); + context.subscriptions.push(commands.registerCommand(Commands.VIEW_PACKAGE_CHANGEREPRESENTATION, instrumented)); + } + + public static changePackageRepresentation(): void { + const representationSetting = Settings.isHierarchicalView() ? PackagePresentation.Flat : PackagePresentation.Hierarchical; + workspace.getConfiguration().update("java.dependency.packagePresentation", representationSetting, false); } public static showOutline(): boolean { @@ -30,8 +39,13 @@ export class Settings { } public static isHierarchicalView(): boolean { - return this._depdendencyConfig.get("packagePresentation") === "hierarchical"; + return this._depdendencyConfig.get("packagePresentation") === PackagePresentation.Hierarchical; } private static _depdendencyConfig: WorkspaceConfiguration = workspace.getConfiguration("java.dependency"); } + +enum PackagePresentation { + Flat = "flat", + Hierarchical = "hierarchical", +} diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index ef05eaa2..8e83941f 100644 --- a/src/views/dataNode.ts +++ b/src/views/dataNode.ts @@ -7,7 +7,7 @@ import { Telemetry } from "../telemetry"; import { ExplorerNode } from "./explorerNode"; export abstract class DataNode extends ExplorerNode { - constructor(private _nodeData: INodeData, parent: DataNode) { + constructor(protected _nodeData: INodeData, parent: DataNode) { super(parent); } @@ -32,9 +32,11 @@ export abstract class DataNode extends ExplorerNode { return this._nodeData.path; } - public async getCorrespondChildNodeWithNodeData(nodeData: INodeData): Promise { + public async revealPaths(paths: INodeData[]): Promise { + const childNodeData = paths.shift(); const childs: ExplorerNode[] = await this.getChildren(); - return childs.find((child: DataNode) => child.nodeData.name === nodeData.name && child.path === nodeData.path); + const childNode = childs.find((child: DataNode) => child.nodeData.name === childNodeData.name && child.path === childNodeData.path); + return paths.length ? childNode.revealPaths(paths) : childNode; } public getChildren(): ProviderResult { diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index a69a0122..1573790a 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -5,12 +5,13 @@ import { commands, Event, EventEmitter, ExtensionContext, ProviderResult, Range, Selection, TextEditorRevealType, TreeDataProvider, TreeItem, Uri, window, workspace, } from "vscode"; -import { instrumentOperation } from "vscode-extension-telemetry-wrapper"; +import { instrumentOperation, instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper"; import { Commands } from "../commands"; import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { Telemetry } from "../telemetry"; import { DataNode } from "./dataNode"; +import { DependencyExplorer } from "./dependencyExplorer"; import { ExplorerNode } from "./explorerNode"; import { ProjectNode } from "./projectNode"; import { WorkspaceNode } from "./workspaceNode"; @@ -68,35 +69,26 @@ export class DependencyDataProvider implements TreeDataProvider { return element.getParent(); } - public async getRootNodeByData(nodeData: INodeData): Promise { - // Server only return project nodes, so use get root projects function - const rootNodes: ExplorerNode[] = await this.getRootProjects(); - return rootNodes.find((node: DataNode) => node.path === nodeData.path && node.nodeData.name === nodeData.name); + public async revealPaths(paths: INodeData[]): Promise { + const projectNodeData = paths.shift(); + const projects = await this.getRootProjects(); + const correspondProject = projects.find((node: DataNode) => + node.path === projectNodeData.path && node.nodeData.name === projectNodeData.name); + return correspondProject.revealPaths(paths); } private async getRootProjects(): Promise { - let result = new Array(); - const folders = workspace.workspaceFolders; - if (folders && folders.length) { - if (folders.length > 1) { - const workspaces = folders.map((folder) => new WorkspaceNode({ - name: folder.name, - uri: folder.uri.toString(), - kind: NodeKind.Workspace, - }, null)); - // return projects of all workspaces - for (const singleworkspace of workspaces) { - const projects = await singleworkspace.getChildren(); - result = result.concat(projects); - } - } else { - const projectsNodeData = await Jdtls.getProjects(folders[0].uri.toString()); - projectsNodeData.forEach((project) => { - result.push(new ProjectNode(project, null)); - }); + const rootElements = this._rootItems ? this._rootItems : await this.getChildren(); + if (rootElements[0] instanceof ProjectNode) { + return rootElements; + } else { + let result = []; + for (const singleworkspace of rootElements) { + const projects = await singleworkspace.getChildren(); + result = result.concat(projects); } + return result; } - return result; } private getRootNodes(): Thenable { diff --git a/src/views/dependencyExplorer.ts b/src/views/dependencyExplorer.ts index 896f14dc..0b9fd734 100644 --- a/src/views/dependencyExplorer.ts +++ b/src/views/dependencyExplorer.ts @@ -40,11 +40,8 @@ export class DependencyExplorer { public async reveal(uri: Uri): Promise { const paths: INodeData[] = await Jdtls.resolvePath(uri.toString()); - // Get correspond project node from dataProvider - let node = await this._dataProvider.getRootNodeByData(paths.shift()); - while (paths.length && node) { - node = await node.getCorrespondChildNodeWithNodeData(paths.shift()); - } + const node = await this._dataProvider.revealPaths(paths); + if (this._dependencyViewer.visible) { this._dependencyViewer.reveal(node); } else { diff --git a/src/views/hierachicalPackageNode.ts b/src/views/hierachicalPackageNode.ts new file mode 100644 index 00000000..3fc7ef46 --- /dev/null +++ b/src/views/hierachicalPackageNode.ts @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import { ProviderResult, TreeItem, TreeItemCollapsibleState } from "vscode"; +import { HierachicalPackageNodeData } from "../java/hierachicalPackageNodeData"; +import { INodeData, NodeKind } from "../java/nodeData"; +import { Telemetry } from "../telemetry"; +import { DataNode } from "./dataNode"; +import { ExplorerNode } from "./explorerNode"; +import { FileNode } from "./fileNode"; +import { PackageNode } from "./packageNode"; +import { ProjectNode } from "./projectNode"; +import { TypeRootNode } from "./typeRootNode"; + +export class HierachicalPackageNode extends PackageNode { + + constructor(nodeData: INodeData, parent: DataNode, protected _project: ProjectNode, protected _rootNode: DataNode) { + super(nodeData, parent, _project, _rootNode); + } + + public getTreeItem(): TreeItem | Promise { + if (this._nodeData) { + const item = new TreeItem(this.getHierarchicalNodeData().displayName, + this.hasChildren() ? TreeItemCollapsibleState.Collapsed : TreeItemCollapsibleState.None); + item.iconPath = this.iconPath; + item.command = this.command; + return item; + } + } + + public getChildren(): ProviderResult { + return this.loadData().then((res) => { + if (!res) { + Telemetry.sendEvent("load data get undefined result", { node_kind: this.nodeData.kind.toString() }); + } else { + // Combine hierachical children and normal packagenode children + res.forEach((node) => this.nodeData.children.push(node)); + } + return this.createChildNodeList(); + }); + } + + public async revealPaths(paths: INodeData[]): Promise { + const hierachicalNodeData = paths[0]; + if (hierachicalNodeData.name === this.nodeData.name) { + paths.shift(); + // reveal as a package node + return super.revealPaths(paths); + } else { + // reveal as a package root node + const childs: ExplorerNode[] = await this.getChildren(); + const childNode = childs.find((child: DataNode) => + child instanceof HierachicalPackageNode && hierachicalNodeData.name.startsWith(child.nodeData.name)); + return childNode.revealPaths(paths); + } + } + + protected loadData(): Thenable { + // Load data only when current node is a package + return this.getHierarchicalNodeData().isPackage ? super.loadData() : Promise.resolve([]); + } + + protected createChildNodeList(): ExplorerNode[] { + const result = []; + if (this.nodeData.children && this.nodeData.children.length) { + this.sort(); + this.nodeData.children.forEach((nodeData) => { + if (nodeData.kind === NodeKind.File) { + result.push(new FileNode(nodeData, this)); + } else if (nodeData instanceof HierachicalPackageNodeData) { + result.push(new HierachicalPackageNode(nodeData, this, this._project, this._rootNode)); + } else { + result.push(new TypeRootNode(nodeData, this)); + } + }); + } + return result; + } + + private getHierarchicalNodeData(): HierachicalPackageNodeData { + return this.nodeData; + } +} diff --git a/src/views/hierachicalPackageRootNode.ts b/src/views/hierachicalPackageRootNode.ts index 95558fdb..d96a9e5e 100644 --- a/src/views/hierachicalPackageRootNode.ts +++ b/src/views/hierachicalPackageRootNode.ts @@ -1,14 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +import { HierachicalPackageNodeData } from "../java/hierachicalPackageNodeData"; import { INodeData, NodeKind } from "../java/nodeData"; -import { PackageTreeNode } from "../java/packageTreeNode"; -import { Settings } from "../settings"; import { DataNode } from "./dataNode"; import { ExplorerNode } from "./explorerNode"; import { FileNode } from "./fileNode"; import { FolderNode } from "./folderNode"; -import { HierachicalPackageRootSubNode } from "./hierachicalPackageRootSubNode"; +import { HierachicalPackageNode } from "./hierachicalPackageNode"; import { PackageRootNode } from "./packageRootNode"; import { ProjectNode } from "./projectNode"; import { TypeRootNode } from "./typeRootNode"; @@ -19,14 +18,12 @@ export class HierachicalPackageRootNode extends PackageRootNode { super(nodeData, parent, _project); } - public async getCorrespondChildNodeWithNodeData(nodeData: INodeData): Promise { - let result: HierachicalPackageRootSubNode = null; - do { - const child: ExplorerNode[] = result ? await result.getChildren() : await this.getChildren(); - result = child.find((node) => node instanceof HierachicalPackageRootSubNode - && nodeData.name.startsWith(node.fullName)); - } while (result && result.fullName !== nodeData.name); - return result; + public async revealPaths(paths: INodeData[]): Promise { + const hierachicalNodeData = paths[0]; + const childs: ExplorerNode[] = await this.getChildren(); + const childNode = childs.find((child: DataNode) => + child instanceof HierachicalPackageNode && hierachicalNodeData.name.startsWith(child.nodeData.name)); + return childNode.revealPaths(paths); } protected createChildNodeList(): ExplorerNode[] { @@ -43,29 +40,22 @@ export class HierachicalPackageRootNode extends PackageRootNode { } }); } - const packageNodeList = this.getHierarchicalPackageNodes(); - return packageNodeList.concat(result); + return this.getHierarchicalPackageNodes().concat(result); } protected getHierarchicalPackageNodes(): ExplorerNode[] { - const result = []; - const packageTree = this.getPackageTree(); - packageTree.childs.forEach((childNode) => { - result.push(new HierachicalPackageRootSubNode(childNode.getNodeDataFromPackageTreeNode(this.nodeData), this, this._project, childNode)); - }); - return result; + return this.getHierarchicalPackageNodeData().children + .map((hierachicalChildrenNode) => new HierachicalPackageNode(hierachicalChildrenNode, this, this._project, this)); } - private getPackageTree(): PackageTreeNode { - const result: PackageTreeNode = PackageTreeNode.createEmptyRootNode(); + private getHierarchicalPackageNodeData(): HierachicalPackageNodeData { if (this.nodeData.children && this.nodeData.children.length) { - this.nodeData.children.forEach((child) => { - if (child.kind === NodeKind.Package) { - result.addPackage(child.name); - } - }); + const nodeDataList = this.nodeData.children + .filter((child) => child.kind === NodeKind.Package); + return HierachicalPackageNodeData.createHierachicalNodeDataByPackageList(nodeDataList); + } else { + // Return a empty hierachical node + return HierachicalPackageNodeData.createHierachicalNodeDataByPackageList([]); } - result.compressTree(); - return result; } } diff --git a/src/views/hierachicalPackageRootSubNode.ts b/src/views/hierachicalPackageRootSubNode.ts deleted file mode 100644 index 23a4a9fb..00000000 --- a/src/views/hierachicalPackageRootSubNode.ts +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -import { Jdtls } from "../java/jdtls"; -import { INodeData, NodeKind } from "../java/nodeData"; -import { PackageTreeNode } from "../java/packageTreeNode"; -import { DataNode } from "./dataNode"; -import { ExplorerNode } from "./explorerNode"; -import { FileNode } from "./fileNode"; -import { FolderNode } from "./folderNode"; -import { ProjectNode } from "./projectNode"; -import { TypeRootNode } from "./typeRootNode"; - -export class HierachicalPackageRootSubNode extends DataNode { - - public packageTree: PackageTreeNode; - - constructor(nodeData: INodeData, parent: DataNode, private _project: ProjectNode, packageTree: PackageTreeNode = null) { - super(nodeData, parent); - this.packageTree = packageTree; - } - - public get fullName() { - return this.packageTree.fullName; - } - - protected loadData(): Thenable { - // Load data only when current node is a package - return this.packageTree.isPackage ? Jdtls.getPackageData({ - kind: NodeKind.Package, projectUri: this._project.nodeData.uri, path: this.packageTree.fullName, rootPath: this.nodeData.path, - }) : Promise.resolve([]); - } - - protected get iconPath(): { light: string; dark: string } { - return ExplorerNode.resolveIconPath("package"); - } - - protected createChildNodeList(): ExplorerNode[] { - const result = []; - if (this.nodeData.children && this.nodeData.children.length) { - this.sort(); - this.nodeData.children.forEach((data) => { - if (data.kind === NodeKind.File) { - result.push(new FileNode(data, this)); - } else if (data.kind === NodeKind.Folder) { - result.push(new FolderNode(data, this, this._project, this)); - } else if (data.kind === NodeKind.TypeRoot) { - result.push(new TypeRootNode(data, this)); - } - }); - } - const packageNodeList = this.getHierarchicalPackageNodes(); - return packageNodeList.concat(result); - } - - protected getHierarchicalPackageNodes(): ExplorerNode[] { - const result = []; - this.packageTree.childs.forEach((childNode) => { - result.push(new HierachicalPackageRootSubNode(childNode.getNodeDataFromPackageTreeNode(this.nodeData), this, this._project, childNode)); - }); - return result; - } -} diff --git a/src/views/packageNode.ts b/src/views/packageNode.ts index a453f84b..9756e79f 100644 --- a/src/views/packageNode.ts +++ b/src/views/packageNode.ts @@ -9,7 +9,7 @@ import { FileNode } from "./fileNode"; import { TypeRootNode } from "./typeRootNode"; export class PackageNode extends DataNode { - constructor(nodeData: INodeData, parent: DataNode, private _project: DataNode, private _rootNode: DataNode) { + constructor(nodeData: INodeData, parent: DataNode, protected _project: DataNode, protected _rootNode: DataNode) { super(nodeData, parent); } From 6055b4b03f772a88443deb0abc19403e08502b06 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Fri, 7 Dec 2018 17:02:56 +0800 Subject: [PATCH 11/12] remove unuse imports --- src/java/hierachicalPackageNodeData.ts | 70 ++++++++++++++++++++++++++ src/java/packageTreeNode.ts | 65 ------------------------ src/views/dependencyDataProvider.ts | 3 +- 3 files changed, 71 insertions(+), 67 deletions(-) create mode 100644 src/java/hierachicalPackageNodeData.ts delete mode 100644 src/java/packageTreeNode.ts diff --git a/src/java/hierachicalPackageNodeData.ts b/src/java/hierachicalPackageNodeData.ts new file mode 100644 index 00000000..676c3279 --- /dev/null +++ b/src/java/hierachicalPackageNodeData.ts @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +import { INodeData, NodeKind } from "./nodeData"; + +export class HierachicalPackageNodeData implements INodeData { + + public static createHierachicalNodeDataByPackageList(packageList: INodeData[]): HierachicalPackageNodeData { + const result = new HierachicalPackageNodeData("", ""); + packageList.forEach((nodeData) => result.addSubPackage(nodeData.name.split("."), nodeData)); + result.compressTree(); + return result; + } + + public name: string; + public children = []; + public displayName: string; + public isPackage: boolean = false; + private nodeData: INodeData = null; + + public get uri() { + return this.nodeData.uri; + } + + public get moduleName() { + return this.nodeData.moduleName; + } + + public get path() { + return this.nodeData.path; + } + + public get kind() { + return this.nodeData ? this.nodeData.kind : NodeKind.Package; + } + + private constructor(displayName: string, parentName: string) { + this.displayName = displayName; + this.name = parentName === "" ? displayName : parentName + "." + displayName; + } + + private compressTree(): void { + // Don't compress the root node + while (this.name !== "" && this.children.length === 1 && !this.isPackage) { + const child = this.children[0]; + this.name = this.name + "." + child.displayName; + this.displayName = this.displayName + "." + child.displayName; + this.children = child.children; + this.isPackage = child.isPackage; + } + this.children.forEach((child) => child.compressTree()); + } + + private addSubPackage(packages: string[], nodeData: INodeData): void { + if (!packages.length) { + this.isPackage = true; + this.nodeData = nodeData; + return; + } + const subPackageDisplayName = packages.shift(); + const childNode = this.children.find((child) => child.displayName === subPackageDisplayName); + if (childNode) { + childNode.addSubPackage(packages); + } else { + const newNode = new HierachicalPackageNodeData(subPackageDisplayName, this.name); + newNode.addSubPackage(packages, nodeData); + this.children.push(newNode); + } + } +} diff --git a/src/java/packageTreeNode.ts b/src/java/packageTreeNode.ts deleted file mode 100644 index 9a4f3974..00000000 --- a/src/java/packageTreeNode.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -import { INodeData, NodeKind } from "./nodeData"; - -export class PackageTreeNode { - - public static createEmptyRootNode(): PackageTreeNode { - return new PackageTreeNode("", ""); - } - - public name: string; - public fullName: string; - public childs: PackageTreeNode[] = []; - public isPackage: boolean = false; - - private constructor(name: string, parentFullName: string) { - this.name = name; - this.fullName = parentFullName === "" ? name : parentFullName + "." + name; - } - - public addPackage(packageName: string): void { - const packages = packageName.split("."); - this.addSubPackage(packages); - } - - public compressTree(): void { - // Don't compress the root node - while (this.name !== "" && this.childs.length === 1 && !this.isPackage) { - const child = this.childs[0]; - this.fullName = this.fullName + "." + child.name; - this.name = this.name + "." + child.name; - this.childs = child.childs; - this.isPackage = child.isPackage; - } - this.childs.forEach((child) => child.compressTree()); - } - - public getNodeDataFromPackageTreeNode(nodeData: INodeData): INodeData { - return { - name: this.name, - moduleName: nodeData.moduleName, - path: nodeData.path, - uri: null, - kind: NodeKind.PackageRoot, - children: null, - }; - } - - private addSubPackage(packages: string[]): void { - if (!packages.length) { - this.isPackage = true; - return; - } - const subPackageName = packages.shift(); - const childNode = this.childs.find((child) => child.name === subPackageName); - if (childNode) { - childNode.addSubPackage(packages); - } else { - const newNode = new PackageTreeNode(subPackageName, this.fullName); - newNode.addSubPackage(packages); - this.childs.push(newNode); - } - } -} diff --git a/src/views/dependencyDataProvider.ts b/src/views/dependencyDataProvider.ts index 1573790a..b27935e1 100644 --- a/src/views/dependencyDataProvider.ts +++ b/src/views/dependencyDataProvider.ts @@ -5,13 +5,12 @@ import { commands, Event, EventEmitter, ExtensionContext, ProviderResult, Range, Selection, TextEditorRevealType, TreeDataProvider, TreeItem, Uri, window, workspace, } from "vscode"; -import { instrumentOperation, instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper"; +import { instrumentOperation } from "vscode-extension-telemetry-wrapper"; import { Commands } from "../commands"; import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; import { Telemetry } from "../telemetry"; import { DataNode } from "./dataNode"; -import { DependencyExplorer } from "./dependencyExplorer"; import { ExplorerNode } from "./explorerNode"; import { ProjectNode } from "./projectNode"; import { WorkspaceNode } from "./workspaceNode"; From 7854efc4047646d233e71eca4c38eb8f2564b4b7 Mon Sep 17 00:00:00 2001 From: Hanxiao Liu Date: Mon, 10 Dec 2018 12:48:12 +0800 Subject: [PATCH 12/12] Resolve comments --- src/java/hierachicalPackageNodeData.ts | 8 +++++--- src/views/dataNode.ts | 2 +- src/views/hierachicalPackageNode.ts | 2 +- src/views/hierachicalPackageRootNode.ts | 10 +++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/java/hierachicalPackageNodeData.ts b/src/java/hierachicalPackageNodeData.ts index 676c3279..51bfbc46 100644 --- a/src/java/hierachicalPackageNodeData.ts +++ b/src/java/hierachicalPackageNodeData.ts @@ -15,7 +15,6 @@ export class HierachicalPackageNodeData implements INodeData { public name: string; public children = []; public displayName: string; - public isPackage: boolean = false; private nodeData: INodeData = null; public get uri() { @@ -34,6 +33,10 @@ export class HierachicalPackageNodeData implements INodeData { return this.nodeData ? this.nodeData.kind : NodeKind.Package; } + public get isPackage() { + return this.nodeData !== null; + } + private constructor(displayName: string, parentName: string) { this.displayName = displayName; this.name = parentName === "" ? displayName : parentName + "." + displayName; @@ -46,14 +49,13 @@ export class HierachicalPackageNodeData implements INodeData { this.name = this.name + "." + child.displayName; this.displayName = this.displayName + "." + child.displayName; this.children = child.children; - this.isPackage = child.isPackage; + this.nodeData = child.nodeData; } this.children.forEach((child) => child.compressTree()); } private addSubPackage(packages: string[], nodeData: INodeData): void { if (!packages.length) { - this.isPackage = true; this.nodeData = nodeData; return; } diff --git a/src/views/dataNode.ts b/src/views/dataNode.ts index 8e83941f..b65ce8a2 100644 --- a/src/views/dataNode.ts +++ b/src/views/dataNode.ts @@ -36,7 +36,7 @@ export abstract class DataNode extends ExplorerNode { const childNodeData = paths.shift(); const childs: ExplorerNode[] = await this.getChildren(); const childNode = childs.find((child: DataNode) => child.nodeData.name === childNodeData.name && child.path === childNodeData.path); - return paths.length ? childNode.revealPaths(paths) : childNode; + return childNode === null ? null : (paths.length ? childNode.revealPaths(paths) : childNode); } public getChildren(): ProviderResult { diff --git a/src/views/hierachicalPackageNode.ts b/src/views/hierachicalPackageNode.ts index 3fc7ef46..3cf9d373 100644 --- a/src/views/hierachicalPackageNode.ts +++ b/src/views/hierachicalPackageNode.ts @@ -51,7 +51,7 @@ export class HierachicalPackageNode extends PackageNode { const childs: ExplorerNode[] = await this.getChildren(); const childNode = childs.find((child: DataNode) => child instanceof HierachicalPackageNode && hierachicalNodeData.name.startsWith(child.nodeData.name)); - return childNode.revealPaths(paths); + return childNode === null ? null : childNode.revealPaths(paths); } } diff --git a/src/views/hierachicalPackageRootNode.ts b/src/views/hierachicalPackageRootNode.ts index d96a9e5e..3d3946b6 100644 --- a/src/views/hierachicalPackageRootNode.ts +++ b/src/views/hierachicalPackageRootNode.ts @@ -23,7 +23,7 @@ export class HierachicalPackageRootNode extends PackageRootNode { const childs: ExplorerNode[] = await this.getChildren(); const childNode = childs.find((child: DataNode) => child instanceof HierachicalPackageNode && hierachicalNodeData.name.startsWith(child.nodeData.name)); - return childNode.revealPaths(paths); + return childNode === null ? null : childNode.revealPaths(paths); } protected createChildNodeList(): ExplorerNode[] { @@ -44,8 +44,9 @@ export class HierachicalPackageRootNode extends PackageRootNode { } protected getHierarchicalPackageNodes(): ExplorerNode[] { - return this.getHierarchicalPackageNodeData().children - .map((hierachicalChildrenNode) => new HierachicalPackageNode(hierachicalChildrenNode, this, this._project, this)); + const hierachicalPackageNodeData = this.getHierarchicalPackageNodeData(); + return hierachicalPackageNodeData === null ? [] : hierachicalPackageNodeData.children.map((hierachicalChildrenNode) => + new HierachicalPackageNode(hierachicalChildrenNode, this, this._project, this)); } private getHierarchicalPackageNodeData(): HierachicalPackageNodeData { @@ -54,8 +55,7 @@ export class HierachicalPackageRootNode extends PackageRootNode { .filter((child) => child.kind === NodeKind.Package); return HierachicalPackageNodeData.createHierachicalNodeDataByPackageList(nodeDataList); } else { - // Return a empty hierachical node - return HierachicalPackageNodeData.createHierachicalNodeDataByPackageList([]); + return null; } } }