feat(ide): IntelliJ-style Java authoring — New → Java scaffolding + full Monaco Java IntelliSense#6076
feat(ide): IntelliJ-style Java authoring — New → Java scaffolding + full Monaco Java IntelliSense#6076iliyan-velichkov wants to merge 9 commits into
Conversation
…ull Monaco Java IntelliSense Make writing client Java in the browser IDE feel like IntelliJ. New → Java submenu (Projects view): - Package (creates the nested folder chain from a dotted name) - Class, Interface, Enum, Annotation, Record, Exception - Controller, Job, Listener, WebSocket, Repository — strong-interface skeletons A fully-qualified name (com.test.MyClass) creates the package folders and the matching package declaration; a simple name lands in the selected folder. Logic lives in a new pure helper js/java-new.js; projects.js orchestrates dialog → nested folder → file → open via the existing WorkspaceService. Java IntelliSense (editor-monaco LSP client): - Auto-import on completion (completionItem/resolve → additionalTextEdits) - Dirigible SDK suggestions ranked first (sortText bucketing) - Code actions: quick-fixes, organize imports, and generate constructor/getters/setters/toString/equals&hashCode with a member-picker dialog - Rename symbol, find references, document formatting - Server→client workspace/applyEdit + configuration handling - Format-on-save for Java reuses the existing TypeScript auto-format mechanism via the new formatting provider (same global toggle) Tests: - CreateJavaArtifactsIT drives New → Java end to end and asserts folders, files, package declarations and skeleton signals over the workspace REST API - Browser.hoverOnElementByAttributePatternAndText + Workbench.createJavaArtifact Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…avaArtifactsIT pass
JDT.LS was launched with -Xmx512m, which OOMs ("Java heap space") while indexing
the full platform classpath (~1000+ entries), killing the language server and with
it completion / auto-import / code actions. Make the max heap configurable via
DIRIGIBLE_JAVA_LSP_MAX_HEAP (DirigibleConfig.JAVA_LSP_MAX_HEAP) and default it to 2g.
Test framework: CreateJavaArtifactsIT now drives the nested New → Java → <item>
context menu reliably. Replaced the strict hover/visibility approach (which cannot
reach a collapsed 3rd-level submenu in headless Chrome, where moveToElement does not
fire mouseenter) with Browser.clickCascadingMenuItem, which scopes to the open
context menu and drives its own Angular mouseenter/click handlers in a single
in-frame script. Verified: the IT passes end to end (package folders, package
declarations and strong-interface skeleton signals all asserted over the workspace
REST API).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up while testing locallyJDT.LS heap fix. JDT.LS launched with Integration test now green. |
…ntity is an input - After creating a Java artefact the project tree now expands to and selects the new file (building/reusing the package folder nodes) instead of reloading the project node, which collapsed the structure. - The Repository skeleton no longer reuses the repository class name as its entity type parameter (DemoRepo → JavaRepository<DemoRepo>). The dialog now prompts for the entity type (simple or fully-qualified; a qualified name adds the import), producing e.g. JavaRepository<Country> with super(Country.class). - CreateJavaArtifactsIT + Workbench.createJavaArtifact updated for the entity prompt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mpletion - Completion now propagates JDT.LS's isIncomplete so Monaco re-queries as you type (fixes the first Ctrl+Space showing nothing), and forwards the real trigger kind/character plus filterText/preselect/commitCharacters for correct filtering. - Registered a Monaco editor opener: Go to Definition / Find References to a symbol in another workspace file now opens that file in the IDE and reveals the line (the single-file editor previously had no model for other files, so navigation silently did nothing). Same-file targets still jump within the editor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… file Renaming a Java symbol (F2) now applies JDT.LS's full rename WorkspaceEdit across the whole workspace instead of only the current file: - Text edits in every referencing file are applied and persisted (read-modify-write over the workspace REST API, CSRF-guarded); the current file goes through the live Monaco model + save. - RenameFile operations are honoured, so renaming a public class/interface/enum also renames its .java file and updates all references; when that file is the one being edited, the editor tab switches to the new file. - Other open editors reload the changed files (dirty editors are skipped to avoid clobbering unsaved work) via a new monaco.file.reload topic. Falls back to current-file-only rename if the IDE persistence hook is unavailable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s, semantic colors, CodeLens, override/implement, keywords Adds JDT.LS-backed language features to the Monaco Java editor: Navigation & structure: - Outline / breadcrumbs / sticky scroll (documentSymbol), code folding (foldingRange), occurrence highlight (documentHighlight), Go to Implementation and Go to Type Definition (reusing the cross-file editor opener), Format Selection (rangeFormatting) and Smart Expand Selection (selectionRange). Editor intelligence: - Inlay hints (parameter names + inferred types) and semantic-token highlighting (legend captured from the initialize result; semanticHighlighting enabled on the editor). - CodeLens with "N references / N implementations" (click opens the peek). - Override/Implement Methods wired into the existing member-picker generate flow. - Always-available Java keyword completion, ranked below SDK/LSP results. Advertises the matching client capabilities and enables the JDT.LS inlay-hint and references/implementations CodeLens settings. All are additive providers; the exact JDT.LS command ids are guarded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…yword colors - Find/Peek References (and go-to-definition/implementation/type-definition) now create in-memory models for the referenced files, so the peek shows a real code preview instead of only file/line/column. - Flush the pending debounced didChange before a completion request, so JDT.LS sees the just-typed text on the first Ctrl+Space (previously the first invocation completed against stale content and only the second worked). - Revert the forced semanticHighlighting flag: JDT.LS emits keyword/modifier semantic tokens the vs-dark-based themes don't style, which left Java keywords uncolored. The semantic-tokens provider stays registered (inert until a theme opts in) so basic Monarch keyword coloring is restored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e after rename Root cause of "no quick-fixes / no Implement Methods / Generate toString does nothing": - We advertised the *PromptSupport extended capabilities, so JDT.LS returned source actions (generate toString/constructors/accessors, override/implement, organize imports) as client-side "java.action.*Prompt" commands that the vscode-java extension implements but we don't — and the server commands we tried to call (checkToStringStatus/generateToString/…) don't exist on JDT.LS. Dropping those flags makes JDT.LS return the same actions as resolvable WorkspaceEdits (all members), which applyCodeAction resolves and applies directly. - Code-action requests sent diagnostics reconstructed from Monaco markers, which lose the LSP code/data JDT.LS matches quick-fixes against. We now keep the original published diagnostics per file and send the ones overlapping the request range, so "Add unimplemented methods", "Create field", etc. appear. Also: the Projects view ignored file rename/move events, so after a class rename the tree still showed the old file. It now reloads on platform.files.renamed/moved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n completion) Renaming a public type (F2) had two defects: - When JDT.LS ordered the RenameFile before the text edit, the edit was keyed by the new URI; we wrote the old content (old type name) into the new file, producing "The public type X must be defined in its own file". Edits are now re-attributed to the on-disk (old) URI before applying, so the new file gets the new type name. - After renaming on disk we never told JDT.LS, so it kept validating stale state until a page refresh and kept suggesting the old type name in completion. We now send textDocument/didClose for the renamed-away file and workspace/didChangeWatchedFiles (Deleted old / Created new / Changed edited) so the server re-indexes immediately — clearing the stale diagnostic and dropping the old name from completion. This also removes the exception/fallback path that made the first Enter occasionally apply only the in-editor edit without renaming the file. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What & why
Authoring client Java in the browser IDE is currently bare: the only Java entry in the workbench New menu is a single "Java Service" template, and the Monaco editor wires JDT.LS for read-only features (completion, hover, diagnostics). This PR makes Java development in the web IDE feel like IntelliJ — fast, strong-interface scaffolding plus a real completion/generation/refactoring layer.
1. New → Java submenu (Projects view)
Right-click a project or folder → New → Java:
com.test.iliyan, the full nested folder chain is created.@Controller+@Get,implements JobHandler,implements MessageHandler,implements WebsocketHandler,@Repository extends JavaRepository<T>).Naming follows IntelliJ: a fully-qualified name (
com.test.MyClass) creates the package folders and emits the matchingpackagedeclaration (mirroring the file's path relative to the project root, as the client-Java compiler requires); a simple name lands in the selected folder with no package line.All Java-specific logic (name parsing/validation + skeleton generation) lives in a new pure, dependency-free helper
view-projects/js/java-new.js;projects.jsonly orchestrates dialog → nested folder → file → open through the existingWorkspaceService(folder creation relies on the server'sforceMkdirto create parents).2. Java IntelliSense (editor-monaco LSP client)
Extends
editor-monaco/js/lsp/java-lsp-client.ts(rebuilt bundle committed):completionItem/resolvepullsadditionalTextEdits, so accepting a type inserts itsimport.org.eclipse.dirigible.sdk.*rank above everything else.toString/equals&hashCodewith a member-picker dialog (BlimpKitDialogHub).workspace/applyEdit+workspace/configurationhandling so command-driven edits land.initializecapabilities are expanded (codeAction literal/resolve, completion resolve, rename prepare, references, formatting, executeCommand, applyEdit) since JDT.LS gates features on them.3. Format on save for Java
Registering the Java document-formatting provider enables the editor's existing TypeScript format-on-save path for Java automatically — same global "Auto-Formatting" toggle and "Toggle Auto-Formatting" action, no Java-specific branch.
Tests
CreateJavaArtifactsITdrives New → Java end to end for the base types, the skeletons, a fully-qualified class and a nested package, asserting the created folders, files,packagedeclarations and skeleton signals over the workspace REST API (deterministic — no Monaco DOM scraping).Browser.hoverOnElementByAttributePatternAndText(for cascading submenu navigation) +Workbench.createJavaArtifact.Verification
mvn -P quick-build installofview-projects+editor-monaco(the Maven esbuild step reproduces the committedjava-lsp-client.jsbyte-for-byte),tsc --noEmitclean.java-new.jsskeleton/parse logic checked under Node; framework + IT modules compile.CreateJavaArtifactsITUI flow runs under the matched Chrome/ChromeDriver in CI.🤖 Generated with Claude Code