дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
fix(editor): describe a Java file outside every project accurately
jdtls still completes and navigates JDK classes in a non-project file such as a scratch; it only skips semantic checks and project classes. The banner said navigation and completion don't work, and in a Maven or Gradle project it offered a build reload that can't bring a file outside the project in. - The banner now says only syntax errors are reported and only JDK classes resolve. - The Maven / Gradle reload is offered only for files inside the open project (or one of its workspace projects).
Цей коміт міститься в:
1 джерело
7fd330912a
коміт
52360c72d2
5 files changed
+75
-13
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { expect, it } from "vitest";
|
||||
import { afterEach, expect, it } from "vitest";
|
||||
import { useProject } from "@/platform/project";
|
||||
import { outsideProjectNotice } from "./outsideProject";
|
||||
|
||||
const text = (message: string) => outsideProjectNotice(message)?.text ?? null;
|
||||
@@ -36,7 +37,22 @@ it("recognizes each server's report that a file is outside its projects", () =>
|
||||
expect(outsideProjectNotice("No packages found for open file x.go.")?.reload).toBeFalsy();
|
||||
});
|
||||
|
||||
afterEach(() => useProject.setState({ project: null }));
|
||||
|
||||
const openProject = (root: string, projects?: string[]) =>
|
||||
useProject.setState({
|
||||
project: {
|
||||
root,
|
||||
name: "p",
|
||||
trusted: true,
|
||||
isGit: false,
|
||||
settings: {},
|
||||
...(projects && { workspace: { version: 1, name: "p", projects } }),
|
||||
},
|
||||
});
|
||||
|
||||
it("shows a banner while the server reports the file, with the build reloads available", async () => {
|
||||
openProject("/p");
|
||||
const { renderHook, act } = await import("@testing-library/react");
|
||||
const { setFileDiagnostics } = await import("./diagnostics");
|
||||
const { registerActions } = await import("@/platform/actions");
|
||||
@@ -64,3 +80,39 @@ it("shows a banner while the server reports the file, with the build reloads ava
|
||||
setFileDiagnostics(path, "jdtls", []);
|
||||
}
|
||||
});
|
||||
|
||||
it("offers a build reload only for files of the open project", async () => {
|
||||
const { renderHook, act } = await import("@testing-library/react");
|
||||
const { setFileDiagnostics } = await import("./diagnostics");
|
||||
const { registerActions } = await import("@/platform/actions");
|
||||
const { outsideProjectBanner } = await import("./outsideProject");
|
||||
const off = registerActions([{ id: "maven.reload", title: "Reload All Maven Projects", run: () => {} }]);
|
||||
openProject("/ws", ["/p"]);
|
||||
// A scratch lives in the app data dir; a module the import missed lives in the project.
|
||||
const cases: [string, string[]][] = [
|
||||
["/data/scratches/scratch.java", []],
|
||||
["/p/tools/Gen.java", ["Reload Maven Projects"]],
|
||||
["/ws/Gen.java", ["Reload Maven Projects"]],
|
||||
];
|
||||
try {
|
||||
for (const [path, labels] of cases) {
|
||||
const { result } = renderHook(() => outsideProjectBanner.useBanner(path));
|
||||
const warning = {
|
||||
range: { start: { line: 0, col: 0 }, end: { line: 0, col: 1 } },
|
||||
severity: "warning" as const,
|
||||
message: `${path.split("/").pop()} is a non-project file, only syntax errors are reported`,
|
||||
source: "Java",
|
||||
code: "32",
|
||||
};
|
||||
act(() => setFileDiagnostics(path, "jdtls", [warning]));
|
||||
expect(result.current?.text, path).toMatch(/only JDK classes resolve/);
|
||||
expect(
|
||||
result.current?.actions?.map((a) => a.label),
|
||||
path,
|
||||
).toEqual(labels);
|
||||
act(() => setFileDiagnostics(path, "jdtls", []));
|
||||
}
|
||||
} finally {
|
||||
off();
|
||||
}
|
||||
});
|
||||
@@ -6,10 +6,15 @@
|
||||
*/
|
||||
import { useSyncExternalStore } from "react";
|
||||
import { executeAction, getAction, isActionEnabled } from "@/platform/actions";
|
||||
import { isSameOrInside } from "@/platform/paths";
|
||||
import { useProject } from "@/platform/project";
|
||||
import type { EditorBannerContribution } from "@/workbench/contributions";
|
||||
import { diagnosticsFor, subscribeDiagnostics } from "./diagnostics";
|
||||
|
||||
/** `reload`: a build reload may bring the file into a project (a module the import missed). */
|
||||
/**
|
||||
* `reload`: a build reload may bring the file into a project (a module the import missed); offered
|
||||
* only for files inside the open project.
|
||||
*/
|
||||
const NOTICES: readonly { test: RegExp; text: string; reload?: boolean }[] = [
|
||||
// jdtls: "Foo.java is not on the classpath of project app, only syntax errors are reported"
|
||||
{
|
||||
@@ -17,10 +22,11 @@ const NOTICES: readonly { test: RegExp; text: string; reload?: boolean }[] = [
|
||||
text: "This file is outside the source folders of its Java module: only syntax errors are reported, and navigation and completion don't work.",
|
||||
reload: true,
|
||||
},
|
||||
// jdtls: "Foo.java is a non-project file, only syntax errors are reported"
|
||||
// jdtls: "Foo.java is a non-project file, only syntax errors are reported". jdtls still completes
|
||||
// and navigates JDK classes in such a file (a scratch, a file opened from outside the project).
|
||||
{
|
||||
test: /is a non-project file, only syntax errors are reported/,
|
||||
text: "This file does not belong to an imported Java project: only syntax errors are reported, and navigation and completion don't work.",
|
||||
text: "This file does not belong to an imported Java project: only syntax errors are reported, and only JDK classes resolve.",
|
||||
reload: true,
|
||||
},
|
||||
// gopls, before its generic "No packages found" below.
|
||||
@@ -73,13 +79,17 @@ export const outsideProjectBanner: EditorBannerContribution = {
|
||||
(l) => subscribeDiagnostics(path, l),
|
||||
() => noticeFor(path),
|
||||
);
|
||||
const inProject = useProject(({ project }) =>
|
||||
[project?.root, ...(project?.workspace?.projects ?? [])].some((root) => !!root && isSameOrInside(path, root)),
|
||||
);
|
||||
if (!notice) return null;
|
||||
const actions = notice.reload
|
||||
? RELOADS.filter(({ id }) => {
|
||||
const action = getAction(id);
|
||||
return action && isActionEnabled(action);
|
||||
}).map(({ id, label }) => ({ label, run: () => void executeAction(id) }))
|
||||
: [];
|
||||
const actions =
|
||||
notice.reload && inProject
|
||||
? RELOADS.filter(({ id }) => {
|
||||
const action = getAction(id);
|
||||
return action && isActionEnabled(action);
|
||||
}).map(({ id, label }) => ({ label, run: () => void executeAction(id) }))
|
||||
: [];
|
||||
return { text: notice.text, level: "warning", actions };
|
||||
},
|
||||
};
|
||||
@@ -5494,7 +5494,7 @@
|
||||
"oxfmt formatting failed": "Échec du formatage avec oxfmt",
|
||||
"oxfmt formatting timed out": "Le formatage avec oxfmt a expiré",
|
||||
"This file is outside the source folders of its Java module: only syntax errors are reported, and navigation and completion don't work.": "Ce fichier est en dehors des dossiers sources de son module Java : seules les erreurs de syntaxe sont signalées, et la navigation et la complétion ne fonctionnent pas.",
|
||||
"This file does not belong to an imported Java project: only syntax errors are reported, and navigation and completion don't work.": "Ce fichier n'appartient à aucun projet Java importé : seules les erreurs de syntaxe sont signalées, et la navigation et la complétion ne fonctionnent pas.",
|
||||
"This file does not belong to an imported Java project: only syntax errors are reported, and only JDK classes resolve.": "Ce fichier n'appartient à aucun projet Java importé : seules les erreurs de syntaxe sont signalées, et seules les classes du JDK sont résolues.",
|
||||
"This Go file belongs to no package of the workspace: code insight is limited.": "Ce fichier Go n'appartient à aucun paquet de l'espace de travail : l'analyse du code est limitée.",
|
||||
"This Rust file is not included in any crate: rust-analyzer can't offer code insight for it.": "Ce fichier Rust n'est inclus dans aucune crate : rust-analyzer ne peut pas proposer d'analyse du code pour celui-ci.",
|
||||
"Reload Maven Projects": "Recharger les projets Maven",
|
||||
|
||||
@@ -5627,7 +5627,7 @@
|
||||
"Java project import failed": "Java 프로젝트 가져오기 실패",
|
||||
"The Java project cannot be imported because these files use a name Windows reserves for devices: {paths}. Delete or rename them, then restart the Java language server.": "다음 파일이 Windows에서 장치용으로 예약된 이름을 사용하므로 Java 프로젝트를 가져올 수 없습니다: {paths}. 파일을 삭제하거나 이름을 변경한 후 Java 언어 서버를 다시 시작하세요.",
|
||||
"This file is outside the source folders of its Java module: only syntax errors are reported, and navigation and completion don't work.": "이 파일은 해당 Java 모듈의 소스 폴더 밖에 있습니다. 구문 오류만 보고되며 탐색과 코드 완성이 작동하지 않습니다.",
|
||||
"This file does not belong to an imported Java project: only syntax errors are reported, and navigation and completion don't work.": "이 파일은 가져온 Java 프로젝트에 속하지 않습니다. 구문 오류만 보고되며 탐색과 코드 완성이 작동하지 않습니다.",
|
||||
"This file does not belong to an imported Java project: only syntax errors are reported, and only JDK classes resolve.": "이 파일은 가져온 Java 프로젝트에 속하지 않습니다. 구문 오류만 보고되며 JDK 클래스만 확인됩니다.",
|
||||
"This Go file belongs to no package of the workspace: code insight is limited.": "이 Go 파일은 작업 공간의 어떤 패키지에도 속하지 않습니다. 코드 인사이트가 제한됩니다.",
|
||||
"This Rust file is not included in any crate: rust-analyzer can't offer code insight for it.": "이 Rust 파일은 어떤 crate에도 포함되어 있지 않습니다. rust-analyzer가 코드 인사이트를 제공할 수 없습니다.",
|
||||
"Reload Maven Projects": "Maven 프로젝트 다시 로드",
|
||||
|
||||
@@ -5655,7 +5655,7 @@
|
||||
"Java project import failed": "Java 项目导入失败",
|
||||
"The Java project cannot be imported because these files use a name Windows reserves for devices: {paths}. Delete or rename them, then restart the Java language server.": "无法导入 Java 项目,因为这些文件使用了 Windows 保留的设备名:{paths}。请删除或重命名这些文件,然后重启 Java 语言服务器。",
|
||||
"This file is outside the source folders of its Java module: only syntax errors are reported, and navigation and completion don't work.": "此文件不在所属 Java 模块的源码目录中:只报告语法错误,跳转和补全不可用。",
|
||||
"This file does not belong to an imported Java project: only syntax errors are reported, and navigation and completion don't work.": "此文件不属于已导入的 Java 项目:只报告语法错误,跳转和补全不可用。",
|
||||
"This file does not belong to an imported Java project: only syntax errors are reported, and only JDK classes resolve.": "此文件不属于已导入的 Java 项目:只报告语法错误,只能解析 JDK 中的类。",
|
||||
"This Go file belongs to no package of the workspace: code insight is limited.": "此 Go 文件不属于工作区中的任何包:代码洞察功能受限。",
|
||||
"This Rust file is not included in any crate: rust-analyzer can't offer code insight for it.": "此 Rust 文件未包含在任何 crate 中:rust-analyzer 无法为它提供代码洞察。",
|
||||
"Reload Maven Projects": "重新加载 Maven 项目",
|
||||
|
||||
Reference in new issue
Заблокувати користувача