From 6205b82e0b732fa7ff44d421e0e26f85b3496865 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Wed, 15 Jul 2026 11:26:53 +0100 Subject: [PATCH] implements PLN-0113 --- discussion/index.ndjson | 2 +- ...e-completion-to-generic-frontend-models.md | 37 +--------------- .../compiler/PBSFrontendLanguageService.java | 43 +++++++++++++++++++ .../services/FrontendEditorialContext.java | 7 +++ .../services/FrontendLanguageService.java | 7 +++ .../CompilerLanguageServiceBridge.java | 22 +++++++--- 6 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendEditorialContext.java diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 92cd3c49..3ca573f0 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -8,7 +8,7 @@ {"type":"discussion","id":"DSC-0059","status":"open","ticket":"multi-frontend-common-lifecycle","title":"Extrair lifecycle comum das responsabilidades do frontend PBS","created_at":"2026-07-15","updated_at":"2026-07-15","tags":["compiler","compiler-general","compiler-pbs","lifecycle","backend","multi-frontend"],"agendas":[{"id":"AGD-0062","file":"AGD-0062-multi-frontend-common-lifecycle.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[],"plans":[],"lessons":[]} {"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":"in_progress","ticket":"multi-frontend-remove-pbs-branches","title":"Generalizar o contrato LSP/editorial para frontends","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":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[{"id":"DEC-0042","file":"DEC-0042-frontend-editorial-language-service-contract-for-lsp.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15","ref_agenda":"AGD-0059"}],"plans":[{"id":"PLN-0111","file":"PLN-0111-define-generic-frontend-editorial-dtos-and-capability-surface.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0112","file":"PLN-0112-migrate-semantic-tokens-to-generic-frontend-language-service.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0113","file":"PLN-0113-migrate-completion-to-generic-frontend-models.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0114","file":"PLN-0114-migrate-hover-and-documentation-to-generic-frontend-models.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0115","file":"PLN-0115-migrate-signature-help-to-generic-frontend-models.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0116","file":"PLN-0116-remove-pbs-imports-from-common-lsp-and-add-boundary-coverage.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0056","status":"in_progress","ticket":"multi-frontend-remove-pbs-branches","title":"Generalizar o contrato LSP/editorial para frontends","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":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15"}],"decisions":[{"id":"DEC-0042","file":"DEC-0042-frontend-editorial-language-service-contract-for-lsp.md","status":"accepted","created_at":"2026-07-15","updated_at":"2026-07-15","ref_agenda":"AGD-0059"}],"plans":[{"id":"PLN-0111","file":"PLN-0111-define-generic-frontend-editorial-dtos-and-capability-surface.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0112","file":"PLN-0112-migrate-semantic-tokens-to-generic-frontend-language-service.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0113","file":"PLN-0113-migrate-completion-to-generic-frontend-models.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0114","file":"PLN-0114-migrate-hover-and-documentation-to-generic-frontend-models.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0115","file":"PLN-0115-migrate-signature-help-to-generic-frontend-models.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]},{"id":"PLN-0116","file":"PLN-0116-remove-pbs-imports-from-common-lsp-and-add-boundary-coverage.md","status":"open","created_at":"2026-07-15","updated_at":"2026-07-15","ref_decisions":["DEC-0042"]}],"lessons":[]} {"type":"discussion","id":"DSC-0055","status":"done","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":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0056","file":"discussion/lessons/DSC-0055-multi-frontend-compiler-vs-language-services/LSN-0056-compile-first-frontends-with-optional-editorial-capabilities.md","status":"done","created_at":"2026-07-15","updated_at":"2026-07-15"}]} {"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":[]} diff --git a/discussion/workflow/plans/PLN-0113-migrate-completion-to-generic-frontend-models.md b/discussion/workflow/plans/PLN-0113-migrate-completion-to-generic-frontend-models.md index 6e783948..17c2db90 100644 --- a/discussion/workflow/plans/PLN-0113-migrate-completion-to-generic-frontend-models.md +++ b/discussion/workflow/plans/PLN-0113-migrate-completion-to-generic-frontend-models.md @@ -2,8 +2,9 @@ id: PLN-0113 ticket: multi-frontend-remove-pbs-branches title: Migrate completion to generic frontend models -status: open +status: done created: 2026-07-15 +completed: 2026-07-15 ref_decisions: [DEC-0042] tags: [compiler, compiler-general, compiler-pbs, studio, frontend, coupling, multi-frontend] --- @@ -62,37 +63,3 @@ Migrate LSP completion handling to generic frontend completion models exposed th - `prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/PBSFrontendLanguageService.java` - `prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridge.java` - Completion-related tests. - -TBD. - -## Objective - -TBD. - -## Dependencies - -TBD. - -## Scope - -TBD. - -## Non-Goals - -TBD. - -## Execution Method - -TBD. - -## Acceptance Criteria - -TBD. - -## Tests - -TBD. - -## Affected Artifacts - -TBD. diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/PBSFrontendLanguageService.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/PBSFrontendLanguageService.java index 8f8decfd..4f29add0 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/PBSFrontendLanguageService.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/PBSFrontendLanguageService.java @@ -6,9 +6,13 @@ import p.studio.compiler.pbs.ast.PbsAst; import p.studio.compiler.pbs.semantics.PbsEditorialCompletionCandidate; import p.studio.compiler.pbs.semantics.PbsEditorialResolvedSymbol; import p.studio.compiler.pbs.semantics.PbsEditorialSignatureHelp; +import p.studio.compiler.pbs.semantics.PbsEditorialSymbolKind; import p.studio.compiler.pbs.semantics.PbsEditorialSupportService; +import p.studio.compiler.services.FrontendCompletionCandidate; import p.studio.compiler.services.FrontendDocumentRequest; +import p.studio.compiler.services.FrontendEditorialContext; import p.studio.compiler.services.FrontendLanguageService; +import p.studio.compiler.services.FrontendSymbolKind; import p.studio.utilities.structures.ReadOnlyList; import java.util.List; @@ -39,6 +43,32 @@ public final class PBSFrontendLanguageService implements FrontendLanguageService return editorialSupportService.completion(sourceText, ast, supplementalTopDecls, feSurfaceContext, offset); } + @Override + public List completion( + final FrontendDocumentRequest request, + final FrontendEditorialContext editorialContext, + final int offset) { + if (request == null + || editorialContext == null + || !(editorialContext.syntaxTree() instanceof PbsAst.File ast) + || !(editorialContext.supplementalDeclarations() instanceof ReadOnlyList supplementalTopDecls) + || !(editorialContext.semanticContext() instanceof FESurfaceContext feSurfaceContext)) { + return List.of(); + } + + @SuppressWarnings("unchecked") + final ReadOnlyList typedSupplementalTopDecls = + (ReadOnlyList) supplementalTopDecls; + return completion( + request.documentText(), + ast, + typedSupplementalTopDecls, + feSurfaceContext, + offset).stream() + .map(this::toFrontendCompletionCandidate) + .toList(); + } + public Optional hover( final String sourceText, final PbsAst.File ast, @@ -65,4 +95,17 @@ public final class PBSFrontendLanguageService implements FrontendLanguageService public List semanticTokens(final String documentText) { return semanticTokenProvider.tokenize(documentText == null ? "" : documentText); } + + private FrontendCompletionCandidate toFrontendCompletionCandidate(final PbsEditorialCompletionCandidate candidate) { + return new FrontendCompletionCandidate( + candidate.label(), + toFrontendSymbolKind(candidate.kind()), + candidate.detail(), + candidate.documentation(), + candidate.origin()); + } + + private FrontendSymbolKind toFrontendSymbolKind(final PbsEditorialSymbolKind kind) { + return FrontendSymbolKind.valueOf(kind.name()); + } } diff --git a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendEditorialContext.java b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendEditorialContext.java new file mode 100644 index 00000000..783d7616 --- /dev/null +++ b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendEditorialContext.java @@ -0,0 +1,7 @@ +package p.studio.compiler.services; + +public record FrontendEditorialContext( + Object syntaxTree, + Object supplementalDeclarations, + Object semanticContext) { +} diff --git a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendLanguageService.java b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendLanguageService.java index 51190bd6..1b876825 100644 --- a/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendLanguageService.java +++ b/prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendLanguageService.java @@ -19,6 +19,13 @@ public interface FrontendLanguageService { return List.of(); } + default List completion( + final FrontendDocumentRequest request, + final FrontendEditorialContext editorialContext, + final int offset) { + return completion(request, offset); + } + default Optional hover( final FrontendDocumentRequest request, final int offset) { 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 e8c4d551..aa2edece 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 @@ -6,8 +6,11 @@ import p.studio.compiler.PBSFrontendLanguageService; import p.studio.compiler.messages.*; import p.studio.compiler.models.*; import p.studio.compiler.pbs.semantics.*; +import p.studio.compiler.services.FrontendCompletionCandidate; import p.studio.compiler.services.FrontendDocumentRequest; +import p.studio.compiler.services.FrontendEditorialContext; import p.studio.compiler.services.FrontendProvider; +import p.studio.compiler.services.FrontendSymbolKind; import p.studio.compiler.services.PBSFrontendPhaseService; import p.studio.compiler.source.identifiers.FileId; import p.studio.compiler.utilities.SourceProviderFactory; @@ -73,18 +76,25 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg final int line, final int character) { Objects.requireNonNull(context, "context"); - final Optional languageService = pbsLanguageService(context); + final var provider = frontendProvider(context); + final var languageService = provider.languageService(); 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 = languageService.orElseThrow().completion( - document.text(), + final FrontendDocumentRequest request = new FrontendDocumentRequest( + context.projectRoot(), + normalizeDocumentPath(documentUri), + document.text()); + final FrontendEditorialContext editorialContext = new FrontendEditorialContext( document.ast(), document.supplementalTopDecls(), - document.feSurfaceContext(), + document.feSurfaceContext()); + final List candidates = languageService.orElseThrow().completion( + request, + editorialContext, offset); return new BaselineCompletion( false, @@ -312,7 +322,7 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg return Path.of(URI.create(Objects.requireNonNull(documentUri, "documentUri"))).toAbsolutePath().normalize(); } - private BaselineCompletionItem mapCompletionItem(final PbsEditorialCompletionCandidate candidate) { + private BaselineCompletionItem mapCompletionItem(final FrontendCompletionCandidate candidate) { return new BaselineCompletionItem( candidate.label(), mapCompletionKind(candidate.kind()), @@ -377,7 +387,7 @@ public final class CompilerLanguageServiceBridge implements LanguageServiceBridg .map(PBSFrontendLanguageService.class::cast); } - private BaselineCompletionItemKind mapCompletionKind(final PbsEditorialSymbolKind kind) { + private BaselineCompletionItemKind mapCompletionKind(final FrontendSymbolKind kind) { return switch (kind) { case KEYWORD -> BaselineCompletionItemKind.KEYWORD; case LOCAL, PARAMETER -> BaselineCompletionItemKind.VARIABLE;