@hydranium/core 1.0.0-next.9 → 1.0.0-next.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/documents/ast-document-manager.d.ts +75 -16
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +57 -19
- package/lib/documents/ast-document-manager.js.map +1 -1
- package/lib/documents/client-ids.d.ts +5 -19
- package/lib/documents/client-ids.d.ts.map +1 -1
- package/lib/documents/client-ids.js +5 -19
- package/lib/documents/client-ids.js.map +1 -1
- package/lib/documents/hydranium-text-documents.d.ts +55 -21
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +142 -46
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/language-client-text-shadow.d.ts +41 -9
- package/lib/documents/language-client-text-shadow.d.ts.map +1 -1
- package/lib/documents/language-client-text-shadow.js +56 -11
- package/lib/documents/language-client-text-shadow.js.map +1 -1
- package/lib/documents/self-save-registry.d.ts +37 -6
- package/lib/documents/self-save-registry.d.ts.map +1 -1
- package/lib/documents/self-save-registry.js +28 -15
- package/lib/documents/self-save-registry.js.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -1
- package/lib/langium/ast-extension/ast-node-builder.d.ts +32 -9
- package/lib/langium/ast-extension/ast-node-builder.d.ts.map +1 -1
- package/lib/langium/ast-extension/ast-node-builder.js +60 -22
- package/lib/langium/ast-extension/ast-node-builder.js.map +1 -1
- package/lib/langium/bootstrap.d.ts.map +1 -1
- package/lib/langium/bootstrap.js +16 -9
- package/lib/langium/bootstrap.js.map +1 -1
- package/lib/langium/config/configuration-provider.d.ts +81 -0
- package/lib/langium/config/configuration-provider.d.ts.map +1 -0
- package/lib/langium/config/configuration-provider.js +112 -0
- package/lib/langium/config/configuration-provider.js.map +1 -0
- package/lib/langium/config/index.d.ts +1 -0
- package/lib/langium/config/index.d.ts.map +1 -1
- package/lib/langium/config/index.js +1 -0
- package/lib/langium/config/index.js.map +1 -1
- package/lib/langium/diagnostics/lsp-logger.d.ts +17 -0
- package/lib/langium/diagnostics/lsp-logger.d.ts.map +1 -1
- package/lib/langium/diagnostics/lsp-logger.js +40 -6
- package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts +13 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js.map +1 -1
- package/lib/langium/document-builder/build-session.d.ts +93 -0
- package/lib/langium/document-builder/build-session.d.ts.map +1 -0
- package/lib/langium/document-builder/build-session.js +72 -0
- package/lib/langium/document-builder/build-session.js.map +1 -0
- package/lib/langium/document-builder/document-builder.d.ts +150 -7
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js +298 -11
- package/lib/langium/document-builder/document-builder.js.map +1 -1
- package/lib/langium/document-builder/index.d.ts +1 -0
- package/lib/langium/document-builder/index.d.ts.map +1 -1
- package/lib/langium/document-builder/index.js +1 -0
- package/lib/langium/document-builder/index.js.map +1 -1
- package/lib/langium/integration-services.d.ts +45 -1
- package/lib/langium/integration-services.d.ts.map +1 -1
- package/lib/langium/integration-services.js +10 -5
- package/lib/langium/integration-services.js.map +1 -1
- package/lib/langium/integrity/integrity-service.d.ts +5 -0
- package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-service.js +34 -1
- package/lib/langium/integrity/integrity-service.js.map +1 -1
- package/lib/langium/keys/containment.d.ts +64 -0
- package/lib/langium/keys/containment.d.ts.map +1 -0
- package/lib/langium/keys/containment.js +53 -0
- package/lib/langium/keys/containment.js.map +1 -0
- package/lib/langium/keys/index.d.ts +1 -0
- package/lib/langium/keys/index.d.ts.map +1 -1
- package/lib/langium/keys/index.js +1 -0
- package/lib/langium/keys/index.js.map +1 -1
- package/lib/langium/keys/name-based-key-provider.d.ts +4 -0
- package/lib/langium/keys/name-based-key-provider.d.ts.map +1 -1
- package/lib/langium/keys/name-based-key-provider.js +4 -0
- package/lib/langium/keys/name-based-key-provider.js.map +1 -1
- package/lib/langium/model-service/model-service.d.ts +149 -10
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +120 -93
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +84 -15
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +26 -12
- package/lib/langium/module.js.map +1 -1
- package/lib/langium/naming/name-provider.d.ts +25 -4
- package/lib/langium/naming/name-provider.d.ts.map +1 -1
- package/lib/langium/naming/name-provider.js +2 -1
- package/lib/langium/naming/name-provider.js.map +1 -1
- package/lib/langium/naming/name-separator-validation.d.ts +23 -0
- package/lib/langium/naming/name-separator-validation.d.ts.map +1 -1
- package/lib/langium/naming/name-separator-validation.js +30 -1
- package/lib/langium/naming/name-separator-validation.js.map +1 -1
- package/lib/langium/residency/cst-residency-service.d.ts +31 -9
- package/lib/langium/residency/cst-residency-service.d.ts.map +1 -1
- package/lib/langium/residency/cst-residency-service.js +13 -56
- package/lib/langium/residency/cst-residency-service.js.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.d.ts +32 -13
- package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.js +37 -20
- package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
- package/lib/langium/service-registry.d.ts +5 -1
- package/lib/langium/service-registry.d.ts.map +1 -1
- package/lib/langium/service-registry.js +4 -0
- package/lib/langium/service-registry.js.map +1 -1
- package/lib/langium/shared-services.d.ts +15 -2
- package/lib/langium/shared-services.d.ts.map +1 -1
- package/lib/langium/shared-services.js.map +1 -1
- package/lib/langium/transfer/transfer-encoder.d.ts +60 -17
- package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
- package/lib/langium/transfer/transfer-encoder.js +38 -16
- package/lib/langium/transfer/transfer-encoder.js.map +1 -1
- package/lib/langium/validation/document-validator.d.ts +294 -10
- package/lib/langium/validation/document-validator.d.ts.map +1 -1
- package/lib/langium/validation/document-validator.js +448 -5
- package/lib/langium/validation/document-validator.js.map +1 -1
- package/lib/langium/workspace/document-uri-policy.d.ts +3 -4
- package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
- package/lib/langium/workspace/document-uri-policy.js +3 -4
- package/lib/langium/workspace/document-uri-policy.js.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts +25 -0
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.js +25 -0
- package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +21 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +28 -0
- package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts +8 -0
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.js +11 -2
- package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
- package/lib/langium/workspace/initialize-workspace.d.ts +22 -2
- package/lib/langium/workspace/initialize-workspace.d.ts.map +1 -1
- package/lib/langium/workspace/initialize-workspace.js +13 -5
- package/lib/langium/workspace/initialize-workspace.js.map +1 -1
- package/lib/langium/workspace/langium-documents.d.ts +79 -17
- package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
- package/lib/langium/workspace/langium-documents.js +83 -28
- package/lib/langium/workspace/langium-documents.js.map +1 -1
- package/lib/locale/index.d.ts +10 -0
- package/lib/locale/index.d.ts.map +1 -0
- package/lib/locale/index.js +10 -0
- package/lib/locale/index.js.map +1 -0
- package/lib/locale/server-locale.d.ts +73 -0
- package/lib/locale/server-locale.d.ts.map +1 -0
- package/lib/locale/server-locale.js +61 -0
- package/lib/locale/server-locale.js.map +1 -0
- package/lib/lsp/hydranium-document-update-handler.js +1 -1
- package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
- package/lib/lsp/index.d.ts +1 -1
- package/lib/lsp/index.d.ts.map +1 -1
- package/lib/lsp/index.js +1 -1
- package/lib/lsp/index.js.map +1 -1
- package/lib/lsp/lsp-latency.d.ts +39 -0
- package/lib/lsp/lsp-latency.d.ts.map +1 -0
- package/lib/lsp/lsp-latency.js +58 -0
- package/lib/lsp/lsp-latency.js.map +1 -0
- package/lib/lsp/semantic-token-provider.d.ts +34 -1
- package/lib/lsp/semantic-token-provider.d.ts.map +1 -1
- package/lib/lsp/semantic-token-provider.js +55 -8
- package/lib/lsp/semantic-token-provider.js.map +1 -1
- package/lib/messages/carriers.d.ts +54 -0
- package/lib/messages/carriers.d.ts.map +1 -0
- package/lib/messages/carriers.js +62 -0
- package/lib/messages/carriers.js.map +1 -0
- package/lib/messages/index.d.ts +25 -0
- package/lib/messages/index.d.ts.map +1 -0
- package/lib/messages/index.js +25 -0
- package/lib/messages/index.js.map +1 -0
- package/lib/messages/renderer.d.ts +136 -0
- package/lib/messages/renderer.d.ts.map +1 -0
- package/lib/messages/renderer.js +159 -0
- package/lib/messages/renderer.js.map +1 -0
- package/lib/node/heap-ceiling.d.ts +61 -0
- package/lib/node/heap-ceiling.d.ts.map +1 -0
- package/lib/node/heap-ceiling.js +72 -0
- package/lib/node/heap-ceiling.js.map +1 -0
- package/lib/node/index.d.ts +1 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +1 -0
- package/lib/node/index.js.map +1 -1
- package/lib/node/latency-from-env.d.ts +1 -1
- package/lib/node/latency-from-env.js +1 -1
- package/lib/node/node-file-system-provider.d.ts.map +1 -1
- package/lib/node/node-file-system-provider.js +1 -40
- package/lib/node/node-file-system-provider.js.map +1 -1
- package/lib/node/profiling-run.d.ts +2 -2
- package/lib/node/profiling-run.js +1 -1
- package/lib/node/profiling-run.js.map +1 -1
- package/lib/node/rename-over-open-readers.d.ts +52 -0
- package/lib/node/rename-over-open-readers.d.ts.map +1 -0
- package/lib/node/rename-over-open-readers.js +66 -0
- package/lib/node/rename-over-open-readers.js.map +1 -0
- package/lib/node/socket-launcher.d.ts +15 -0
- package/lib/node/socket-launcher.d.ts.map +1 -1
- package/lib/node/socket-launcher.js +3 -2
- package/lib/node/socket-launcher.js.map +1 -1
- package/lib/testing/fake-document.d.ts +16 -4
- package/lib/testing/fake-document.d.ts.map +1 -1
- package/lib/testing/fake-document.js +18 -3
- package/lib/testing/fake-document.js.map +1 -1
- package/lib/testing/make-noop-shared-services.d.ts +14 -0
- package/lib/testing/make-noop-shared-services.d.ts.map +1 -1
- package/lib/testing/make-noop-shared-services.js +28 -2
- package/lib/testing/make-noop-shared-services.js.map +1 -1
- package/lib/testing/make-test-services.d.ts +44 -8
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +19 -3
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/node/spawned-server.d.ts +14 -0
- package/lib/testing/node/spawned-server.d.ts.map +1 -1
- package/lib/testing/node/spawned-server.js +33 -1
- package/lib/testing/node/spawned-server.js.map +1 -1
- package/lib/testing/playwright/flaky-network-proxy.d.ts +76 -0
- package/lib/testing/playwright/flaky-network-proxy.d.ts.map +1 -0
- package/lib/testing/playwright/flaky-network-proxy.js +164 -0
- package/lib/testing/playwright/flaky-network-proxy.js.map +1 -0
- package/lib/testing/playwright/index.d.ts +1 -0
- package/lib/testing/playwright/index.d.ts.map +1 -1
- package/lib/testing/playwright/index.js +1 -0
- package/lib/testing/playwright/index.js.map +1 -1
- package/lib/testing/playwright/server-log-capture.d.ts +14 -4
- package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-capture.js +21 -4
- package/lib/testing/playwright/server-log-capture.js.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-rename-reporter.js +10 -1
- package/lib/testing/playwright/server-log-rename-reporter.js.map +1 -1
- package/lib/testing/stub-ast-document-manager.d.ts +5 -5
- package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.js +4 -6
- package/lib/testing/stub-ast-document-manager.js.map +1 -1
- package/lib/testing/stub-document-builder.d.ts +8 -0
- package/lib/testing/stub-document-builder.d.ts.map +1 -1
- package/lib/testing/stub-document-builder.js +22 -3
- package/lib/testing/stub-document-builder.js.map +1 -1
- package/lib/testing/stub-langium-documents.d.ts +3 -2
- package/lib/testing/stub-langium-documents.d.ts.map +1 -1
- package/lib/testing/stub-langium-documents.js.map +1 -1
- package/lib/testing/stub-model-service.d.ts +5 -4
- package/lib/testing/stub-model-service.d.ts.map +1 -1
- package/lib/testing/stub-model-service.js +2 -2
- package/lib/testing/stub-model-service.js.map +1 -1
- package/package.json +17 -8
- package/src/documents/ast-document-manager.ts +129 -36
- package/src/documents/client-ids.ts +5 -22
- package/src/documents/hydranium-text-documents.ts +167 -61
- package/src/documents/language-client-text-shadow.ts +59 -11
- package/src/documents/self-save-registry.ts +52 -13
- package/src/index.ts +5 -0
- package/src/langium/ast-extension/ast-node-builder.ts +66 -22
- package/src/langium/bootstrap.ts +16 -9
- package/src/langium/config/configuration-provider.ts +119 -0
- package/src/langium/config/index.ts +1 -0
- package/src/langium/diagnostics/lsp-logger.ts +41 -6
- package/src/langium/document-builder/build-pipeline-integration.ts +14 -1
- package/src/langium/document-builder/build-session.ts +87 -0
- package/src/langium/document-builder/document-builder.ts +339 -11
- package/src/langium/document-builder/index.ts +1 -0
- package/src/langium/integration-services.ts +67 -6
- package/src/langium/integrity/integrity-service.ts +35 -1
- package/src/langium/keys/containment.ts +87 -0
- package/src/langium/keys/index.ts +1 -0
- package/src/langium/keys/name-based-key-provider.ts +4 -0
- package/src/langium/model-service/model-service.ts +211 -30
- package/src/langium/module.ts +106 -21
- package/src/langium/naming/name-provider.ts +27 -5
- package/src/langium/naming/name-separator-validation.ts +34 -5
- package/src/langium/residency/cst-residency-service.ts +36 -12
- package/src/langium/scope/hydranium-scope-provider.ts +40 -22
- package/src/langium/service-registry.ts +6 -2
- package/src/langium/shared-services.ts +19 -2
- package/src/langium/transfer/transfer-encoder.ts +85 -24
- package/src/langium/validation/document-validator.ts +537 -11
- package/src/langium/workspace/document-uri-policy.ts +3 -4
- package/src/langium/workspace/hydranium-langium-document-factory.ts +34 -0
- package/src/langium/workspace/hydranium-workspace-manager.ts +30 -1
- package/src/langium/workspace/in-memory-file-system-provider.ts +13 -3
- package/src/langium/workspace/initialize-workspace.ts +34 -5
- package/src/langium/workspace/langium-documents.ts +106 -33
- package/src/locale/index.ts +10 -0
- package/src/locale/server-locale.ts +86 -0
- package/src/lsp/hydranium-document-update-handler.ts +1 -1
- package/src/lsp/index.ts +1 -1
- package/src/lsp/lsp-latency.ts +62 -0
- package/src/lsp/semantic-token-provider.ts +74 -7
- package/src/messages/carriers.ts +78 -0
- package/src/messages/index.ts +36 -0
- package/src/messages/renderer.ts +204 -0
- package/src/node/heap-ceiling.ts +108 -0
- package/src/node/index.ts +1 -0
- package/src/node/latency-from-env.ts +1 -1
- package/src/node/node-file-system-provider.ts +1 -41
- package/src/node/profiling-run.ts +3 -3
- package/src/node/rename-over-open-readers.ts +78 -0
- package/src/node/socket-launcher.ts +18 -2
- package/src/testing/fake-document.ts +24 -5
- package/src/testing/make-noop-shared-services.ts +50 -2
- package/src/testing/make-test-services.ts +73 -18
- package/src/testing/node/spawned-server.ts +35 -1
- package/src/testing/playwright/flaky-network-proxy.ts +240 -0
- package/src/testing/playwright/index.ts +1 -0
- package/src/testing/playwright/server-log-capture.ts +24 -5
- package/src/testing/playwright/server-log-rename-reporter.ts +12 -1
- package/src/testing/stub-ast-document-manager.ts +10 -14
- package/src/testing/stub-document-builder.ts +32 -3
- package/src/testing/stub-langium-documents.ts +3 -2
- package/src/testing/stub-model-service.ts +7 -6
- package/lib/lsp/instrument-connection.d.ts +0 -36
- package/lib/lsp/instrument-connection.d.ts.map +0 -1
- package/lib/lsp/instrument-connection.js +0 -62
- package/lib/lsp/instrument-connection.js.map +0 -1
- package/src/lsp/instrument-connection.ts +0 -66
package/src/langium/module.ts
CHANGED
|
@@ -7,30 +7,34 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import { type Clock, type Logger, type Project, type Tracer,
|
|
10
|
+
import { type Clock, type Logger, type Project, type Tracer, NoopLogger, SystemClock } from '@hydranium/protocol';
|
|
11
|
+
import { DefaultServerLocale, type ServerLocale } from '../locale/server-locale.js';
|
|
12
|
+
import { DefaultMessageRenderer, type MessageRenderer } from '../messages/renderer.js';
|
|
11
13
|
import { ServerTracer } from './diagnostics/server-tracer.js';
|
|
12
14
|
import { HydraniumLangiumProfiler } from './diagnostics/hydranium-langium-profiler.js';
|
|
13
15
|
import { type AstNode, type Module } from '@hydranium/langium';
|
|
14
16
|
import { type DefaultSharedModuleContext, type LangiumSharedServices, type PartialLangiumSharedServices } from '@hydranium/langium/lsp';
|
|
15
17
|
import { type TextDocument } from 'vscode-languageserver-textdocument';
|
|
16
|
-
import { ModelService } from './model-service/model-service.js';
|
|
18
|
+
import { DefaultModelService, type ModelService } from './model-service/model-service.js';
|
|
17
19
|
import { type ProjectManager } from './project/project-manager.js';
|
|
18
20
|
import { SingleProjectManager } from './project/single-project-manager.js';
|
|
19
|
-
import { TransferEncoder } from './transfer/transfer-encoder.js';
|
|
21
|
+
import { DefaultTransferEncoder, type TransferEncoder } from './transfer/transfer-encoder.js';
|
|
20
22
|
import { HydraniumDocumentBuilder } from './document-builder/document-builder.js';
|
|
21
|
-
import { BuildPipelineIntegration } from './document-builder/build-pipeline-integration.js';
|
|
23
|
+
import { DefaultBuildPipelineIntegration, type BuildPipelineIntegration } from './document-builder/build-pipeline-integration.js';
|
|
22
24
|
import { type BuildPhasePassContribution } from './build-phase-pass/build-phase-pass.js';
|
|
23
25
|
import { type BuildPhasePassService, DefaultBuildPhasePassService } from './build-phase-pass/build-phase-pass-service.js';
|
|
24
|
-
import { CstResidencyService } from './residency/index.js';
|
|
26
|
+
import { DefaultCstResidencyService, type CstResidencyService } from './residency/index.js';
|
|
27
|
+
import { HydraniumConfigurationProvider } from './config/configuration-provider.js';
|
|
25
28
|
import { HydraniumIndexManager } from './workspace/index-manager.js';
|
|
26
29
|
import { HydraniumWorkspaceManager } from './workspace/hydranium-workspace-manager.js';
|
|
27
30
|
import { HydraniumWorkspaceLock } from './workspace/hydranium-workspace-lock.js';
|
|
28
31
|
import { HydraniumLangiumDocumentFactory } from './workspace/hydranium-langium-document-factory.js';
|
|
32
|
+
import { type HydraniumDocumentRegistry, HydraniumLangiumDocuments } from './workspace/langium-documents.js';
|
|
29
33
|
import { type AdditionalDocumentContribution } from './workspace/additional-document-contribution.js';
|
|
30
34
|
import { DefaultDocumentUriPolicy, type DocumentUriPolicy } from './workspace/document-uri-policy.js';
|
|
31
35
|
import { HydraniumTextDocuments } from '../documents/hydranium-text-documents.js';
|
|
32
|
-
import { AstDocumentManager, type WritableFileSystemProvider } from '../documents/ast-document-manager.js';
|
|
33
|
-
import { SelfSaveRegistry } from '../documents/self-save-registry.js';
|
|
36
|
+
import { DefaultAstDocumentManager, type AstDocumentManager, type WritableFileSystemProvider } from '../documents/ast-document-manager.js';
|
|
37
|
+
import { DefaultSelfSaveRegistry, type SelfSaveRegistry } from '../documents/self-save-registry.js';
|
|
34
38
|
import { DefaultEmptyFileSystemProvider } from './workspace/file-system-provider.js';
|
|
35
39
|
import { type ServerLanguageServices } from './language-module.js';
|
|
36
40
|
import { ExtendedServiceRegistry } from './service-registry.js';
|
|
@@ -91,6 +95,24 @@ export interface ServerAddedSharedServices<TProject extends Project = Project> {
|
|
|
91
95
|
* plain `DefaultTracer` with their own `MemoryReader`.
|
|
92
96
|
*/
|
|
93
97
|
Tracer: Tracer;
|
|
98
|
+
/**
|
|
99
|
+
* Renders each user-facing message once, before the server sends it — so
|
|
100
|
+
* every message is rendered by the side that knows the reading user's
|
|
101
|
+
* language. All three heads inherit one diagnostics pass, which is what
|
|
102
|
+
* makes this the single slot an adopter with i18n rebinds; the same binding
|
|
103
|
+
* serves framework codes and their own `defineMessage` codes alike.
|
|
104
|
+
*
|
|
105
|
+
* The framework ships English only and selects no locale, so the default
|
|
106
|
+
* returns every sentence unchanged. Adopters subclass and override
|
|
107
|
+
* `translationsFor`.
|
|
108
|
+
*/
|
|
109
|
+
MessageRenderer: MessageRenderer;
|
|
110
|
+
/**
|
|
111
|
+
* The locale an init handed the server, for whoever renders in it. Held
|
|
112
|
+
* apart from the renderer so replacing the renderer cannot drop locale
|
|
113
|
+
* handling.
|
|
114
|
+
*/
|
|
115
|
+
ServerLocale: ServerLocale;
|
|
94
116
|
/**
|
|
95
117
|
* LSP-bound slots layered on top of Langium's `LangiumSharedLSPServices`.
|
|
96
118
|
* The framework contributes a single string slot here —
|
|
@@ -113,6 +135,12 @@ export interface ServerAddedSharedServices<TProject extends Project = Project> {
|
|
|
113
135
|
workspace: {
|
|
114
136
|
/* override */ TextDocuments: HydraniumTextDocuments<TextDocument>;
|
|
115
137
|
/* override */ WorkspaceManager: HydraniumWorkspaceManager;
|
|
138
|
+
/**
|
|
139
|
+
* Narrow Langium's registry slot to the framework surface, which adds
|
|
140
|
+
* `createEmptyDocument` — reachable only through this narrowing, and
|
|
141
|
+
* wanted by a scope provider querying a URI before the file exists.
|
|
142
|
+
*/
|
|
143
|
+
/* override */ LangiumDocuments: HydraniumDocumentRegistry;
|
|
116
144
|
/**
|
|
117
145
|
* Narrow Langium's `IndexManager` slot to the framework subclass, which
|
|
118
146
|
* layers an `elementsByName` map over Langium's index and exposes
|
|
@@ -188,7 +216,7 @@ export interface ServerAddedSharedServices<TProject extends Project = Project> {
|
|
|
188
216
|
* that need to narrow the diagnostic type or override lifecycle
|
|
189
217
|
* behaviour rebind this slot with a subclass.
|
|
190
218
|
*/
|
|
191
|
-
AstDocumentManager: AstDocumentManager<AstNode
|
|
219
|
+
AstDocumentManager: AstDocumentManager<AstNode>;
|
|
192
220
|
/**
|
|
193
221
|
* Wires the framework's build-time features (integrity, AST
|
|
194
222
|
* enrichment) into Langium's build pipeline: owns the build-phase
|
|
@@ -228,15 +256,23 @@ export interface ServerAddedSharedServices<TProject extends Project = Project> {
|
|
|
228
256
|
* heads read both slots from shared services rather than constructor
|
|
229
257
|
* arguments.
|
|
230
258
|
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
259
|
+
* `TransferEncoder` is the INTERFACE, not `DefaultTransferEncoder` — an
|
|
260
|
+
* adopter can therefore REPLACE this declaration (see
|
|
261
|
+
* {@link WithServiceOverrides}) rather than intersect with it, which is what
|
|
262
|
+
* keeps slot resolution independent of the order a services type is written
|
|
263
|
+
* in. `ModelService` is still a class and does not yet have that property.
|
|
264
|
+
*
|
|
265
|
+
* A class in a slot costs two things, both measured. Its `protected` members
|
|
266
|
+
* join every assignability check and are compared NOMINALLY, so a subclass
|
|
267
|
+
* declared against a second physical copy of this package cannot satisfy it.
|
|
268
|
+
* And where the class is generic over a map reached through `keyof`, that
|
|
269
|
+
* parameter is measured INVARIANT — instantiations then relate only when
|
|
270
|
+
* their arguments are mutually assignable, which no adopter map is with the
|
|
271
|
+
* framework's. Neither survives on an interface.
|
|
236
272
|
*/
|
|
237
273
|
model: {
|
|
238
|
-
TransferEncoder: TransferEncoder
|
|
239
|
-
ModelService: ModelService<AstNode
|
|
274
|
+
TransferEncoder: TransferEncoder;
|
|
275
|
+
ModelService: ModelService<AstNode>;
|
|
240
276
|
};
|
|
241
277
|
/**
|
|
242
278
|
* Shared contribution group for batch-level build-phase passes (see
|
|
@@ -279,6 +315,45 @@ export type ServerSharedServices<TProject extends Project = Project> = Omit<Lang
|
|
|
279
315
|
workspace: Omit<LangiumSharedServices['workspace'], 'TextDocuments' | 'DocumentBuilder'>;
|
|
280
316
|
} & ServerAddedSharedServices<TProject>;
|
|
281
317
|
|
|
318
|
+
/**
|
|
319
|
+
* The service-tree namespaces — the keys whose value groups further slots
|
|
320
|
+
* rather than being a slot itself.
|
|
321
|
+
*
|
|
322
|
+
* Consumed by {@link WithServiceOverrides} to know where to merge one level
|
|
323
|
+
* deeper. **Add a namespace to {@link ServerAddedSharedServices} and you must
|
|
324
|
+
* add it here**, and the failure of forgetting is silent in the direction that
|
|
325
|
+
* matters: an unlisted namespace is treated as a leaf, so an adopter overriding
|
|
326
|
+
* one slot inside it replaces the WHOLE namespace and loses the sibling slots
|
|
327
|
+
* with no diagnostic. The reverse mistake — listing a leaf — fails loudly.
|
|
328
|
+
*/
|
|
329
|
+
type ServiceNamespace = 'lsp' | 'workspace' | 'model';
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Compose an adopter's service tree so its declarations REPLACE the framework's
|
|
333
|
+
* rather than intersecting with them.
|
|
334
|
+
*
|
|
335
|
+
* Langium composes services by intersection, which accumulates: two
|
|
336
|
+
* declarations of one slot survive as an overload set, and which one a call
|
|
337
|
+
* resolves to depends on the order the intersection was written in — silently,
|
|
338
|
+
* with no diagnostic at the point a reorder changes it. There is no override
|
|
339
|
+
* operator for intersections, so the framework's declaration has to be removed
|
|
340
|
+
* before the adopter's is added. This does that, one level deep for each
|
|
341
|
+
* {@link ServiceNamespace}, so a narrowed slot replaces its framework twin
|
|
342
|
+
* while its siblings survive.
|
|
343
|
+
*
|
|
344
|
+
* Only slots typed as INTERFACES can be replaced this way. A class-typed slot
|
|
345
|
+
* drags its `protected` members into the assignability check — compared
|
|
346
|
+
* nominally — so an adopter subclass does not satisfy it and the framework's
|
|
347
|
+
* declaration cannot be dropped.
|
|
348
|
+
*/
|
|
349
|
+
export type WithServiceOverrides<TBase, TOverrides> = Omit<TBase, keyof TOverrides> & {
|
|
350
|
+
[K in keyof TOverrides]: K extends ServiceNamespace
|
|
351
|
+
? K extends keyof TBase
|
|
352
|
+
? Omit<TBase[K], keyof TOverrides[K]> & TOverrides[K]
|
|
353
|
+
: TOverrides[K]
|
|
354
|
+
: TOverrides[K];
|
|
355
|
+
};
|
|
356
|
+
|
|
282
357
|
/**
|
|
283
358
|
* Construction context for {@link createServerSharedModule}.
|
|
284
359
|
*
|
|
@@ -327,6 +402,8 @@ export function createServerSharedModule(
|
|
|
327
402
|
ServiceRegistry: services => new ExtendedServiceRegistry<ServerLanguageServices>(services),
|
|
328
403
|
Logger: () => new NoopLogger(),
|
|
329
404
|
Tracer: services => new ServerTracer(services.Logger, services.Clock),
|
|
405
|
+
ServerLocale: services => new DefaultServerLocale(services),
|
|
406
|
+
MessageRenderer: services => new DefaultMessageRenderer(services),
|
|
330
407
|
// Bind Langium's per-grammar-rule / per-`$type` parse/link/validate
|
|
331
408
|
// profiler (the data the framework's own `Tracer`/`ProfileSession` passes
|
|
332
409
|
// cannot produce), routed through our `Logger` and debug-gated. At the
|
|
@@ -388,16 +465,24 @@ export function createServerSharedModule(
|
|
|
388
465
|
TextDocuments: services => new HydraniumTextDocuments(services),
|
|
389
466
|
WorkspaceManager: services => new HydraniumWorkspaceManager(services),
|
|
390
467
|
IndexManager: services => new HydraniumIndexManager(services),
|
|
468
|
+
// Langium's default asks only about sections named after registered
|
|
469
|
+
// language ids, so a section `lsp.configurationRoot` is bound to reads
|
|
470
|
+
// `undefined` forever with no request on the wire.
|
|
471
|
+
ConfigurationProvider: services => new HydraniumConfigurationProvider(services),
|
|
391
472
|
// Override Langium's factory so a `fromModel` (code-built) virtual
|
|
392
473
|
// document retains serialized text via the per-language Serializer,
|
|
393
474
|
// making it re-read-safe through the virtual-aware FileSystemProvider.
|
|
394
475
|
LangiumDocumentFactory: services => new HydraniumLangiumDocumentFactory(services),
|
|
476
|
+
// Langium's default routes through no identity seam and treats every
|
|
477
|
+
// failed load alike, so leaving this unbound opts a server out of both
|
|
478
|
+
// with nothing to signal it.
|
|
479
|
+
LangiumDocuments: services => new HydraniumLangiumDocuments(services),
|
|
395
480
|
DocumentBuilder: services => new HydraniumDocumentBuilder(services),
|
|
396
481
|
// The write-lock scope this marks is inert unless a host installs a
|
|
397
482
|
// scope tracker — `@hydranium/core/node` does.
|
|
398
483
|
WorkspaceLock: () => new HydraniumWorkspaceLock(),
|
|
399
484
|
ProjectManager: services => new SingleProjectManager(services),
|
|
400
|
-
SelfSaveRegistry: services => new
|
|
485
|
+
SelfSaveRegistry: services => new DefaultSelfSaveRegistry(services),
|
|
401
486
|
DocumentUriPolicy: () => new DefaultDocumentUriPolicy(),
|
|
402
487
|
// Writable filesystem with two paths:
|
|
403
488
|
// - Adopter passed `context.fileSystemProvider` and it returned a
|
|
@@ -421,20 +506,20 @@ export function createServerSharedModule(
|
|
|
421
506
|
}
|
|
422
507
|
return new DefaultEmptyFileSystemProvider(services);
|
|
423
508
|
},
|
|
424
|
-
AstDocumentManager: services => new
|
|
509
|
+
AstDocumentManager: services => new DefaultAstDocumentManager(services),
|
|
425
510
|
// Eagerly constructed, so its build-phase listeners attach before the
|
|
426
511
|
// first build.
|
|
427
|
-
BuildPipelineIntegration: services => new
|
|
512
|
+
BuildPipelineIntegration: services => new DefaultBuildPipelineIntegration(services),
|
|
428
513
|
BuildPhasePassService: services => new DefaultBuildPhasePassService(services),
|
|
429
514
|
// Eagerly constructed, so its `Validated` pass registers before the
|
|
430
515
|
// first build.
|
|
431
|
-
CstResidencyService: services => new
|
|
516
|
+
CstResidencyService: services => new DefaultCstResidencyService(services)
|
|
432
517
|
},
|
|
433
518
|
model: {
|
|
434
519
|
// Generic walker — adopters with a typed `$type → wire shape` overlay
|
|
435
520
|
// rebind this slot with a subclass.
|
|
436
|
-
TransferEncoder: services => new
|
|
437
|
-
ModelService: services => new
|
|
521
|
+
TransferEncoder: services => new DefaultTransferEncoder(services),
|
|
522
|
+
ModelService: services => new DefaultModelService(services)
|
|
438
523
|
},
|
|
439
524
|
// Empty default so `services.buildPhasePasses` always resolves (Langium
|
|
440
525
|
// throws on access to an unbound slot). The framework's own integrity /
|
|
@@ -59,6 +59,16 @@ export interface NameProviderOptions {
|
|
|
59
59
|
* an `id` field) override explicitly; the explicit override at
|
|
60
60
|
* the adopter side documents the grammar's convention rather than
|
|
61
61
|
* burying it in a framework default.
|
|
62
|
+
*
|
|
63
|
+
* **The override is not optional where `name` is a display LABEL rather
|
|
64
|
+
* than an identifier**, and getting it wrong is quiet at first and then
|
|
65
|
+
* loud. A `name=STRING` holding `"Order.Line"` is legitimate content, but
|
|
66
|
+
* the default reads it as the identifier: `getName` composes a qualified
|
|
67
|
+
* name whose segments cannot be told apart from the label's own dots, and
|
|
68
|
+
* `nameSeparatorCheck` reports `hydranium/core/separator-in-name` on every
|
|
69
|
+
* such node. That diagnostic then names the wrong remedy — it asks for a
|
|
70
|
+
* different character, when the fix is to point this option at the property
|
|
71
|
+
* that really is the identifier.
|
|
62
72
|
*/
|
|
63
73
|
readonly nameProperties?: readonly string[];
|
|
64
74
|
}
|
|
@@ -244,10 +254,21 @@ export interface NameProvider extends LangiumNameProvider {
|
|
|
244
254
|
/**
|
|
245
255
|
* Find a unique name for a new node within `container`, using `base`
|
|
246
256
|
* as a stem. Walks the AST subtree rooted at `container` and avoids
|
|
247
|
-
* names already
|
|
248
|
-
* generates `${base}1`,
|
|
249
|
-
* found. Used by create-element
|
|
250
|
-
* uniqueness scope is one AST subtree.
|
|
257
|
+
* names already held there by nodes of `type` or of any subtype of it,
|
|
258
|
+
* as `AstReflection.isSubtype` reports. Default generates `${base}1`,
|
|
259
|
+
* `${base}2`, ... until an unused value is found. Used by create-element
|
|
260
|
+
* operation handlers when the uniqueness scope is one AST subtree.
|
|
261
|
+
*
|
|
262
|
+
* Subtype-closed rather than `$type`-exact, because a name space shared by
|
|
263
|
+
* several concrete types is named by their common supertype and by no
|
|
264
|
+
* concrete type at all — the shape a cross-reference whose target type is
|
|
265
|
+
* that supertype produces. An exact filter finds no collisions for such a
|
|
266
|
+
* call and returns the proposal unchanged, which a caller cannot tell from
|
|
267
|
+
* a name that was genuinely free.
|
|
268
|
+
* {@link NameProvider.findNextDocumentQualifiedName} and
|
|
269
|
+
* {@link NameProvider.findNextProjectQualifiedName} resolve `type` the same
|
|
270
|
+
* way, through `IndexManager.allElements`, so one type argument does not
|
|
271
|
+
* mean different sets at different tiers.
|
|
251
272
|
*/
|
|
252
273
|
findNextName(type: string, base: string, container: AstNode): string;
|
|
253
274
|
|
|
@@ -486,8 +507,9 @@ export class DefaultNameProvider implements NameProvider {
|
|
|
486
507
|
|
|
487
508
|
findNextName(type: string, base: string, container: AstNode): string {
|
|
488
509
|
const proposal = base.replaceAll(this.nameSeparator, '_');
|
|
510
|
+
const reflection = this.services.shared.AstReflection;
|
|
489
511
|
const knownNames = AstUtils.streamAst(container)
|
|
490
|
-
.filter(node => node.$type
|
|
512
|
+
.filter(node => reflection.isSubtype(node.$type, type))
|
|
491
513
|
.map(node => this.getOwnName(node))
|
|
492
514
|
.nonNullable()
|
|
493
515
|
.toArray();
|
|
@@ -8,10 +8,39 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
10
|
import { type AstNode, type ValidationAcceptor, type ValidationChecks } from '@hydranium/langium';
|
|
11
|
+
import { defineMessage } from '@hydranium/protocol';
|
|
12
|
+
import { acceptMessage } from '../../messages/carriers.js';
|
|
11
13
|
import { type ServerLanguageServices } from '../language-module.js';
|
|
12
14
|
import { type ValidationCheckContribution, type ValidationCheckRegistry } from '../validation/validation-contribution.js';
|
|
13
15
|
import type { NameProvider } from './name-provider.js';
|
|
14
16
|
|
|
17
|
+
/**
|
|
18
|
+
* A name value that collides with the qualified-name separator.
|
|
19
|
+
*
|
|
20
|
+
* **The sentence addresses a MODELLER, and the remedy it names is theirs**:
|
|
21
|
+
* where `name` really is the identifier, a different character is the fix and
|
|
22
|
+
* the only one available to whoever is typing.
|
|
23
|
+
*
|
|
24
|
+
* **The adopter-facing failure is a different one, and this message cannot
|
|
25
|
+
* carry it.** With `nameProperties` left at its default `['name']` over a
|
|
26
|
+
* grammar where `name` is a display LABEL — a `STRING` legitimately holding
|
|
27
|
+
* `"Order.Line"` — this fires on every dotted label at once, and "use a
|
|
28
|
+
* different character" is then advice nobody can act on: the content is
|
|
29
|
+
* correct and the configuration is not. A burst of this diagnostic across
|
|
30
|
+
* unrelated nodes is that misconfiguration, not a naming problem, and the fix
|
|
31
|
+
* is `nameProperties`. Widening the sentence to say both was rejected: a
|
|
32
|
+
* modeller cannot act on a DI option, and naming one in an editor squiggle
|
|
33
|
+
* teaches the wrong audience.
|
|
34
|
+
*
|
|
35
|
+
* Unreachable from a grammar whose identifier charset excludes the separator,
|
|
36
|
+
* which is every example here and the reference adopter — so it reads as dead
|
|
37
|
+
* and is not: it guards the configuration, not the content.
|
|
38
|
+
*/
|
|
39
|
+
export const SEPARATOR_IN_NAME = defineMessage(
|
|
40
|
+
'hydranium/core/separator-in-name',
|
|
41
|
+
"Name '{name}' contains the configured name separator '{separator}', which is reserved for qualified-name composition — use a different character."
|
|
42
|
+
);
|
|
43
|
+
|
|
15
44
|
/**
|
|
16
45
|
* Per-node validation check: flag name-bearing AST nodes whose name
|
|
17
46
|
* value contains the configured name separator. Such values produce
|
|
@@ -38,11 +67,11 @@ export function nameSeparatorCheck(nameProvider: NameProvider): (node: AstNode,
|
|
|
38
67
|
}
|
|
39
68
|
const separator = nameProvider.nameSeparator;
|
|
40
69
|
if (ownName.includes(separator)) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
);
|
|
70
|
+
// `{ node }` rather than `{ node, property: 'name' }`: moving the
|
|
71
|
+
// squiggle onto the name property is a behaviour change to the one
|
|
72
|
+
// diagnostic every adopter receives by default, so it is decided on its
|
|
73
|
+
// own merits rather than carried in by a mechanical migration.
|
|
74
|
+
acceptMessage(accept, 'error', SEPARATOR_IN_NAME, { node }, { name: ownName, separator });
|
|
46
75
|
}
|
|
47
76
|
};
|
|
48
77
|
}
|
|
@@ -24,9 +24,13 @@ import { type ServerSharedServicesMinimal } from '../shared-services.js';
|
|
|
24
24
|
/**
|
|
25
25
|
* Default priority of the CST-residency pass. Deliberately very high so it runs
|
|
26
26
|
* *last* among `Validated` build-phase passes (the registry iterates priority
|
|
27
|
-
* ascending)
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* ascending).
|
|
28
|
+
*
|
|
29
|
+
* The ordering is defensive, not load-bearing: the pass only arms or cancels an
|
|
30
|
+
* idle timer, so every pass at `Validated` reads a resident CST whichever order
|
|
31
|
+
* they run in, and lowering it changes nothing observable while that holds. It
|
|
32
|
+
* becomes load-bearing the moment the shed stops being deferred — a pass that
|
|
33
|
+
* frees the CST synchronously has to run after every reader of it.
|
|
30
34
|
*/
|
|
31
35
|
export const CST_RESIDENCY_PASS_PRIORITY = 1_000_000;
|
|
32
36
|
|
|
@@ -225,9 +229,29 @@ function rehydrateCst(document: LangiumDocument, factory: LangiumDocumentFactory
|
|
|
225
229
|
* demand by the identity-preserving graft of {@link rehydrateNode} /
|
|
226
230
|
* {@link rehydrate}, driven transparently from the framework
|
|
227
231
|
* `NameProvider.getNameNode` chokepoint, the comment provider, and
|
|
228
|
-
* `
|
|
232
|
+
* `HydraniumLangiumDocuments.getOrCreateDocument`.
|
|
233
|
+
*/
|
|
234
|
+
/**
|
|
235
|
+
* Keeps a document's CST available to the readers that need one, shedding it
|
|
236
|
+
* for documents that have gone idle and re-grafting on demand.
|
|
229
237
|
*/
|
|
230
|
-
export
|
|
238
|
+
export interface CstResidencyService {
|
|
239
|
+
/**
|
|
240
|
+
* Ensure `document` has a CST, re-parsing its retained text if it was shed.
|
|
241
|
+
* A resident document is left exactly as it is, so this is safe to call on
|
|
242
|
+
* a hot path and safe to call twice.
|
|
243
|
+
*/
|
|
244
|
+
rehydrate(document: LangiumDocument): void;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Node-level convenience over {@link rehydrate}, cheap enough for an
|
|
248
|
+
* unconditional call: a node whose `$cstNode` is already set returns
|
|
249
|
+
* without resolving its document.
|
|
250
|
+
*/
|
|
251
|
+
rehydrateNode(node: AstNode): void;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export class DefaultCstResidencyService implements CstResidencyService {
|
|
231
255
|
protected readonly strategy: CstResidencyStrategy;
|
|
232
256
|
/** Bytes-per-node for the optional reclaim estimate in traces; `0` disables it. */
|
|
233
257
|
protected readonly estimatedBytesPerShedNode: number;
|
|
@@ -277,8 +301,8 @@ export class CstResidencyService {
|
|
|
277
301
|
* until navigation latency on shed files is actually observed to hurt. This
|
|
278
302
|
* method is where that hook goes.
|
|
279
303
|
*/
|
|
280
|
-
rehydrate(document: LangiumDocument):
|
|
281
|
-
|
|
304
|
+
rehydrate(document: LangiumDocument): void {
|
|
305
|
+
rehydrateCst(document, this.services.workspace.LangiumDocumentFactory);
|
|
282
306
|
}
|
|
283
307
|
|
|
284
308
|
/**
|
|
@@ -287,11 +311,11 @@ export class CstResidencyService {
|
|
|
287
311
|
* `true` without even resolving the document, so hot read paths
|
|
288
312
|
* (`getNameNode`, comment lookup) call this unconditionally.
|
|
289
313
|
*/
|
|
290
|
-
rehydrateNode(node: AstNode):
|
|
314
|
+
rehydrateNode(node: AstNode): void {
|
|
291
315
|
if (node.$cstNode !== undefined) {
|
|
292
|
-
return
|
|
316
|
+
return;
|
|
293
317
|
}
|
|
294
|
-
|
|
318
|
+
this.rehydrate(AstUtils.getDocument(node));
|
|
295
319
|
}
|
|
296
320
|
|
|
297
321
|
/**
|
|
@@ -353,8 +377,8 @@ export class CstResidencyService {
|
|
|
353
377
|
this.shedTotal += this.shed(document);
|
|
354
378
|
}
|
|
355
379
|
|
|
356
|
-
/** Cancel
|
|
357
|
-
|
|
380
|
+
/** Cancel every armed shed, so a document that has gone idle keeps its CST. */
|
|
381
|
+
cancelPendingShed(): void {
|
|
358
382
|
for (const timer of this.idleTimers.values()) {
|
|
359
383
|
timer.dispose();
|
|
360
384
|
}
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
type AstNodeLocator,
|
|
25
25
|
AstUtils,
|
|
26
26
|
DefaultScopeProvider,
|
|
27
|
-
type LangiumDocuments,
|
|
28
27
|
MapScope,
|
|
29
28
|
type ReferenceInfo,
|
|
30
29
|
type Scope,
|
|
@@ -35,9 +34,11 @@ import {
|
|
|
35
34
|
WorkspaceCache,
|
|
36
35
|
stream
|
|
37
36
|
} from '@hydranium/langium';
|
|
37
|
+
import { buildAstNode } from '../ast-extension/ast-node-builder.js';
|
|
38
38
|
import { type LogNameOptions } from '../diagnostics/logger.js';
|
|
39
39
|
import { type HydraniumLanguageServices } from '../language-module.js';
|
|
40
40
|
import { type NameProvider } from '../naming/name-provider.js';
|
|
41
|
+
import { type HydraniumDocumentRegistry } from '../workspace/langium-documents.js';
|
|
41
42
|
import { type ScopeExtensionService } from './scope-extension-service.js';
|
|
42
43
|
import { isTieredDescription } from './scoped-ast-node-description.js';
|
|
43
44
|
|
|
@@ -143,7 +144,7 @@ export interface ScopeContext {
|
|
|
143
144
|
* `reference-candidate-provider.ts` module.
|
|
144
145
|
*/
|
|
145
146
|
export class HydraniumScopeProvider extends DefaultScopeProvider {
|
|
146
|
-
protected readonly langiumDocuments:
|
|
147
|
+
protected readonly langiumDocuments: HydraniumDocumentRegistry;
|
|
147
148
|
protected readonly astNodeLocator: AstNodeLocator;
|
|
148
149
|
protected readonly scopeExtensionService: ScopeExtensionService;
|
|
149
150
|
protected readonly options: HydraniumScopeProviderOptions;
|
|
@@ -469,12 +470,13 @@ export class HydraniumScopeProvider extends DefaultScopeProvider {
|
|
|
469
470
|
* Convert a protocol-layer {@link ReferenceContext} into a Langium
|
|
470
471
|
* {@link ReferenceInfo} the rest of the scope/linking machinery accepts.
|
|
471
472
|
*
|
|
472
|
-
* Walks `syntheticPath` by FABRICATING a
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* the
|
|
473
|
+
* Walks `syntheticPath` by FABRICATING a stub per step, so a scope can be
|
|
474
|
+
* queried for an element that does not exist yet — which is what synthetic
|
|
475
|
+
* paths are for. A stub carries the grammar's declared defaults and nothing
|
|
476
|
+
* else, so its containment lists are present but EMPTY: a caller that needs
|
|
477
|
+
* to read a populated collection off the leaf wants
|
|
478
|
+
* {@link resolveReferenceSource} instead, which walks the same path into the
|
|
479
|
+
* real tree.
|
|
478
480
|
*
|
|
479
481
|
* Throws if the context references an unresolvable source; callers
|
|
480
482
|
* that prefer a soft failure should catch and fall back to
|
|
@@ -486,16 +488,15 @@ export class HydraniumScopeProvider extends DefaultScopeProvider {
|
|
|
486
488
|
throw new Error('Invalid reference source');
|
|
487
489
|
}
|
|
488
490
|
for (const step of ctx.syntheticPath ?? []) {
|
|
489
|
-
container = {
|
|
491
|
+
container = buildAstNode(this.services.shared.AstReflection, step.type, {
|
|
490
492
|
$container: container,
|
|
491
493
|
$containerProperty: step.containerProperty,
|
|
492
494
|
// Part of Langium's own container contract, so a stub that omits it
|
|
493
495
|
// is an under-specified node: anything reading position off the
|
|
494
496
|
// chain (a key provider, an adopter scope extension) sees
|
|
495
497
|
// `undefined` where the caller named a slot.
|
|
496
|
-
$containerIndex: step.index
|
|
497
|
-
|
|
498
|
-
};
|
|
498
|
+
$containerIndex: step.index
|
|
499
|
+
});
|
|
499
500
|
}
|
|
500
501
|
return {
|
|
501
502
|
reference: { $refText: '', ref: undefined },
|
|
@@ -586,18 +587,35 @@ export class HydraniumScopeProvider extends DefaultScopeProvider {
|
|
|
586
587
|
}
|
|
587
588
|
|
|
588
589
|
/**
|
|
589
|
-
* Build a transient AST-node stub for a {@link SyntheticSource} request
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
590
|
+
* Build a transient AST-node stub for a {@link SyntheticSource} request: a
|
|
591
|
+
* node of the requested type, contained by the document at `source.uri`.
|
|
592
|
+
*
|
|
593
|
+
* **The container is materialised when no document is loaded there**, which
|
|
594
|
+
* is the case the source type exists for — a `SyntheticSource` names a node
|
|
595
|
+
* that does not exist yet, and the create-element flow asks at the FOLDER
|
|
596
|
+
* the file is about to be written into. Abstaining there would answer an
|
|
597
|
+
* empty candidate list, which a client cannot tell from "nothing matches".
|
|
598
|
+
*
|
|
599
|
+
* The stand-in parses under THIS provider's grammar, because a folder URI
|
|
600
|
+
* carries no extension for the routing ladder to end on and this provider is
|
|
601
|
+
* bound per grammar. Reaching for `createEmptyDocument(uri)` without the id
|
|
602
|
+
* instead fails inside the parse, on an empty extension rather than on the
|
|
603
|
+
* URI.
|
|
604
|
+
*
|
|
605
|
+
* The materialised document is unregistered and transient; see
|
|
606
|
+
* `createEmptyDocument`. Overriding is still open to a consumer whose
|
|
607
|
+
* "container" is an inner element rather than the parse root, or one that
|
|
608
|
+
* deliberately declines to answer for an absent document.
|
|
609
|
+
*
|
|
610
|
+
* The stub carries the grammar's declared defaults, so an extension reading a
|
|
611
|
+
* containment list off it sees an empty array rather than `undefined`.
|
|
594
612
|
*/
|
|
595
613
|
protected resolveSyntheticSource(source: SyntheticSource): AstNode | undefined {
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
return
|
|
614
|
+
const uri = UriUtils.toUri(source.uri);
|
|
615
|
+
const document =
|
|
616
|
+
this.langiumDocuments.getDocument(uri) ??
|
|
617
|
+
this.langiumDocuments.createEmptyDocument(uri, this.services.LanguageMetaData.languageId);
|
|
618
|
+
return buildAstNode(this.services.shared.AstReflection, source.type, { $container: document.parseResult.value });
|
|
601
619
|
}
|
|
602
620
|
|
|
603
621
|
/**
|
|
@@ -255,9 +255,13 @@ export class ExtendedServiceRegistry<
|
|
|
255
255
|
* inherited Langium semantics, which throws on miss). Used for
|
|
256
256
|
* dynamically-routed lookups where the language id comes from
|
|
257
257
|
* external input.
|
|
258
|
+
*
|
|
259
|
+
* The cast is sound because {@link register} is the only way a language
|
|
260
|
+
* enters and takes `TServices`; `languageIdMap` is inherited and typed to
|
|
261
|
+
* Langium's base, which is the only reason one is needed.
|
|
258
262
|
*/
|
|
259
|
-
getServicesById(languageId: string):
|
|
260
|
-
return this.languageIdMap.get(languageId);
|
|
263
|
+
getServicesById(languageId: string): TServices | undefined {
|
|
264
|
+
return this.languageIdMap.get(languageId) as TServices | undefined;
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
/**
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import type { Clock, Logger, Project, Tracer } from '@hydranium/protocol';
|
|
11
11
|
import type { LangiumSharedCoreServices } from '@hydranium/langium';
|
|
12
|
+
import type { ServerLocale } from '../locale/server-locale.js';
|
|
13
|
+
import type { MessageRenderer } from '../messages/renderer.js';
|
|
12
14
|
import type { SelfSaveRegistry } from '../documents/self-save-registry.js';
|
|
13
15
|
import type { WritableFileSystemProvider } from '../documents/ast-document-manager.js';
|
|
16
|
+
import type { HydraniumDocumentRegistry } from './workspace/langium-documents.js';
|
|
14
17
|
import type { BuildPhasePassService } from './build-phase-pass/build-phase-pass-service.js';
|
|
15
18
|
import type { CstResidencyService } from './residency/cst-residency-service.js';
|
|
16
19
|
import type { BuildPipelineIntegration } from './document-builder/build-pipeline-integration.js';
|
|
@@ -27,8 +30,9 @@ import type { AdditionalDocumentContribution } from './workspace/additional-docu
|
|
|
27
30
|
* framework additions that other framework services consume: the dedicated
|
|
28
31
|
* {@link Clock}, {@link Logger} and {@link Tracer} top-level slots (injectable
|
|
29
32
|
* time source, emission-only logger, and the measure-and-emit tracer composed
|
|
30
|
-
* from the other two), the {@link AdditionalDocumentContribution} group,
|
|
31
|
-
* {@link
|
|
33
|
+
* from the other two), the {@link AdditionalDocumentContribution} group, the
|
|
34
|
+
* {@link MessageRenderer} and the {@link ServerLocale} it renders in,
|
|
35
|
+
* an {@link ExtendedServiceRegistry}, and on `workspace` a writable file-system
|
|
32
36
|
* provider plus {@link HydraniumWorkspaceManager}, {@link ProjectManager},
|
|
33
37
|
* {@link SelfSaveRegistry}, {@link BuildPipelineIntegration},
|
|
34
38
|
* {@link BuildPhasePassService}, {@link CstResidencyService} and
|
|
@@ -57,6 +61,14 @@ export interface ServerSharedServicesMinimal<TProject extends Project = Project>
|
|
|
57
61
|
* adopters deep-merge contributions that seed built-in / stdlib documents.
|
|
58
62
|
*/
|
|
59
63
|
additionalDocuments: Record<string, AdditionalDocumentContribution>;
|
|
64
|
+
/**
|
|
65
|
+
* Renders each user-facing message once, before the server sends it. On the
|
|
66
|
+
* shared tier with no workspace dependency, because all three heads'
|
|
67
|
+
* messages pass through it.
|
|
68
|
+
*/
|
|
69
|
+
MessageRenderer: MessageRenderer;
|
|
70
|
+
/** The locale an init handed the server, for whoever renders in it. */
|
|
71
|
+
ServerLocale: ServerLocale;
|
|
60
72
|
/**
|
|
61
73
|
* Narrows Langium's base `ServiceRegistry` slot to the framework impl the
|
|
62
74
|
* framework always binds, so the abstaining lookups — `getServicesFor`
|
|
@@ -75,6 +87,11 @@ export interface ServerSharedServicesMinimal<TProject extends Project = Project>
|
|
|
75
87
|
// framework always binds, so `wsRelativePath` and the folder-walk are
|
|
76
88
|
// reachable from the minimal surface without a cast.
|
|
77
89
|
WorkspaceManager: HydraniumWorkspaceManager;
|
|
90
|
+
// Same, for the registry: the framework always binds
|
|
91
|
+
// `HydraniumLangiumDocuments`, and `createEmptyDocument` is reachable
|
|
92
|
+
// only through this narrowing — a scope provider querying a URI before
|
|
93
|
+
// the file exists is the caller that needs it.
|
|
94
|
+
/* override */ LangiumDocuments: HydraniumDocumentRegistry;
|
|
78
95
|
ProjectManager: ProjectManager<TProject>;
|
|
79
96
|
SelfSaveRegistry: SelfSaveRegistry;
|
|
80
97
|
BuildPipelineIntegration: BuildPipelineIntegration;
|