@hydranium/core 1.0.0-next.16 → 1.0.0-next.168
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/README.md +5 -1
- package/lib/documents/ast-document-manager.d.ts +190 -29
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +235 -38
- 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/client-session-errors.d.ts +15 -0
- package/lib/documents/client-session-errors.d.ts.map +1 -0
- package/lib/documents/client-session-errors.js +15 -0
- package/lib/documents/client-session-errors.js.map +1 -0
- package/lib/documents/client-session-registry.d.ts +138 -0
- package/lib/documents/client-session-registry.d.ts.map +1 -0
- package/lib/documents/client-session-registry.js +187 -0
- package/lib/documents/client-session-registry.js.map +1 -0
- package/lib/documents/file-system-task-queue.d.ts +49 -0
- package/lib/documents/file-system-task-queue.d.ts.map +1 -0
- package/lib/documents/file-system-task-queue.js +34 -0
- package/lib/documents/file-system-task-queue.js.map +1 -0
- package/lib/documents/hydranium-text-documents.d.ts +439 -82
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +769 -159
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/index.d.ts +3 -0
- package/lib/documents/index.d.ts.map +1 -1
- package/lib/documents/index.js +3 -0
- package/lib/documents/index.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 +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +6 -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 +21 -1
- package/lib/langium/document-builder/build-pipeline-integration.d.ts.map +1 -1
- package/lib/langium/document-builder/build-pipeline-integration.js +32 -5
- 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 +365 -19
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js +637 -44
- 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-rule.d.ts +13 -5
- package/lib/langium/integrity/integrity-rule.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-rule.js.map +1 -1
- package/lib/langium/integrity/integrity-service.d.ts +50 -6
- package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-service.js +193 -17
- 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/language-module.d.ts +27 -2
- package/lib/langium/language-module.d.ts.map +1 -1
- package/lib/langium/language-module.js +16 -2
- package/lib/langium/language-module.js.map +1 -1
- package/lib/langium/model-service/client-session.d.ts +307 -0
- package/lib/langium/model-service/client-session.d.ts.map +1 -0
- package/lib/langium/model-service/client-session.js +395 -0
- package/lib/langium/model-service/client-session.js.map +1 -0
- package/lib/langium/model-service/index.d.ts +1 -0
- package/lib/langium/model-service/index.d.ts.map +1 -1
- package/lib/langium/model-service/index.js +1 -0
- package/lib/langium/model-service/index.js.map +1 -1
- package/lib/langium/model-service/model-service.d.ts +261 -198
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +234 -346
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +144 -35
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +45 -34
- 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/project/abstract-project-manager.d.ts.map +1 -1
- package/lib/langium/project/abstract-project-manager.js +9 -2
- package/lib/langium/project/abstract-project-manager.js.map +1 -1
- package/lib/langium/project/project-change-event.d.ts +2 -2
- package/lib/langium/residency/cst-residency-service.d.ts +31 -11
- 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 +48 -13
- package/lib/langium/scope/hydranium-scope-provider.d.ts.map +1 -1
- package/lib/langium/scope/hydranium-scope-provider.js +56 -20
- package/lib/langium/scope/hydranium-scope-provider.js.map +1 -1
- package/lib/langium/serialization/abstract-serializer.d.ts +11 -20
- package/lib/langium/serialization/abstract-serializer.d.ts.map +1 -1
- package/lib/langium/serialization/abstract-serializer.js +12 -21
- package/lib/langium/serialization/abstract-serializer.js.map +1 -1
- package/lib/langium/service-registry.d.ts +15 -1
- package/lib/langium/service-registry.d.ts.map +1 -1
- package/lib/langium/service-registry.js +16 -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/trivia/comment-preserver.d.ts +423 -0
- package/lib/langium/trivia/comment-preserver.d.ts.map +1 -0
- package/lib/langium/trivia/comment-preserver.js +906 -0
- package/lib/langium/trivia/comment-preserver.js.map +1 -0
- package/lib/langium/trivia/document-ending-preserver.d.ts +43 -0
- package/lib/langium/trivia/document-ending-preserver.d.ts.map +1 -0
- package/lib/langium/trivia/document-ending-preserver.js +48 -0
- package/lib/langium/trivia/document-ending-preserver.js.map +1 -0
- package/lib/langium/trivia/index.d.ts +14 -0
- package/lib/langium/trivia/index.d.ts.map +1 -0
- package/lib/langium/trivia/index.js +14 -0
- package/lib/langium/trivia/index.js.map +1 -0
- package/lib/langium/trivia/trivia-contribution.d.ts +37 -0
- package/lib/langium/trivia/trivia-contribution.d.ts.map +1 -0
- package/lib/langium/trivia/trivia-contribution.js +10 -0
- package/lib/langium/trivia/trivia-contribution.js.map +1 -0
- package/lib/langium/trivia/trivia-preserver.d.ts +50 -0
- package/lib/langium/trivia/trivia-preserver.d.ts.map +1 -0
- package/lib/langium/trivia/trivia-preserver.js +10 -0
- package/lib/langium/trivia/trivia-preserver.js.map +1 -0
- package/lib/langium/trivia/trivia-service.d.ts +70 -0
- package/lib/langium/trivia/trivia-service.d.ts.map +1 -0
- package/lib/langium/trivia/trivia-service.js +56 -0
- package/lib/langium/trivia/trivia-service.js.map +1 -0
- package/lib/langium/update-rewrite/update-rewrite.d.ts +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 +17 -12
- package/lib/langium/workspace/document-uri-policy.d.ts.map +1 -1
- package/lib/langium/workspace/document-uri-policy.js +10 -9
- package/lib/langium/workspace/document-uri-policy.js.map +1 -1
- package/lib/langium/workspace/file-not-found.d.ts +17 -0
- package/lib/langium/workspace/file-not-found.d.ts.map +1 -0
- package/lib/langium/workspace/file-not-found.js +20 -0
- package/lib/langium/workspace/file-not-found.js.map +1 -0
- package/lib/langium/workspace/file-system-provider.d.ts +84 -8
- package/lib/langium/workspace/file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/file-system-provider.js +93 -14
- package/lib/langium/workspace/file-system-provider.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-lock.d.ts +13 -0
- package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-lock.js +18 -0
- package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +77 -8
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +115 -9
- package/lib/langium/workspace/hydranium-workspace-manager.js.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts +25 -2
- package/lib/langium/workspace/in-memory-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/in-memory-file-system-provider.js +41 -15
- package/lib/langium/workspace/in-memory-file-system-provider.js.map +1 -1
- package/lib/langium/workspace/initialize-workspace.d.ts +31 -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 +91 -29
- package/lib/langium/workspace/langium-documents.js.map +1 -1
- package/lib/langium/workspace/persistent-file-system-provider.d.ts +0 -7
- package/lib/langium/workspace/persistent-file-system-provider.d.ts.map +1 -1
- package/lib/langium/workspace/persistent-file-system-provider.js +0 -7
- package/lib/langium/workspace/persistent-file-system-provider.js.map +1 -1
- package/lib/langium/workspace/virtual-document.d.ts +48 -15
- package/lib/langium/workspace/virtual-document.d.ts.map +1 -1
- package/lib/langium/workspace/virtual-document.js +78 -18
- package/lib/langium/workspace/virtual-document.js.map +1 -1
- package/lib/langium/workspace/write-lock-scope.d.ts +4 -3
- package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
- package/lib/langium/workspace/write-lock-scope.js +4 -3
- package/lib/langium/workspace/write-lock-scope.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/completion/hydranium-completion-provider.d.ts +44 -2
- package/lib/lsp/completion/hydranium-completion-provider.d.ts.map +1 -1
- package/lib/lsp/completion/hydranium-completion-provider.js +68 -0
- package/lib/lsp/completion/hydranium-completion-provider.js.map +1 -1
- package/lib/lsp/connection-features.d.ts +23 -0
- package/lib/lsp/connection-features.d.ts.map +1 -0
- package/lib/lsp/connection-features.js +60 -0
- package/lib/lsp/connection-features.js.map +1 -0
- package/lib/lsp/diagnostics-connection.d.ts +27 -0
- package/lib/lsp/diagnostics-connection.d.ts.map +1 -0
- package/lib/lsp/diagnostics-connection.js +53 -0
- package/lib/lsp/diagnostics-connection.js.map +1 -0
- package/lib/lsp/hydranium-document-update-handler.d.ts +90 -79
- package/lib/lsp/hydranium-document-update-handler.d.ts.map +1 -1
- package/lib/lsp/hydranium-document-update-handler.js +152 -99
- package/lib/lsp/hydranium-document-update-handler.js.map +1 -1
- package/lib/lsp/index.d.ts +3 -1
- package/lib/lsp/index.d.ts.map +1 -1
- package/lib/lsp/index.js +3 -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/lsp/shared-module.d.ts +4 -8
- package/lib/lsp/shared-module.d.ts.map +1 -1
- package/lib/lsp/shared-module.js.map +1 -1
- package/lib/lsp/start-language-server.d.ts +8 -7
- package/lib/lsp/start-language-server.d.ts.map +1 -1
- package/lib/lsp/start-language-server.js +13 -7
- package/lib/lsp/start-language-server.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 +142 -0
- package/lib/messages/renderer.d.ts.map +1 -0
- package/lib/messages/renderer.js +165 -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/measure-memory.d.ts.map +1 -1
- package/lib/node/measure-memory.js +1 -0
- package/lib/node/measure-memory.js.map +1 -1
- package/lib/node/node-file-system-provider.d.ts +39 -4
- package/lib/node/node-file-system-provider.d.ts.map +1 -1
- package/lib/node/node-file-system-provider.js +109 -49
- package/lib/node/node-file-system-provider.js.map +1 -1
- package/lib/node/profile-capture.d.ts +8 -2
- package/lib/node/profile-capture.d.ts.map +1 -1
- package/lib/node/profile-capture.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 +16 -1
- package/lib/node/socket-launcher.d.ts.map +1 -1
- package/lib/node/socket-launcher.js +4 -3
- package/lib/node/socket-launcher.js.map +1 -1
- package/lib/node/stdio-launcher.d.ts +1 -1
- package/lib/node/stdio-launcher.d.ts.map +1 -1
- package/lib/node/stdio-launcher.js +1 -1
- package/lib/node/stdio-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 +62 -14
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +27 -6
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/node/index.d.ts +1 -0
- package/lib/testing/node/index.d.ts.map +1 -1
- package/lib/testing/node/index.js +1 -0
- package/lib/testing/node/index.js.map +1 -1
- package/lib/testing/node/lsp-harness.d.ts.map +1 -1
- package/lib/testing/node/lsp-harness.js +2 -0
- package/lib/testing/node/lsp-harness.js.map +1 -1
- package/lib/testing/node/lsp-server-connection.d.ts +11 -3
- package/lib/testing/node/lsp-server-connection.d.ts.map +1 -1
- package/lib/testing/node/lsp-server-connection.js +42 -9
- package/lib/testing/node/lsp-server-connection.js.map +1 -1
- package/lib/testing/node/scratch-workspace.d.ts.map +1 -1
- package/lib/testing/node/scratch-workspace.js +10 -5
- package/lib/testing/node/scratch-workspace.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/node/unhandled-rejections.d.ts +20 -0
- package/lib/testing/node/unhandled-rejections.d.ts.map +1 -0
- package/lib/testing/node/unhandled-rejections.js +32 -0
- package/lib/testing/node/unhandled-rejections.js.map +1 -0
- 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/run-update-pipeline.d.ts +4 -4
- package/lib/testing/run-update-pipeline.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.d.ts +10 -9
- package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.js +17 -9
- package/lib/testing/stub-ast-document-manager.js.map +1 -1
- package/lib/testing/stub-document-builder.d.ts +26 -11
- package/lib/testing/stub-document-builder.d.ts.map +1 -1
- package/lib/testing/stub-document-builder.js +57 -4
- package/lib/testing/stub-document-builder.js.map +1 -1
- package/lib/testing/stub-hydranium-text-documents.d.ts +22 -7
- package/lib/testing/stub-hydranium-text-documents.d.ts.map +1 -1
- package/lib/testing/stub-hydranium-text-documents.js +92 -15
- package/lib/testing/stub-hydranium-text-documents.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 +7 -6
- package/lib/testing/stub-model-service.d.ts.map +1 -1
- package/lib/testing/stub-model-service.js +4 -4
- package/lib/testing/stub-model-service.js.map +1 -1
- package/lib/util/connection-liveness.d.ts +7 -6
- package/lib/util/connection-liveness.d.ts.map +1 -1
- package/lib/util/connection-liveness.js +35 -14
- package/lib/util/connection-liveness.js.map +1 -1
- package/package.json +17 -8
- package/src/documents/ast-document-manager.ts +348 -64
- package/src/documents/client-ids.ts +5 -22
- package/src/documents/client-session-errors.ts +24 -0
- package/src/documents/client-session-registry.ts +240 -0
- package/src/documents/file-system-task-queue.ts +68 -0
- package/src/documents/hydranium-text-documents.ts +959 -201
- package/src/documents/index.ts +3 -0
- package/src/documents/language-client-text-shadow.ts +59 -11
- package/src/documents/self-save-registry.ts +52 -13
- package/src/index.ts +6 -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 +50 -5
- package/src/langium/document-builder/build-session.ts +87 -0
- package/src/langium/document-builder/document-builder.ts +720 -43
- package/src/langium/document-builder/index.ts +1 -0
- package/src/langium/integration-services.ts +67 -6
- package/src/langium/integrity/integrity-rule.ts +13 -5
- package/src/langium/integrity/integrity-service.ts +202 -17
- 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/language-module.ts +42 -4
- package/src/langium/model-service/client-session.ts +606 -0
- package/src/langium/model-service/index.ts +1 -0
- package/src/langium/model-service/model-service.ts +395 -351
- package/src/langium/module.ts +192 -63
- package/src/langium/naming/name-provider.ts +27 -5
- package/src/langium/naming/name-separator-validation.ts +34 -5
- package/src/langium/project/abstract-project-manager.ts +9 -1
- package/src/langium/project/project-change-event.ts +2 -2
- package/src/langium/residency/cst-residency-service.ts +36 -14
- package/src/langium/scope/hydranium-scope-provider.ts +60 -22
- package/src/langium/serialization/abstract-serializer.ts +13 -32
- package/src/langium/service-registry.ts +19 -2
- package/src/langium/shared-services.ts +19 -2
- package/src/langium/transfer/transfer-encoder.ts +85 -24
- package/src/langium/trivia/comment-preserver.ts +1100 -0
- package/src/langium/trivia/document-ending-preserver.ts +55 -0
- package/src/langium/trivia/index.ts +14 -0
- package/src/langium/trivia/trivia-contribution.ts +39 -0
- package/src/langium/trivia/trivia-preserver.ts +54 -0
- package/src/langium/trivia/trivia-service.ts +99 -0
- package/src/langium/update-rewrite/update-rewrite.ts +1 -1
- package/src/langium/validation/document-validator.ts +537 -11
- package/src/langium/workspace/document-uri-policy.ts +17 -12
- package/src/langium/workspace/file-not-found.ts +23 -0
- package/src/langium/workspace/file-system-provider.ts +153 -16
- package/src/langium/workspace/hydranium-langium-document-factory.ts +34 -0
- package/src/langium/workspace/hydranium-workspace-lock.ts +21 -0
- package/src/langium/workspace/hydranium-workspace-manager.ts +133 -12
- package/src/langium/workspace/in-memory-file-system-provider.ts +47 -16
- package/src/langium/workspace/initialize-workspace.ts +43 -5
- package/src/langium/workspace/langium-documents.ts +113 -33
- package/src/langium/workspace/persistent-file-system-provider.ts +0 -7
- package/src/langium/workspace/virtual-document.ts +96 -19
- package/src/langium/workspace/write-lock-scope.ts +4 -3
- package/src/locale/index.ts +10 -0
- package/src/locale/server-locale.ts +86 -0
- package/src/lsp/completion/hydranium-completion-provider.ts +82 -2
- package/src/lsp/connection-features.ts +67 -0
- package/src/lsp/diagnostics-connection.ts +56 -0
- package/src/lsp/hydranium-document-update-handler.ts +182 -106
- package/src/lsp/index.ts +3 -1
- package/src/lsp/lsp-latency.ts +62 -0
- package/src/lsp/semantic-token-provider.ts +74 -7
- package/src/lsp/shared-module.ts +4 -8
- package/src/lsp/start-language-server.ts +13 -7
- package/src/messages/carriers.ts +78 -0
- package/src/messages/index.ts +36 -0
- package/src/messages/renderer.ts +212 -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/measure-memory.ts +1 -0
- package/src/node/node-file-system-provider.ts +122 -51
- package/src/node/profile-capture.ts +8 -2
- package/src/node/profiling-run.ts +3 -3
- package/src/node/rename-over-open-readers.ts +78 -0
- package/src/node/socket-launcher.ts +19 -4
- package/src/node/stdio-launcher.ts +1 -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 +103 -27
- package/src/testing/node/index.ts +1 -0
- package/src/testing/node/lsp-harness.ts +2 -0
- package/src/testing/node/lsp-server-connection.ts +61 -11
- package/src/testing/node/scratch-workspace.ts +10 -5
- package/src/testing/node/spawned-server.ts +35 -1
- package/src/testing/node/unhandled-rejections.ts +31 -0
- 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/run-update-pipeline.ts +4 -4
- package/src/testing/stub-ast-document-manager.ts +28 -21
- package/src/testing/stub-document-builder.ts +83 -17
- package/src/testing/stub-hydranium-text-documents.ts +127 -22
- package/src/testing/stub-langium-documents.ts +3 -2
- package/src/testing/stub-model-service.ts +9 -8
- package/src/util/connection-liveness.ts +37 -14
- 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
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 CrossBreeze, EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the MIT License which is available in the project root.
|
|
6
|
+
*
|
|
7
|
+
* SPDX-License-Identifier: MIT
|
|
8
|
+
********************************************************************************/
|
|
9
|
+
|
|
10
|
+
import { type URI } from '@hydranium/langium';
|
|
11
|
+
|
|
12
|
+
// Not re-exported from the workspace barrel: the framework's providers share
|
|
13
|
+
// it, and it is no API of theirs.
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A missing-file error shaped as a Node file system raises it, with code
|
|
17
|
+
* `ENOENT` and the path: callers tell a missing file from any other failure by
|
|
18
|
+
* those two fields, whichever provider is bound. The last close relies on it to
|
|
19
|
+
* tell a document gone meanwhile from any other failed rebuild.
|
|
20
|
+
*/
|
|
21
|
+
export function notFound(message: string, uri: URI): Error {
|
|
22
|
+
return Object.assign(new Error(message), { code: 'ENOENT', path: uri.fsPath });
|
|
23
|
+
}
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
|
|
10
10
|
import { type Tracer } from '@hydranium/protocol';
|
|
11
11
|
import { EmptyFileSystemProvider } from '@hydranium/langium';
|
|
12
|
-
import type { URI } from '@hydranium/langium';
|
|
12
|
+
import type { FileSystemNode, URI } from '@hydranium/langium';
|
|
13
13
|
import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
|
|
14
14
|
import { type LogNameOptions } from '../diagnostics/logger.js';
|
|
15
15
|
import { type ServerSharedServicesMinimal } from '../shared-services.js';
|
|
16
|
-
import { serveVirtualDocument } from './virtual-document.js';
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
|
-
* Empty-filesystem
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Node-backed
|
|
23
|
-
* lives in `@hydranium/core/node` (it pulls
|
|
18
|
+
* Empty-filesystem {@link WritableFileSystemProvider}. For browser / test / CLI
|
|
19
|
+
* hosts that don't have a real filesystem. All writes are no-ops. On the
|
|
20
|
+
* portable `.` entry it is the {@link FileSystemProviderRegistry.host} when
|
|
21
|
+
* `context.fileSystemProvider` gives no writable provider; the Node-backed
|
|
22
|
+
* `DefaultFileSystemProvider` lives in `@hydranium/core/node` (it pulls
|
|
23
|
+
* `node:fs`).
|
|
24
24
|
*/
|
|
25
25
|
export class DefaultEmptyFileSystemProvider extends EmptyFileSystemProvider implements WritableFileSystemProvider {
|
|
26
26
|
protected readonly tracer: Tracer;
|
|
@@ -37,16 +37,153 @@ export class DefaultEmptyFileSystemProvider extends EmptyFileSystemProvider impl
|
|
|
37
37
|
// no-op
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
// `async` so the base's refusal becomes a rejection: it throws
|
|
41
|
+
// SYNCHRONOUSLY from a method declared to return a promise, and a
|
|
42
|
+
// synchronous throw escapes the promise chain — `.catch()` never attaches
|
|
43
|
+
// and `Promise.all` dies while its argument array is still being built, so
|
|
44
|
+
// a caller reading several URIs cannot handle the miss it asked about. The
|
|
45
|
+
// base declares `readFile` and `readBinary` param-less, so the param is
|
|
46
|
+
// optional there.
|
|
47
|
+
override async readFile(_uri?: URI): Promise<string> {
|
|
48
|
+
return super.readFile();
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
override
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
override async readBinary(_uri?: URI): Promise<Uint8Array> {
|
|
52
|
+
return super.readBinary();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override async stat(uri: URI): Promise<FileSystemNode> {
|
|
56
|
+
return super.stat(uri);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The provider bound on `workspace.FileSystemProvider`: it dispatches each call
|
|
62
|
+
* by the URI's scheme to the provider registered for it in the shared
|
|
63
|
+
* `fileSystemProviders` group, and to the {@link host} for any scheme without
|
|
64
|
+
* one.
|
|
65
|
+
*
|
|
66
|
+
* So one provider answers for each scheme, and a host's provider needs to know
|
|
67
|
+
* only its own: the framework registers `virtual:` there, and an adopter adds a
|
|
68
|
+
* scheme by contributing to the group. The host takes every unclaimed scheme
|
|
69
|
+
* rather than `file:` alone, which keeps an in-memory workspace under `memory:`
|
|
70
|
+
* or any other scheme on the host's provider.
|
|
71
|
+
*
|
|
72
|
+
* `THost` types the host, so an adopter whose own provider has more members
|
|
73
|
+
* than the base declares the slot as `FileSystemProviderRegistry<MyProvider>`,
|
|
74
|
+
* binds a {@link DefaultFileSystemProviderRegistry} with that host, and reads
|
|
75
|
+
* those members through `services.workspace.FileSystemProvider.host`.
|
|
76
|
+
*/
|
|
77
|
+
export interface FileSystemProviderRegistry<
|
|
78
|
+
THost extends WritableFileSystemProvider = WritableFileSystemProvider
|
|
79
|
+
> extends WritableFileSystemProvider {
|
|
80
|
+
/** The provider for every scheme no entry of `fileSystemProviders` claims. */
|
|
81
|
+
readonly host: THost;
|
|
82
|
+
/** The provider that answers for `uri`. */
|
|
83
|
+
providerFor(uri: URI): WritableFileSystemProvider;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Options for {@link DefaultFileSystemProviderRegistry}. */
|
|
87
|
+
export interface FileSystemProviderRegistryOptions<
|
|
88
|
+
THost extends WritableFileSystemProvider = WritableFileSystemProvider
|
|
89
|
+
> extends LogNameOptions {
|
|
90
|
+
/**
|
|
91
|
+
* The provider for every scheme no entry of `fileSystemProviders` claims.
|
|
92
|
+
* The framework passes the provider `context.fileSystemProvider` returns,
|
|
93
|
+
* or a {@link DefaultEmptyFileSystemProvider} when that is not writable.
|
|
94
|
+
*/
|
|
95
|
+
host: THost;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The framework's {@link FileSystemProviderRegistry}.
|
|
100
|
+
*
|
|
101
|
+
* A directory is listed by the provider of its own scheme, so a workspace
|
|
102
|
+
* root's tree comes from that provider alone.
|
|
103
|
+
*
|
|
104
|
+
* `realpath` and `mtimeMs` are always present and forward to the scheme's
|
|
105
|
+
* provider. Where that provider lacks one, `realpath` returns the URI unchanged
|
|
106
|
+
* and `mtimeMs` returns `undefined`: the answers `RealpathDocumentUriPolicy`
|
|
107
|
+
* and the self-save filter already give a provider without them.
|
|
108
|
+
*/
|
|
109
|
+
export class DefaultFileSystemProviderRegistry<
|
|
110
|
+
THost extends WritableFileSystemProvider = WritableFileSystemProvider
|
|
111
|
+
> implements FileSystemProviderRegistry<THost> {
|
|
112
|
+
readonly host: THost;
|
|
113
|
+
protected readonly tracer: Tracer;
|
|
114
|
+
|
|
115
|
+
constructor(
|
|
116
|
+
protected readonly services: ServerSharedServicesMinimal & { fileSystemProviders: Record<string, WritableFileSystemProvider> },
|
|
117
|
+
options: FileSystemProviderRegistryOptions<THost>
|
|
118
|
+
) {
|
|
119
|
+
this.host = options.host;
|
|
120
|
+
this.tracer = services.Tracer.for(options.logName ?? this.constructor.name).trace('instantiated');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The group is read per call, not in the constructor, so a registered
|
|
125
|
+
* provider is built on first use and may read slots that reach back to this
|
|
126
|
+
* one. Only an OWN key of the group counts: the DI container resolves any
|
|
127
|
+
* key found on the prototype chain, so a scheme such as `constructor` would
|
|
128
|
+
* otherwise dispatch to a function.
|
|
129
|
+
*/
|
|
130
|
+
providerFor(uri: URI): WritableFileSystemProvider {
|
|
131
|
+
const providers = this.services.fileSystemProviders;
|
|
132
|
+
return Object.hasOwn(providers, uri.scheme) ? providers[uri.scheme] : this.host;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// The async methods are `async` so a provider that throws synchronously from
|
|
136
|
+
// one still rejects, for the reason `DefaultEmptyFileSystemProvider` gives.
|
|
137
|
+
async writeFile(uri: URI, content: string): Promise<void> {
|
|
138
|
+
return this.providerFor(uri).writeFile(uri, content);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async mtimeMs(uri: URI): Promise<number | undefined> {
|
|
142
|
+
return this.providerFor(uri).mtimeMs?.(uri);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
realpath(uri: URI): URI | undefined {
|
|
146
|
+
const provider = this.providerFor(uri);
|
|
147
|
+
return provider.realpath ? provider.realpath(uri) : uri;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async stat(uri: URI): Promise<FileSystemNode> {
|
|
151
|
+
return this.providerFor(uri).stat(uri);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
statSync(uri: URI): FileSystemNode {
|
|
155
|
+
return this.providerFor(uri).statSync(uri);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async exists(uri: URI): Promise<boolean> {
|
|
159
|
+
return this.providerFor(uri).exists(uri);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
existsSync(uri: URI): boolean {
|
|
163
|
+
return this.providerFor(uri).existsSync(uri);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async readBinary(uri: URI): Promise<Uint8Array> {
|
|
167
|
+
return this.providerFor(uri).readBinary(uri);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
readBinarySync(uri: URI): Uint8Array {
|
|
171
|
+
return this.providerFor(uri).readBinarySync(uri);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async readFile(uri: URI): Promise<string> {
|
|
175
|
+
return this.providerFor(uri).readFile(uri);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
readFileSync(uri: URI): string {
|
|
179
|
+
return this.providerFor(uri).readFileSync(uri);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async readDirectory(uri: URI): Promise<FileSystemNode[]> {
|
|
183
|
+
return this.providerFor(uri).readDirectory(uri);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
readDirectorySync(uri: URI): FileSystemNode[] {
|
|
187
|
+
return this.providerFor(uri).readDirectorySync(uri);
|
|
51
188
|
}
|
|
52
189
|
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type ParseResult,
|
|
16
16
|
type URI
|
|
17
17
|
} from '@hydranium/langium';
|
|
18
|
+
import { type ExtendedServiceRegistry } from '../service-registry.js';
|
|
18
19
|
import { type Serializer } from '../serialization/serializer.js';
|
|
19
20
|
|
|
20
21
|
/** Structural view of the per-language serializer slot on the resolved services. */
|
|
@@ -49,6 +50,39 @@ interface WithSerializer {
|
|
|
49
50
|
* node identity is preserved.
|
|
50
51
|
*/
|
|
51
52
|
export class HydraniumLangiumDocumentFactory extends DefaultLangiumDocumentFactory {
|
|
53
|
+
/**
|
|
54
|
+
* Narrows the inherited Langium `ServiceRegistry` field to the framework's
|
|
55
|
+
* {@link ExtendedServiceRegistry}, so the by-id lookup below needs no
|
|
56
|
+
* per-callsite cast. The framework's shared module binds that class.
|
|
57
|
+
*/
|
|
58
|
+
declare protected readonly serviceRegistry: ExtendedServiceRegistry;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Parse `text` for `uri` under the grammar `languageId` names, instead of
|
|
62
|
+
* the one `uri` routes to.
|
|
63
|
+
*
|
|
64
|
+
* For a URI that routes to no grammar at all: a directory, or any other URI
|
|
65
|
+
* that names no file and so carries no extension. Langium's ladder ends at
|
|
66
|
+
* the extension, so it reports `no services for the extension ''` from
|
|
67
|
+
* inside the parse — naming neither the URI nor the caller that could have
|
|
68
|
+
* said which grammar it meant.
|
|
69
|
+
*
|
|
70
|
+
* The caller supplies the language because nothing else can. A URI with no
|
|
71
|
+
* extension carries no routing signal, and choosing on its behalf would be a
|
|
72
|
+
* guess the moment a second grammar is registered — which is why this takes
|
|
73
|
+
* the id rather than falling back to a sole registered language.
|
|
74
|
+
*
|
|
75
|
+
* @throws when `languageId` names no registered grammar.
|
|
76
|
+
*/
|
|
77
|
+
fromStringInLanguage<T extends AstNode = AstNode>(text: string, uri: URI, languageId: string): LangiumDocument<T> {
|
|
78
|
+
const services = this.serviceRegistry.getServicesById(languageId);
|
|
79
|
+
if (!services) {
|
|
80
|
+
throw new Error(`No grammar is registered for the language id '${languageId}' (parsing ${uri.toString()}).`);
|
|
81
|
+
}
|
|
82
|
+
const parseResult: ParseResult<T> = services.parser.LangiumParser.parse<T>(text);
|
|
83
|
+
return this.createLangiumDocument<T>(parseResult, uri, undefined, text);
|
|
84
|
+
}
|
|
85
|
+
|
|
52
86
|
override fromModel<T extends AstNode = AstNode>(model: T, uri: URI): LangiumDocument<T> {
|
|
53
87
|
// Make the code-built AST as structurally complete as a parsed one — the
|
|
54
88
|
// parser links containers, `fromModel` does not. In place (identity kept).
|
|
@@ -29,7 +29,28 @@ import { runInWriteLockScope } from './write-lock-scope.js';
|
|
|
29
29
|
* would turn ordinary read-then-write sequences into false positives.
|
|
30
30
|
*/
|
|
31
31
|
export class HydraniumWorkspaceLock extends DefaultWorkspaceLock {
|
|
32
|
+
/** Backs {@link writeCancellations}. */
|
|
33
|
+
protected cancelledWriteCount = 0;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* How many calls have cancelled the lock's latest write: every `write`,
|
|
37
|
+
* which cancels the write before it, and every `cancelWrite`. A caller that
|
|
38
|
+
* reads this right after queuing a write, and reads the same number later,
|
|
39
|
+
* holds a write nothing has cancelled, whether it is still queued or
|
|
40
|
+
* already running. Its token answers that only once the write runs, since
|
|
41
|
+
* a queued write has not been handed it yet.
|
|
42
|
+
*/
|
|
43
|
+
get writeCancellations(): number {
|
|
44
|
+
return this.cancelledWriteCount;
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
override write(action: (token: CancellationToken) => MaybePromise<void>): Promise<void> {
|
|
33
48
|
return super.write(token => runInWriteLockScope(() => action(token)));
|
|
34
49
|
}
|
|
50
|
+
|
|
51
|
+
/** Counted here rather than in {@link write}, because Langium's `write` cancels through this method too. */
|
|
52
|
+
override cancelWrite(): void {
|
|
53
|
+
this.cancelledWriteCount++;
|
|
54
|
+
super.cancelWrite();
|
|
55
|
+
}
|
|
35
56
|
}
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
10
|
import { Deferred, type Logger, type Tracer } from '@hydranium/protocol';
|
|
11
|
-
import { DefaultWorkspaceManager, DocumentState, type LangiumDocument, UriUtils, type URI } from '@hydranium/langium';
|
|
12
|
-
import { type CancellationToken } from 'vscode-languageserver';
|
|
11
|
+
import { DefaultWorkspaceManager, DocumentState, type LangiumDocument, type Stream, UriUtils, type URI } from '@hydranium/langium';
|
|
12
|
+
import { type CancellationToken, type InitializeParams } from 'vscode-languageserver';
|
|
13
13
|
import type { WorkspaceFolder } from 'vscode-languageserver-types';
|
|
14
14
|
import { type LogNameOptions, resolveLogFilePlaceholder, toLogFileWorkspaceToken } from '../diagnostics/logger.js';
|
|
15
|
+
import type { ServerLocale } from '../../locale/server-locale.js';
|
|
15
16
|
import type { ProjectChangeEvent } from '../project/project-change-event.js';
|
|
16
17
|
import type { ProjectManager } from '../project/project-manager.js';
|
|
17
18
|
import type { ServerSharedServicesMinimal } from '../shared-services.js';
|
|
@@ -92,6 +93,18 @@ export function installOperationCancelledSuppression(logger: Logger): void {
|
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
/** Options for {@link HydraniumWorkspaceManager}. */
|
|
97
|
+
export interface HydraniumWorkspaceManagerOptions extends LogNameOptions {
|
|
98
|
+
/**
|
|
99
|
+
* Whether startup warns about seeded documents the bound
|
|
100
|
+
* `FileSystemProvider` cannot serve (see
|
|
101
|
+
* {@link HydraniumWorkspaceManager.warnIfDocumentsUnserved}). Defaults to
|
|
102
|
+
* `true`; turn it off for a host that drops such documents at their last
|
|
103
|
+
* close on purpose.
|
|
104
|
+
*/
|
|
105
|
+
warnUnservedDocuments?: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
/**
|
|
96
109
|
* Framework {@link DefaultWorkspaceManager} subclass that integrates the
|
|
97
110
|
* project tier with Langium's workspace startup.
|
|
@@ -124,8 +137,8 @@ export function installOperationCancelledSuppression(logger: Logger): void {
|
|
|
124
137
|
* URIs (its own members plus any transitive dependents per the
|
|
125
138
|
* `getAffectedProjects` hook). This manager re-runs
|
|
126
139
|
* `DocumentBuilder.resetToState(doc, DocumentState.Changed)` on each
|
|
127
|
-
* affected document so the
|
|
128
|
-
* visibility scope.
|
|
140
|
+
* affected document so the build of the update that changed the descriptor
|
|
141
|
+
* re-links them with the new visibility scope.
|
|
129
142
|
*
|
|
130
143
|
* Descriptor URIs that triggered the cycle are intentionally excluded
|
|
131
144
|
* from the affected set by `AbstractProjectManager.onBuildUpdate` —
|
|
@@ -156,19 +169,27 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
156
169
|
readonly workspaceInitialized: Promise<unknown> = this.workspaceInitializedDeferred.promise;
|
|
157
170
|
|
|
158
171
|
protected readonly uriPolicy: DocumentUriPolicy;
|
|
172
|
+
/** Handed the client's locale at init; read by whoever renders in it. */
|
|
173
|
+
protected readonly serverLocale: ServerLocale;
|
|
159
174
|
protected readonly writableFileSystemProvider: WritableFileSystemProvider;
|
|
160
175
|
protected readonly additionalDocuments: Record<string, AdditionalDocumentContribution>;
|
|
161
176
|
/** Registry consulted by {@link warnIfUnroutable} to check a seeded document routes. */
|
|
162
177
|
protected readonly languageRegistry: ServerSharedServicesMinimal['ServiceRegistry'];
|
|
178
|
+
/** Whether startup runs {@link warnIfDocumentsUnserved}. */
|
|
179
|
+
protected readonly warnUnservedDocuments: boolean;
|
|
180
|
+
/** URIs of the documents the running startup's file traversal loaded; see {@link loadWorkspaceDocuments}. */
|
|
181
|
+
protected readonly traversedUris = new Set<string>();
|
|
163
182
|
|
|
164
|
-
constructor(services: ServerSharedServicesMinimal, options:
|
|
183
|
+
constructor(services: ServerSharedServicesMinimal, options: HydraniumWorkspaceManagerOptions = {}) {
|
|
165
184
|
super(services);
|
|
166
185
|
this.projectManager = services.workspace.ProjectManager;
|
|
167
186
|
this.projectManager.onProjectsChanged(event => this.onProjectsChanged(event));
|
|
168
187
|
this.uriPolicy = services.workspace.DocumentUriPolicy;
|
|
188
|
+
this.serverLocale = services.ServerLocale;
|
|
169
189
|
this.writableFileSystemProvider = services.workspace.FileSystemProvider;
|
|
170
190
|
this.additionalDocuments = services.additionalDocuments;
|
|
171
191
|
this.languageRegistry = services.ServiceRegistry;
|
|
192
|
+
this.warnUnservedDocuments = options.warnUnservedDocuments ?? true;
|
|
172
193
|
this.tracer = services.Tracer.for(options.logName ?? 'WorkspaceManager').trace('instantiated');
|
|
173
194
|
installOperationCancelledSuppression(this.tracer);
|
|
174
195
|
}
|
|
@@ -197,16 +218,16 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
197
218
|
// seeded. `tags` is read at the done-emit, so the document count pushed
|
|
198
219
|
// inside the callback appears in the log line.
|
|
199
220
|
const tags: string[] = [`${contributions.length} contributions`];
|
|
200
|
-
|
|
221
|
+
const seeded: LangiumDocument[] = [];
|
|
201
222
|
await this.tracer.time(
|
|
202
223
|
'Load additional documents',
|
|
203
224
|
async () => {
|
|
204
225
|
await collectAdditionalDocuments(this.additionalDocuments, folders, document => {
|
|
205
|
-
|
|
226
|
+
seeded.push(document);
|
|
206
227
|
this.warnIfUnroutable(document);
|
|
207
228
|
collector(document);
|
|
208
229
|
});
|
|
209
|
-
tags.push(`${
|
|
230
|
+
tags.push(`${seeded.length} documents`);
|
|
210
231
|
},
|
|
211
232
|
'info',
|
|
212
233
|
{ logAfterMs: 0, tags }
|
|
@@ -268,11 +289,86 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
268
289
|
discovered.push(document);
|
|
269
290
|
}
|
|
270
291
|
}
|
|
271
|
-
|
|
292
|
+
this.traversedUris.clear();
|
|
293
|
+
let documents: LangiumDocument[];
|
|
294
|
+
try {
|
|
295
|
+
documents = await super.performStartup(folders);
|
|
296
|
+
if (this.warnUnservedDocuments) {
|
|
297
|
+
await this.warnIfDocumentsUnserved(documents.filter(document => !this.traversedUris.has(document.uri.toString())));
|
|
298
|
+
}
|
|
299
|
+
} finally {
|
|
300
|
+
this.traversedUris.clear();
|
|
301
|
+
}
|
|
272
302
|
this.probePathDivergence(folders);
|
|
273
303
|
return this.withDiscoveredDescriptors(documents, discovered);
|
|
274
304
|
}
|
|
275
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Record each document the file traversal loads, so startup can tell them
|
|
308
|
+
* from the documents `loadAdditionalDocuments` seeded, through the
|
|
309
|
+
* `additionalDocuments` group or an override of its own.
|
|
310
|
+
*
|
|
311
|
+
* The traversal found each of its documents through the provider, so asking
|
|
312
|
+
* it again whether they exist costs one call per workspace file and cannot
|
|
313
|
+
* come out false. Telling them apart by scheme does not work either: the
|
|
314
|
+
* registry's host answers every scheme no other provider claims, a seeded
|
|
315
|
+
* scheme nobody serves included. An override that loads documents without
|
|
316
|
+
* delegating here leaves them unrecorded, so startup asks the provider
|
|
317
|
+
* about each of them.
|
|
318
|
+
*/
|
|
319
|
+
protected override async loadWorkspaceDocuments(uris: Stream<URI>, collector: (document: LangiumDocument) => void): Promise<void> {
|
|
320
|
+
await super.loadWorkspaceDocuments(uris, document => {
|
|
321
|
+
this.traversedUris.add(document.uri.toString());
|
|
322
|
+
collector(document);
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Warn once when the bound `FileSystemProvider` cannot serve a seeded
|
|
328
|
+
* document, naming each such document's scheme.
|
|
329
|
+
*
|
|
330
|
+
* The last close keeps a document only if the provider says it `exists`, so
|
|
331
|
+
* each such document leaves the workspace the first time an editor closes
|
|
332
|
+
* it, and whatever resolved against it breaks. The framework's registry
|
|
333
|
+
* serves `virtual:` through the `fileSystemProviders` group and every other
|
|
334
|
+
* scheme through its host, which knows nothing of a scheme an adopter
|
|
335
|
+
* invented for its seeded documents, and nothing else reports the loss. A
|
|
336
|
+
* provider that throws counts as not serving the document, since a startup
|
|
337
|
+
* that failed on a diagnostic would be worse than the loss.
|
|
338
|
+
*
|
|
339
|
+
* Runs over every document startup collected outside the file traversal,
|
|
340
|
+
* which is what `loadAdditionalDocuments` seeded, through the
|
|
341
|
+
* `additionalDocuments` group or an override of that method, once startup
|
|
342
|
+
* has added them to the workspace, unless `warnUnservedDocuments` is
|
|
343
|
+
* `false`.
|
|
344
|
+
*/
|
|
345
|
+
protected async warnIfDocumentsUnserved(documents: readonly LangiumDocument[]): Promise<void> {
|
|
346
|
+
const unserved: URI[] = [];
|
|
347
|
+
for (const document of documents) {
|
|
348
|
+
let served = false;
|
|
349
|
+
try {
|
|
350
|
+
served = await this.writableFileSystemProvider.exists(document.uri);
|
|
351
|
+
} catch {
|
|
352
|
+
// Counted as unserved, below.
|
|
353
|
+
}
|
|
354
|
+
if (!served) {
|
|
355
|
+
unserved.push(document.uri);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (unserved.length === 0) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const schemes = [...new Set(unserved.map(uri => uri.scheme))];
|
|
362
|
+
const named = unserved.slice(0, 3).map(uri => uri.toString());
|
|
363
|
+
this.tracer.warn(
|
|
364
|
+
`${unserved.length} seeded document(s) under ${schemes.map(scheme => `${scheme}:`).join(', ')} cannot be served by the bound workspace.FileSystemProvider ` +
|
|
365
|
+
`(${named.join(', ')}${unserved.length > 3 ? ', …' : ''}), so each leaves the workspace at its ` +
|
|
366
|
+
`last close. Register a provider under the key ${schemes.map(scheme => `'${scheme}'`).join(', ')} in the shared ` +
|
|
367
|
+
'fileSystemProviders group, or serve the scheme from the host provider; set warnUnservedDocuments: false ' +
|
|
368
|
+
'to accept the loss.'
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
276
372
|
/**
|
|
277
373
|
* Add back the documents project discovery created that Langium's file
|
|
278
374
|
* traversal then filtered out.
|
|
@@ -360,6 +456,31 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
360
456
|
}
|
|
361
457
|
}
|
|
362
458
|
|
|
459
|
+
/**
|
|
460
|
+
* Forward the locale the client declared, then Langium's own read of the
|
|
461
|
+
* params. `DefaultWorkspaceManager.initialize` reads `workspaceFolders`
|
|
462
|
+
* alone, so `params.locale` would otherwise be discarded — and this is the
|
|
463
|
+
* only place it arrives, which the headless init seams route through too.
|
|
464
|
+
*
|
|
465
|
+
* **The ABSENT case is reported from here rather than from `ServerLocale`,
|
|
466
|
+
* because this is the only end that can see it.** `accept` is not called
|
|
467
|
+
* when no locale was declared — nor should it be, since `''` is a claim
|
|
468
|
+
* about a language rather than the absence of one — so a log written there
|
|
469
|
+
* covers one of the two outcomes and leaves the other looking like a server
|
|
470
|
+
* that never reached init. Both lines are at `info` for the reason `accept`
|
|
471
|
+
* gives: the framework ships no catalogue, so an undeclared locale and an
|
|
472
|
+
* untranslated code produce the same English and the log is what separates
|
|
473
|
+
* them.
|
|
474
|
+
*/
|
|
475
|
+
override initialize(params: InitializeParams): void {
|
|
476
|
+
if (params.locale) {
|
|
477
|
+
this.serverLocale.accept(params.locale);
|
|
478
|
+
} else {
|
|
479
|
+
this.tracer.info("no locale declared at init — rendering messages in the framework's English");
|
|
480
|
+
}
|
|
481
|
+
super.initialize(params);
|
|
482
|
+
}
|
|
483
|
+
|
|
363
484
|
/**
|
|
364
485
|
* Override of Langium's workspace setup to resolve / reject
|
|
365
486
|
* {@link workspaceInitializedDeferred} once setup completes. Adopters with
|
|
@@ -380,9 +501,9 @@ export class HydraniumWorkspaceManager extends DefaultWorkspaceManager {
|
|
|
380
501
|
|
|
381
502
|
/**
|
|
382
503
|
* Default cascade-rebuild handler. Iterates {@link ProjectChangeEvent.affectedDocuments}
|
|
383
|
-
* and resets each to {@link DocumentState.Changed} so the
|
|
384
|
-
* re-runs the pipeline (parse → link → validate)
|
|
385
|
-
* visibility scope.
|
|
504
|
+
* and resets each to {@link DocumentState.Changed} so the build of the update
|
|
505
|
+
* that changed the descriptor re-runs the pipeline (parse → link → validate)
|
|
506
|
+
* under the new project visibility scope.
|
|
386
507
|
*
|
|
387
508
|
* Subclasses can override for additional behaviour (e.g. logging,
|
|
388
509
|
* telemetry, custom rebuild policies); call `super` to preserve the
|
|
@@ -8,11 +8,40 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
10
|
import { type FileSystemNode, URI } from '@hydranium/langium';
|
|
11
|
-
import { type Tracer } from '@hydranium/protocol';
|
|
11
|
+
import { defineMessage, type Tracer } from '@hydranium/protocol';
|
|
12
12
|
import { type WritableFileSystemProvider } from '../../documents/ast-document-manager.js';
|
|
13
13
|
import { type LogNameOptions } from '../diagnostics/logger.js';
|
|
14
14
|
import { serverSharedFactory, type ServerSharedServicesMinimal } from '../shared-services.js';
|
|
15
|
-
import {
|
|
15
|
+
import { notFound } from './file-not-found.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A provider's spelling of "the document is not there", raised wherever a read
|
|
19
|
+
* finds no content — this filesystem, or a URI naming no location a disk-backed
|
|
20
|
+
* provider can reach. Distinct from `NO_LOADABLE_CONTENT`, which the URI policy
|
|
21
|
+
* raises when it can settle the question AHEAD of the read; a provider with no
|
|
22
|
+
* `realpath` cannot, so the miss surfaces here instead.
|
|
23
|
+
*/
|
|
24
|
+
export const NO_SUCH_FILE = defineMessage('hydranium/core/no-such-file', 'No such file: {uri}');
|
|
25
|
+
|
|
26
|
+
/** The same for a node of any kind, so it also covers a directory. */
|
|
27
|
+
export const NO_SUCH_PATH = defineMessage('hydranium/core/no-such-path', 'No such file or directory: {uri}');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A write addressed a URI the provider cannot reach on disk.
|
|
31
|
+
*
|
|
32
|
+
* Deliberately not a not-found code: {@link NO_SUCH_FILE} reports something
|
|
33
|
+
* missing, which a caller may reasonably answer by creating it — exactly the
|
|
34
|
+
* wrong reading here. The destination is not missing; the URI names no disk
|
|
35
|
+
* location at all, and no retry makes it one.
|
|
36
|
+
*
|
|
37
|
+
* Declared here rather than beside the Node provider that raises it, so the
|
|
38
|
+
* message catalog stays reachable from the portable `.` entry — the Node
|
|
39
|
+
* module pulls `node:fs` and is server-only.
|
|
40
|
+
*/
|
|
41
|
+
export const UNSUPPORTED_WRITE = defineMessage(
|
|
42
|
+
'hydranium/core/unsupported-write',
|
|
43
|
+
'Cannot write {uri}: the scheme names no location on disk'
|
|
44
|
+
);
|
|
16
45
|
|
|
17
46
|
/**
|
|
18
47
|
* File content keyed by path, for seeding an {@link InMemoryFileSystemProvider}.
|
|
@@ -116,32 +145,34 @@ export class InMemoryFileSystemProvider implements WritableFileSystemProvider {
|
|
|
116
145
|
this.setFile(uri, content);
|
|
117
146
|
}
|
|
118
147
|
|
|
119
|
-
|
|
120
|
-
|
|
148
|
+
// `async` on each read whose sync twin can throw, rather than
|
|
149
|
+
// `Promise.resolve(this.<x>Sync(uri))`. That form evaluates the sync call
|
|
150
|
+
// FIRST, so a miss throws before `Promise.resolve` is ever reached — and a
|
|
151
|
+
// synchronous throw escapes the promise chain: `.catch()` never attaches and
|
|
152
|
+
// `Promise.all` dies while its argument array is still being built, so a
|
|
153
|
+
// caller reading several URIs cannot handle the miss it asked about.
|
|
154
|
+
async readFile(uri: URI): Promise<string> {
|
|
155
|
+
return this.readFileSync(uri);
|
|
121
156
|
}
|
|
122
157
|
|
|
123
158
|
readFileSync(uri: URI): string {
|
|
124
|
-
const served = serveVirtualDocument(this.services, uri);
|
|
125
|
-
if (served !== undefined) {
|
|
126
|
-
return served;
|
|
127
|
-
}
|
|
128
159
|
const content = this.files.get(normalize(uri));
|
|
129
160
|
if (content === undefined) {
|
|
130
|
-
throw
|
|
161
|
+
throw notFound(NO_SUCH_FILE.format({ uri: uri.toString() }), uri);
|
|
131
162
|
}
|
|
132
163
|
return content;
|
|
133
164
|
}
|
|
134
165
|
|
|
135
|
-
readBinary(uri: URI): Promise<Uint8Array> {
|
|
136
|
-
return
|
|
166
|
+
async readBinary(uri: URI): Promise<Uint8Array> {
|
|
167
|
+
return this.readBinarySync(uri);
|
|
137
168
|
}
|
|
138
169
|
|
|
139
170
|
readBinarySync(uri: URI): Uint8Array {
|
|
140
171
|
return new TextEncoder().encode(this.readFileSync(uri));
|
|
141
172
|
}
|
|
142
173
|
|
|
143
|
-
stat(uri: URI): Promise<FileSystemNode> {
|
|
144
|
-
return
|
|
174
|
+
async stat(uri: URI): Promise<FileSystemNode> {
|
|
175
|
+
return this.statSync(uri);
|
|
145
176
|
}
|
|
146
177
|
|
|
147
178
|
statSync(uri: URI): FileSystemNode {
|
|
@@ -152,7 +183,7 @@ export class InMemoryFileSystemProvider implements WritableFileSystemProvider {
|
|
|
152
183
|
if (this.hasChildren(path)) {
|
|
153
184
|
return { isFile: false, isDirectory: true, uri };
|
|
154
185
|
}
|
|
155
|
-
throw
|
|
186
|
+
throw notFound(NO_SUCH_PATH.format({ uri: uri.toString() }), uri);
|
|
156
187
|
}
|
|
157
188
|
|
|
158
189
|
exists(uri: URI): Promise<boolean> {
|
|
@@ -229,8 +260,8 @@ function normalize(uri: URI | string): string {
|
|
|
229
260
|
* services context exactly where a Node host spreads `NodeFileSystem`.
|
|
230
261
|
*
|
|
231
262
|
* A host that needs to reach the provider afterwards — to seed or mutate it
|
|
232
|
-
* mid-test —
|
|
233
|
-
* slot owns construction.
|
|
263
|
+
* mid-test — narrows `shared.workspace.FileSystemProvider.host` to this
|
|
264
|
+
* class, since the slot owns construction.
|
|
234
265
|
*/
|
|
235
266
|
export function inMemoryFileSystem(options: InMemoryFileSystemOptions = {}): {
|
|
236
267
|
fileSystemProvider: (services: unknown) => WritableFileSystemProvider;
|