@hydranium/core 1.0.0-next.19 → 1.0.0-next.193
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 +6 -2
- package/lib/documents/ast-document-manager.d.ts +222 -63
- package/lib/documents/ast-document-manager.d.ts.map +1 -1
- package/lib/documents/ast-document-manager.js +250 -83
- 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 +523 -101
- package/lib/documents/hydranium-text-documents.d.ts.map +1 -1
- package/lib/documents/hydranium-text-documents.js +961 -177
- package/lib/documents/hydranium-text-documents.js.map +1 -1
- package/lib/documents/index.d.ts +5 -0
- package/lib/documents/index.d.ts.map +1 -1
- package/lib/documents/index.js +5 -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/model-ledger.d.ts +47 -0
- package/lib/documents/model-ledger.d.ts.map +1 -0
- package/lib/documents/model-ledger.js +30 -0
- package/lib/documents/model-ledger.js.map +1 -0
- 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/documents/version-sync-service.d.ts +134 -0
- package/lib/documents/version-sync-service.d.ts.map +1 -0
- package/lib/documents/version-sync-service.js +171 -0
- package/lib/documents/version-sync-service.js.map +1 -0
- 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-extension-service.d.ts.map +1 -1
- package/lib/langium/ast-extension/ast-extension-service.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 +32 -9
- package/lib/langium/bootstrap.js.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass-service.d.ts.map +1 -1
- package/lib/langium/build-phase-pass/build-phase-pass-service.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/config/settings.js.map +1 -1
- package/lib/langium/diagnostics/hydranium-langium-profiler.d.ts.map +1 -1
- package/lib/langium/diagnostics/hydranium-langium-profiler.js.map +1 -1
- package/lib/langium/diagnostics/logger.d.ts +10 -3
- package/lib/langium/diagnostics/logger.d.ts.map +1 -1
- package/lib/langium/diagnostics/logger.js +12 -5
- package/lib/langium/diagnostics/logger.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 +56 -13
- package/lib/langium/diagnostics/lsp-logger.js.map +1 -1
- package/lib/langium/diagnostics/server-tracer.d.ts.map +1 -1
- package/lib/langium/diagnostics/server-tracer.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 +382 -29
- package/lib/langium/document-builder/document-builder.d.ts.map +1 -1
- package/lib/langium/document-builder/document-builder.js +659 -61
- 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/documentation/comment-provider.d.ts.map +1 -1
- package/lib/langium/documentation/comment-provider.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 +58 -13
- package/lib/langium/integrity/integrity-service.d.ts.map +1 -1
- package/lib/langium/integrity/integrity-service.js +204 -29
- 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/keys/positional-key-provider.d.ts.map +1 -1
- package/lib/langium/keys/positional-key-provider.js.map +1 -1
- package/lib/langium/labeling/label-provider.d.ts.map +1 -1
- package/lib/langium/labeling/label-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 +330 -0
- package/lib/langium/model-service/client-session.d.ts.map +1 -0
- package/lib/langium/model-service/client-session.js +418 -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 +353 -253
- package/lib/langium/model-service/model-service.d.ts.map +1 -1
- package/lib/langium/model-service/model-service.js +361 -408
- package/lib/langium/model-service/model-service.js.map +1 -1
- package/lib/langium/module.d.ts +150 -35
- package/lib/langium/module.d.ts.map +1 -1
- package/lib/langium/module.js +50 -35
- 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/project/single-project-manager.d.ts.map +1 -1
- package/lib/langium/project/single-project-manager.js.map +1 -1
- 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 +23 -57
- package/lib/langium/residency/cst-residency-service.js.map +1 -1
- package/lib/langium/scope/ast-node-description-provider.d.ts.map +1 -1
- package/lib/langium/scope/ast-node-description-provider.js.map +1 -1
- package/lib/langium/scope/hydranium-scope-computation.d.ts.map +1 -1
- package/lib/langium/scope/hydranium-scope-computation.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/scope/reference-builder.d.ts.map +1 -1
- package/lib/langium/scope/reference-builder.js.map +1 -1
- package/lib/langium/scope/reference-candidate-provider.d.ts.map +1 -1
- package/lib/langium/scope/reference-candidate-provider.js.map +1 -1
- package/lib/langium/scope/scope-extension-service.d.ts.map +1 -1
- package/lib/langium/scope/scope-extension-service.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/serialization/json-serializer.d.ts +1 -1
- package/lib/langium/serialization/json-serializer.d.ts.map +1 -1
- package/lib/langium/serialization/json-serializer.js.map +1 -1
- package/lib/langium/serialization/yaml-serializer.d.ts.map +1 -1
- package/lib/langium/serialization/yaml-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 +21 -4
- 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 +75 -23
- package/lib/langium/transfer/transfer-encoder.d.ts.map +1 -1
- package/lib/langium/transfer/transfer-encoder.js +44 -21
- 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/normalize-empty-strings.d.ts.map +1 -1
- package/lib/langium/update-rewrite/update-rewrite-service.d.ts.map +1 -1
- package/lib/langium/update-rewrite/update-rewrite-service.js.map +1 -1
- 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/validation/validation-contribution-collector.d.ts.map +1 -1
- package/lib/langium/validation/validation-contribution-collector.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 +56 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-langium-document-factory.js +79 -0
- package/lib/langium/workspace/hydranium-langium-document-factory.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-lock.d.ts +43 -1
- package/lib/langium/workspace/hydranium-workspace-lock.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-lock.js +58 -1
- package/lib/langium/workspace/hydranium-workspace-lock.js.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts +81 -8
- package/lib/langium/workspace/hydranium-workspace-manager.d.ts.map +1 -1
- package/lib/langium/workspace/hydranium-workspace-manager.js +128 -10
- 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/index-manager.d.ts.map +1 -1
- package/lib/langium/workspace/index-manager.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 +86 -17
- package/lib/langium/workspace/langium-documents.d.ts.map +1 -1
- package/lib/langium/workspace/langium-documents.js +101 -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 +20 -10
- package/lib/langium/workspace/write-lock-scope.d.ts.map +1 -1
- package/lib/langium/workspace/write-lock-scope.js +12 -4
- 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 +153 -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/event-loop-monitor.js.map +1 -1
- 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/lint-grammar.js.map +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/memory-monitor.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/process-memory.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/profile-digest.js.map +1 -1
- package/lib/node/profiling-run.d.ts +13 -3
- package/lib/node/profiling-run.d.ts.map +1 -1
- package/lib/node/profiling-run.js +17 -8
- 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/document-uri-policy-conformance.js.map +1 -1
- package/lib/testing/fake-description.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/index.d.ts +1 -1
- package/lib/testing/index.d.ts.map +1 -1
- package/lib/testing/index.js +2 -1
- package/lib/testing/index.js.map +1 -1
- package/lib/testing/langium-test-helpers.d.ts.map +1 -1
- package/lib/testing/langium-test-helpers.js +1 -0
- package/lib/testing/langium-test-helpers.js.map +1 -1
- package/lib/testing/make-noop-language-services.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 +69 -14
- package/lib/testing/make-test-services.d.ts.map +1 -1
- package/lib/testing/make-test-services.js +39 -10
- package/lib/testing/make-test-services.js.map +1 -1
- package/lib/testing/make-test-tracer.js.map +1 -1
- package/lib/testing/node/golden-corpus.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/browser-capture-bridge.js.map +1 -1
- package/lib/testing/playwright/e2e-profiling.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 +24 -8
- package/lib/testing/playwright/server-log-capture.d.ts.map +1 -1
- package/lib/testing/playwright/server-log-capture.js +27 -6
- 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 +11 -9
- package/lib/testing/stub-ast-document-manager.d.ts.map +1 -1
- package/lib/testing/stub-ast-document-manager.js +25 -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 +97 -15
- package/lib/testing/stub-hydranium-text-documents.js.map +1 -1
- package/lib/testing/stub-index-manager.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/testing/stub-project-manager.js.map +1 -1
- package/lib/testing/stub-service-registry.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/lib/util/environment.d.ts.map +1 -1
- package/lib/util/environment.js.map +1 -1
- package/lib/util/registry.d.ts.map +1 -1
- package/package.json +35 -26
- package/src/documents/ast-document-manager.ts +395 -126
- 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 +1175 -225
- package/src/documents/index.ts +5 -0
- package/src/documents/language-client-text-shadow.ts +59 -11
- package/src/documents/model-ledger.ts +66 -0
- package/src/documents/self-save-registry.ts +52 -13
- package/src/documents/version-sync-service.ts +267 -0
- package/src/index.ts +6 -0
- package/src/langium/ast-extension/ast-node-builder.ts +66 -22
- package/src/langium/bootstrap.ts +32 -9
- package/src/langium/config/configuration-provider.ts +119 -0
- package/src/langium/config/index.ts +1 -0
- package/src/langium/diagnostics/logger.ts +12 -5
- package/src/langium/diagnostics/lsp-logger.ts +58 -12
- 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 +776 -59
- 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 +220 -30
- 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 +649 -0
- package/src/langium/model-service/index.ts +1 -0
- package/src/langium/model-service/model-service.ts +570 -433
- package/src/langium/module.ts +201 -64
- 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 +46 -15
- 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 +25 -4
- package/src/langium/transfer/transfer-encoder.ts +102 -34
- 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 +117 -0
- package/src/langium/workspace/hydranium-workspace-lock.ts +86 -2
- package/src/langium/workspace/hydranium-workspace-manager.ts +153 -13
- 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 +124 -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 +24 -11
- 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 +185 -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 +30 -8
- 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/index.ts +2 -1
- package/src/testing/langium-test-helpers.ts +1 -0
- package/src/testing/make-noop-shared-services.ts +50 -2
- package/src/testing/make-test-services.ts +120 -31
- 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 +45 -11
- 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 +40 -23
- package/src/testing/stub-document-builder.ts +83 -17
- package/src/testing/stub-hydranium-text-documents.ts +133 -23
- 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/src/util/environment.ts +9 -1
- 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
|
@@ -9,13 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
type DocumentBuilder,
|
|
12
|
+
type DocumentBuildListener,
|
|
12
13
|
type DocumentPhaseListener,
|
|
13
14
|
type DocumentState,
|
|
14
15
|
type DocumentUpdateListener,
|
|
15
16
|
type LangiumDocument,
|
|
16
|
-
type URI
|
|
17
|
+
type URI,
|
|
18
|
+
type WorkspaceLock
|
|
17
19
|
} from '@hydranium/langium';
|
|
18
20
|
import { type CancellationToken, Disposable } from 'vscode-languageserver';
|
|
21
|
+
import { type HydraniumDocumentBuilder } from '../langium/document-builder/document-builder.js';
|
|
19
22
|
|
|
20
23
|
/** Recorded call to a stubbed {@link DocumentBuilder} method. */
|
|
21
24
|
export interface RecordedBuilderCall<TArgs extends unknown[]> {
|
|
@@ -45,8 +48,7 @@ export interface StubWaitUntilGate {
|
|
|
45
48
|
|
|
46
49
|
/**
|
|
47
50
|
* Stub for Langium's {@link DocumentBuilder}. Implements the slice production
|
|
48
|
-
* code reads
|
|
49
|
-
* `onDocumentPhase` / `onUpdate`) plus test-only helpers:
|
|
51
|
+
* code reads on the framework's test paths, plus test-only helpers:
|
|
50
52
|
*
|
|
51
53
|
* - {@link firePhase} — synchronously dispatch the registered phase
|
|
52
54
|
* listener(s) for a document, simulating a build completing.
|
|
@@ -64,16 +66,17 @@ export interface StubWaitUntilGate {
|
|
|
64
66
|
* Picks the methods the framework reads from {@link DocumentBuilder} on
|
|
65
67
|
* the slot path — the compiler enforces those signatures stay aligned.
|
|
66
68
|
* `update`, `onDocumentPhase`, `onUpdate`, and `waitUntil` carry stubbed
|
|
67
|
-
* implementations
|
|
68
|
-
*
|
|
69
|
-
*
|
|
69
|
+
* implementations, and `scheduleUpdate` calls `update` in one lock write per
|
|
70
|
+
* call (see {@link makeStubDocumentBuilder}); `build`, `onBuildPhase`, and
|
|
71
|
+
* `resetToState` are implemented as loud-failing `notSupported` throwers
|
|
72
|
+
* so production code that goes through the cast at the bind site (i.e. accesses methods the
|
|
70
73
|
* stub claims but doesn't meaningfully implement) fails with a clear
|
|
71
74
|
* message instead of "undefined is not a function".
|
|
72
75
|
*/
|
|
73
|
-
export interface StubDocumentBuilder
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
> {
|
|
76
|
+
export interface StubDocumentBuilder
|
|
77
|
+
extends
|
|
78
|
+
Pick<DocumentBuilder, 'update' | 'onDocumentPhase' | 'onUpdate' | 'build' | 'onBuildPhase' | 'resetToState' | 'updateBuildOptions'>,
|
|
79
|
+
Pick<HydraniumDocumentBuilder, 'onDocumentPhaseDelivered' | 'scheduleUpdate'> {
|
|
77
80
|
/**
|
|
78
81
|
* Single-overload stub of {@link DocumentBuilder.waitUntil}. Real has
|
|
79
82
|
* two overloads (`(state, cancelToken?): Promise<void>` and
|
|
@@ -87,13 +90,22 @@ export interface StubDocumentBuilder extends Pick<
|
|
|
87
90
|
readonly waitUntilCalls: ReadonlyArray<RecordedBuilderCall<[DocumentState, URI | undefined]>>;
|
|
88
91
|
/**
|
|
89
92
|
* Synchronously fire the phase listener(s) registered for `state` with
|
|
90
|
-
* `document
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
+
* `document`, then, unless `cancelToken` is cancelled, the
|
|
94
|
+
* `onDocumentPhaseDelivered` listeners. `cancelToken` defaults to a
|
|
95
|
+
* non-cancelled token; pass a cancelled token to simulate a build preempted
|
|
96
|
+
* by a concurrent write lock.
|
|
93
97
|
*/
|
|
94
98
|
firePhase(state: DocumentState, document: LangiumDocument, cancelToken?: CancellationToken): void;
|
|
95
99
|
/** Synchronously fire every registered `onUpdate` listener. */
|
|
96
100
|
fireOnUpdate(changed: URI[], deleted: URI[]): void;
|
|
101
|
+
/**
|
|
102
|
+
* Synchronously fire the BUILD-phase listener(s) for `state` with the whole
|
|
103
|
+
* batch. The per-build counterpart of {@link firePhase}: a subject that
|
|
104
|
+
* reports once per build rather than once per document subscribes here, and
|
|
105
|
+
* a stub that only fired {@link firePhase} would leave it silent while
|
|
106
|
+
* looking wired.
|
|
107
|
+
*/
|
|
108
|
+
fireBuildPhase(state: DocumentState, built: LangiumDocument[], cancelToken?: CancellationToken): void;
|
|
97
109
|
/**
|
|
98
110
|
* Hold the next {@link waitUntil} call. The returned handle releases it;
|
|
99
111
|
* the call's return value resolves on the next tick after `resolve` runs.
|
|
@@ -128,9 +140,16 @@ function reraise(result: unknown): void {
|
|
|
128
140
|
* want to observe rebuilt state should `set` the new root on the document
|
|
129
141
|
* registry and then call `firePhase` to trigger the framework's post-build
|
|
130
142
|
* read path.
|
|
143
|
+
*
|
|
144
|
+
* `workspaceLock` is the lock `scheduleUpdate` writes under, without the real
|
|
145
|
+
* builder's sharing: pass the services tree's own, so a caller's lock ordering
|
|
146
|
+
* and reentrancy behave as against the real builder. Without one,
|
|
147
|
+
* `scheduleUpdate` records the update unlocked.
|
|
131
148
|
*/
|
|
132
|
-
export function makeStubDocumentBuilder(): StubDocumentBuilder {
|
|
149
|
+
export function makeStubDocumentBuilder(workspaceLock?: WorkspaceLock): StubDocumentBuilder {
|
|
133
150
|
const phaseListeners = new Map<DocumentState, DocumentPhaseListener[]>();
|
|
151
|
+
const deliveredListeners = new Map<DocumentState, Array<(document: LangiumDocument, version: number) => void>>();
|
|
152
|
+
const buildPhaseListeners = new Map<DocumentState, DocumentBuildListener[]>();
|
|
134
153
|
const onUpdateListeners: DocumentUpdateListener[] = [];
|
|
135
154
|
const gates: Array<{ take(release: () => void): void }> = [];
|
|
136
155
|
const updateCalls: RecordedBuilderCall<[URI[], URI[]]>[] = [];
|
|
@@ -140,6 +159,9 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
|
|
|
140
159
|
throw new Error(`StubDocumentBuilder.${method} is not implemented; wire a real DocumentBuilder if your test needs it.`);
|
|
141
160
|
};
|
|
142
161
|
const stub: StubDocumentBuilder = {
|
|
162
|
+
// Langium's own default, so a session write waits for `Validated` here
|
|
163
|
+
// as it does against the real builder.
|
|
164
|
+
updateBuildOptions: { validation: { categories: ['built-in', 'fast'] } },
|
|
143
165
|
get updateCalls() {
|
|
144
166
|
return updateCalls;
|
|
145
167
|
},
|
|
@@ -149,6 +171,9 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
|
|
|
149
171
|
async update(changed: URI[], deleted: URI[]) {
|
|
150
172
|
updateCalls.push({ args: [changed, deleted] });
|
|
151
173
|
},
|
|
174
|
+
scheduleUpdate(changed: URI[], deleted: URI[]) {
|
|
175
|
+
return workspaceLock ? workspaceLock.write(() => stub.update(changed, deleted)) : stub.update(changed, deleted);
|
|
176
|
+
},
|
|
152
177
|
async waitUntil(state: DocumentState, uri?: URI) {
|
|
153
178
|
waitUntilCalls.push({ args: [state, uri] });
|
|
154
179
|
const gate = gates.shift();
|
|
@@ -185,15 +210,58 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
|
|
|
185
210
|
onCancellationRequested: () => Disposable.create(() => undefined)
|
|
186
211
|
} as CancellationToken);
|
|
187
212
|
const listeners = phaseListeners.get(state) ?? [];
|
|
213
|
+
const delivered = deliveredListeners.get(state) ?? [];
|
|
214
|
+
// Taken before the listeners, as the real builder does: one of them
|
|
215
|
+
// may stand in for a write that moves the version on. Read only when
|
|
216
|
+
// someone is told, since many fakes carry no text document.
|
|
217
|
+
const version = delivered.length > 0 ? document.textDocument.version : 0;
|
|
188
218
|
for (const listener of listeners) {
|
|
189
219
|
reraise(listener(document, token));
|
|
190
220
|
}
|
|
221
|
+
if (!token.isCancellationRequested) {
|
|
222
|
+
for (const listener of delivered) {
|
|
223
|
+
listener(document, version);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
onDocumentPhaseDelivered(state: DocumentState, listener: (document: LangiumDocument, version: number) => void) {
|
|
228
|
+
const list = deliveredListeners.get(state) ?? [];
|
|
229
|
+
list.push(listener);
|
|
230
|
+
deliveredListeners.set(state, list);
|
|
231
|
+
return Disposable.create(() => {
|
|
232
|
+
const idx = list.indexOf(listener);
|
|
233
|
+
if (idx >= 0) {
|
|
234
|
+
list.splice(idx, 1);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
191
237
|
},
|
|
192
238
|
fireOnUpdate(changed: URI[], deleted: URI[]) {
|
|
193
239
|
for (const listener of onUpdateListeners.slice()) {
|
|
194
240
|
reraise(listener(changed, deleted));
|
|
195
241
|
}
|
|
196
242
|
},
|
|
243
|
+
onBuildPhase(state: DocumentState, listener: DocumentBuildListener) {
|
|
244
|
+
const list = buildPhaseListeners.get(state) ?? [];
|
|
245
|
+
list.push(listener);
|
|
246
|
+
buildPhaseListeners.set(state, list);
|
|
247
|
+
return Disposable.create(() => {
|
|
248
|
+
const idx = list.indexOf(listener);
|
|
249
|
+
if (idx >= 0) {
|
|
250
|
+
list.splice(idx, 1);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
},
|
|
254
|
+
fireBuildPhase(state: DocumentState, built: LangiumDocument[], cancelToken?: CancellationToken) {
|
|
255
|
+
const token =
|
|
256
|
+
cancelToken ??
|
|
257
|
+
({
|
|
258
|
+
isCancellationRequested: false,
|
|
259
|
+
onCancellationRequested: () => Disposable.create(() => undefined)
|
|
260
|
+
} as CancellationToken);
|
|
261
|
+
for (const listener of buildPhaseListeners.get(state) ?? []) {
|
|
262
|
+
reraise(listener(built, token));
|
|
263
|
+
}
|
|
264
|
+
},
|
|
197
265
|
gateNextWaitUntil(): StubWaitUntilGate {
|
|
198
266
|
let release: (() => void) | undefined;
|
|
199
267
|
const entry = {
|
|
@@ -224,14 +292,12 @@ export function makeStubDocumentBuilder(): StubDocumentBuilder {
|
|
|
224
292
|
build() {
|
|
225
293
|
return notSupported('build');
|
|
226
294
|
},
|
|
227
|
-
onBuildPhase() {
|
|
228
|
-
return notSupported('onBuildPhase');
|
|
229
|
-
},
|
|
230
295
|
resetToState() {
|
|
231
296
|
return notSupported('resetToState');
|
|
232
297
|
},
|
|
233
298
|
reset() {
|
|
234
299
|
phaseListeners.clear();
|
|
300
|
+
deliveredListeners.clear();
|
|
235
301
|
onUpdateListeners.length = 0;
|
|
236
302
|
gates.length = 0;
|
|
237
303
|
updateCalls.length = 0;
|
|
@@ -7,12 +7,18 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import type
|
|
10
|
+
import { type CanonicalUri, textHash } from '@hydranium/protocol';
|
|
11
11
|
import type { ApplyWorkspaceEditResult } from 'vscode-languageserver';
|
|
12
|
-
import { Disposable } from 'vscode-languageserver';
|
|
12
|
+
import { Disposable, Emitter } from 'vscode-languageserver';
|
|
13
13
|
import type { TextDocument } from 'vscode-languageserver-textdocument';
|
|
14
14
|
import { LANGUAGE_CLIENT_ID } from '../documents/client-ids.js';
|
|
15
|
-
import
|
|
15
|
+
import { ClientSessionRegistry } from '../documents/client-session-registry.js';
|
|
16
|
+
import type {
|
|
17
|
+
ClientTextDocumentChangeEvent,
|
|
18
|
+
DocumentDirtyChangedEvent,
|
|
19
|
+
HydraniumTextDocuments,
|
|
20
|
+
LastOpenClosedEvent
|
|
21
|
+
} from '../documents/hydranium-text-documents.js';
|
|
16
22
|
|
|
17
23
|
/** Snapshot of an open document tracked by the stub. */
|
|
18
24
|
export interface StubTextDocumentEntry {
|
|
@@ -27,9 +33,14 @@ export interface StubTextDocumentEntry {
|
|
|
27
33
|
* reads from on test paths — the content channel
|
|
28
34
|
* (`notifyDidChangeTextDocument` / `applyContentChange` / `version` /
|
|
29
35
|
* `getAuthor`), the open-state probes (`isOpenInLanguageClient` /
|
|
30
|
-
* `isOpenInAnyClient` / `
|
|
31
|
-
*
|
|
32
|
-
*
|
|
36
|
+
* `isOpenInAnyClient` / `isOpenInClient` / `isRevertPending` /
|
|
37
|
+
* `openDocuments`), the push channel
|
|
38
|
+
* to the language client (`applyEditToLanguageClient` / `stagePendingContent`),
|
|
39
|
+
* the save / close notifications, the dirty state (`isDirty` / `textState` /
|
|
40
|
+
* `onDidChangeDirty` / `updateDiskBaseline`, against a baseline {@link seedOpen}
|
|
41
|
+
* sets and a save that carries its text moves), and the client-session table
|
|
42
|
+
* (`registerSession` / `closeSession` / `onDidCloseSession`), which is a real
|
|
43
|
+
* `ClientSessionRegistry` — plus test-only helpers:
|
|
33
44
|
*
|
|
34
45
|
* - {@link seedOpen} — pre-populate an open document without firing change
|
|
35
46
|
* events. Use to set up a baseline version before exercising an `update`.
|
|
@@ -66,9 +77,20 @@ export interface StubHydraniumTextDocuments extends Pick<
|
|
|
66
77
|
| 'getAuthor'
|
|
67
78
|
| 'isOpenInLanguageClient'
|
|
68
79
|
| 'isOpenInAnyClient'
|
|
80
|
+
| 'isRevertPending'
|
|
69
81
|
| 'applyEditToLanguageClient'
|
|
70
82
|
| 'stagePendingContent'
|
|
71
83
|
| 'openDocuments'
|
|
84
|
+
| 'isOpenInClient'
|
|
85
|
+
| 'attachClient'
|
|
86
|
+
| 'registerSession'
|
|
87
|
+
| 'closeSession'
|
|
88
|
+
| 'onDidCloseSession'
|
|
89
|
+
| 'onDidCloseLastOpen'
|
|
90
|
+
| 'isDirty'
|
|
91
|
+
| 'textState'
|
|
92
|
+
| 'onDidChangeDirty'
|
|
93
|
+
| 'updateDiskBaseline'
|
|
72
94
|
> {
|
|
73
95
|
/**
|
|
74
96
|
* Stub-tailored read accessor. Returns just the surface the framework's
|
|
@@ -87,13 +109,23 @@ export interface StubHydraniumTextDocuments extends Pick<
|
|
|
87
109
|
onDidSave(listener: (event: { document: { uri: string }; clientId: string }) => void): Disposable;
|
|
88
110
|
/** Real-shaped close subscription — listener gets {@link ClientTextDocumentChangeEvent}. */
|
|
89
111
|
onDidClose(listener: (event: ClientTextDocumentChangeEvent<TextDocument>) => void): Disposable;
|
|
90
|
-
/** Pre-populate an open document without firing change events. */
|
|
112
|
+
/** Pre-populate an open document without firing change events; `text` is also its disk baseline. */
|
|
91
113
|
seedOpen(uri: string, text: string, clientId: string): void;
|
|
92
114
|
/** Mark `uri` as open in the LSP textual language client (drives {@link isOpenInLanguageClient}). */
|
|
93
115
|
seedOpenInLanguageClient(uri: string): void;
|
|
94
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* Synchronously deliver `onDidClose` to subscribers, then `onDidCloseLastOpen`
|
|
118
|
+
* when no client has `uri` open any more. The stub keeps no revert grace, so
|
|
119
|
+
* a last close is announced at once.
|
|
120
|
+
*/
|
|
95
121
|
fireClose(uri: string, clientId: string): void;
|
|
96
|
-
/**
|
|
122
|
+
/**
|
|
123
|
+
* Drop recorded state. Useful for `beforeEach` resets.
|
|
124
|
+
*
|
|
125
|
+
* Sessions end without announcing it, so a model service built on this
|
|
126
|
+
* stub still holds the handles it started before the reset. Build a fresh
|
|
127
|
+
* service after a reset rather than reusing one across it.
|
|
128
|
+
*/
|
|
97
129
|
reset(): void;
|
|
98
130
|
readonly changes: readonly StubTextDocumentEntry[];
|
|
99
131
|
readonly saves: readonly { uri: string; clientId: string }[];
|
|
@@ -125,8 +157,31 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
125
157
|
let applyEditHandler: (uri: string, text: string) => ApplyWorkspaceEditResult | undefined = () => ({ applied: true });
|
|
126
158
|
const saveListeners: Array<(event: { document: { uri: string }; clientId: string }) => void> = [];
|
|
127
159
|
const closeListeners: Array<(event: ClientTextDocumentChangeEvent<TextDocument>) => void> = [];
|
|
160
|
+
// The real registry, so the session table, the opens and the closing state
|
|
161
|
+
// behave as the store's do. The stub's plain-string keys
|
|
162
|
+
// stand in for canonical URIs (one stub-boundary cast, like `fireClose`).
|
|
163
|
+
const sessions = new ClientSessionRegistry();
|
|
164
|
+
const key = (uri: string): CanonicalUri => uri as CanonicalUri;
|
|
165
|
+
const lastOpenClosed = new Emitter<LastOpenClosedEvent>();
|
|
166
|
+
const baselines = new Map<string, string | undefined>();
|
|
167
|
+
const dirty = new Set<string>();
|
|
168
|
+
const dirtyChanged = new Emitter<DocumentDirtyChangedEvent>();
|
|
169
|
+
// As the real store: dirty while held with text other than the baseline,
|
|
170
|
+
// announced only when the answer changes.
|
|
171
|
+
const refreshDirty = (uri: string): void => {
|
|
172
|
+
const held = docs.get(uri);
|
|
173
|
+
const now = held !== undefined && held.text !== baselines.get(uri);
|
|
174
|
+
if (now !== dirty.has(uri)) {
|
|
175
|
+
if (now) {
|
|
176
|
+
dirty.add(uri);
|
|
177
|
+
} else {
|
|
178
|
+
dirty.delete(uri);
|
|
179
|
+
}
|
|
180
|
+
dirtyChanged.fire({ uri: key(uri), text: { version: held?.version ?? 0, hash: textHash(held?.text ?? ''), dirty: now } });
|
|
181
|
+
}
|
|
182
|
+
};
|
|
128
183
|
|
|
129
|
-
|
|
184
|
+
const stub: StubHydraniumTextDocuments = {
|
|
130
185
|
get changes() {
|
|
131
186
|
return changes;
|
|
132
187
|
},
|
|
@@ -146,6 +201,10 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
146
201
|
version(uri) {
|
|
147
202
|
return docs.get(uri)?.version ?? 0;
|
|
148
203
|
},
|
|
204
|
+
textState(uri) {
|
|
205
|
+
const held = docs.get(uri);
|
|
206
|
+
return held && { version: held.version, hash: textHash(held.text), dirty: dirty.has(uri) };
|
|
207
|
+
},
|
|
149
208
|
notifyDidChangeTextDocument(event, clientId = LANGUAGE_CLIENT_ID) {
|
|
150
209
|
const existing = docs.get(event.textDocument.uri);
|
|
151
210
|
const next: StubTextDocumentEntry = {
|
|
@@ -159,6 +218,7 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
159
218
|
}
|
|
160
219
|
docs.set(event.textDocument.uri, next);
|
|
161
220
|
changes.push(next);
|
|
221
|
+
refreshDirty(event.textDocument.uri);
|
|
162
222
|
},
|
|
163
223
|
applyContentChange(uri, text, clientId) {
|
|
164
224
|
const existing = docs.get(uri);
|
|
@@ -172,9 +232,13 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
172
232
|
const next: StubTextDocumentEntry = changed ? { uri, version: existing.version + 1, text, clientId } : existing;
|
|
173
233
|
docs.set(uri, next);
|
|
174
234
|
changes.push({ uri, version: next.version, text, clientId });
|
|
235
|
+
refreshDirty(uri);
|
|
175
236
|
return next.version;
|
|
176
237
|
},
|
|
177
238
|
notifyDidSaveTextDocument(event, clientId) {
|
|
239
|
+
if (event.text !== undefined) {
|
|
240
|
+
stub.updateDiskBaseline(event.textDocument.uri, event.text);
|
|
241
|
+
}
|
|
178
242
|
saves.push({ uri: event.textDocument.uri, clientId });
|
|
179
243
|
for (const listener of saveListeners.slice()) {
|
|
180
244
|
listener({ document: { uri: event.textDocument.uri }, clientId });
|
|
@@ -207,21 +271,52 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
207
271
|
isOpenInAnyClient(uri) {
|
|
208
272
|
return docs.has(uri) || languageClientOpen.has(uri);
|
|
209
273
|
},
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
274
|
+
isOpenInClient(uri, clientId) {
|
|
275
|
+
return sessions.isOpenIn(key(uri), clientId);
|
|
276
|
+
},
|
|
277
|
+
isRevertPending(uri) {
|
|
278
|
+
return sessions.isRevertPending(key(uri));
|
|
279
|
+
},
|
|
280
|
+
attachClient(uri, clientId) {
|
|
281
|
+
return docs.has(uri) && sessions.addOpen(key(uri), clientId);
|
|
282
|
+
},
|
|
283
|
+
registerSession(clientId) {
|
|
284
|
+
sessions.register(clientId);
|
|
285
|
+
},
|
|
286
|
+
closeSession(clientId) {
|
|
287
|
+
if (!sessions.isRegistered(clientId)) {
|
|
288
|
+
return;
|
|
216
289
|
}
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
290
|
+
try {
|
|
291
|
+
for (const uri of sessions.beginClose(clientId)) {
|
|
292
|
+
stub.fireClose(uri, clientId);
|
|
293
|
+
}
|
|
294
|
+
} finally {
|
|
295
|
+
sessions.unregister(clientId);
|
|
221
296
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return
|
|
297
|
+
},
|
|
298
|
+
get onDidCloseSession() {
|
|
299
|
+
return sessions.onDidCloseSession;
|
|
300
|
+
},
|
|
301
|
+
get onDidCloseLastOpen() {
|
|
302
|
+
return lastOpenClosed.event;
|
|
303
|
+
},
|
|
304
|
+
isDirty(uri) {
|
|
305
|
+
return dirty.has(uri);
|
|
306
|
+
},
|
|
307
|
+
get onDidChangeDirty() {
|
|
308
|
+
return dirtyChanged.event;
|
|
309
|
+
},
|
|
310
|
+
updateDiskBaseline(uri, text) {
|
|
311
|
+
if (docs.has(uri)) {
|
|
312
|
+
baselines.set(uri, text);
|
|
313
|
+
refreshDirty(uri);
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
openDocuments() {
|
|
317
|
+
// From the registry that also answers `isOpenInClient`, which both
|
|
318
|
+
// seeding channels feed, so the two never disagree about an open.
|
|
319
|
+
return sessions.openDocuments();
|
|
225
320
|
},
|
|
226
321
|
setApplyEditHandler(handler) {
|
|
227
322
|
applyEditHandler = handler;
|
|
@@ -234,9 +329,12 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
234
329
|
staged.push({ uri, text });
|
|
235
330
|
},
|
|
236
331
|
seedOpen(uri, text, clientId) {
|
|
332
|
+
sessions.addOpen(key(uri), clientId);
|
|
237
333
|
docs.set(uri, { uri, version: 1, text, clientId });
|
|
334
|
+
baselines.set(uri, text);
|
|
238
335
|
},
|
|
239
336
|
seedOpenInLanguageClient(uri) {
|
|
337
|
+
sessions.addOpen(key(uri), LANGUAGE_CLIENT_ID);
|
|
240
338
|
languageClientOpen.add(uri);
|
|
241
339
|
},
|
|
242
340
|
fireClose(uri, clientId) {
|
|
@@ -246,7 +344,9 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
246
344
|
const holder = docs.get(uri);
|
|
247
345
|
if (holder && holder.clientId === clientId) {
|
|
248
346
|
docs.delete(uri);
|
|
347
|
+
refreshDirty(uri);
|
|
249
348
|
}
|
|
349
|
+
const removed = sessions.removeOpen(key(uri), clientId);
|
|
250
350
|
if (clientId === LANGUAGE_CLIENT_ID) {
|
|
251
351
|
languageClientOpen.delete(uri);
|
|
252
352
|
}
|
|
@@ -254,6 +354,9 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
254
354
|
for (const listener of closeListeners.slice()) {
|
|
255
355
|
listener(event);
|
|
256
356
|
}
|
|
357
|
+
if (removed && !sessions.isOpen(key(uri))) {
|
|
358
|
+
lastOpenClosed.fire({ uri: key(uri) });
|
|
359
|
+
}
|
|
257
360
|
},
|
|
258
361
|
reset() {
|
|
259
362
|
docs.clear();
|
|
@@ -262,9 +365,16 @@ export function makeStubHydraniumTextDocuments(): StubHydraniumTextDocuments {
|
|
|
262
365
|
languageClientOpen.clear();
|
|
263
366
|
appliedEdits.length = 0;
|
|
264
367
|
staged.length = 0;
|
|
368
|
+
baselines.clear();
|
|
369
|
+
dirty.clear();
|
|
265
370
|
saveListeners.length = 0;
|
|
266
371
|
closeListeners.length = 0;
|
|
267
372
|
applyEditHandler = () => ({ applied: true });
|
|
373
|
+
// Cleared in place rather than replaced: a model service built on the
|
|
374
|
+
// stub subscribed to `onDidCloseSession` once, and a new registry would
|
|
375
|
+
// leave that subscription on one nothing fires.
|
|
376
|
+
sessions.clear();
|
|
268
377
|
}
|
|
269
378
|
};
|
|
379
|
+
return stub;
|
|
270
380
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { type AstNode, type LangiumDocument, type LangiumDocuments, stream, type URI } from '@hydranium/langium';
|
|
11
11
|
import { makeFakeAstNode, makeFakeDocument, type FakeDocumentOptions } from './fake-document.js';
|
|
12
|
+
import { type AstDiagnostic } from '../langium/validation/document-validator.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Map-backed stub for Langium's {@link LangiumDocuments} registry. Implements
|
|
@@ -31,7 +32,7 @@ import { makeFakeAstNode, makeFakeDocument, type FakeDocumentOptions } from './f
|
|
|
31
32
|
* production code reads the slot value through the `LangiumDocuments`
|
|
32
33
|
* interface and a narrowing cast bridges the stub at the binding site.
|
|
33
34
|
*/
|
|
34
|
-
export interface StubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic =
|
|
35
|
+
export interface StubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic> extends Pick<
|
|
35
36
|
LangiumDocuments,
|
|
36
37
|
'getDocument' | 'hasDocument' | 'getOrCreateDocument' | 'all'
|
|
37
38
|
> {
|
|
@@ -51,7 +52,7 @@ export interface StubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnosti
|
|
|
51
52
|
* Build a {@link StubLangiumDocuments}. Seed entries via the optional
|
|
52
53
|
* `seeds` parameter so simple tests don't need a separate `set` call.
|
|
53
54
|
*/
|
|
54
|
-
export function makeStubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic =
|
|
55
|
+
export function makeStubLangiumDocuments<TAst extends AstNode = AstNode, TDiagnostic extends AstDiagnostic = AstDiagnostic>(
|
|
55
56
|
seeds: ReadonlyArray<{ uri: string | URI; root: TAst; options?: FakeDocumentOptions<TAst, TDiagnostic> }> = []
|
|
56
57
|
): StubLangiumDocuments<TAst, TDiagnostic> {
|
|
57
58
|
const docs = new Map<string, LangiumDocument<TAst>>();
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
* SPDX-License-Identifier: MIT
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type { TransferElement } from '@hydranium/protocol';
|
|
11
|
+
import type { AstDiagnostic } from '../langium/validation/document-validator.js';
|
|
11
12
|
import type { AstNode } from '@hydranium/langium';
|
|
12
|
-
import { ModelService, type ModelServiceOptions } from '../langium/model-service/model-service.js';
|
|
13
|
+
import { DefaultModelService, type ModelService, type ModelServiceOptions } from '../langium/model-service/model-service.js';
|
|
13
14
|
import type { ServerSharedServices } from '../langium/module.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -21,9 +22,9 @@ import type { ServerSharedServices } from '../langium/module.js';
|
|
|
21
22
|
*/
|
|
22
23
|
class StubModelServiceImpl<
|
|
23
24
|
TAst extends AstNode,
|
|
24
|
-
TDiagnostic extends
|
|
25
|
+
TDiagnostic extends AstDiagnostic = AstDiagnostic,
|
|
25
26
|
TTransfer extends TransferElement = TransferElement
|
|
26
|
-
> extends
|
|
27
|
+
> extends DefaultModelService<TAst, TDiagnostic, TTransfer> {
|
|
27
28
|
constructor(
|
|
28
29
|
services: ServerSharedServices,
|
|
29
30
|
protected readonly serializeFn: (uri: string, root: TTransfer) => string,
|
|
@@ -40,7 +41,7 @@ class StubModelServiceImpl<
|
|
|
40
41
|
/** The type of the model-service test double produced by {@link makeStubModelService}. */
|
|
41
42
|
export type StubModelService<
|
|
42
43
|
TAst extends AstNode,
|
|
43
|
-
TDiagnostic extends
|
|
44
|
+
TDiagnostic extends AstDiagnostic = AstDiagnostic,
|
|
44
45
|
TTransfer extends TransferElement = TransferElement
|
|
45
46
|
> = ModelService<TAst, TDiagnostic, TTransfer>;
|
|
46
47
|
|
|
@@ -52,8 +53,8 @@ export type StubModelService<
|
|
|
52
53
|
* `makeTestServices` wires this stub automatically.
|
|
53
54
|
*
|
|
54
55
|
* `options` are the framework {@link ModelServiceOptions}, forwarded verbatim, so
|
|
55
|
-
* a test can exercise an option-gated code path (`
|
|
56
|
-
*
|
|
56
|
+
* a test can exercise an option-gated code path (`allowReentrantBuilds`) without
|
|
57
|
+
* hand-rolling a subclass just to reach the constructor.
|
|
57
58
|
*
|
|
58
59
|
* Adopters that need richer override behaviour — the framework's own extension
|
|
59
60
|
* surface is {@link ModelService.rewriteModel} alongside `serialize` — should
|
|
@@ -61,7 +62,7 @@ export type StubModelService<
|
|
|
61
62
|
*/
|
|
62
63
|
export function makeStubModelService<
|
|
63
64
|
TAst extends AstNode,
|
|
64
|
-
TDiagnostic extends
|
|
65
|
+
TDiagnostic extends AstDiagnostic = AstDiagnostic,
|
|
65
66
|
TTransfer extends TransferElement = TransferElement
|
|
66
67
|
>(
|
|
67
68
|
services: ServerSharedServices,
|
|
@@ -8,39 +8,62 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Phrases
|
|
12
|
-
*
|
|
11
|
+
* Phrases that mean a call lost its connection. Matched on the message because
|
|
12
|
+
* the condition surfaces in shapes that share no discriminator:
|
|
13
13
|
*
|
|
14
14
|
* - a **throw** from `throwIfClosedOrDisposed` (`Connection is disposed.` /
|
|
15
15
|
* `Connection is closed.`), a `ConnectionError` raised synchronously by
|
|
16
16
|
* `sendRequest` / `sendNotification` and by `RemoteConsole.send`;
|
|
17
17
|
* - a **rejection** of an already-issued request (`Pending response rejected
|
|
18
18
|
* since connection got disposed`), a `ResponseError` produced when the
|
|
19
|
-
* pending-response map is drained on teardown
|
|
19
|
+
* pending-response map is drained on teardown;
|
|
20
|
+
* - a **write into a destroyed transport** (`Cannot call write after a stream
|
|
21
|
+
* was destroyed`), Node's own error for a message the writer queued before
|
|
22
|
+
* the connection was disposed and flushed after its stream was destroyed.
|
|
23
|
+
* A notification rejects with Node's error itself, which
|
|
24
|
+
* {@link isDestroyedStreamError} catches by its code; a request rejects with
|
|
25
|
+
* a `ResponseError` that copies only the message, so the phrase is needed
|
|
26
|
+
* too.
|
|
20
27
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
28
|
+
* The typed errors come from different classes carrying codes from different
|
|
29
|
+
* enums, so no single code check covers them. Kept lowercase-normalised and
|
|
30
|
+
* anchored on `connection` or `stream` so an unrelated "disposed" message
|
|
31
|
+
* cannot match.
|
|
25
32
|
*/
|
|
26
|
-
const CONNECTION_GONE_PATTERNS = [
|
|
33
|
+
const CONNECTION_GONE_PATTERNS = [
|
|
34
|
+
/connection is disposed/,
|
|
35
|
+
/connection is closed/,
|
|
36
|
+
/connection got disposed/,
|
|
37
|
+
/connection got closed/,
|
|
38
|
+
/after a stream was destroyed/
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const DESTROYED_STREAM_CODE = 'ERR_STREAM_DESTROYED';
|
|
42
|
+
|
|
43
|
+
function isDestroyedStreamError(err: unknown): boolean {
|
|
44
|
+
return err instanceof Error && 'code' in err && err.code === DESTROYED_STREAM_CODE;
|
|
45
|
+
}
|
|
27
46
|
|
|
28
47
|
/**
|
|
29
48
|
* Whether `err` means "the peer is gone", as opposed to a genuine failure of
|
|
30
49
|
* the operation.
|
|
31
50
|
*
|
|
32
|
-
* The
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
51
|
+
* The two are indistinguishable at the call site otherwise, and callers act on
|
|
52
|
+
* the answer: a gone peer is logged at `debug` or dropped, a genuine failure is
|
|
53
|
+
* logged at `error` or re-raised as an unhandled rejection. Pushing an edit to
|
|
54
|
+
* a language client that has already disconnected is a no-op, not a fault — it
|
|
55
|
+
* happens on every ordinary shutdown — so a `false` here turns routine teardown
|
|
56
|
+
* into errors that look like they need investigation. A `true` for a real
|
|
57
|
+
* `applyEdit` failure (the client refused, the request malformed) hides it.
|
|
38
58
|
*
|
|
39
59
|
* Callers that only need to *survive* a dead connection rather than classify it
|
|
40
60
|
* should just catch — see `LspLogger.emit`, whose fallback path does exactly
|
|
41
61
|
* that, since a logger has nowhere to report a logging failure anyway.
|
|
42
62
|
*/
|
|
43
63
|
export function isConnectionGoneError(err: unknown): boolean {
|
|
64
|
+
if (isDestroyedStreamError(err)) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
44
67
|
const message = err instanceof Error ? err.message : String(err);
|
|
45
68
|
const normalized = message.toLowerCase();
|
|
46
69
|
return CONNECTION_GONE_PATTERNS.some(pattern => pattern.test(normalized));
|
package/src/util/environment.ts
CHANGED
|
@@ -44,7 +44,15 @@ export function isCaseInsensitiveFileSystem(): boolean {
|
|
|
44
44
|
|
|
45
45
|
/** Node `process` lifecycle / error / signal events accepted by {@link onProcessEvent}. */
|
|
46
46
|
export type ProcessEvent =
|
|
47
|
-
|
|
47
|
+
| 'exit'
|
|
48
|
+
| 'beforeExit'
|
|
49
|
+
| 'uncaughtException'
|
|
50
|
+
| 'unhandledRejection'
|
|
51
|
+
| 'rejectionHandled'
|
|
52
|
+
| 'warning'
|
|
53
|
+
| 'SIGINT'
|
|
54
|
+
| 'SIGTERM'
|
|
55
|
+
| 'SIGHUP';
|
|
48
56
|
|
|
49
57
|
/**
|
|
50
58
|
* Register a process lifecycle handler (`'exit'`, `'unhandledRejection'`, …) if
|