@reqlan/language 1.4.0
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 +24 -0
- package/out/file-path-rewrite.d.ts +25 -0
- package/out/file-path-rewrite.js +56 -0
- package/out/file-path-rewrite.js.map +1 -0
- package/out/generated/ast.d.ts +1157 -0
- package/out/generated/ast.js +980 -0
- package/out/generated/ast.js.map +1 -0
- package/out/generated/grammar.d.ts +7 -0
- package/out/generated/grammar.js +3071 -0
- package/out/generated/grammar.js.map +1 -0
- package/out/generated/module.d.ts +20 -0
- package/out/generated/module.js +32 -0
- package/out/generated/module.js.map +1 -0
- package/out/index.d.ts +34 -0
- package/out/index.js +35 -0
- package/out/index.js.map +1 -0
- package/out/reqlan-attribute-catalog.d.ts +19 -0
- package/out/reqlan-attribute-catalog.js +87 -0
- package/out/reqlan-attribute-catalog.js.map +1 -0
- package/out/reqlan-code-action-provider.d.ts +55 -0
- package/out/reqlan-code-action-provider.js +269 -0
- package/out/reqlan-code-action-provider.js.map +1 -0
- package/out/reqlan-code-lens-provider.d.ts +13 -0
- package/out/reqlan-code-lens-provider.js +27 -0
- package/out/reqlan-code-lens-provider.js.map +1 -0
- package/out/reqlan-code-lens-settings.d.ts +34 -0
- package/out/reqlan-code-lens-settings.js +12 -0
- package/out/reqlan-code-lens-settings.js.map +1 -0
- package/out/reqlan-comment-resolver.d.ts +35 -0
- package/out/reqlan-comment-resolver.js +308 -0
- package/out/reqlan-comment-resolver.js.map +1 -0
- package/out/reqlan-completion-context.d.ts +46 -0
- package/out/reqlan-completion-context.js +244 -0
- package/out/reqlan-completion-context.js.map +1 -0
- package/out/reqlan-completion-provider.d.ts +41 -0
- package/out/reqlan-completion-provider.js +317 -0
- package/out/reqlan-completion-provider.js.map +1 -0
- package/out/reqlan-definition-provider.d.ts +31 -0
- package/out/reqlan-definition-provider.js +240 -0
- package/out/reqlan-definition-provider.js.map +1 -0
- package/out/reqlan-document-highlight-provider.d.ts +10 -0
- package/out/reqlan-document-highlight-provider.js +11 -0
- package/out/reqlan-document-highlight-provider.js.map +1 -0
- package/out/reqlan-document-link-provider.d.ts +14 -0
- package/out/reqlan-document-link-provider.js +24 -0
- package/out/reqlan-document-link-provider.js.map +1 -0
- package/out/reqlan-embedded-file-references.d.ts +11 -0
- package/out/reqlan-embedded-file-references.js +50 -0
- package/out/reqlan-embedded-file-references.js.map +1 -0
- package/out/reqlan-file-link-resolver.d.ts +44 -0
- package/out/reqlan-file-link-resolver.js +347 -0
- package/out/reqlan-file-link-resolver.js.map +1 -0
- package/out/reqlan-file-references.d.ts +15 -0
- package/out/reqlan-file-references.js +72 -0
- package/out/reqlan-file-references.js.map +1 -0
- package/out/reqlan-grammar-config.d.ts +5 -0
- package/out/reqlan-grammar-config.js +9 -0
- package/out/reqlan-grammar-config.js.map +1 -0
- package/out/reqlan-idea-reference-site.d.ts +14 -0
- package/out/reqlan-idea-reference-site.js +47 -0
- package/out/reqlan-idea-reference-site.js.map +1 -0
- package/out/reqlan-idea-summary.d.ts +6 -0
- package/out/reqlan-idea-summary.js +134 -0
- package/out/reqlan-idea-summary.js.map +1 -0
- package/out/reqlan-ignore-error.d.ts +10 -0
- package/out/reqlan-ignore-error.js +42 -0
- package/out/reqlan-ignore-error.js.map +1 -0
- package/out/reqlan-import-bindings.d.ts +12 -0
- package/out/reqlan-import-bindings.js +65 -0
- package/out/reqlan-import-bindings.js.map +1 -0
- package/out/reqlan-import-edits.d.ts +17 -0
- package/out/reqlan-import-edits.js +96 -0
- package/out/reqlan-import-edits.js.map +1 -0
- package/out/reqlan-imports.d.ts +22 -0
- package/out/reqlan-imports.js +61 -0
- package/out/reqlan-imports.js.map +1 -0
- package/out/reqlan-inbound-reference-inlay-label.d.ts +27 -0
- package/out/reqlan-inbound-reference-inlay-label.js +142 -0
- package/out/reqlan-inbound-reference-inlay-label.js.map +1 -0
- package/out/reqlan-inlay-hint-provider.d.ts +15 -0
- package/out/reqlan-inlay-hint-provider.js +54 -0
- package/out/reqlan-inlay-hint-provider.js.map +1 -0
- package/out/reqlan-inlay-hint-settings.d.ts +10 -0
- package/out/reqlan-inlay-hint-settings.js +10 -0
- package/out/reqlan-inlay-hint-settings.js.map +1 -0
- package/out/reqlan-linker.d.ts +26 -0
- package/out/reqlan-linker.js +83 -0
- package/out/reqlan-linker.js.map +1 -0
- package/out/reqlan-markdown-links.d.ts +28 -0
- package/out/reqlan-markdown-links.js +113 -0
- package/out/reqlan-markdown-links.js.map +1 -0
- package/out/reqlan-module.d.ts +41 -0
- package/out/reqlan-module.js +78 -0
- package/out/reqlan-module.js.map +1 -0
- package/out/reqlan-name-catalog.d.ts +23 -0
- package/out/reqlan-name-catalog.js +63 -0
- package/out/reqlan-name-catalog.js.map +1 -0
- package/out/reqlan-name-provider.d.ts +10 -0
- package/out/reqlan-name-provider.js +38 -0
- package/out/reqlan-name-provider.js.map +1 -0
- package/out/reqlan-namespace-import-links.d.ts +10 -0
- package/out/reqlan-namespace-import-links.js +69 -0
- package/out/reqlan-namespace-import-links.js.map +1 -0
- package/out/reqlan-path-completion.d.ts +50 -0
- package/out/reqlan-path-completion.js +304 -0
- package/out/reqlan-path-completion.js.map +1 -0
- package/out/reqlan-path-references.d.ts +5 -0
- package/out/reqlan-path-references.js +124 -0
- package/out/reqlan-path-references.js.map +1 -0
- package/out/reqlan-path-resolve.d.ts +81 -0
- package/out/reqlan-path-resolve.js +245 -0
- package/out/reqlan-path-resolve.js.map +1 -0
- package/out/reqlan-quoted-strings.d.ts +9 -0
- package/out/reqlan-quoted-strings.js +26 -0
- package/out/reqlan-quoted-strings.js.map +1 -0
- package/out/reqlan-reference-at-position.d.ts +20 -0
- package/out/reqlan-reference-at-position.js +89 -0
- package/out/reqlan-reference-at-position.js.map +1 -0
- package/out/reqlan-reference-code-lens.d.ts +32 -0
- package/out/reqlan-reference-code-lens.js +240 -0
- package/out/reqlan-reference-code-lens.js.map +1 -0
- package/out/reqlan-reference-search-site.d.ts +34 -0
- package/out/reqlan-reference-search-site.js +136 -0
- package/out/reqlan-reference-search-site.js.map +1 -0
- package/out/reqlan-references.d.ts +16 -0
- package/out/reqlan-references.js +51 -0
- package/out/reqlan-references.js.map +1 -0
- package/out/reqlan-scope.d.ts +25 -0
- package/out/reqlan-scope.js +259 -0
- package/out/reqlan-scope.js.map +1 -0
- package/out/reqlan-semantic-token-provider.d.ts +8 -0
- package/out/reqlan-semantic-token-provider.js +91 -0
- package/out/reqlan-semantic-token-provider.js.map +1 -0
- package/out/reqlan-token-builder.d.ts +12 -0
- package/out/reqlan-token-builder.js +459 -0
- package/out/reqlan-token-builder.js.map +1 -0
- package/out/reqlan-validator.d.ts +25 -0
- package/out/reqlan-validator.js +119 -0
- package/out/reqlan-validator.js.map +1 -0
- package/out/reqlan-workspace-attribute-catalog.d.ts +6 -0
- package/out/reqlan-workspace-attribute-catalog.js +54 -0
- package/out/reqlan-workspace-attribute-catalog.js.map +1 -0
- package/out/src/file-path-rewrite.d.ts +25 -0
- package/out/src/file-path-rewrite.js +56 -0
- package/out/src/file-path-rewrite.js.map +1 -0
- package/out/src/generated/ast.d.ts +1173 -0
- package/out/src/generated/ast.js +994 -0
- package/out/src/generated/ast.js.map +1 -0
- package/out/src/generated/grammar.d.ts +7 -0
- package/out/src/generated/grammar.js +3045 -0
- package/out/src/generated/grammar.js.map +1 -0
- package/out/src/generated/module.d.ts +20 -0
- package/out/src/generated/module.js +32 -0
- package/out/src/generated/module.js.map +1 -0
- package/out/src/index.d.ts +29 -0
- package/out/src/index.js +30 -0
- package/out/src/index.js.map +1 -0
- package/out/src/reqlan-attribute-catalog.d.ts +19 -0
- package/out/src/reqlan-attribute-catalog.js +87 -0
- package/out/src/reqlan-attribute-catalog.js.map +1 -0
- package/out/src/reqlan-code-action-provider.d.ts +34 -0
- package/out/src/reqlan-code-action-provider.js +206 -0
- package/out/src/reqlan-code-action-provider.js.map +1 -0
- package/out/src/reqlan-comment-resolver.d.ts +35 -0
- package/out/src/reqlan-comment-resolver.js +308 -0
- package/out/src/reqlan-comment-resolver.js.map +1 -0
- package/out/src/reqlan-completion-context.d.ts +46 -0
- package/out/src/reqlan-completion-context.js +244 -0
- package/out/src/reqlan-completion-context.js.map +1 -0
- package/out/src/reqlan-completion-provider.d.ts +41 -0
- package/out/src/reqlan-completion-provider.js +320 -0
- package/out/src/reqlan-completion-provider.js.map +1 -0
- package/out/src/reqlan-definition-provider.d.ts +31 -0
- package/out/src/reqlan-definition-provider.js +240 -0
- package/out/src/reqlan-definition-provider.js.map +1 -0
- package/out/src/reqlan-document-highlight-provider.d.ts +10 -0
- package/out/src/reqlan-document-highlight-provider.js +11 -0
- package/out/src/reqlan-document-highlight-provider.js.map +1 -0
- package/out/src/reqlan-document-link-provider.d.ts +14 -0
- package/out/src/reqlan-document-link-provider.js +24 -0
- package/out/src/reqlan-document-link-provider.js.map +1 -0
- package/out/src/reqlan-embedded-file-references.d.ts +11 -0
- package/out/src/reqlan-embedded-file-references.js +50 -0
- package/out/src/reqlan-embedded-file-references.js.map +1 -0
- package/out/src/reqlan-file-link-resolver.d.ts +44 -0
- package/out/src/reqlan-file-link-resolver.js +347 -0
- package/out/src/reqlan-file-link-resolver.js.map +1 -0
- package/out/src/reqlan-file-references.d.ts +15 -0
- package/out/src/reqlan-file-references.js +72 -0
- package/out/src/reqlan-file-references.js.map +1 -0
- package/out/src/reqlan-grammar-config.d.ts +5 -0
- package/out/src/reqlan-grammar-config.js +9 -0
- package/out/src/reqlan-grammar-config.js.map +1 -0
- package/out/src/reqlan-idea-summary.d.ts +6 -0
- package/out/src/reqlan-idea-summary.js +78 -0
- package/out/src/reqlan-idea-summary.js.map +1 -0
- package/out/src/reqlan-ignore-error.d.ts +10 -0
- package/out/src/reqlan-ignore-error.js +42 -0
- package/out/src/reqlan-ignore-error.js.map +1 -0
- package/out/src/reqlan-import-bindings.d.ts +12 -0
- package/out/src/reqlan-import-bindings.js +65 -0
- package/out/src/reqlan-import-bindings.js.map +1 -0
- package/out/src/reqlan-import-edits.d.ts +17 -0
- package/out/src/reqlan-import-edits.js +96 -0
- package/out/src/reqlan-import-edits.js.map +1 -0
- package/out/src/reqlan-imports.d.ts +22 -0
- package/out/src/reqlan-imports.js +61 -0
- package/out/src/reqlan-imports.js.map +1 -0
- package/out/src/reqlan-inbound-reference-inlay-label.d.ts +23 -0
- package/out/src/reqlan-inbound-reference-inlay-label.js +128 -0
- package/out/src/reqlan-inbound-reference-inlay-label.js.map +1 -0
- package/out/src/reqlan-inlay-hint-provider.d.ts +15 -0
- package/out/src/reqlan-inlay-hint-provider.js +54 -0
- package/out/src/reqlan-inlay-hint-provider.js.map +1 -0
- package/out/src/reqlan-inlay-hint-settings.d.ts +10 -0
- package/out/src/reqlan-inlay-hint-settings.js +10 -0
- package/out/src/reqlan-inlay-hint-settings.js.map +1 -0
- package/out/src/reqlan-linker.d.ts +26 -0
- package/out/src/reqlan-linker.js +86 -0
- package/out/src/reqlan-linker.js.map +1 -0
- package/out/src/reqlan-markdown-links.d.ts +28 -0
- package/out/src/reqlan-markdown-links.js +113 -0
- package/out/src/reqlan-markdown-links.js.map +1 -0
- package/out/src/reqlan-module.d.ts +41 -0
- package/out/src/reqlan-module.js +76 -0
- package/out/src/reqlan-module.js.map +1 -0
- package/out/src/reqlan-name-catalog.d.ts +23 -0
- package/out/src/reqlan-name-catalog.js +63 -0
- package/out/src/reqlan-name-catalog.js.map +1 -0
- package/out/src/reqlan-name-provider.d.ts +10 -0
- package/out/src/reqlan-name-provider.js +38 -0
- package/out/src/reqlan-name-provider.js.map +1 -0
- package/out/src/reqlan-namespace-import-links.d.ts +10 -0
- package/out/src/reqlan-namespace-import-links.js +81 -0
- package/out/src/reqlan-namespace-import-links.js.map +1 -0
- package/out/src/reqlan-path-completion.d.ts +50 -0
- package/out/src/reqlan-path-completion.js +304 -0
- package/out/src/reqlan-path-completion.js.map +1 -0
- package/out/src/reqlan-path-references.d.ts +5 -0
- package/out/src/reqlan-path-references.js +124 -0
- package/out/src/reqlan-path-references.js.map +1 -0
- package/out/src/reqlan-path-resolve.d.ts +59 -0
- package/out/src/reqlan-path-resolve.js +173 -0
- package/out/src/reqlan-path-resolve.js.map +1 -0
- package/out/src/reqlan-quoted-strings.d.ts +9 -0
- package/out/src/reqlan-quoted-strings.js +26 -0
- package/out/src/reqlan-quoted-strings.js.map +1 -0
- package/out/src/reqlan-reference-at-position.d.ts +20 -0
- package/out/src/reqlan-reference-at-position.js +89 -0
- package/out/src/reqlan-reference-at-position.js.map +1 -0
- package/out/src/reqlan-references.d.ts +16 -0
- package/out/src/reqlan-references.js +51 -0
- package/out/src/reqlan-references.js.map +1 -0
- package/out/src/reqlan-scope.d.ts +25 -0
- package/out/src/reqlan-scope.js +266 -0
- package/out/src/reqlan-scope.js.map +1 -0
- package/out/src/reqlan-semantic-token-provider.d.ts +8 -0
- package/out/src/reqlan-semantic-token-provider.js +97 -0
- package/out/src/reqlan-semantic-token-provider.js.map +1 -0
- package/out/src/reqlan-token-builder.d.ts +12 -0
- package/out/src/reqlan-token-builder.js +459 -0
- package/out/src/reqlan-token-builder.js.map +1 -0
- package/out/src/reqlan-validator.d.ts +25 -0
- package/out/src/reqlan-validator.js +119 -0
- package/out/src/reqlan-validator.js.map +1 -0
- package/out/src/reqlan-workspace-attribute-catalog.d.ts +6 -0
- package/out/src/reqlan-workspace-attribute-catalog.js +54 -0
- package/out/src/reqlan-workspace-attribute-catalog.js.map +1 -0
- package/out/test/code-actions.test.d.ts +1 -0
- package/out/test/code-actions.test.js +126 -0
- package/out/test/code-actions.test.js.map +1 -0
- package/out/test/comment-in-string.test.d.ts +1 -0
- package/out/test/comment-in-string.test.js +100 -0
- package/out/test/comment-in-string.test.js.map +1 -0
- package/out/test/completion.test.d.ts +1 -0
- package/out/test/completion.test.js +467 -0
- package/out/test/completion.test.js.map +1 -0
- package/out/test/file-path-rewrite.test.d.ts +1 -0
- package/out/test/file-path-rewrite.test.js +64 -0
- package/out/test/file-path-rewrite.test.js.map +1 -0
- package/out/test/ignore-error.test.d.ts +1 -0
- package/out/test/ignore-error.test.js +87 -0
- package/out/test/ignore-error.test.js.map +1 -0
- package/out/test/implicit-import-extension.test.d.ts +1 -0
- package/out/test/implicit-import-extension.test.js +203 -0
- package/out/test/implicit-import-extension.test.js.map +1 -0
- package/out/test/import-edits.test.d.ts +1 -0
- package/out/test/import-edits.test.js +20 -0
- package/out/test/import-edits.test.js.map +1 -0
- package/out/test/inlay-hints.test.d.ts +1 -0
- package/out/test/inlay-hints.test.js +238 -0
- package/out/test/inlay-hints.test.js.map +1 -0
- package/out/test/linking.test.d.ts +1 -0
- package/out/test/linking.test.js +754 -0
- package/out/test/linking.test.js.map +1 -0
- package/out/test/naked-strings.test.d.ts +1 -0
- package/out/test/naked-strings.test.js +50 -0
- package/out/test/naked-strings.test.js.map +1 -0
- package/out/test/parsing.test.d.ts +1 -0
- package/out/test/parsing.test.js +773 -0
- package/out/test/parsing.test.js.map +1 -0
- package/out/test/path-resolve.test.d.ts +1 -0
- package/out/test/path-resolve.test.js +88 -0
- package/out/test/path-resolve.test.js.map +1 -0
- package/out/test/references.test.d.ts +1 -0
- package/out/test/references.test.js +168 -0
- package/out/test/references.test.js.map +1 -0
- package/out/test/rqconfig.test.d.ts +1 -0
- package/out/test/rqconfig.test.js +275 -0
- package/out/test/rqconfig.test.js.map +1 -0
- package/out/test/test-requirement-refs.d.ts +8 -0
- package/out/test/test-requirement-refs.js +35 -0
- package/out/test/test-requirement-refs.js.map +1 -0
- package/out/test/testing.test.d.ts +1 -0
- package/out/test/testing.test.js +23 -0
- package/out/test/testing.test.js.map +1 -0
- package/out/test/validating.test.d.ts +1 -0
- package/out/test/validating.test.js +117 -0
- package/out/test/validating.test.js.map +1 -0
- package/out/tsconfig.tsbuildinfo +1 -0
- package/package.json +54 -0
- package/src/chevrotain.d.ts +8 -0
- package/src/file-path-rewrite.ts +96 -0
- package/src/generated/ast.ts +1481 -0
- package/src/generated/grammar.ts +3074 -0
- package/src/generated/module.ts +38 -0
- package/src/index.ts +34 -0
- package/src/reqlan-attribute-catalog.ts +100 -0
- package/src/reqlan-code-action-provider.ts +385 -0
- package/src/reqlan-code-lens-provider.ts +54 -0
- package/src/reqlan-code-lens-settings.ts +42 -0
- package/src/reqlan-comment-resolver.ts +372 -0
- package/src/reqlan-comment.langium +23 -0
- package/src/reqlan-completion-context.ts +330 -0
- package/src/reqlan-completion-provider.ts +400 -0
- package/src/reqlan-definition-provider.ts +319 -0
- package/src/reqlan-document-highlight-provider.ts +21 -0
- package/src/reqlan-document-link-provider.ts +45 -0
- package/src/reqlan-embedded-file-references.ts +72 -0
- package/src/reqlan-file-link-resolver.ts +485 -0
- package/src/reqlan-file-references.ts +84 -0
- package/src/reqlan-grammar-config.ts +14 -0
- package/src/reqlan-idea-reference-site.ts +74 -0
- package/src/reqlan-idea-summary.ts +162 -0
- package/src/reqlan-ignore-error.ts +50 -0
- package/src/reqlan-import-bindings.ts +87 -0
- package/src/reqlan-import-edits.ts +124 -0
- package/src/reqlan-imports.ts +115 -0
- package/src/reqlan-inbound-reference-inlay-label.ts +194 -0
- package/src/reqlan-inlay-hint-provider.ts +88 -0
- package/src/reqlan-inlay-hint-settings.ts +15 -0
- package/src/reqlan-linker.ts +108 -0
- package/src/reqlan-markdown-links.ts +136 -0
- package/src/reqlan-module.ts +104 -0
- package/src/reqlan-name-catalog.ts +81 -0
- package/src/reqlan-name-provider.ts +56 -0
- package/src/reqlan-namespace-import-links.ts +92 -0
- package/src/reqlan-path-completion.ts +420 -0
- package/src/reqlan-path-references.ts +140 -0
- package/src/reqlan-path-resolve.ts +346 -0
- package/src/reqlan-quoted-strings.ts +30 -0
- package/src/reqlan-reference-at-position.ts +154 -0
- package/src/reqlan-reference-code-lens.ts +323 -0
- package/src/reqlan-reference-search-site.ts +202 -0
- package/src/reqlan-references.ts +76 -0
- package/src/reqlan-scope.ts +312 -0
- package/src/reqlan-semantic-token-provider.ts +113 -0
- package/src/reqlan-token-builder.ts +492 -0
- package/src/reqlan-validator.ts +149 -0
- package/src/reqlan-workspace-attribute-catalog.ts +62 -0
- package/src/reqlan.langium +236 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact idea body summaries for inline editor hints and indexing.
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
isBodyLine,
|
|
6
|
+
isBracketReference,
|
|
7
|
+
isFileReference,
|
|
8
|
+
isFileSymbolReference,
|
|
9
|
+
isIdea,
|
|
10
|
+
isLocalReference,
|
|
11
|
+
isMarkdownLink,
|
|
12
|
+
isOneLinerIdea,
|
|
13
|
+
isQualifiedReference,
|
|
14
|
+
isRichTextPart,
|
|
15
|
+
isWikiLink,
|
|
16
|
+
type BodyLine,
|
|
17
|
+
type BracketReference,
|
|
18
|
+
type IdeaDeclaration,
|
|
19
|
+
type OneLinerIdea,
|
|
20
|
+
type ReferenceTarget,
|
|
21
|
+
type WikiLink
|
|
22
|
+
} from './generated/ast.js';
|
|
23
|
+
import { parseMarkdownLink, referenceIdea, unquoteReqlanString } from './reqlan-references.js';
|
|
24
|
+
|
|
25
|
+
/** Preserve the source token so consumers can restyle/link refs (not a bare "[ref]"). */
|
|
26
|
+
function summarizeReferencePart(part: WikiLink | BracketReference): string {
|
|
27
|
+
const raw = part.$cstNode?.text?.replace(/\s+/g, ' ').trim();
|
|
28
|
+
if (raw) {
|
|
29
|
+
return raw;
|
|
30
|
+
}
|
|
31
|
+
const label = referenceDisplayName(part);
|
|
32
|
+
if (isWikiLink(part)) {
|
|
33
|
+
return label ? `[[${label}]]` : '[ref]';
|
|
34
|
+
}
|
|
35
|
+
return label ? `[${label}]` : '[ref]';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function wikiAliasText(part: WikiLink): string | undefined {
|
|
39
|
+
const alias = part.alias
|
|
40
|
+
?.map(piece => piece.text ?? '')
|
|
41
|
+
.join('')
|
|
42
|
+
.replace(/\s+/g, ' ')
|
|
43
|
+
.trim();
|
|
44
|
+
return alias || undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function referenceTargetLabel(target: ReferenceTarget | undefined): string | undefined {
|
|
48
|
+
if (!target) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
if (isFileReference(target)) {
|
|
52
|
+
return fileBaseName(unquoteReqlanString(target.file));
|
|
53
|
+
}
|
|
54
|
+
if (isFileSymbolReference(target)) {
|
|
55
|
+
return fileBaseName(unquoteReqlanString(target.file));
|
|
56
|
+
}
|
|
57
|
+
if (isQualifiedReference(target) || isLocalReference(target)) {
|
|
58
|
+
const idea = referenceIdea(target);
|
|
59
|
+
const name = idea?.ref?.name ?? idea?.$refText;
|
|
60
|
+
if (name) {
|
|
61
|
+
return name;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return target.$cstNode?.text?.replace(/\s+/g, ' ').trim();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function referenceDisplayName(part: WikiLink | BracketReference): string | undefined {
|
|
68
|
+
if (isWikiLink(part)) {
|
|
69
|
+
const alias = wikiAliasText(part);
|
|
70
|
+
if (alias) {
|
|
71
|
+
return alias;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return referenceTargetLabel(part.target);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function fileBaseName(path: string): string {
|
|
78
|
+
const cleaned = path.trim();
|
|
79
|
+
const segments = cleaned.split(/[/\\]/).filter(Boolean);
|
|
80
|
+
return segments[segments.length - 1] || cleaned;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function summarizeOneLinerPart(part: NonNullable<OneLinerIdea['body']>['content'][number]): string {
|
|
84
|
+
if (typeof part === 'string') {
|
|
85
|
+
return part;
|
|
86
|
+
}
|
|
87
|
+
if (isMarkdownLink(part)) {
|
|
88
|
+
return parseMarkdownLink(part.raw)?.label ?? part.raw;
|
|
89
|
+
}
|
|
90
|
+
if (isWikiLink(part) || isBracketReference(part)) {
|
|
91
|
+
return summarizeReferencePart(part);
|
|
92
|
+
}
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function summarizeRichTextPart(part: BodyLine['parts'][number]): string {
|
|
97
|
+
if (typeof part === 'string') {
|
|
98
|
+
return part;
|
|
99
|
+
}
|
|
100
|
+
if (isRichTextPart(part) && part.$type === 'RichTextPart') {
|
|
101
|
+
return part.text ?? part.inlineCode ?? part.lparen ?? part.rparen ?? '';
|
|
102
|
+
}
|
|
103
|
+
if (isMarkdownLink(part)) {
|
|
104
|
+
return parseMarkdownLink(part.raw)?.label ?? part.raw;
|
|
105
|
+
}
|
|
106
|
+
if (isWikiLink(part) || isBracketReference(part)) {
|
|
107
|
+
return summarizeReferencePart(part);
|
|
108
|
+
}
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function summarizeOneLinerBody(idea: OneLinerIdea): string {
|
|
113
|
+
if (!idea.body) {
|
|
114
|
+
return '';
|
|
115
|
+
}
|
|
116
|
+
return idea.body.content
|
|
117
|
+
.map(summarizeOneLinerPart)
|
|
118
|
+
.join(' ')
|
|
119
|
+
.replace(/\s+/g, ' ')
|
|
120
|
+
.trim();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function summarizeBlockIdeaBody(idea: IdeaDeclaration): string {
|
|
124
|
+
if (!isIdea(idea)) {
|
|
125
|
+
return '';
|
|
126
|
+
}
|
|
127
|
+
const lines: string[] = [];
|
|
128
|
+
for (const element of idea.elements) {
|
|
129
|
+
if (!isBodyLine(element)) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const line = element.parts
|
|
133
|
+
.map(summarizeRichTextPart)
|
|
134
|
+
.filter(part => part.length > 0)
|
|
135
|
+
.join(' ')
|
|
136
|
+
.replace(/\s+([.,!?;:])/g, '$1')
|
|
137
|
+
.replace(/\s+/g, ' ')
|
|
138
|
+
.trim();
|
|
139
|
+
if (line) {
|
|
140
|
+
lines.push(line);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function summarizeIdeaDeclaration(idea: IdeaDeclaration): string {
|
|
147
|
+
if (isOneLinerIdea(idea)) {
|
|
148
|
+
return summarizeOneLinerBody(idea);
|
|
149
|
+
}
|
|
150
|
+
if (isIdea(idea)) {
|
|
151
|
+
return summarizeBlockIdeaBody(idea);
|
|
152
|
+
}
|
|
153
|
+
return '';
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function truncateSummary(text: string, maxLength = 80): string {
|
|
157
|
+
const normalized = text.replace(/\s+/g, ' ').trim();
|
|
158
|
+
if (normalized.length <= maxLength) {
|
|
159
|
+
return normalized;
|
|
160
|
+
}
|
|
161
|
+
return `${normalized.slice(0, maxLength - 1).trimEnd()}…`;
|
|
162
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suppresses diagnostics on lines immediately following `//rq-ignore-error`.
|
|
3
|
+
* rq:["../../../reqlan rq/language/syntax.rq".comment_reference_ignore]
|
|
4
|
+
*/
|
|
5
|
+
import { DocumentState, type LangiumDocument, type LangiumSharedCoreServices } from 'langium';
|
|
6
|
+
import type { Diagnostic } from 'vscode-languageserver';
|
|
7
|
+
import { findLineCommentStart } from './reqlan-comment-resolver.js';
|
|
8
|
+
|
|
9
|
+
const RQ_IGNORE_ERROR = /\/\/\s*rq-ignore-error\b/;
|
|
10
|
+
|
|
11
|
+
export function findRqIgnoreErrorTargetLines(text: string): Set<number> {
|
|
12
|
+
const lines = text.split(/\r?\n/);
|
|
13
|
+
const targetLines = new Set<number>();
|
|
14
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
|
|
15
|
+
const line = lines[lineIndex]!;
|
|
16
|
+
const commentStart = findLineCommentStart(line);
|
|
17
|
+
if (commentStart < 0) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const commentText = line.slice(commentStart);
|
|
21
|
+
if (RQ_IGNORE_ERROR.test(commentText) && lineIndex + 1 < lines.length) {
|
|
22
|
+
targetLines.add(lineIndex + 1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return targetLines;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function filterRqIgnoredDiagnostics(text: string, diagnostics: Diagnostic[]): Diagnostic[] {
|
|
29
|
+
const ignoredLines = findRqIgnoreErrorTargetLines(text);
|
|
30
|
+
if (ignoredLines.size === 0) {
|
|
31
|
+
return diagnostics;
|
|
32
|
+
}
|
|
33
|
+
return diagnostics.filter(diagnostic => !ignoredLines.has(diagnostic.range.start.line));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function applyRqIgnoreErrorFiltering(document: LangiumDocument): void {
|
|
37
|
+
if (!document.diagnostics?.length) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
document.diagnostics = filterRqIgnoredDiagnostics(
|
|
41
|
+
document.textDocument.getText(),
|
|
42
|
+
document.diagnostics
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function registerRqIgnoreErrorFiltering(shared: LangiumSharedCoreServices): void {
|
|
47
|
+
shared.workspace.DocumentBuilder.onDocumentPhase(DocumentState.Validated, (document: LangiumDocument) => {
|
|
48
|
+
applyRqIgnoreErrorFiltering(document);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { AstNode } from 'langium';
|
|
2
|
+
import {
|
|
3
|
+
isFromImport,
|
|
4
|
+
isNamespaceImport,
|
|
5
|
+
isQualifiedImport,
|
|
6
|
+
type FromImportSpecifier,
|
|
7
|
+
type Import
|
|
8
|
+
} from './generated/ast.js';
|
|
9
|
+
|
|
10
|
+
export interface ImportBinding {
|
|
11
|
+
name: string;
|
|
12
|
+
node: AstNode;
|
|
13
|
+
property: 'alias' | 'idea';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function specifierBindingName(specifier: FromImportSpecifier): string | undefined {
|
|
17
|
+
return specifier.alias ?? specifier.idea.$refText;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function importBindings(importDecl: Import): ImportBinding[] {
|
|
21
|
+
if (isFromImport(importDecl)) {
|
|
22
|
+
return importDecl.specifiers.flatMap(specifier => {
|
|
23
|
+
const name = specifierBindingName(specifier);
|
|
24
|
+
if (!name) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
return [{
|
|
28
|
+
name,
|
|
29
|
+
node: specifier,
|
|
30
|
+
property: specifier.alias ? 'alias' as const : 'idea' as const
|
|
31
|
+
}];
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (isQualifiedImport(importDecl)) {
|
|
35
|
+
const name = importDecl.alias ?? importDecl.idea.$refText;
|
|
36
|
+
if (!name) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
return [{
|
|
40
|
+
name,
|
|
41
|
+
node: importDecl,
|
|
42
|
+
property: importDecl.alias ? 'alias' : 'idea'
|
|
43
|
+
}];
|
|
44
|
+
}
|
|
45
|
+
if (importDecl.alias) {
|
|
46
|
+
return [{ name: importDecl.alias, node: importDecl, property: 'alias' }];
|
|
47
|
+
}
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function importedIdeaNames(importDecl: Import): string[] {
|
|
52
|
+
if (isFromImport(importDecl)) {
|
|
53
|
+
return importDecl.specifiers.map(specifier => specifier.idea.$refText);
|
|
54
|
+
}
|
|
55
|
+
if (isQualifiedImport(importDecl)) {
|
|
56
|
+
return [importDecl.idea.$refText];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function findNamespaceImportByAlias(imports: Import[], alias: string): Import | undefined {
|
|
62
|
+
for (const importDecl of imports) {
|
|
63
|
+
if (!isNamespaceImport(importDecl) || importDecl.alias !== alias) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
return importDecl;
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function findFromImportSpecifierByBinding(
|
|
72
|
+
imports: Import[],
|
|
73
|
+
bindingName: string
|
|
74
|
+
): FromImportSpecifier | undefined {
|
|
75
|
+
for (const importDecl of imports) {
|
|
76
|
+
if (!isFromImport(importDecl)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const specifier = importDecl.specifiers.find(
|
|
80
|
+
entry => specifierBindingName(entry) === bindingName
|
|
81
|
+
);
|
|
82
|
+
if (specifier) {
|
|
83
|
+
return specifier;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared WorkspaceEdit helpers for import insertion used by unresolved-reference quick fixes.
|
|
3
|
+
* rq:["../../../reqlan rq/extension/language-support/features-imports.rq".import_error]
|
|
4
|
+
*/
|
|
5
|
+
import type { LangiumDocument, URI } from 'langium';
|
|
6
|
+
import { UriUtils } from 'langium';
|
|
7
|
+
import type { Position, TextEdit } from 'vscode-languageserver';
|
|
8
|
+
import {
|
|
9
|
+
isFromImport,
|
|
10
|
+
isModel,
|
|
11
|
+
isNamespaceImport,
|
|
12
|
+
type FromImport,
|
|
13
|
+
type Model
|
|
14
|
+
} from './generated/ast.js';
|
|
15
|
+
import { unquoteReqlanString } from './reqlan-references.js';
|
|
16
|
+
|
|
17
|
+
export function relativeRqImportPath(fromUri: URI, toUri: URI): string {
|
|
18
|
+
const sourceDir = UriUtils.dirname(fromUri);
|
|
19
|
+
let relativePath = UriUtils.relative(sourceDir, toUri);
|
|
20
|
+
if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {
|
|
21
|
+
relativePath = `./${relativePath}`;
|
|
22
|
+
}
|
|
23
|
+
return relativePath;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function findImportInsertPosition(model: Model): { position: Position; trailingNewline: boolean } {
|
|
27
|
+
if (model.imports.length > 0) {
|
|
28
|
+
const last = model.imports[model.imports.length - 1]!;
|
|
29
|
+
const end = last.$cstNode?.range.end;
|
|
30
|
+
if (end) {
|
|
31
|
+
return {
|
|
32
|
+
position: { line: end.line + 1, character: 0 },
|
|
33
|
+
trailingNewline: false
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const firstElement = model.elements[0];
|
|
38
|
+
if (firstElement?.$cstNode) {
|
|
39
|
+
return {
|
|
40
|
+
position: firstElement.$cstNode.range.start,
|
|
41
|
+
trailingNewline: true
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { position: { line: 0, character: 0 }, trailingNewline: true };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function findExistingFromImport(model: Model, importPath: string): FromImport | undefined {
|
|
48
|
+
return model.imports.find((decl): decl is FromImport => {
|
|
49
|
+
if (!isFromImport(decl)) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return unquoteReqlanString(decl.path) === importPath;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function hasNamespaceImport(model: Model, importPath: string): boolean {
|
|
57
|
+
return model.imports.some(decl =>
|
|
58
|
+
isNamespaceImport(decl) && unquoteReqlanString(decl.path) === importPath
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function buildFromImportEdit(
|
|
63
|
+
document: LangiumDocument,
|
|
64
|
+
importPath: string,
|
|
65
|
+
symbolName: string
|
|
66
|
+
): TextEdit | undefined {
|
|
67
|
+
const model = document.parseResult.value;
|
|
68
|
+
if (!isModel(model)) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const existing = findExistingFromImport(model, importPath);
|
|
72
|
+
if (existing) {
|
|
73
|
+
const alreadyImported = existing.specifiers.some(specifier => {
|
|
74
|
+
const binding = specifier.alias ?? specifier.idea.$refText;
|
|
75
|
+
return binding === symbolName || specifier.idea.$refText === symbolName;
|
|
76
|
+
});
|
|
77
|
+
if (alreadyImported) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
const lastSpecifier = existing.specifiers[existing.specifiers.length - 1];
|
|
81
|
+
const insertAt = lastSpecifier?.$cstNode?.range.end ?? existing.$cstNode?.range.end;
|
|
82
|
+
if (!insertAt) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
range: { start: insertAt, end: insertAt },
|
|
87
|
+
newText: `, ${symbolName}`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const insert = findImportInsertPosition(model);
|
|
91
|
+
const line = `from "${importPath}" import ${symbolName}`;
|
|
92
|
+
return {
|
|
93
|
+
range: { start: insert.position, end: insert.position },
|
|
94
|
+
newText: insert.trailingNewline ? `${line}\n\n` : `${line}\n`
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function buildNamespaceImportEdit(
|
|
99
|
+
document: LangiumDocument,
|
|
100
|
+
importPath: string,
|
|
101
|
+
alias: string
|
|
102
|
+
): TextEdit | undefined {
|
|
103
|
+
const model = document.parseResult.value;
|
|
104
|
+
if (!isModel(model)) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
if (hasNamespaceImport(model, importPath)) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const insert = findImportInsertPosition(model);
|
|
111
|
+
const line = `import "${importPath}" as ${alias}`;
|
|
112
|
+
return {
|
|
113
|
+
range: { start: insert.position, end: insert.position },
|
|
114
|
+
newText: insert.trailingNewline ? `${line}\n\n` : `${line}\n`
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function fileBasenameAlias(fileUri: string | URI): string {
|
|
119
|
+
const uriString = typeof fileUri === 'string' ? fileUri : fileUri.toString();
|
|
120
|
+
const base = uriString.split('/').pop() ?? uriString;
|
|
121
|
+
const withoutExt = base.replace(/\.rq$/i, '');
|
|
122
|
+
const cleaned = withoutExt.replace(/[^A-Za-z0-9_]+/g, '_').replace(/^(\d)/, '_$1');
|
|
123
|
+
return cleaned || 'imported';
|
|
124
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves imported requirement documents from relative and import-root-aliased paths.
|
|
3
|
+
* Interacts with scope linking and go-to-definition for import paths.
|
|
4
|
+
* rq:["../../../reqlan rq/extension/language-support/features-imports.rq".implicit_file_extension]
|
|
5
|
+
*/
|
|
6
|
+
import type { FileSystemProvider, LangiumDocument, LangiumDocuments, URI } from 'langium';
|
|
7
|
+
import {
|
|
8
|
+
resolveDocumentPathUri,
|
|
9
|
+
type PathResolveContext
|
|
10
|
+
} from './reqlan-path-resolve.js';
|
|
11
|
+
|
|
12
|
+
export type { PathResolveContext };
|
|
13
|
+
|
|
14
|
+
export const IMPLICIT_IMPORT_EXTENSION = '.rq';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Import paths written without an extension mean `.rq`; the literal path stays a fallback so
|
|
18
|
+
* extensionless files on disk keep resolving.
|
|
19
|
+
*/
|
|
20
|
+
export function importPathCandidates(path: string): string[] {
|
|
21
|
+
const implicit = importPathWithImplicitExtension(path);
|
|
22
|
+
return implicit ? [implicit, path] : [path];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function importPathWithImplicitExtension(path: string): string | undefined {
|
|
26
|
+
const basename = path.slice(path.lastIndexOf('/') + 1);
|
|
27
|
+
if (basename.length === 0 || basename === '.' || basename === '..') {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
if (basename.includes('.', 1)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return `${path}${IMPLICIT_IMPORT_EXTENSION}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resolveImportUri(
|
|
37
|
+
path: string,
|
|
38
|
+
document: LangiumDocument,
|
|
39
|
+
context?: PathResolveContext
|
|
40
|
+
) {
|
|
41
|
+
return resolveDocumentPathUri(path, document, context);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Candidate URIs in preference order: implicit `.rq` first, then the path as written. */
|
|
45
|
+
export function resolveImportCandidateUris(
|
|
46
|
+
path: string,
|
|
47
|
+
document: LangiumDocument,
|
|
48
|
+
context?: PathResolveContext
|
|
49
|
+
): URI[] {
|
|
50
|
+
return importPathCandidates(path).map(candidate =>
|
|
51
|
+
resolveDocumentPathUri(candidate, document, context)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function isResolvableImportPath(
|
|
56
|
+
path: string,
|
|
57
|
+
document: LangiumDocument,
|
|
58
|
+
documents: LangiumDocuments,
|
|
59
|
+
fileSystem?: FileSystemProvider,
|
|
60
|
+
context?: PathResolveContext
|
|
61
|
+
): boolean {
|
|
62
|
+
return resolveImportCandidateUris(path, document, withFileSystem(context, fileSystem))
|
|
63
|
+
.some(uri => isImportTarget(uri, documents, fileSystem));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function findImportedDocument(
|
|
67
|
+
path: string,
|
|
68
|
+
document: LangiumDocument,
|
|
69
|
+
documents: LangiumDocuments,
|
|
70
|
+
context?: PathResolveContext
|
|
71
|
+
): LangiumDocument | undefined {
|
|
72
|
+
for (const uri of resolveImportCandidateUris(path, document, context)) {
|
|
73
|
+
const imported = documents.getDocument(uri);
|
|
74
|
+
if (imported) {
|
|
75
|
+
return imported;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** First candidate that exists, falling back to the path as written when none do. */
|
|
82
|
+
export function resolveExistingImportUri(
|
|
83
|
+
path: string,
|
|
84
|
+
document: LangiumDocument,
|
|
85
|
+
documents: LangiumDocuments,
|
|
86
|
+
fileSystem?: FileSystemProvider,
|
|
87
|
+
context?: PathResolveContext
|
|
88
|
+
): URI {
|
|
89
|
+
const uris = resolveImportCandidateUris(path, document, withFileSystem(context, fileSystem));
|
|
90
|
+
return uris.find(uri => isImportTarget(uri, documents, fileSystem)) ?? uris[uris.length - 1]!;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function isImportTarget(
|
|
94
|
+
uri: URI,
|
|
95
|
+
documents: LangiumDocuments,
|
|
96
|
+
fileSystem: FileSystemProvider | undefined
|
|
97
|
+
): boolean {
|
|
98
|
+
if (documents.getDocument(uri)) {
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
if (!fileSystem?.existsSync(uri)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return !fileSystem.statSync(uri).isDirectory;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function withFileSystem(
|
|
108
|
+
context: PathResolveContext | undefined,
|
|
109
|
+
fileSystem: FileSystemProvider | undefined
|
|
110
|
+
): PathResolveContext | undefined {
|
|
111
|
+
if (!fileSystem && !context) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
return { ...context, fileSystem: fileSystem ?? context?.fileSystem };
|
|
115
|
+
}
|