@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,38 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
* This file was generated by langium-cli 4.3.0.
|
|
3
|
+
* DO NOT EDIT MANUALLY!
|
|
4
|
+
******************************************************************************/
|
|
5
|
+
|
|
6
|
+
import type { LangiumSharedCoreServices, LangiumCoreServices, LangiumGeneratedCoreServices, LangiumGeneratedSharedCoreServices, LanguageMetaData, Module } from 'langium';
|
|
7
|
+
import { ReqlanAstReflection } from './ast.js';
|
|
8
|
+
import { ReqlanGrammar, ReqlanCommentGrammar } from './grammar.js';
|
|
9
|
+
|
|
10
|
+
export const ReqlanLanguageMetaData = {
|
|
11
|
+
languageId: 'reqlan',
|
|
12
|
+
fileExtensions: ['.rq'],
|
|
13
|
+
caseInsensitive: false,
|
|
14
|
+
mode: 'development'
|
|
15
|
+
} as const satisfies LanguageMetaData;
|
|
16
|
+
|
|
17
|
+
export const ReqlanCommentLanguageMetaData = {
|
|
18
|
+
languageId: 'reqlan-comment',
|
|
19
|
+
fileExtensions: [],
|
|
20
|
+
caseInsensitive: false,
|
|
21
|
+
mode: 'development'
|
|
22
|
+
} as const satisfies LanguageMetaData;
|
|
23
|
+
|
|
24
|
+
export const ReqlanGeneratedSharedModule: Module<LangiumSharedCoreServices, LangiumGeneratedSharedCoreServices> = {
|
|
25
|
+
AstReflection: () => new ReqlanAstReflection()
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const ReqlanGeneratedModule: Module<LangiumCoreServices, LangiumGeneratedCoreServices> = {
|
|
29
|
+
Grammar: () => ReqlanGrammar(),
|
|
30
|
+
LanguageMetaData: () => ReqlanLanguageMetaData,
|
|
31
|
+
parser: {}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const ReqlanCommentGeneratedModule: Module<LangiumCoreServices, LangiumGeneratedCoreServices> = {
|
|
35
|
+
Grammar: () => ReqlanCommentGrammar(),
|
|
36
|
+
LanguageMetaData: () => ReqlanCommentLanguageMetaData,
|
|
37
|
+
parser: {}
|
|
38
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export * from './reqlan-module.js';
|
|
2
|
+
export * from './reqlan-validator.js';
|
|
3
|
+
export * from './reqlan-comment-resolver.js';
|
|
4
|
+
export * from './reqlan-ignore-error.js';
|
|
5
|
+
export * from './reqlan-file-references.js';
|
|
6
|
+
export * from './reqlan-embedded-file-references.js';
|
|
7
|
+
export * from './file-path-rewrite.js';
|
|
8
|
+
export * from './reqlan-path-references.js';
|
|
9
|
+
export * from './reqlan-path-resolve.js';
|
|
10
|
+
export * from './reqlan-imports.js';
|
|
11
|
+
export * from './reqlan-quoted-strings.js';
|
|
12
|
+
export * from './reqlan-references.js';
|
|
13
|
+
export * from './reqlan-reference-at-position.js';
|
|
14
|
+
export * from './reqlan-attribute-catalog.js';
|
|
15
|
+
export * from './reqlan-completion-context.js';
|
|
16
|
+
export * from './reqlan-completion-provider.js';
|
|
17
|
+
export * from './reqlan-path-completion.js';
|
|
18
|
+
export * from './reqlan-code-action-provider.js';
|
|
19
|
+
export * from './reqlan-idea-reference-site.js';
|
|
20
|
+
export * from './reqlan-reference-search-site.js';
|
|
21
|
+
export * from './reqlan-import-edits.js';
|
|
22
|
+
export * from './reqlan-import-bindings.js';
|
|
23
|
+
export * from './reqlan-namespace-import-links.js';
|
|
24
|
+
export * from './reqlan-name-catalog.js';
|
|
25
|
+
export * from './reqlan-workspace-attribute-catalog.js';
|
|
26
|
+
export * from './reqlan-inlay-hint-settings.js';
|
|
27
|
+
export * from './reqlan-code-lens-settings.js';
|
|
28
|
+
export * from './reqlan-reference-code-lens.js';
|
|
29
|
+
export { ReqlanInlayHintProvider } from './reqlan-inlay-hint-provider.js';
|
|
30
|
+
export { ReqlanCodeLensProvider } from './reqlan-code-lens-provider.js';
|
|
31
|
+
export { summarizeIdeaDeclaration, truncateSummary } from './reqlan-idea-summary.js';
|
|
32
|
+
export * from './generated/ast.js';
|
|
33
|
+
export * from './generated/grammar.js';
|
|
34
|
+
export * from './generated/module.js';
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Endorsed attribute keys and workspace-wide attribute value catalog for completion.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** Common attributes from reqlan rq/language/syntax.rq attribute_forms. */
|
|
6
|
+
export const ENDORSED_ATTRIBUTE_KEYS = [
|
|
7
|
+
'plan',
|
|
8
|
+
'status',
|
|
9
|
+
'priority',
|
|
10
|
+
'criticality',
|
|
11
|
+
'confirmation',
|
|
12
|
+
'owner',
|
|
13
|
+
'log',
|
|
14
|
+
'tags',
|
|
15
|
+
'references',
|
|
16
|
+
'refs',
|
|
17
|
+
'required',
|
|
18
|
+
'deprecated',
|
|
19
|
+
'tests'
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
export interface AttributeCatalog {
|
|
23
|
+
keys: string[];
|
|
24
|
+
valuesByKey: Record<string, string[]>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class AttributeCatalogStore {
|
|
28
|
+
private catalog: AttributeCatalog = {
|
|
29
|
+
keys: [...ENDORSED_ATTRIBUTE_KEYS],
|
|
30
|
+
valuesByKey: {}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
get(): AttributeCatalog {
|
|
34
|
+
return this.catalog;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
update(catalog: AttributeCatalog): void {
|
|
38
|
+
this.catalog = mergeAttributeCatalogs(this.catalog, catalog);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
reset(): void {
|
|
42
|
+
this.catalog = {
|
|
43
|
+
keys: [...ENDORSED_ATTRIBUTE_KEYS],
|
|
44
|
+
valuesByKey: {}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
mergeWorkspaceKeys(keys: Iterable<string>, valuesByKey: Record<string, Iterable<string>>): void {
|
|
49
|
+
const mergedKeys = new Set<string>([...ENDORSED_ATTRIBUTE_KEYS, ...this.catalog.keys]);
|
|
50
|
+
for (const key of keys) {
|
|
51
|
+
mergedKeys.add(key);
|
|
52
|
+
}
|
|
53
|
+
const mergedValues: Record<string, string[]> = { ...this.catalog.valuesByKey };
|
|
54
|
+
for (const [key, values] of Object.entries(valuesByKey)) {
|
|
55
|
+
mergedKeys.add(key);
|
|
56
|
+
const existing = new Set(mergedValues[key] ?? []);
|
|
57
|
+
for (const value of values) {
|
|
58
|
+
if (value) {
|
|
59
|
+
existing.add(value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
mergedValues[key] = [...existing].sort((left, right) => left.localeCompare(right));
|
|
63
|
+
}
|
|
64
|
+
this.catalog = {
|
|
65
|
+
keys: [...mergedKeys].sort((left, right) => left.localeCompare(right)),
|
|
66
|
+
valuesByKey: mergedValues
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const REQLAN_ATTRIBUTE_CATALOG_NOTIFICATION = 'reqlan/attributeCatalog';
|
|
72
|
+
|
|
73
|
+
export const sharedAttributeCatalog = new AttributeCatalogStore();
|
|
74
|
+
|
|
75
|
+
export function mergeAttributeCatalogs(...catalogs: AttributeCatalog[]): AttributeCatalog {
|
|
76
|
+
const keys = new Set<string>(ENDORSED_ATTRIBUTE_KEYS);
|
|
77
|
+
const valuesByKey = new Map<string, Set<string>>();
|
|
78
|
+
for (const catalog of catalogs) {
|
|
79
|
+
for (const key of catalog.keys) {
|
|
80
|
+
keys.add(key);
|
|
81
|
+
}
|
|
82
|
+
for (const [key, values] of Object.entries(catalog.valuesByKey)) {
|
|
83
|
+
keys.add(key);
|
|
84
|
+
if (!valuesByKey.has(key)) {
|
|
85
|
+
valuesByKey.set(key, new Set());
|
|
86
|
+
}
|
|
87
|
+
for (const value of values) {
|
|
88
|
+
if (value) {
|
|
89
|
+
valuesByKey.get(key)!.add(value);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
keys: [...keys].sort((left, right) => left.localeCompare(right)),
|
|
96
|
+
valuesByKey: Object.fromEntries(
|
|
97
|
+
[...valuesByKey.entries()].map(([key, values]) => [key, [...values].sort()])
|
|
98
|
+
)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick fixes for unresolved references: add import, rewrite qualified ref, search, create.
|
|
3
|
+
* Also offers a search code action when the cursor is inside a [reference] / [[wikilink]].
|
|
4
|
+
* rq:["../../../reqlan rq/extension/language-support/features-imports.rq".import_error]
|
|
5
|
+
* rq:["../../../reqlan rq/extension/features-commands.rq".search_code_actions]
|
|
6
|
+
*/
|
|
7
|
+
import type { LangiumDocument, URI } from 'langium';
|
|
8
|
+
import { DocumentValidator, URI as UriCtor, UriUtils } from 'langium';
|
|
9
|
+
import type { CodeActionParams, Command, Diagnostic } from 'vscode-languageserver';
|
|
10
|
+
import { CodeActionKind } from 'vscode-languageserver';
|
|
11
|
+
import type { CodeActionProvider } from 'langium/lsp';
|
|
12
|
+
import {
|
|
13
|
+
isIdea,
|
|
14
|
+
isIdeaSet,
|
|
15
|
+
isModel,
|
|
16
|
+
isOneLinerIdea,
|
|
17
|
+
type Model
|
|
18
|
+
} from './generated/ast.js';
|
|
19
|
+
import {
|
|
20
|
+
buildFromImportEdit,
|
|
21
|
+
relativeRqImportPath
|
|
22
|
+
} from './reqlan-import-edits.js';
|
|
23
|
+
import type { ReqlanServices } from './reqlan-module.js';
|
|
24
|
+
import {
|
|
25
|
+
sharedNameCatalog,
|
|
26
|
+
type NameCatalogEntry,
|
|
27
|
+
type NameCatalogKind
|
|
28
|
+
} from './reqlan-name-catalog.js';
|
|
29
|
+
import { findReferenceSearchSite, buildContextForRange } from './reqlan-reference-search-site.js';
|
|
30
|
+
|
|
31
|
+
export const REQLAN_IMPORT_ERROR_SEARCH_COMMAND = 'reqlan.importError.search';
|
|
32
|
+
export const REQLAN_IMPORT_ERROR_CREATE_COMMAND = 'reqlan.importError.createFile';
|
|
33
|
+
export const REQLAN_SEARCH_REFERENCE_COMMAND = 'reqlan.searchReference';
|
|
34
|
+
|
|
35
|
+
const MAX_IMPORT_SUGGESTIONS = 5;
|
|
36
|
+
|
|
37
|
+
interface LinkingDiagnosticData {
|
|
38
|
+
code?: string;
|
|
39
|
+
containerType?: string;
|
|
40
|
+
property?: string;
|
|
41
|
+
refText?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ImportErrorCommandArgs {
|
|
45
|
+
documentUri: string;
|
|
46
|
+
refText: string;
|
|
47
|
+
range: Diagnostic['range'];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Args for reference search webview (replace existing ref or wrap prose). */
|
|
51
|
+
export interface SearchReferenceCommandArgs {
|
|
52
|
+
documentUri: string;
|
|
53
|
+
refText: string;
|
|
54
|
+
range: Diagnostic['range'];
|
|
55
|
+
mode: 'replace' | 'wrap';
|
|
56
|
+
context?: {
|
|
57
|
+
ideaName: string;
|
|
58
|
+
before: string;
|
|
59
|
+
target: string;
|
|
60
|
+
after: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface SymbolMatch {
|
|
65
|
+
name: string;
|
|
66
|
+
kind: NameCatalogKind;
|
|
67
|
+
fileUri: string;
|
|
68
|
+
importPath: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type CodeActionLike = import('vscode-languageserver').CodeAction;
|
|
72
|
+
|
|
73
|
+
export class ReqlanCodeActionProvider implements CodeActionProvider {
|
|
74
|
+
private readonly documents: ReqlanServices['shared']['workspace']['LangiumDocuments'];
|
|
75
|
+
private readonly indexManager: ReqlanServices['shared']['workspace']['IndexManager'];
|
|
76
|
+
|
|
77
|
+
constructor(services: ReqlanServices) {
|
|
78
|
+
this.documents = services.shared.workspace.LangiumDocuments;
|
|
79
|
+
this.indexManager = services.shared.workspace.IndexManager;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getCodeActions(document: LangiumDocument, params: CodeActionParams): Array<Command | CodeActionLike> {
|
|
83
|
+
const actions: Array<Command | CodeActionLike> = [];
|
|
84
|
+
for (const diagnostic of params.context.diagnostics) {
|
|
85
|
+
actions.push(...this.actionsForDiagnostic(document, diagnostic));
|
|
86
|
+
}
|
|
87
|
+
const searchFromCursor = this.createSearchReferenceAction(document, params);
|
|
88
|
+
if (searchFromCursor) {
|
|
89
|
+
actions.push(searchFromCursor);
|
|
90
|
+
}
|
|
91
|
+
return actions;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* When the cursor/selection is inside a [reference], or on prose that can
|
|
96
|
+
* become one, offer a search action that opens the idea-search webview.
|
|
97
|
+
*/
|
|
98
|
+
private createSearchReferenceAction(
|
|
99
|
+
document: LangiumDocument,
|
|
100
|
+
params: CodeActionParams
|
|
101
|
+
): CodeActionLike | undefined {
|
|
102
|
+
const site = findReferenceSearchSite(document, params.range);
|
|
103
|
+
if (!site) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
// Avoid duplicating the linking-error search action on the same range.
|
|
107
|
+
const alreadyHasSearch = site.mode === 'replace' && params.context.diagnostics.some(diagnostic => {
|
|
108
|
+
const data = diagnostic.data as LinkingDiagnosticData | undefined;
|
|
109
|
+
return data?.code === DocumentValidator.LinkingError
|
|
110
|
+
&& data.refText === site.refText
|
|
111
|
+
&& rangesOverlap(diagnostic.range, site.range);
|
|
112
|
+
});
|
|
113
|
+
if (alreadyHasSearch) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
const args: SearchReferenceCommandArgs = {
|
|
117
|
+
documentUri: document.textDocument.uri,
|
|
118
|
+
refText: site.refText,
|
|
119
|
+
range: site.range,
|
|
120
|
+
mode: site.mode,
|
|
121
|
+
context: site.context
|
|
122
|
+
};
|
|
123
|
+
const title = site.mode === 'wrap'
|
|
124
|
+
? (site.refText
|
|
125
|
+
? `Wrap '${site.refText}' as idea reference…`
|
|
126
|
+
: 'Wrap selection as idea reference…')
|
|
127
|
+
: (site.refText
|
|
128
|
+
? `Search for idea to replace '${site.refText}'…`
|
|
129
|
+
: 'Search for idea reference…');
|
|
130
|
+
return {
|
|
131
|
+
title,
|
|
132
|
+
kind: CodeActionKind.Refactor,
|
|
133
|
+
command: {
|
|
134
|
+
title: 'Search for idea reference',
|
|
135
|
+
command: REQLAN_SEARCH_REFERENCE_COMMAND,
|
|
136
|
+
arguments: [args]
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private actionsForDiagnostic(
|
|
142
|
+
document: LangiumDocument,
|
|
143
|
+
diagnostic: Diagnostic
|
|
144
|
+
): Array<Command | CodeActionLike> {
|
|
145
|
+
const data = diagnostic.data as LinkingDiagnosticData | undefined;
|
|
146
|
+
if (data?.code !== DocumentValidator.LinkingError || !data.refText) {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
if (!isResolvableIdeaProperty(data.property)) {
|
|
150
|
+
return [];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const refText = data.refText;
|
|
154
|
+
const actions: Array<Command | CodeActionLike> = [];
|
|
155
|
+
const matches = this.findMatches(document, refText);
|
|
156
|
+
let preferredSet = false;
|
|
157
|
+
|
|
158
|
+
for (const match of matches.slice(0, MAX_IMPORT_SUGGESTIONS)) {
|
|
159
|
+
if (match.kind === 'ideaset' || match.kind === 'file') {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const addImport = this.createAddImportAction(document, diagnostic, match, !preferredSet);
|
|
163
|
+
if (addImport) {
|
|
164
|
+
actions.push(addImport);
|
|
165
|
+
preferredSet = true;
|
|
166
|
+
}
|
|
167
|
+
const rewrite = this.createQualifiedRewriteAction(document, diagnostic, match);
|
|
168
|
+
if (rewrite) {
|
|
169
|
+
actions.push(rewrite);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
actions.push(this.createSearchCommand(document, diagnostic, refText));
|
|
174
|
+
actions.push(this.createCreateFileCommand(document, diagnostic, refText));
|
|
175
|
+
return actions;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private findMatches(document: LangiumDocument, refText: string): SymbolMatch[] {
|
|
179
|
+
const byKey = new Map<string, SymbolMatch>();
|
|
180
|
+
const add = (match: SymbolMatch) => {
|
|
181
|
+
if (UriUtils.equals(UriCtor.parse(match.fileUri), document.uri)) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const key = `${match.kind}:${match.fileUri}:${match.name}`;
|
|
185
|
+
if (!byKey.has(key)) {
|
|
186
|
+
byKey.set(key, match);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
for (const entry of sharedNameCatalog.findExact(refText)) {
|
|
191
|
+
add(this.toMatch(document.uri, entry));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for (const doc of this.documents.all) {
|
|
195
|
+
if (UriUtils.equals(doc.uri, document.uri)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const model = doc.parseResult.value;
|
|
199
|
+
if (!isModel(model)) {
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
for (const element of model.elements) {
|
|
203
|
+
if ((isIdea(element) || isOneLinerIdea(element) || isIdeaSet(element)) && element.name === refText) {
|
|
204
|
+
add({
|
|
205
|
+
name: element.name,
|
|
206
|
+
kind: isIdeaSet(element) ? 'ideaset' : isOneLinerIdea(element) ? 'oneliner' : 'idea',
|
|
207
|
+
fileUri: doc.uri.toString(),
|
|
208
|
+
importPath: relativeRqImportPath(document.uri, doc.uri)
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
for (const description of this.indexManager.allElements()) {
|
|
215
|
+
if (description.name !== refText || UriUtils.equals(description.documentUri, document.uri)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const kind = nodeTypeToKind(description.type);
|
|
219
|
+
if (!kind) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
add({
|
|
223
|
+
name: description.name,
|
|
224
|
+
kind,
|
|
225
|
+
fileUri: description.documentUri.toString(),
|
|
226
|
+
importPath: relativeRqImportPath(document.uri, description.documentUri)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return [...byKey.values()].sort((left, right) =>
|
|
231
|
+
left.importPath.length - right.importPath.length || left.name.localeCompare(right.name)
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private toMatch(fromUri: URI, entry: NameCatalogEntry): SymbolMatch {
|
|
236
|
+
return {
|
|
237
|
+
name: entry.name,
|
|
238
|
+
kind: entry.kind,
|
|
239
|
+
fileUri: entry.fileUri,
|
|
240
|
+
importPath: relativeRqImportPath(fromUri, UriCtor.parse(entry.fileUri))
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private createAddImportAction(
|
|
245
|
+
document: LangiumDocument,
|
|
246
|
+
diagnostic: Diagnostic,
|
|
247
|
+
match: SymbolMatch,
|
|
248
|
+
isPreferred: boolean
|
|
249
|
+
): CodeActionLike | undefined {
|
|
250
|
+
const edit = buildFromImportEdit(document, match.importPath, match.name);
|
|
251
|
+
if (!edit) {
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
title: `Add import from "${match.importPath}"`,
|
|
256
|
+
kind: CodeActionKind.QuickFix,
|
|
257
|
+
diagnostics: [diagnostic],
|
|
258
|
+
isPreferred,
|
|
259
|
+
edit: {
|
|
260
|
+
changes: {
|
|
261
|
+
[document.textDocument.uri]: [edit]
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private createQualifiedRewriteAction(
|
|
268
|
+
document: LangiumDocument,
|
|
269
|
+
diagnostic: Diagnostic,
|
|
270
|
+
match: SymbolMatch
|
|
271
|
+
): CodeActionLike | undefined {
|
|
272
|
+
return {
|
|
273
|
+
title: `Change to ["${match.importPath}".${match.name}]`,
|
|
274
|
+
kind: CodeActionKind.QuickFix,
|
|
275
|
+
diagnostics: [diagnostic],
|
|
276
|
+
edit: {
|
|
277
|
+
changes: {
|
|
278
|
+
[document.textDocument.uri]: [{
|
|
279
|
+
range: diagnostic.range,
|
|
280
|
+
newText: `"${match.importPath}".${match.name}`
|
|
281
|
+
}]
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private createSearchCommand(
|
|
288
|
+
document: LangiumDocument,
|
|
289
|
+
diagnostic: Diagnostic,
|
|
290
|
+
refText: string
|
|
291
|
+
): CodeActionLike {
|
|
292
|
+
const args: SearchReferenceCommandArgs = {
|
|
293
|
+
documentUri: document.textDocument.uri,
|
|
294
|
+
refText,
|
|
295
|
+
range: diagnostic.range,
|
|
296
|
+
mode: 'replace',
|
|
297
|
+
context: buildContextForRange(document, diagnostic.range)
|
|
298
|
+
};
|
|
299
|
+
return {
|
|
300
|
+
title: `Search for idea to replace '${refText}'…`,
|
|
301
|
+
kind: CodeActionKind.QuickFix,
|
|
302
|
+
diagnostics: [diagnostic],
|
|
303
|
+
command: {
|
|
304
|
+
title: `Search for idea to replace '${refText}'`,
|
|
305
|
+
command: REQLAN_SEARCH_REFERENCE_COMMAND,
|
|
306
|
+
arguments: [args]
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private createCreateFileCommand(
|
|
312
|
+
document: LangiumDocument,
|
|
313
|
+
diagnostic: Diagnostic,
|
|
314
|
+
refText: string
|
|
315
|
+
): CodeActionLike {
|
|
316
|
+
const args: ImportErrorCommandArgs = {
|
|
317
|
+
documentUri: document.textDocument.uri,
|
|
318
|
+
refText,
|
|
319
|
+
range: diagnostic.range
|
|
320
|
+
};
|
|
321
|
+
return {
|
|
322
|
+
title: `Create '${refText}' in a new file and import it…`,
|
|
323
|
+
kind: CodeActionKind.QuickFix,
|
|
324
|
+
diagnostics: [diagnostic],
|
|
325
|
+
command: {
|
|
326
|
+
title: `Create '${refText}' in a new file`,
|
|
327
|
+
command: REQLAN_IMPORT_ERROR_CREATE_COMMAND,
|
|
328
|
+
arguments: [args]
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function isResolvableIdeaProperty(property: string | undefined): boolean {
|
|
335
|
+
return property === 'idea' || property === 'ideaset' || property === 'members';
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function rangesOverlap(
|
|
339
|
+
left: { start: { line: number; character: number }; end: { line: number; character: number } },
|
|
340
|
+
right: { start: { line: number; character: number }; end: { line: number; character: number } }
|
|
341
|
+
): boolean {
|
|
342
|
+
if (left.end.line < right.start.line || right.end.line < left.start.line) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
if (left.end.line === right.start.line && left.end.character < right.start.character) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
if (right.end.line === left.start.line && right.end.character < left.start.character) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function nodeTypeToKind(type: string): NameCatalogKind | undefined {
|
|
355
|
+
switch (type) {
|
|
356
|
+
case 'Idea':
|
|
357
|
+
return 'idea';
|
|
358
|
+
case 'OneLinerIdea':
|
|
359
|
+
return 'oneliner';
|
|
360
|
+
case 'IdeaSet':
|
|
361
|
+
return 'ideaset';
|
|
362
|
+
default:
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Test helper: collect quick fixes for linking diagnostics on a document. */
|
|
368
|
+
export function collectImportErrorCodeActions(
|
|
369
|
+
provider: ReqlanCodeActionProvider,
|
|
370
|
+
document: LangiumDocument
|
|
371
|
+
): Array<Command | CodeActionLike> {
|
|
372
|
+
const diagnostics = (document.diagnostics ?? []).filter(diagnostic => {
|
|
373
|
+
const data = diagnostic.data as LinkingDiagnosticData | undefined;
|
|
374
|
+
return data?.code === DocumentValidator.LinkingError;
|
|
375
|
+
});
|
|
376
|
+
return provider.getCodeActions(document, {
|
|
377
|
+
textDocument: { uri: document.textDocument.uri },
|
|
378
|
+
range: diagnostics[0]?.range ?? { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },
|
|
379
|
+
context: { diagnostics }
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export function isModelDocument(document: LangiumDocument): document is LangiumDocument<Model> {
|
|
384
|
+
return isModel(document.parseResult.value);
|
|
385
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeLens buttons classifying references (idea, reqlan/other file, folder).
|
|
3
|
+
*/
|
|
4
|
+
import type { LangiumDocument } from 'langium';
|
|
5
|
+
import { AstUtils } from 'langium';
|
|
6
|
+
import type { CodeLensProvider } from 'langium/lsp';
|
|
7
|
+
import type { CancellationToken } from 'vscode-languageserver';
|
|
8
|
+
import type { CodeLens, CodeLensParams } from 'vscode-languageserver';
|
|
9
|
+
import {
|
|
10
|
+
REQLAN_REFERENCE_CODE_LENS_SETTING,
|
|
11
|
+
referenceCodeLensEnabled,
|
|
12
|
+
type ReferenceCodeLensSettings
|
|
13
|
+
} from './reqlan-code-lens-settings.js';
|
|
14
|
+
import {
|
|
15
|
+
buildReferenceCodeLens,
|
|
16
|
+
classifyReferenceForCodeLens
|
|
17
|
+
} from './reqlan-reference-code-lens.js';
|
|
18
|
+
import type { ReqlanServices } from './reqlan-module.js';
|
|
19
|
+
|
|
20
|
+
export class ReqlanCodeLensProvider implements CodeLensProvider {
|
|
21
|
+
|
|
22
|
+
private readonly services: ReqlanServices;
|
|
23
|
+
|
|
24
|
+
constructor(services: ReqlanServices) {
|
|
25
|
+
this.services = services;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async provideCodeLens(
|
|
29
|
+
document: LangiumDocument,
|
|
30
|
+
_params: CodeLensParams,
|
|
31
|
+
_cancelToken?: CancellationToken
|
|
32
|
+
): Promise<CodeLens[] | undefined> {
|
|
33
|
+
const settings = await this.services.shared.workspace.ConfigurationProvider.getConfiguration(
|
|
34
|
+
'reqlan',
|
|
35
|
+
REQLAN_REFERENCE_CODE_LENS_SETTING
|
|
36
|
+
) as ReferenceCodeLensSettings | undefined;
|
|
37
|
+
if (!referenceCodeLensEnabled(settings)) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const lenses: CodeLens[] = [];
|
|
42
|
+
for (const node of AstUtils.streamAst(document.parseResult.value)) {
|
|
43
|
+
const classification = classifyReferenceForCodeLens(this.services, node);
|
|
44
|
+
if (!classification) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const lens = buildReferenceCodeLens(this.services, node, classification);
|
|
48
|
+
if (lens) {
|
|
49
|
+
lenses.push(lens);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return lenses;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace settings for reference CodeLens classification buttons.
|
|
3
|
+
*/
|
|
4
|
+
export const REQLAN_REFERENCE_CODE_LENS_SETTING = 'referencesCodeLens';
|
|
5
|
+
|
|
6
|
+
/** VS Code command invoked when clicking a reference classification CodeLens. */
|
|
7
|
+
export const REQLAN_OPEN_REFERENCE_CODE_LENS_COMMAND = 'reqlan.openReferenceCodeLens';
|
|
8
|
+
|
|
9
|
+
/** VS Code command palette toggle for reference CodeLens. */
|
|
10
|
+
export const REQLAN_TOGGLE_REFERENCE_CODE_LENS_COMMAND = 'reqlan.toggleReferenceCodeLens';
|
|
11
|
+
|
|
12
|
+
export interface ReferenceCodeLensSettings {
|
|
13
|
+
enabled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function referenceCodeLensEnabled(settings: ReferenceCodeLensSettings | undefined): boolean {
|
|
17
|
+
return settings?.enabled === true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type ReferenceCodeLensKind = 'idea' | 'reqlan-file' | 'file' | 'folder';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Payload for the CodeLens click handler. Opens a reference card (not direct navigation —
|
|
24
|
+
* references already act as editor links).
|
|
25
|
+
*/
|
|
26
|
+
export interface ReferenceCodeLensPayload {
|
|
27
|
+
kind: ReferenceCodeLensKind;
|
|
28
|
+
/** Classification label, e.g. `open idea` / `open ts file`. */
|
|
29
|
+
classification: string;
|
|
30
|
+
/** Short target name shown on the card. */
|
|
31
|
+
displayName: string;
|
|
32
|
+
targetUri: string;
|
|
33
|
+
line?: number;
|
|
34
|
+
character?: number;
|
|
35
|
+
folderFiles?: string[];
|
|
36
|
+
/** File extension without leading dot, used for `open {extension} file` labels. */
|
|
37
|
+
extension?: string;
|
|
38
|
+
/** Idea body / path summary for the card. */
|
|
39
|
+
summary?: string;
|
|
40
|
+
/** Stats lines shown on the card (referencers, last edited, etc.). */
|
|
41
|
+
stats: string[];
|
|
42
|
+
}
|