feat: Show non Java Projects in the Java Projects explorer (#744)

* feat: Show non Java Projects in the Java Projects explorer
---------

Signed-off-by: Sheng Chen <sheche@microsoft.com>
This commit is contained in:
Sheng Chen 2023-04-12 16:03:25 +08:00 коммит произвёл GitHub
Родитель 169e166424
Коммит e5565db7f0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 75 добавлений и 40 удалений

Просмотреть файл

@ -7,10 +7,10 @@ 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)
- Show non Java Projects in the Java Projects explorer. [#736](https://github.com/microsoft/vscode-java-dependency/issues/736)
- Support creating files and folders in Java Projects explorer. [#598](https://github.com/microsoft/vscode-java-dependency/issues/598)
- Apply file decorators to project level. [#481](https://github.com/microsoft/vscode-java-dependency/issues/481)
- Give more hints about the project import status. [#580](https://github.com/microsoft/vscode-java-dependency/issues/580)
- Support creating files and folders in Java Projects explorer. [#598](https://github.com/microsoft/vscode-java-dependency/issues/598)
### Fixed
- Apply `files.exclude` to Java Projects explorer. [#214](https://github.com/microsoft/vscode-java-dependency/issues/214)

Просмотреть файл

@ -28,3 +28,6 @@ export { languageServerApiManager } from "./src/languageServerApi/languageServer
// tasks
export { BuildTaskProvider, categorizePaths, getFinalPaths } from "./src/tasks/build/buildTaskProvider";
// delegate commands
export { Jdtls } from "./src/java/jdtls";

Просмотреть файл

@ -19,6 +19,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
@ -31,6 +32,7 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
@ -257,18 +259,22 @@ public class PackageCommand {
* Get the class path container list.
*/
private static List<PackageNode> getProjectChildren(PackageParams query, IProgressMonitor pm) {
IJavaProject javaProject = getJavaProject(query.getProjectUri());
if (javaProject != null) {
refreshLocal(javaProject.getProject(), pm);
List<Object> children = new LinkedList<>();
boolean hasReferencedLibraries = false;
try {
IProject project = getProject(query.getProjectUri());
if (project == null) {
JdtlsExtActivator.logError("Failed to find project at: " + query.getProjectUri());
}
List<Object> children = new LinkedList<>();
boolean hasReferencedLibraries = false;
IJavaProject javaProject = JavaCore.create(project);
try {
if (ProjectUtils.isJavaProject(project) && javaProject != null) {
refreshLocal(javaProject.getProject(), pm);
IClasspathEntry[] references = javaProject.getRawClasspath();
for (IClasspathEntry entry : references) {
int entryKind = entry.getEntryKind();
if (entryKind == IClasspathEntry.CPE_SOURCE) {
IPackageFragmentRoot[] packageFragmentRoots = javaProject.findPackageFragmentRoots(entry);
children.addAll(Arrays.asList(packageFragmentRoots));
Collections.addAll(children, javaProject.findPackageFragmentRoots(entry));
} else if (entryKind == IClasspathEntry.CPE_CONTAINER) {
children.add(entry);
} else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
@ -278,24 +284,32 @@ public class PackageCommand {
}
}
Collections.addAll(children, javaProject.getNonJavaResources());
} catch (CoreException e) {
JdtlsExtActivator.logException("Problem load project library ", e);
} else {
Set<IPath> projectPaths = Arrays.stream(ProjectUtils.getAllProjects())
.map(IProject::getLocation).collect(Collectors.toSet());
IResource[] members = project.members();
for (IResource member : members) {
if (!projectPaths.contains(member.getLocation())) {
children.add(member);
}
}
}
ResourceSet resourceSet = new ResourceSet(children);
ResourceVisitor visitor = new JavaResourceVisitor(javaProject);
resourceSet.accept(visitor);
List<PackageNode> result = visitor.getNodes();
// Invisible project will always have the referenced libraries entry
if (!ProjectUtils.isVisibleProject(javaProject.getProject())) {
result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER);
} else if (hasReferencedLibraries) {
result.add(PackageNode.IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER);
}
return result;
} catch (CoreException e) {
JdtlsExtActivator.logException("Problem load project library ", e);
}
return Collections.emptyList();
ResourceSet resourceSet = new ResourceSet(children);
ResourceVisitor visitor = new JavaResourceVisitor(javaProject);
resourceSet.accept(visitor);
List<PackageNode> result = visitor.getNodes();
// Invisible project will always have the referenced libraries entry
if (!ProjectUtils.isVisibleProject(project)) {
result.add(PackageNode.REFERENCED_LIBRARIES_CONTAINER);
} else if (hasReferencedLibraries) {
result.add(PackageNode.IMMUTABLE_REFERENCED_LIBRARIES_CONTAINER);
}
return result;
}
private static List<PackageNode> getContainerChildren(PackageParams query, IProgressMonitor pm) {
@ -567,7 +581,7 @@ public class PackageCommand {
return null;
}
public static IJavaProject getJavaProject(String projectUri) {
public static IProject getProject(String projectUri) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IContainer[] containers = root.findContainersForLocationURI(JDTUtils.toURI(projectUri));
@ -576,8 +590,7 @@ public class PackageCommand {
}
// For multi-module scenario, findContainersForLocationURI API may return a container array,
// need filter out non-Java project and put the result from the nearest project in front.
containers = Arrays.stream(containers).filter(c -> ProjectUtils.isJavaProject(c.getProject())).toArray(IContainer[]::new);
// put the result from the nearest project in front.
Arrays.sort(containers, (Comparator<IContainer>) (IContainer a, IContainer b) -> {
return a.getFullPath().toPortableString().length() - b.getFullPath().toPortableString().length();
});
@ -587,11 +600,16 @@ public class PackageCommand {
if (!project.exists()) {
return null;
}
return JavaCore.create(project);
return project;
}
return null;
}
public static IJavaProject getJavaProject(String projectUri) {
IProject project = getProject(projectUri);
return JavaCore.create(project);
}
private static void refreshLocal(IResource resource, IProgressMonitor monitor) {
if (resource == null || !resource.exists()) {
return;

Просмотреть файл

@ -18,6 +18,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@ -98,10 +99,20 @@ public final class ProjectCommand {
String workspaceUri = (String) arguments.get(0);
IPath workspaceFolderPath = ResourceUtils.canonicalFilePathFromURI(workspaceUri);
IJavaProject[] javaProjects = ProjectUtils.getJavaProjects();
IProject[] projects;
boolean includeNonJava = false;
if (arguments.size() > 1) {
includeNonJava = (boolean) arguments.get(1);
}
if (includeNonJava) {
projects = ProjectUtils.getAllProjects();
} else {
projects = Arrays.stream(ProjectUtils.getJavaProjects())
.map(IJavaProject::getProject).toArray(IProject[]::new);
}
ArrayList<PackageNode> children = new ArrayList<>();
for (IJavaProject javaProject : javaProjects) {
IProject project = javaProject.getProject();
for (IProject project : projects) {
if (!project.isAccessible() || project.getLocation() == null) {
continue;
}

Просмотреть файл

@ -11,7 +11,12 @@ import { INodeData } from "./nodeData";
export namespace Jdtls {
export async function getProjects(params: string): Promise<INodeData[]> {
return await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.JAVA_PROJECT_LIST, params) || [];
return await commands.executeCommand(
Commands.EXECUTE_WORKSPACE_COMMAND,
Commands.JAVA_PROJECT_LIST,
params,
true /*includeNonJavaProjects*/
) || [];
}
export async function getProjectUris(): Promise<string[]> {

Просмотреть файл

@ -5,8 +5,8 @@ import * as assert from "assert";
import * as clipboardy from "clipboardy";
import * as path from "path";
import * as vscode from "vscode";
import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode, IMainClassInfo,
INodeData, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle";
import { Commands, ContainerNode, contextManager, DataNode, DependencyExplorer, FileNode,
INodeData, Jdtls, NodeKind, PackageNode, PackageRootNode, PrimaryTypeNode, ProjectNode } from "../../extension.bundle";
import { fsPath, setupTestEnv, Uris } from "../shared";
import { sleep } from "../util";
@ -175,8 +175,7 @@ suite("Maven Project View Tests", () => {
test("Can execute command java.project.list correctly", async function() {
const workspaceFolders = vscode.workspace.workspaceFolders;
assert.ok(workspaceFolders, `There should be valid workspace folders`);
const projects = await vscode.commands.executeCommand<INodeData[]>(Commands.EXECUTE_WORKSPACE_COMMAND,
Commands.JAVA_PROJECT_LIST, workspaceFolders![0].uri.toString());
const projects = await Jdtls.getProjects(workspaceFolders![0].uri.toString());
assert.equal(projects?.length, 1, "project's length should be 1");
assert.equal(projects![0].name, "my-app", "project should be my-app");
});
@ -217,8 +216,7 @@ suite("Maven Project View Tests", () => {
test("Can execute command java.project.getMainClasses correctly", async function() {
const workspaceFolders = vscode.workspace.workspaceFolders;
assert.ok(workspaceFolders, `There should be valid workspace folders`);
const mainClasses = await vscode.commands.executeCommand<IMainClassInfo[]>(Commands.EXECUTE_WORKSPACE_COMMAND,
Commands.JAVA_PROJECT_GETMAINCLASSES, workspaceFolders![0].uri.toString());
const mainClasses = await Jdtls.getMainClasses(workspaceFolders![0].uri.toString());
assert.equal(mainClasses?.length, 1, "mainClasses' length should be 1");
assert.equal(mainClasses![0].name, "com.mycompany.app.App", "mainClasses[0]'s name should be com.mycompany.app.App");
});