prometeu-studio/discussion/lessons/DSC-0055-multi-frontend-compiler-vs-language-services/LSN-0056-compile-first-frontends-with-optional-editorial-capabilities.md
bQUARKz 4233b90b82
All checks were successful
JaCoCo Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 61.54% (17430/28323) * Branch Coverage: 52.41% (6739/12858) * Lines of Code: 28323 * Cyclomatic Complexity: 11353 #### Quality Gates Summary Output truncated.
Test / Build skipped: 15, passed: 611
Intrepid/Prometeu/Studio/pipeline/pr-master This commit looks good
Intrepid/Prometeu/Studio/pipeline/head This commit looks good
housekeep DSC-0055
2026-07-15 09:55:08 +01:00

4.8 KiB

Compile-first frontends with optional editorial capabilities

Original Problem

Prometeu is moving from a PBS-centered compiler/editor stack toward a multi-frontend compiler. PBS already provides compilation plus rich editor assistance, so it was easy for shared code, LSP, or Studio consumers to assume that every frontend can provide diagnostics, semantic tokens, completion, hover, and signature help as one package.

That assumption makes future frontend adoption too expensive. A new frontend must be able to compile before it has a complete IDE experience.

Consolidated Decision

The frontend contract is compile-first.

Every frontend must provide a compiler capability through FrontendProvider.compiler(). Editorial services are optional and live behind FrontendProvider.languageService().

A frontend that can compile but has no language service is valid. Missing editor assistance must not block analyze, compile, build, backend lowering, bytecode emission, verification, or artifact writing.

LSP and Studio consumers must query editorial capability before invoking editor-specific behavior. Absence of a capability is a normal state, not a compiler failure.

Final Implementation

The compiler pipeline spec now defines the provider boundary explicitly:

  • compiler() is the only required executable frontend capability.
  • languageService() is optional.
  • editor capabilities such as completion, hover, definition, signature help, semantic tokens, formatting, rename, and code actions are optional unless a future accepted decision narrows the requirement.
  • absent editor capabilities have deterministic fallback behavior.
  • compiler diagnostics and editor diagnostics are separate ownership surfaces.

PBS keeps its rich editor assistance, but now exposes it through PBSFrontendLanguageService, returned by PBSFrontendProvider.languageService().

The LSP bridge resolves the active FrontendProvider and checks for languageService() before using editor behavior. For now, PBS remains an adapter-specific implementation because the common language-service DTOs are not yet generalized. That is acceptable because the important boundary is already enforced: the LSP no longer assumes that compiler support implies editor support.

Conformance coverage now includes:

  • a compile-only provider fixture with no language service;
  • LSP neutral responses when editor capability is absent;
  • PBS regression coverage for existing completion, hover, signature help, semantic tokens, and documentation behavior;
  • architecture tests preventing common modules from directly instantiating PBS editor support.

Examples

A compile-only frontend should look like this at the provider boundary:

public final class ExampleFrontendProvider implements FrontendProvider {
    @Override
    public FrontendSpec specification() {
        return EXAMPLE_SPEC;
    }

    @Override
    public FrontendPhaseService compiler() {
        return exampleCompiler;
    }
}

It does not need to override languageService(). The default empty optional is a valid frontend state.

An editor consumer should treat missing services as a normal fallback:

return provider.languageService()
        .filter(ExpectedLanguageService.class::isInstance)
        .map(ExpectedLanguageService.class::cast)
        .map(service -> service.completion(...))
        .orElseGet(List::of);

Pitfalls

Do not use PBS as the minimum frontend contract. PBS is the first rich frontend, not the definition of frontend validity.

Do not make editor diagnostics a prerequisite for compilation. Build/analyze diagnostics are compiler output; live editor diagnostics may reuse compiler results but have different latency, cancellation, overlay, and UX concerns.

Do not split the language service into many top-level interfaces before implementation pressure proves a real lifecycle or ownership boundary. The current contract intentionally keeps an aggregated optional language-service surface.

Do not call PBS editorial classes directly from common compiler, LSP, Studio, or app code. Go through FrontendProvider.languageService() and adapter-local capability checks.

References

  • Spec: docs/specs/compiler/23. Compiler Pipeline Entry Points Specification.md
  • Provider API: prometeu-compiler/prometeu-frontend-api/src/main/java/p/studio/compiler/services/FrontendProvider.java
  • PBS language service: prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/PBSFrontendLanguageService.java
  • LSP bridge: prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridge.java
  • Conformance tests:
    • prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/specs/FrontendProviderBoundaryTest.java
    • prometeu-lsp/prometeu-lsp-v1/src/test/java/p/studio/lsp/services/compiler/CompilerLanguageServiceBridgeTest.java