implements PLN-0109

This commit is contained in:
bQUARKz 2026-07-15 09:43:30 +01:00
parent bc95b33bd9
commit fee89d7522
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
3 changed files with 33 additions and 12 deletions

View File

@ -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":[]}

View File

@ -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]

View File

@ -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<PBSFrontendLanguageService> 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<PbsEditorialCompletionCandidate> candidates = editorialSupportService.completion(
final List<PbsEditorialCompletionCandidate> 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<PBSFrontendLanguageService> 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<PBSFrontendLanguageService> 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<FrontendSemanticToken> tokens = frontend.getSemanticTokenProvider().tokenize(effectiveText);
final List<FrontendSemanticToken> tokens = pbsLanguageService(context)
.map(languageService -> languageService.semanticTokens(effectiveText))
.orElseGet(List::of);
final var positionMapper = new DocumentPositionMapper(effectiveText);
final var semanticTokens = new ArrayList<BaselineSemanticToken>();
@ -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<PBSFrontendLanguageService> 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;