From fee89d752258b515dc070e37f6153ea907651084 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Wed, 15 Jul 2026 09:43:30 +0100 Subject: [PATCH] implements PLN-0109 --- discussion/index.ndjson | 2 +- ...ke-lsp-editorial-calls-capability-aware.md | 2 +- .../CompilerLanguageServiceBridge.java | 41 ++++++++++++++----- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 9bbf5c5d..9d7be19c 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -9,7 +9,7 @@ {"type":"discussion","id":"DSC-0058","status":"open","ticket":"multi-frontend-serializable-ir","title":"Manter a IR comum serializavel por design","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","ir","backend","serialization","multi-frontend"],"agendas":[{"id":"AGD-0061","file":"AGD-0061-multi-frontend-serializable-ir.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0057","status":"open","ticket":"multi-frontend-frontend-backend-contract","title":"Estabilizar contrato entre frontend e backend comum","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","ir","backend","multi-frontend"],"agendas":[{"id":"AGD-0060","file":"AGD-0060-multi-frontend-frontend-backend-contract.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0056","status":"open","ticket":"multi-frontend-remove-pbs-branches","title":"Remover verificacoes explicitas de PBS do codigo comum","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","studio","frontend","coupling","multi-frontend"],"agendas":[{"id":"AGD-0059","file":"AGD-0059-multi-frontend-remove-pbs-branches.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]} -{"type":"discussion","id":"DSC-0055","status":"in_progress","ticket":"multi-frontend-compiler-vs-language-services","title":"Separar compilacao de servicos editoriais de frontend","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","studio","lsp","editor","frontend","multi-frontend"],"agendas":[{"id":"AGD-0058","file":"AGD-0058-multi-frontend-compiler-vs-language-services.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[{"id":"DEC-0041","file":"DEC-0041-separate-frontend-compilation-from-editorial-language-services.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15","ref_agenda":"AGD-0058"}],"plans":[{"id":"PLN-0107","file":"PLN-0107-specify-frontend-compiler-and-editorial-capability-boundary.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]},{"id":"PLN-0108","file":"PLN-0108-move-pbs-editor-assistance-behind-optional-language-service.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]},{"id":"PLN-0109","file":"PLN-0109-make-lsp-editorial-calls-capability-aware.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]},{"id":"PLN-0110","file":"PLN-0110-add-compile-only-frontend-and-absent-capability-conformance-coverage.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0055","status":"in_progress","ticket":"multi-frontend-compiler-vs-language-services","title":"Separar compilacao de servicos editoriais de frontend","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","studio","lsp","editor","frontend","multi-frontend"],"agendas":[{"id":"AGD-0058","file":"AGD-0058-multi-frontend-compiler-vs-language-services.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[{"id":"DEC-0041","file":"DEC-0041-separate-frontend-compilation-from-editorial-language-services.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15","ref_agenda":"AGD-0058"}],"plans":[{"id":"PLN-0107","file":"PLN-0107-specify-frontend-compiler-and-editorial-capability-boundary.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]},{"id":"PLN-0108","file":"PLN-0108-move-pbs-editor-assistance-behind-optional-language-service.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]},{"id":"PLN-0109","file":"PLN-0109-make-lsp-editorial-calls-capability-aware.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]},{"id":"PLN-0110","file":"PLN-0110-add-compile-only-frontend-and-absent-capability-conformance-coverage.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0041"]}],"lessons":[]} {"type":"discussion","id":"DSC-0054","status":"done","ticket":"multi-frontend-provider-contract","title":"Introduzir provider completo de frontend","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","studio","frontend","registry","multi-frontend"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0055","file":"discussion/lessons/DSC-0054-multi-frontend-provider-contract/LSN-0055-static-frontend-providers-before-plugin-architecture.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15"}]} {"type":"discussion","id":"DSC-0053","status":"open","ticket":"pbs-lsp-call-and-type-hierarchy","title":"PBS LSP Call and Type Hierarchy","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["studio","lsp","vscode","compiler-pbs","editor","call-hierarchy","type-hierarchy"],"agendas":[{"id":"AGD-0056","file":"AGD-0056-pbs-lsp-call-and-type-hierarchy.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0052","status":"open","ticket":"pbs-lsp-document-links","title":"PBS LSP Document Links","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["studio","lsp","vscode","compiler-pbs","editor","document-links","imports"],"agendas":[{"id":"AGD-0055","file":"AGD-0055-pbs-lsp-document-links.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]} diff --git a/discussion/workflow/plans/PLN-0109-make-lsp-editorial-calls-capability-aware.md b/discussion/workflow/plans/PLN-0109-make-lsp-editorial-calls-capability-aware.md index ea7bcf36..221f8bc7 100644 --- a/discussion/workflow/plans/PLN-0109-make-lsp-editorial-calls-capability-aware.md +++ b/discussion/workflow/plans/PLN-0109-make-lsp-editorial-calls-capability-aware.md @@ -2,7 +2,7 @@ id: PLN-0109 ticket: multi-frontend-compiler-vs-language-services title: Make LSP editorial calls capability aware -status: open +status: done created: 2026-07-15 ref_decisions: [DEC-0041] tags: [compiler, compiler-general, studio, lsp, editor, frontend, multi-frontend] diff --git a/prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridge.java b/prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridge.java index e7196e61..980ed8f4 100644 --- a/prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridge.java +++ b/prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridge.java @@ -2,6 +2,7 @@ package p.studio.lsp.services.compiler; import org.apache.commons.lang3.StringUtils; import p.studio.compiler.FrontendRegistryService; +import p.studio.compiler.PBSFrontendLanguageService; import p.studio.compiler.messages.*; import p.studio.compiler.models.*; import p.studio.compiler.pbs.semantics.*; @@ -21,7 +22,6 @@ import java.util.*; public final class CompilerLanguageServiceBridge implements LanguageServiceBridge { private final AssetSurfaceContextLoader assetSurfaceContextLoader = new AssetSurfaceContextLoader(); - private final PbsEditorialSupportService editorialSupportService = new PbsEditorialSupportService(); @Override public BaselineServerDescription describeServer(final LspProjectContext context) { @@ -61,10 +61,14 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg final int line, final int character) { Objects.requireNonNull(context, "context"); + final Optional languageService = pbsLanguageService(context); + if (languageService.isEmpty()) { + return new BaselineCompletion(false, List.of()); + } return editorialDocument(context, documentUri, text) .map(document -> { final int offset = new DocumentPositionMapper(document.text()).byteOffsetOf(line, character); - final List candidates = editorialSupportService.completion( + final List candidates = languageService.orElseThrow().completion( document.text(), document.ast(), document.supplementalTopDecls(), @@ -85,10 +89,14 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg final int line, final int character) { Objects.requireNonNull(context, "context"); + final Optional languageService = pbsLanguageService(context); + if (languageService.isEmpty()) { + return new BaselineHover("No symbol information."); + } return editorialDocument(context, documentUri, text) .flatMap(document -> { final int offset = new DocumentPositionMapper(document.text()).byteOffsetOf(line, character); - return editorialSupportService.hover( + return languageService.orElseThrow().hover( document.text(), document.ast(), document.supplementalTopDecls(), @@ -107,10 +115,14 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg final int line, final int character) { Objects.requireNonNull(context, "context"); + final Optional languageService = pbsLanguageService(context); + if (languageService.isEmpty()) { + return new BaselineSignatureHelp(List.of(), 0, 0); + } return editorialDocument(context, documentUri, text) .flatMap(document -> { final int offset = new DocumentPositionMapper(document.text()).byteOffsetOf(line, character); - return editorialSupportService.signatureHelp( + return languageService.orElseThrow().signatureHelp( document.text(), document.ast(), document.supplementalTopDecls(), @@ -133,9 +145,11 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg final String text) { Objects.requireNonNull(context, "context"); final String effectiveText = text == null ? "" : text; - final var frontend = frontendSpec(context); + final var frontend = frontendProvider(context).specification(); final FrontendSemanticPresentationSpec presentation = frontend.getSemanticPresentation(); - final List tokens = frontend.getSemanticTokenProvider().tokenize(effectiveText); + final List tokens = pbsLanguageService(context) + .map(languageService -> languageService.semanticTokens(effectiveText)) + .orElseGet(List::of); final var positionMapper = new DocumentPositionMapper(effectiveText); final var semanticTokens = new ArrayList(); @@ -177,9 +191,6 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg final LspProjectContext context, final String documentUri, final String text) { - if (!"pbs".equals(context.languageId())) { - return Optional.empty(); - } final Path documentPath = normalizeDocumentPath(documentUri); final BuilderPipelineContext pipelineContext = BuilderPipelineContext.fromConfig( new BuilderPipelineConfig( @@ -335,10 +346,20 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg } private p.studio.compiler.models.FrontendSpec frontendSpec(final LspProjectContext context) { - return FrontendRegistryService.getFrontendSpec(context.languageId()) + return frontendProvider(context).specification(); + } + + private p.studio.compiler.services.FrontendProvider frontendProvider(final LspProjectContext context) { + return FrontendRegistryService.getProvider(context.languageId()) .orElseThrow(() -> new IllegalArgumentException("no frontend registered for languageId: " + context.languageId())); } + private Optional pbsLanguageService(final LspProjectContext context) { + return frontendProvider(context).languageService() + .filter(PBSFrontendLanguageService.class::isInstance) + .map(PBSFrontendLanguageService.class::cast); + } + private BaselineCompletionItemKind mapCompletionKind(final PbsEditorialSymbolKind kind) { return switch (kind) { case KEYWORD -> BaselineCompletionItemKind.KEYWORD;