From 1c9052fd829201791e8d2d6060410a5d390637f0 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Tue, 4 Apr 2023 11:25:52 +0800 Subject: [PATCH 1/2] feat: Display non-java resources in the Project explorer Signed-off-by: Sheng Chen --- .../jdtls/ext/core/PackageCommand.java | 76 ++++++++++++------- .../jdtls/ext/core/parser/ResourceSet.java | 62 +++++++++++++-- src/explorerCommands/rename.ts | 3 + src/syncHandler.ts | 63 +++++++++------ src/views/projectNode.ts | 23 +----- test/gradle-suite/projectView.test.ts | 13 ++-- test/maven-suite/projectView.test.ts | 36 ++++----- test/simple-suite/projectView.test.ts | 8 +- 8 files changed, 179 insertions(+), 105 deletions(-) diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java index e34a3cd6..b2e96a49 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java @@ -78,10 +78,10 @@ public class PackageCommand { static { commands = new HashMap<>(); - commands.put(NodeKind.PROJECT, PackageCommand::getContainers); - commands.put(NodeKind.CONTAINER, PackageCommand::getPackageFragmentRoots); - commands.put(NodeKind.PACKAGEROOT, PackageCommand::getPackages); - commands.put(NodeKind.PACKAGE, PackageCommand::getRootTypes); + commands.put(NodeKind.PROJECT, PackageCommand::getProjectChildren); + commands.put(NodeKind.CONTAINER, PackageCommand::getContainerChildren); + commands.put(NodeKind.PACKAGEROOT, PackageCommand::getPackageRootChildren); + commands.put(NodeKind.PACKAGE, PackageCommand::getPackageChildren); commands.put(NodeKind.FOLDER, PackageCommand::getFolderChildren); } @@ -225,10 +225,17 @@ public static List resolvePath(List arguments, IProgressMon * @throws JavaModelException when fails to get path or resource */ private static List getParentAncestorNodes(IResource element) throws JavaModelException { - List nodeList = new ArrayList<>(); - while (element != null) { + List nodeList = new LinkedList<>(); + while (element != null && !(element instanceof IWorkspaceRoot)) { IJavaElement javaElement = JavaCore.create(element); - if (javaElement instanceof IPackageFragmentRoot) { + if (javaElement == null) { + PackageNode entry = PackageNode.createNodeForResource(element); + if (entry != null) { + nodeList.add(0, entry); + } + } else if (javaElement instanceof IJavaProject) { + nodeList.add(0, PackageNode.createNodeForProject(javaElement)); + } else if (javaElement instanceof IPackageFragmentRoot) { IPackageFragmentRoot pkgRoot = (IPackageFragmentRoot) javaElement; nodeList.add(0, new PackageRootNode(pkgRoot, element.getProjectRelativePath().toPortableString(), NodeKind.PACKAGEROOT)); @@ -239,12 +246,6 @@ private static List getParentAncestorNodes(IResource element) throw if (packageFragment.containsJavaResources() || packageFragment.getNonJavaResources().length > 0) { nodeList.add(0, PackageNode.createNodeForPackageFragment(packageFragment)); } - - } else if (javaElement == null) { - PackageNode entry = PackageNode.createNodeForResource(element); - if (entry != null) { - nodeList.add(0, entry); - } } element = element.getParent(); } @@ -255,20 +256,28 @@ private static List getParentAncestorNodes(IResource element) throw /** * Get the class path container list. */ - private static List getContainers(PackageParams query, IProgressMonitor pm) { + private static List getProjectChildren(PackageParams query, IProgressMonitor pm) { IJavaProject javaProject = getJavaProject(query.getProjectUri()); if (javaProject != null) { + refreshLocal(javaProject.getProject(), pm); List children = new LinkedList<>(); boolean hasReferencedLibraries = false; try { IClasspathEntry[] references = javaProject.getRawClasspath(); for (IClasspathEntry entry : references) { - if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY && entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE) { + int entryKind = entry.getEntryKind(); + if (entryKind == IClasspathEntry.CPE_SOURCE) { + IPackageFragmentRoot[] packageFragmentRoots = javaProject.findPackageFragmentRoots(entry); + children.addAll(Arrays.asList(packageFragmentRoots)); + } else if (entryKind == IClasspathEntry.CPE_CONTAINER) { children.add(entry); - } else { + } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) { hasReferencedLibraries = true; + } else { + // TODO: handle IClasspathEntry.CPE_PROJECT } } + Collections.addAll(children, javaProject.getNonJavaResources()); } catch (CoreException e) { JdtlsExtActivator.logException("Problem load project library ", e); } @@ -278,7 +287,7 @@ private static List getContainers(PackageParams query, IProgressMon resourceSet.accept(visitor); List result = visitor.getNodes(); - // Invisble project will always have the referenced libraries entry + // Invisible project will always have the referenced libraries entry if (!ProjectUtils.isVisibleProject(javaProject.getProject())) { result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER); } else if (hasReferencedLibraries) { @@ -289,7 +298,7 @@ private static List getContainers(PackageParams query, IProgressMon return Collections.emptyList(); } - private static List getPackageFragmentRoots(PackageParams query, IProgressMonitor pm) { + private static List getContainerChildren(PackageParams query, IProgressMonitor pm) { IJavaProject javaProject = getJavaProject(query.getProjectUri()); if (javaProject == null) { return Collections.emptyList(); @@ -311,6 +320,7 @@ private static List getPackageFragmentRoots(PackageParams query, IP for (IPackageFragmentRoot fragmentRoot : packageFragmentRoots) { children.add(fragmentRoot); + children.addAll(Arrays.asList(fragmentRoot.getNonJavaResources())); } } } catch (CoreException e) { @@ -343,7 +353,7 @@ private static IPackageFragmentRoot[] findPackageFragmentRoots(IJavaProject java return null; } - private static List getPackages(PackageParams query, IProgressMonitor pm) { + private static List getPackageRootChildren(PackageParams query, IProgressMonitor pm) { try { IPackageFragmentRoot packageRoot = getPackageFragmentRootFromQuery(query); if (packageRoot == null) { @@ -351,7 +361,7 @@ private static List getPackages(PackageParams query, IProgressMonit new Status(IStatus.ERROR, JdtlsExtActivator.PLUGIN_ID, String.format("No package root found for %s", query.getPath()))); } List result = getPackageFragmentRootContent(packageRoot, query.isHierarchicalView(), pm); - ResourceSet resourceSet = new ResourceSet(result); + ResourceSet resourceSet = new ResourceSet(result, query.isHierarchicalView()); ResourceVisitor visitor = new JavaResourceVisitor(packageRoot.getJavaProject()); resourceSet.accept(visitor); return visitor.getNodes(); @@ -375,7 +385,6 @@ private static IPackageFragmentRoot getPackageFragmentRootFromQuery(PackageParam return javaProject.findPackageFragmentRoot(Path.fromPortableString(query.getRootPath())); } catch (JavaModelException e) { JdtlsExtActivator.log(e); - return null; } } } @@ -383,20 +392,21 @@ private static IPackageFragmentRoot getPackageFragmentRootFromQuery(PackageParam return null; } - private static List getRootTypes(PackageParams query, IProgressMonitor pm) { + private static List getPackageChildren(PackageParams query, IProgressMonitor pm) { IPackageFragment packageFragment = (IPackageFragment) JavaCore.create(query.getHandlerIdentifier()); - List children = getChildrenForPackage(packageFragment); + List children = getChildrenForPackage(packageFragment, pm); ResourceSet resourceSet = new ResourceSet(children); ResourceVisitor visitor = new JavaResourceVisitor(packageFragment.getJavaProject()); resourceSet.accept(visitor); return visitor.getNodes(); } - public static List getChildrenForPackage(IPackageFragment packageFragment) { + public static List getChildrenForPackage(IPackageFragment packageFragment, IProgressMonitor pm) { if (packageFragment == null) { return Collections.emptyList(); } + refreshLocal(packageFragment.getResource(), pm); List children = new LinkedList<>(); try { for (IJavaElement element : packageFragment.getChildren()) { @@ -412,10 +422,7 @@ public static List getChildrenForPackage(IPackageFragment packageFragmen } } - Object[] nonJavaResources = packageFragment.getNonJavaResources(); - for (Object resource : nonJavaResources) { - children.add(resource); - } + Collections.addAll(children, packageFragment.getNonJavaResources()); } catch (JavaModelException e) { JdtlsExtActivator.log(e); } @@ -458,6 +465,7 @@ private static List getFolderChildren(PackageParams query, IProgres // general resource folder. IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder(Path.fromPortableString(query.getPath())); if (folder.exists()) { + refreshLocal(folder, pm); children.addAll(Arrays.asList(folder.members())); javaProject = JavaCore.create(folder.getProject()); } @@ -488,6 +496,7 @@ private static List getFolderChildren(PackageParams query, IProgres */ public static List getPackageFragmentRootContent(IPackageFragmentRoot root, boolean isHierarchicalView, IProgressMonitor pm) throws CoreException { ArrayList result = new ArrayList<>(); + refreshLocal(root.getResource(), pm); if (isHierarchicalView) { Map map = new HashMap<>(); for (IJavaElement child : root.getChildren()) { @@ -583,4 +592,15 @@ public static IJavaProject getJavaProject(String projectUri) { } return null; } + + private static void refreshLocal(IResource resource, IProgressMonitor monitor) { + if (resource == null || !resource.exists()) { + return; + } + try { + resource.refreshLocal(IResource.DEPTH_ONE, monitor); + } catch (CoreException e) { + JdtlsExtActivator.log(e); + } + } } diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ResourceSet.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ResourceSet.java index f49105fb..50ba9eba 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ResourceSet.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ResourceSet.java @@ -15,9 +15,13 @@ import java.util.ListIterator; import java.util.Objects; +import org.eclipse.core.internal.utils.FileUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IClasspathEntry; @@ -26,6 +30,7 @@ import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.ls.core.internal.ProjectUtils; import com.microsoft.jdtls.ext.core.JdtlsExtActivator; @@ -35,9 +40,15 @@ public class ResourceSet { private List resources; + private boolean isHierarchicalView; public ResourceSet(List resources) { + this(resources, false); + } + + public ResourceSet(List resources, boolean isHierarchicalView) { this.resources = resources; + this.isHierarchicalView = isHierarchicalView; } public void accept(ResourceVisitor visitor) { @@ -58,11 +69,11 @@ public void accept(ResourceVisitor visitor) { } // skip invisible project's linked folder and add its children to the iterator. - if (!ProjectUtils.isVisibleProject(javaProject.getProject()) && + if (ProjectUtils.isUnmanagedFolder(javaProject.getProject()) && Objects.equals(ProjectUtils.WORKSPACE_LINK, pkgRoot.getElementName())) { try { List nextObjs = PackageCommand.getPackageFragmentRootContent( - pkgRoot, false, new NullProgressMonitor()); + pkgRoot, isHierarchicalView, new NullProgressMonitor()); for (Object nextObj : nextObjs) { iterator.add(nextObj); iterator.previous(); @@ -76,9 +87,9 @@ public void accept(ResourceVisitor visitor) { } } else if (resource instanceof IPackageFragment) { IPackageFragment fragment = (IPackageFragment) resource; - // skil default package and add its children to the iterator. + // skip default package and add its children to the iterator. if (fragment.isDefaultPackage()) { - List nextObjs = PackageCommand.getChildrenForPackage(fragment); + List nextObjs = PackageCommand.getChildrenForPackage(fragment, new NullProgressMonitor()); for (Object nextObj : nextObjs) { iterator.add(nextObj); iterator.previous(); @@ -91,12 +102,51 @@ public void accept(ResourceVisitor visitor) { } else if (resource instanceof IClassFile) { visitor.visit((IClassFile) resource); } else if (resource instanceof IFile) { - visitor.visit((IFile) resource); + if (shouldVisit((IFile) resource)) { + visitor.visit((IFile) resource); + } } else if (resource instanceof IFolder) { - visitor.visit((IFolder) resource); + if (shouldVisit((IFolder) resource)) { + visitor.visit((IFolder) resource); + } } else if (resource instanceof IJarEntryResource) { visitor.visit((IJarEntryResource) resource); } } } + + /** + * Check if the IFolder or IFile should be visited. The following conditions will skip visit: + *
    + *
  • the resource is null.
  • + *
  • the resource does not belong to any project.
  • + *
  • the resource is not in the project's real location.
  • + *
  • the resource is a java element.
  • + *
+ */ + private boolean shouldVisit(IResource resource) { + if (resource == null) { + return false; + } + + IProject project = resource.getProject(); + if (project == null) { + return false; + } + + IPath projectRealFolder = ProjectUtils.getProjectRealFolder(project.getProject()); + IPath resourcePath = FileUtil.toPath(resource.getLocationURI()); + // check if the resource stores in the project's real location. + if (!projectRealFolder.isPrefixOf(resourcePath)) { + return false; + } + + // skip linked folder. + if (Objects.equals(projectRealFolder, resourcePath) && + Objects.equals(ProjectUtils.WORKSPACE_LINK, resource.getName())) { + return false; + } + + return JavaCore.create(resource) == null; + } } diff --git a/src/explorerCommands/rename.ts b/src/explorerCommands/rename.ts index 5d4af1b3..9246e7b8 100644 --- a/src/explorerCommands/rename.ts +++ b/src/explorerCommands/rename.ts @@ -71,6 +71,9 @@ function getValueSelection(uri: string): [number, number] | undefined { } function CheckQualifiedInputName(value: string, nodeKind: NodeKind): string { + if (nodeKind === NodeKind.Folder || nodeKind === NodeKind.File) { + return ""; + } const javaValidateMessage = checkJavaQualifiedName(value); if (javaValidateMessage) { diff --git a/src/syncHandler.ts b/src/syncHandler.ts index 6e91547d..031aa190 100644 --- a/src/syncHandler.ts +++ b/src/syncHandler.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import * as path from "path"; +import * as fse from "fs-extra"; import { commands, Disposable, FileSystemWatcher, RelativePattern, Uri, workspace } from "vscode"; import { instrumentOperation } from "vscode-extension-telemetry-wrapper"; import { Commands } from "./commands"; @@ -11,6 +12,7 @@ import { Settings } from "./settings"; import { DataNode } from "./views/dataNode"; import { ExplorerNode } from "./views/explorerNode"; import { explorerNodeCache } from "./views/nodeCache/explorerNodeCache"; +import { Jdtls } from "./java/jdtls"; const ENABLE_AUTO_REFRESH: string = "java.view.package.enableAutoRefresh"; const DISABLE_AUTO_REFRESH: string = "java.view.package.disableAutoRefresh"; @@ -47,14 +49,9 @@ class SyncHandler implements Disposable { })); try { - const result: IListCommandResult | undefined = await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, - Commands.JAVA_PROJECT_LIST_SOURCE_PATHS); - if (!result || !result.status || !result.data || result.data.length === 0) { - throw new Error("Failed to list the source paths"); - } - - for (const sourcePathData of result.data) { - const normalizedPath: string = Uri.file(sourcePathData.path).fsPath; + const uris = await this.getWatchingUris(); + for (const uri of uris) { + const normalizedPath: string = uri.fsPath; const pattern: RelativePattern = new RelativePattern(normalizedPath, "**/*"); const watcher: FileSystemWatcher = workspace.createFileSystemWatcher(pattern); this.disposables.push(watcher); @@ -67,9 +64,23 @@ class SyncHandler implements Disposable { } } + private async getWatchingUris(): Promise { + return (await Jdtls.getProjectUris()).map((uri) => Uri.parse(uri)); + // TODO: get source path uris if non-java resources are hidden + // const result: IListCommandResult | undefined = await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, + // Commands.JAVA_PROJECT_LIST_SOURCE_PATHS); + // if (!result || !result.status || !result.data || result.data.length === 0) { + // throw new Error("Failed to list the source paths"); + // } + + // for (const sourcePathData of result.data) { + // const normalizedPath: string = Uri.file(sourcePathData.path).fsPath; + // } + } + private setupWatchers(watcher: FileSystemWatcher): void { - this.disposables.push(watcher.onDidChange((uri: Uri) => { - if (path.extname(uri.fsPath) !== ".java" || !Settings.showMembers()) { + this.disposables.push(watcher.onDidChange(async (uri: Uri) => { + if (!await this.needRefresh(uri.fsPath)) { return; } const node: DataNode | undefined = explorerNodeCache.getDataNode(uri); @@ -86,6 +97,14 @@ class SyncHandler implements Disposable { } + private async needRefresh(fsPath: string): Promise { + if (Settings.showMembers() && path.extname(fsPath) === ".java") { + return true; + } + + return (await fse.lstat(fsPath)).isDirectory(); + } + private getParentNodeInExplorer(uri: Uri): ExplorerNode | undefined { let node: DataNode | undefined = explorerNodeCache.findBestMatchNodeByUri(uri); @@ -122,17 +141,17 @@ class SyncHandler implements Disposable { } } -interface ISourcePath { - path: string; - displayPath: string; - projectName: string; - projectType: string; -} - -interface IListCommandResult { - status: boolean; - message: string; - data?: ISourcePath[]; -} +// interface ISourcePath { +// path: string; +// displayPath: string; +// projectName: string; +// projectType: string; +// } + +// interface IListCommandResult { +// status: boolean; +// message: string; +// data?: ISourcePath[]; +// } export const syncHandler: SyncHandler = new SyncHandler(); diff --git a/src/views/projectNode.ts b/src/views/projectNode.ts index d4b2b79b..a19ace6d 100644 --- a/src/views/projectNode.ts +++ b/src/views/projectNode.ts @@ -3,7 +3,6 @@ import { ThemeIcon, Uri, workspace } from "vscode"; import { Explorer } from "../constants"; -import { ContainerEntryKind, IContainerNodeData } from "../java/containerNodeData"; import { HierarchicalPackageNodeData } from "../java/hierarchicalPackageNodeData"; import { Jdtls } from "../java/jdtls"; import { INodeData, NodeKind } from "../java/nodeData"; @@ -60,27 +59,7 @@ export class ProjectNode extends DataNode { } protected async loadData(): Promise { - let result: INodeData[] = []; - return Jdtls.getPackageData({ kind: NodeKind.Project, projectUri: this.nodeData.uri }).then((res) => { - const sourceContainer: IContainerNodeData[] = []; - res.forEach((node) => { - const containerNode = node; - if (containerNode.entryKind === ContainerEntryKind.CPE_SOURCE) { - sourceContainer.push(containerNode); - } else { - result.push(node); - } - }); - if (sourceContainer.length > 0) { - return Promise.all(sourceContainer.map((c) => Jdtls.getPackageData({ kind: NodeKind.Container, projectUri: this.uri, path: c.path }))) - .then((rootPackages) => { - result = result.concat(...rootPackages); - return result; - }); - } else { - return result; - } - }); + return Jdtls.getPackageData({ kind: NodeKind.Project, projectUri: this.nodeData.uri }); } protected createChildNodeList(): ExplorerNode[] { diff --git a/test/gradle-suite/projectView.test.ts b/test/gradle-suite/projectView.test.ts index 48fecf0d..ec5a045d 100644 --- a/test/gradle-suite/projectView.test.ts +++ b/test/gradle-suite/projectView.test.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import * as assert from "assert"; -import { ContainerNode, contextManager, DependencyExplorer, +import { ContainerNode, contextManager, DataNode, DependencyExplorer, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle"; import { fsPath, setupTestEnv, Uris } from "../shared"; @@ -21,12 +21,13 @@ suite("Gradle Project View Tests", () => { assert.equal(projectNode.name, "gradle", "Project name should be \"gradle\""); // validate package root/dependency nodes - const packageRoots = await projectNode.getChildren(); - assert.equal(packageRoots.length, 3, "Number of root packages should be 3"); - const mainPackage = packageRoots[0] as PackageRootNode; + const projectChildren = await projectNode.getChildren(); + assert.ok(!!projectChildren.find((c: DataNode) => c.name === "build.gradle")); + assert.ok(!!projectChildren.find((c: DataNode) => c.name === ".vscode")); + const mainPackage = projectChildren[0] as PackageRootNode; assert.equal(mainPackage.name, "src/main/java", "Package name should be \"src/main/java\""); - const systemLibrary = packageRoots[1] as ContainerNode; - const gradleDependency = packageRoots[2] as ContainerNode; + const systemLibrary = projectChildren[1] as ContainerNode; + const gradleDependency = projectChildren[2] as ContainerNode; // only match prefix of system library since JDK version may differ assert.ok(systemLibrary.name.startsWith("JRE System Library"), "Container name should start with JRE System Library"); assert.equal(gradleDependency.name, "Project and External Dependencies", "Container name should be \"Project and External Dependencies\""); diff --git a/test/maven-suite/projectView.test.ts b/test/maven-suite/projectView.test.ts index 21071310..ae73ccd0 100644 --- a/test/maven-suite/projectView.test.ts +++ b/test/maven-suite/projectView.test.ts @@ -5,7 +5,7 @@ import * as assert from "assert"; import * as clipboardy from "clipboardy"; import * as path from "path"; import * as vscode from "vscode"; -import { Commands, ContainerNode, contextManager, DependencyExplorer, IMainClassInfo, +import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode, IMainClassInfo, INodeData, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle"; import { fsPath, setupTestEnv, Uris } from "../shared"; import { sleep } from "../util"; @@ -26,9 +26,11 @@ suite("Maven Project View Tests", () => { const projectNode = roots![0] as ProjectNode; assert.equal(projectNode.name, "my-app", "Project name should be \"my-app\""); - const packageRoots = await projectNode.getChildren(); - assert.equal(packageRoots.length, 4, "Number of root packages should be 4"); - const mainPackage = packageRoots[0] as PackageRootNode; + const projectChildren = await projectNode.getChildren(); + assert.ok(!!projectChildren.find((c: DataNode) => c.name === "pom.xml")); + assert.ok(!!projectChildren.find((c: DataNode) => c.name === ".vscode")); + assert.equal(projectChildren.length, 8, "Number of children should be 8"); + const mainPackage = projectChildren[0] as PackageRootNode; assert.equal(mainPackage.name, "src/main/java", "Package name should be \"src/main/java\""); const primarySubPackages = await mainPackage.getChildren(); @@ -69,14 +71,15 @@ suite("Maven Project View Tests", () => { assert.ok(projectTreeItem.resourceUri !== undefined, "Project tree item should have resourceUri"); // validate package root/dependency nodes - const packageRoots = await projectNode.getChildren(); - assert.equal(packageRoots.length, 4, "Number of root packages should be 4"); - const mainPackage = packageRoots[0] as PackageRootNode; - const testPackage = packageRoots[1] as PackageRootNode; + const projectChildren = await projectNode.getChildren(); + assert.ok(!!projectChildren.find((c: DataNode) => c.name === "pom.xml")); + assert.ok(!!projectChildren.find((c: DataNode) => c.name === ".vscode")); + const mainPackage = projectChildren[0] as PackageRootNode; + const testPackage = projectChildren[1] as PackageRootNode; assert.equal(mainPackage.name, "src/main/java", "Package name should be \"src/main/java\""); assert.equal(testPackage.name, "src/test/java", "Package name should be \"src/test/java\""); - const systemLibrary = packageRoots[2] as ContainerNode; - const mavenDependency = packageRoots[3] as ContainerNode; + const systemLibrary = projectChildren[2] as ContainerNode; + const mavenDependency = projectChildren[3] as ContainerNode; // only match prefix of system library since JDK version may differ assert.ok(systemLibrary.name.startsWith("JRE System Library"), "Container name should start with JRE System Library"); assert.equal(mavenDependency.name, "Maven Dependencies", "Container name should be \"Maven Dependencies\""); @@ -202,14 +205,13 @@ suite("Maven Project View Tests", () => { const explorer = DependencyExplorer.getInstance(contextManager.context); const projectNode = (await explorer.dataProvider.getChildren())![0] as ProjectNode; - const packageRoots = await projectNode.getChildren(); - const mainPackage = packageRoots[0] as PackageRootNode; + const projectChildren = await projectNode.getChildren(); + const fileNode = projectChildren.find((node: DataNode) => node.nodeData.name === "pom.xml") as FileNode; const paths = await vscode.commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, - Commands.JAVA_RESOLVEPATH, mainPackage.nodeData.uri); - assert.equal(paths?.length, 3, "paths' length should be 3"); - assert.equal(paths![0].name, "src", "path[0]'s name should be src"); - assert.equal(paths![1].name, "main", "path[1]'s name should be main"); - assert.equal(paths![2].name, "java", "path[2]'s name should be java"); + Commands.JAVA_RESOLVEPATH, fileNode.nodeData.uri); + assert.equal(paths?.length, 2, "paths' length should be 2"); + assert.equal(paths![0].name, projectNode.name); + assert.equal(paths![1].name, fileNode.name); }); test("Can execute command java.project.getMainClasses correctly", async function() { diff --git a/test/simple-suite/projectView.test.ts b/test/simple-suite/projectView.test.ts index ccced02e..862b28d4 100644 --- a/test/simple-suite/projectView.test.ts +++ b/test/simple-suite/projectView.test.ts @@ -21,11 +21,11 @@ suite("Simple Project View Tests", () => { assert.equal(projectNode.name, "1.helloworld", "Project name should be \"1.helloworld\""); // validate package root/dependency nodes - const packageRoots = await projectNode.getChildren(); - assert.equal(packageRoots.length, 2, "Number of root packages should be 2"); - const mainPackage = packageRoots[0] as PackageRootNode; + const projectChildren = await projectNode.getChildren(); + assert.equal(projectChildren.length, 6, "Number of children nodes should be 6"); + const mainPackage = projectChildren[0] as PackageRootNode; assert.equal(mainPackage.name, "src/main/java", "Package name should be \"src/main/java\""); - const systemLibrary = packageRoots[1] as ContainerNode; + const systemLibrary = projectChildren[1] as ContainerNode; // only match prefix of system library since JDK version may differ assert.ok(systemLibrary.name.startsWith("JRE System Library"), "Container name should start with JRE System Library"); From f39bb4dde198809a8f248d45fbbce2021604aa0e Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Mon, 10 Apr 2023 12:24:57 +0800 Subject: [PATCH 2/2] Address comments --- CHANGELOG.md | 1 + .../src/com/microsoft/jdtls/ext/core/PackageCommand.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83ab0235..ce7e306f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## 0.22.0 ### Added +- Display non-Java files in Java Projects explorer. [#145](https://github.com/microsoft/vscode-java-dependency/issues/145) - Apply file decorators to project level. [#481](https://github.com/microsoft/vscode-java-dependency/issues/481) ## 0.21.2 diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java index b2e96a49..f91eb429 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/PackageCommand.java @@ -320,7 +320,6 @@ private static List getContainerChildren(PackageParams query, IProg for (IPackageFragmentRoot fragmentRoot : packageFragmentRoots) { children.add(fragmentRoot); - children.addAll(Arrays.asList(fragmentRoot.getNonJavaResources())); } } } catch (CoreException e) {