@likec4/language-server 0.6.2 → 0.6.3

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.
Files changed (63) hide show
  1. package/contrib/likec4.monarch.ts +31 -0
  2. package/contrib/likec4.tmLanguage.json +73 -0
  3. package/dist/ast.d.ts +73 -0
  4. package/dist/ast.js +133 -0
  5. package/dist/builtin.d.ts +4 -0
  6. package/dist/builtin.js +8 -0
  7. package/dist/elementRef.d.ts +6 -0
  8. package/dist/elementRef.js +39 -0
  9. package/dist/generated/ast.d.ts +359 -0
  10. package/dist/generated/ast.js +376 -0
  11. package/dist/generated/grammar.d.ts +6 -0
  12. package/dist/generated/grammar.js +2542 -0
  13. package/dist/generated/module.d.ts +9 -0
  14. package/dist/generated/module.js +26 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +1 -0
  17. package/dist/logger.d.ts +8 -0
  18. package/dist/logger.js +20 -0
  19. package/dist/lsp/DocumentSymbolProvider.d.ts +21 -0
  20. package/dist/lsp/DocumentSymbolProvider.js +149 -0
  21. package/dist/lsp/HoverProvider.d.ts +8 -0
  22. package/dist/lsp/HoverProvider.js +54 -0
  23. package/dist/lsp/SemanticTokenProvider.d.ts +6 -0
  24. package/dist/lsp/SemanticTokenProvider.js +221 -0
  25. package/dist/lsp/index.d.ts +3 -0
  26. package/dist/lsp/index.js +3 -0
  27. package/dist/model/fqn-index.d.ts +17 -0
  28. package/dist/model/fqn-index.js +138 -0
  29. package/dist/model/index.d.ts +3 -0
  30. package/dist/model/index.js +3 -0
  31. package/dist/model/model-builder.d.ts +26 -0
  32. package/dist/model/model-builder.js +332 -0
  33. package/dist/model/model-locator.d.ts +16 -0
  34. package/dist/model/model-locator.js +108 -0
  35. package/dist/module.d.ts +20 -0
  36. package/dist/module.js +65 -0
  37. package/dist/references/index.d.ts +2 -0
  38. package/dist/references/index.js +2 -0
  39. package/dist/references/scope-computation.d.ts +10 -0
  40. package/dist/references/scope-computation.js +76 -0
  41. package/dist/references/scope-provider.d.ts +15 -0
  42. package/dist/references/scope-provider.js +110 -0
  43. package/dist/registerProtocolHandlers.d.ts +2 -0
  44. package/dist/registerProtocolHandlers.js +64 -0
  45. package/dist/shared/CodeLensProvider.d.ts +8 -0
  46. package/dist/shared/CodeLensProvider.js +35 -0
  47. package/dist/shared/WorkspaceManager.d.ts +13 -0
  48. package/dist/shared/WorkspaceManager.js +19 -0
  49. package/dist/shared/index.d.ts +2 -0
  50. package/dist/shared/index.js +2 -0
  51. package/dist/utils.d.ts +2 -0
  52. package/dist/utils.js +7 -0
  53. package/dist/validation/element.d.ts +5 -0
  54. package/dist/validation/element.js +20 -0
  55. package/dist/validation/index.d.ts +2 -0
  56. package/dist/validation/index.js +22 -0
  57. package/dist/validation/relation.d.ts +4 -0
  58. package/dist/validation/relation.js +53 -0
  59. package/dist/validation/specification.d.ts +5 -0
  60. package/dist/validation/specification.js +33 -0
  61. package/dist/validation/view.d.ts +4 -0
  62. package/dist/validation/view.js +20 -0
  63. package/package.json +3 -3
@@ -0,0 +1,9 @@
1
+ /******************************************************************************
2
+ * This file was generated by langium-cli 1.1.0.
3
+ * DO NOT EDIT MANUALLY!
4
+ ******************************************************************************/
5
+ import { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumSharedServices, LangiumServices, LanguageMetaData, Module, IParserConfig } from 'langium';
6
+ export declare const LikeC4LanguageMetaData: LanguageMetaData;
7
+ export declare const parserConfig: IParserConfig;
8
+ export declare const LikeC4GeneratedSharedModule: Module<LangiumSharedServices, LangiumGeneratedSharedServices>;
9
+ export declare const LikeC4GeneratedModule: Module<LangiumServices, LangiumGeneratedServices>;
@@ -0,0 +1,26 @@
1
+ /******************************************************************************
2
+ * This file was generated by langium-cli 1.1.0.
3
+ * DO NOT EDIT MANUALLY!
4
+ ******************************************************************************/
5
+ import 'langium';
6
+ import { LikeC4AstReflection } from './ast';
7
+ import { LikeC4Grammar } from './grammar';
8
+ export const LikeC4LanguageMetaData = {
9
+ languageId: 'likec4',
10
+ fileExtensions: ['.c4', '.likec4', '.like-c4'],
11
+ caseInsensitive: false
12
+ };
13
+ export const parserConfig = {
14
+ recoveryEnabled: true,
15
+ nodeLocationTracking: 'full',
16
+ };
17
+ export const LikeC4GeneratedSharedModule = {
18
+ AstReflection: () => new LikeC4AstReflection()
19
+ };
20
+ export const LikeC4GeneratedModule = {
21
+ Grammar: () => LikeC4Grammar(),
22
+ LanguageMetaData: () => LikeC4LanguageMetaData,
23
+ parser: {
24
+ ParserConfig: () => parserConfig
25
+ }
26
+ };
@@ -0,0 +1,2 @@
1
+ export { createLanguageServices } from './module';
2
+ export type { LikeC4Services } from './module';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createLanguageServices } from './module';
@@ -0,0 +1,8 @@
1
+ export declare const logger: {
2
+ debug(message: string): void;
3
+ info(message: string): void;
4
+ warn(message: string | Error | unknown): void;
5
+ log(message: string): void;
6
+ error(message: string | Error | unknown): void;
7
+ trace(message: string): void;
8
+ };
package/dist/logger.js ADDED
@@ -0,0 +1,20 @@
1
+ export const logger = {
2
+ debug(message) {
3
+ console.debug(message);
4
+ },
5
+ info(message) {
6
+ console.info(message);
7
+ },
8
+ warn(message) {
9
+ console.warn(message);
10
+ },
11
+ log(message) {
12
+ console.log(message);
13
+ },
14
+ error(message) {
15
+ console.error(message);
16
+ },
17
+ trace(message) {
18
+ console.debug(message);
19
+ }
20
+ };
@@ -0,0 +1,21 @@
1
+ /******************************************************************************
2
+ * Copyright 2021 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ /// <reference types="react" />
7
+ import { type DocumentSymbolProvider, type MaybePromise } from 'langium';
8
+ import { type DocumentSymbol } from 'vscode-languageserver-protocol';
9
+ import { type LikeC4LangiumDocument, ast } from '../ast';
10
+ import type { LikeC4Services } from '../module';
11
+ export declare class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
12
+ private services;
13
+ constructor(services: LikeC4Services);
14
+ getSymbols(document: LikeC4LangiumDocument): MaybePromise<DocumentSymbol[]>;
15
+ protected getSpecSymbols: (astSpec: ast.SpecificationRule | undefined) => DocumentSymbol[];
16
+ protected getModelSymbols: (astModel: ast.Model | undefined) => DocumentSymbol[];
17
+ protected getElementsSymbol: (el: ast.Element | ast.Relation | ast.ExtendElement) => DocumentSymbol[];
18
+ protected getExtendElementSymbol: (astElement: ast.ExtendElement) => DocumentSymbol[];
19
+ protected getElementSymbol: (astElement: ast.Element) => DocumentSymbol[];
20
+ protected getModelViewsSymbols: (astViews: ast.ModelViews | undefined) => DocumentSymbol[];
21
+ }
@@ -0,0 +1,149 @@
1
+ /******************************************************************************
2
+ * Copyright 2021 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ import invariant from 'tiny-invariant';
7
+ import { findNodeForProperty } from 'langium';
8
+ import { SymbolKind } from 'vscode-languageserver-protocol';
9
+ import { ast } from '../ast';
10
+ export class LikeC4DocumentSymbolProvider {
11
+ services;
12
+ constructor(services) {
13
+ this.services = services;
14
+ }
15
+ getSymbols(document) {
16
+ const { specification, model, views } = document.parseResult.value;
17
+ return [
18
+ ...this.getSpecSymbols(specification),
19
+ ...this.getModelSymbols(model),
20
+ ...this.getModelViewsSymbols(views)
21
+ ];
22
+ }
23
+ getSpecSymbols = (astSpec) => {
24
+ const cstModel = astSpec?.$cstNode;
25
+ if (!cstModel)
26
+ return [];
27
+ const specKeywordNode = findNodeForProperty(cstModel, 'name');
28
+ if (!specKeywordNode)
29
+ return [];
30
+ const specSymbols = [];
31
+ const getElementKindSymbol = (astKind) => {
32
+ invariant(astKind.$cstNode, 'SpecificationElementKind must have a CST node');
33
+ invariant(astKind.kind.$cstNode, 'SpecificationElementKind name must have a CST node');
34
+ return {
35
+ kind: SymbolKind.Class,
36
+ name: astKind.kind.name,
37
+ range: astKind.$cstNode.range,
38
+ selectionRange: astKind.kind.$cstNode.range
39
+ };
40
+ };
41
+ for (const astKind of astSpec.elementKinds) {
42
+ specSymbols.push(getElementKindSymbol(astKind));
43
+ }
44
+ const getTagSymbol = (astTag) => {
45
+ invariant(astTag.$cstNode, 'TagSpec must have a CST node');
46
+ invariant(astTag.tag.$cstNode, 'Tag name must have a CST node');
47
+ return {
48
+ kind: SymbolKind.EnumMember,
49
+ name: '#' + astTag.tag.name,
50
+ range: astTag.$cstNode.range,
51
+ selectionRange: astTag.tag.$cstNode.range
52
+ };
53
+ };
54
+ for (const astTag of astSpec.tags) {
55
+ specSymbols.push(getTagSymbol(astTag));
56
+ }
57
+ if (specSymbols.length === 0)
58
+ return [];
59
+ return [
60
+ {
61
+ kind: SymbolKind.Class,
62
+ name: astSpec.name,
63
+ range: cstModel.range,
64
+ selectionRange: specKeywordNode.range,
65
+ children: specSymbols
66
+ }
67
+ ];
68
+ };
69
+ getModelSymbols = (astModel) => {
70
+ const cstModel = astModel?.$cstNode;
71
+ if (!cstModel)
72
+ return [];
73
+ const nameNode = findNodeForProperty(cstModel, 'name');
74
+ if (!nameNode)
75
+ return [];
76
+ return [
77
+ {
78
+ kind: SymbolKind.Class,
79
+ name: astModel.name,
80
+ range: cstModel.range,
81
+ selectionRange: nameNode.range,
82
+ children: astModel.elements.flatMap(this.getElementsSymbol)
83
+ }
84
+ ];
85
+ };
86
+ getElementsSymbol = (el) => {
87
+ if (ast.isExtendElement(el)) {
88
+ return this.getExtendElementSymbol(el);
89
+ }
90
+ if (ast.isElement(el)) {
91
+ return this.getElementSymbol(el);
92
+ }
93
+ return [];
94
+ };
95
+ getExtendElementSymbol = (astElement) => {
96
+ const cst = astElement.$cstNode;
97
+ const nameNode = astElement.element.$cstNode;
98
+ if (!cst || !nameNode)
99
+ return [];
100
+ return [
101
+ {
102
+ kind: SymbolKind.Constructor,
103
+ name: nameNode.text,
104
+ range: cst.range,
105
+ selectionRange: nameNode.range,
106
+ children: astElement.body.elements.flatMap(this.getElementsSymbol)
107
+ }
108
+ ];
109
+ };
110
+ getElementSymbol = (astElement) => {
111
+ const cst = astElement.$cstNode;
112
+ if (!cst)
113
+ return [];
114
+ const nameNode = findNodeForProperty(cst, 'name');
115
+ if (!nameNode)
116
+ return [];
117
+ const name = astElement.name;
118
+ const kind = astElement.kind.$refText;
119
+ // TODO: return the title as well
120
+ const detail = kind; // + (astElement.title ? ': ' + astElement.title : '').replaceAll('\n', ' ').trim()
121
+ return [
122
+ {
123
+ kind: SymbolKind.Constructor,
124
+ name: name,
125
+ range: cst.range,
126
+ selectionRange: nameNode.range,
127
+ detail,
128
+ children: astElement.body?.elements.flatMap(this.getElementsSymbol) ?? []
129
+ }
130
+ ];
131
+ };
132
+ getModelViewsSymbols = (astViews) => {
133
+ const cst = astViews?.$cstNode;
134
+ if (!cst)
135
+ return [];
136
+ const nameNode = findNodeForProperty(cst, 'name');
137
+ if (!nameNode)
138
+ return [];
139
+ return [
140
+ {
141
+ kind: SymbolKind.Class,
142
+ name: astViews.name,
143
+ range: cst.range,
144
+ selectionRange: nameNode.range,
145
+ children: []
146
+ }
147
+ ];
148
+ };
149
+ }
@@ -0,0 +1,8 @@
1
+ import { type AstNode, AstNodeHoverProvider, type MaybePromise } from 'langium';
2
+ import type { Hover } from 'vscode-languageserver-protocol';
3
+ import type { LikeC4Services } from '../module';
4
+ export declare class LikeC4HoverProvider extends AstNodeHoverProvider {
5
+ private locator;
6
+ constructor(services: LikeC4Services);
7
+ protected getAstNodeHoverContent(node: AstNode): MaybePromise<Hover | undefined>;
8
+ }
@@ -0,0 +1,54 @@
1
+ import { AstNodeHoverProvider } from 'langium';
2
+ import stripIndent from 'strip-indent';
3
+ import { ast } from '../ast';
4
+ export class LikeC4HoverProvider extends AstNodeHoverProvider {
5
+ locator;
6
+ constructor(services) {
7
+ super(services);
8
+ this.locator = services.likec4.ModelLocator;
9
+ }
10
+ getAstNodeHoverContent(node) {
11
+ if (ast.isTag(node)) {
12
+ return {
13
+ contents: {
14
+ kind: 'markdown',
15
+ value: stripIndent(`
16
+ tag: \`${node.name}\`
17
+ `)
18
+ }
19
+ };
20
+ }
21
+ // if (ast.isElementKind(node)) {
22
+ // const spec = this.specIndex.get(node.name as ElementKind)
23
+ // return {
24
+ // contents: {
25
+ // kind: 'markdown',
26
+ // value: stripIndent(`
27
+ // kind: **${spec.id}**
28
+ // shape: ${spec.style.shape}
29
+ // `)
30
+ // }
31
+ // }
32
+ // }
33
+ if (ast.isElement(node)) {
34
+ const el = this.locator.getParsedElement(node);
35
+ if (!el) {
36
+ return;
37
+ }
38
+ const lines = [el.id, `${el.kind}: **${el.title}**`];
39
+ if (el.tags && el.tags.length > 0) {
40
+ lines.push(' \n', el.tags.map(t => '#' + t).join(', '));
41
+ }
42
+ if (el.description) {
43
+ lines.push(' \n', el.description);
44
+ }
45
+ return {
46
+ contents: {
47
+ kind: 'markdown',
48
+ value: lines.join(' \n')
49
+ }
50
+ };
51
+ }
52
+ return;
53
+ }
54
+ }
@@ -0,0 +1,6 @@
1
+ import { AbstractSemanticTokenProvider, type AstNode, type SemanticTokenAcceptor } from 'langium';
2
+ export declare class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
3
+ protected highlightElement(node: AstNode, acceptor: SemanticTokenAcceptor): void;
4
+ private highlightAstElement;
5
+ private highlightView;
6
+ }
@@ -0,0 +1,221 @@
1
+ import { AbstractSemanticTokenProvider } from 'langium';
2
+ import { SemanticTokenModifiers, SemanticTokenTypes } from 'vscode-languageserver-protocol';
3
+ import { ast } from '../ast';
4
+ import { isElementRefHead } from '../elementRef';
5
+ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
6
+ highlightElement(node, acceptor) {
7
+ const keyword = (keyword, _index) => acceptor({
8
+ node,
9
+ keyword,
10
+ type: SemanticTokenTypes.keyword
11
+ });
12
+ if (ast.isElementRef(node) || ast.isStrictElementRef(node)) {
13
+ acceptor({
14
+ node,
15
+ property: 'el',
16
+ type: isElementRefHead(node) ? SemanticTokenTypes.variable : SemanticTokenTypes.property
17
+ });
18
+ return;
19
+ }
20
+ if (ast.isWildcardExpression(node)) {
21
+ acceptor({
22
+ node,
23
+ property: 'isWildcard',
24
+ type: SemanticTokenTypes.variable
25
+ });
26
+ return;
27
+ }
28
+ if (ast.isRelationExpression(node) ||
29
+ ast.isIncomingExpression(node) ||
30
+ ast.isOutgoingExpression(node)) {
31
+ keyword('->');
32
+ return;
33
+ }
34
+ if (ast.isInOutExpression(node)) {
35
+ keyword('->', 0);
36
+ keyword('->', 1);
37
+ return;
38
+ }
39
+ if (ast.isRelation(node)) {
40
+ keyword('->');
41
+ if ('title' in node) {
42
+ acceptor({
43
+ node,
44
+ property: 'title',
45
+ type: SemanticTokenTypes.string
46
+ });
47
+ }
48
+ return;
49
+ }
50
+ if (ast.isElementKind(node)) {
51
+ acceptor({
52
+ node,
53
+ property: 'name',
54
+ type: SemanticTokenTypes.type,
55
+ modifier: [SemanticTokenModifiers.definition]
56
+ });
57
+ return;
58
+ }
59
+ // if (ast.isElementKindSpec(node)) {
60
+ // keyword('element')
61
+ // // keyword('nested')
62
+ // // if (node.nested.length > 0) {
63
+ // // acceptor({
64
+ // // node,
65
+ // // property: 'nested',
66
+ // // type: SemanticTokenTypes.type,
67
+ // // })
68
+ // // }
69
+ // // acceptor({
70
+ // // node,
71
+ // // property: 'kind',
72
+ // // type: SemanticTokenTypes.type,
73
+ // // })
74
+ // return
75
+ // }
76
+ // if (ast.isTagSpec(node)) {
77
+ // keyword('tag')
78
+ // acceptor({
79
+ // node,
80
+ // property: 'tag',
81
+ // type: SemanticTokenTypes.enumMember
82
+ // })
83
+ // return
84
+ // }
85
+ if (ast.isTags(node)) {
86
+ acceptor({
87
+ node,
88
+ property: 'value',
89
+ type: SemanticTokenTypes.macro
90
+ });
91
+ return;
92
+ }
93
+ if (ast.isTag(node)) {
94
+ acceptor({
95
+ node,
96
+ property: 'name',
97
+ type: SemanticTokenTypes.macro
98
+ });
99
+ return;
100
+ }
101
+ if (ast.isAStyleProperty(node)) {
102
+ acceptor({
103
+ node,
104
+ property: 'key',
105
+ type: SemanticTokenTypes.keyword
106
+ });
107
+ acceptor({
108
+ node,
109
+ property: 'value',
110
+ type: SemanticTokenTypes.enumMember
111
+ });
112
+ return;
113
+ }
114
+ if (ast.isAnyStringProperty(node)) {
115
+ acceptor({
116
+ node,
117
+ property: 'key',
118
+ type: SemanticTokenTypes.keyword
119
+ });
120
+ acceptor({
121
+ node,
122
+ property: 'value',
123
+ type: SemanticTokenTypes.string
124
+ });
125
+ return;
126
+ }
127
+ // if (ast.isModel(node)) {
128
+ // keyword('model')
129
+ // return
130
+ // }
131
+ // if (ast.isModelViews(node)) {
132
+ // keyword('views')
133
+ // return
134
+ // }
135
+ if (ast.isElement(node)) {
136
+ return this.highlightAstElement(node, acceptor);
137
+ }
138
+ // if (ast.isExtendElement(node)) {
139
+ // keyword('extend')
140
+ // return
141
+ // }
142
+ // if (ast.isElementProperty(node) || ast.isRelationProperty(node) || ast.isViewProperty(node)) {
143
+ // acceptor({
144
+ // node,
145
+ // property: 'key',
146
+ // type: SemanticTokenTypes.property,
147
+ // modifier: [SemanticTokenModifiers.definition]
148
+ // })
149
+ // if ('value' in node) {
150
+ // acceptor({
151
+ // node,
152
+ // property: 'value',
153
+ // type: SemanticTokenTypes.string
154
+ // })
155
+ // }
156
+ // return
157
+ // }
158
+ if (ast.isView(node)) {
159
+ return this.highlightView(node, acceptor);
160
+ }
161
+ // if (ast.isDynamicViewSteps(node)) {
162
+ // keyword('steps')
163
+ // return
164
+ // }
165
+ // if (ast.isViewRuleAutoLayout(node)) {
166
+ // keyword('autoLayout')
167
+ // return
168
+ // }
169
+ // if (ast.isViewRuleStyle(node)) {
170
+ // keyword('style')
171
+ // return
172
+ // }
173
+ // if (ast.isViewRuleExpression(node)) {
174
+ // keyword(node.isInclude ? 'include' : 'exclude')
175
+ // return
176
+ // }
177
+ // //
178
+ }
179
+ highlightAstElement(node, acceptor) {
180
+ acceptor({
181
+ node,
182
+ property: 'name',
183
+ type: SemanticTokenTypes.variable,
184
+ modifier: [SemanticTokenModifiers.declaration]
185
+ });
186
+ acceptor({
187
+ node,
188
+ property: 'kind',
189
+ type: SemanticTokenTypes.keyword,
190
+ modifier: []
191
+ });
192
+ if ('title' in node) {
193
+ acceptor({
194
+ node,
195
+ property: 'title',
196
+ type: SemanticTokenTypes.string
197
+ });
198
+ }
199
+ }
200
+ highlightView(node, acceptor) {
201
+ if (node.name) {
202
+ acceptor({
203
+ node,
204
+ property: 'name',
205
+ type: SemanticTokenTypes.variable
206
+ });
207
+ }
208
+ if (node.viewOf) {
209
+ acceptor({
210
+ node,
211
+ keyword: 'of',
212
+ type: SemanticTokenTypes.keyword
213
+ });
214
+ }
215
+ acceptor({
216
+ node,
217
+ keyword: 'view',
218
+ type: SemanticTokenTypes.keyword
219
+ });
220
+ }
221
+ }
@@ -0,0 +1,3 @@
1
+ export * from './DocumentSymbolProvider';
2
+ export * from './HoverProvider';
3
+ export * from './SemanticTokenProvider';
@@ -0,0 +1,3 @@
1
+ export * from './DocumentSymbolProvider';
2
+ export * from './HoverProvider';
3
+ export * from './SemanticTokenProvider';
@@ -0,0 +1,17 @@
1
+ import { StreamImpl } from 'langium';
2
+ import type { AstNodeDescription, AstNodeDescriptionProvider } from 'langium';
3
+ import { ast } from '../ast';
4
+ import type { LikeC4Services } from '../module';
5
+ import { Fqn } from '@likec4/core/types';
6
+ export declare class FqnIndex {
7
+ #private;
8
+ private services;
9
+ protected readonly descriptions: AstNodeDescriptionProvider;
10
+ constructor(services: LikeC4Services);
11
+ get(el: ast.Element): Fqn | null;
12
+ byFqn(fqn: Fqn): readonly AstNodeDescription[];
13
+ directChildrenOf(parent: Fqn): import("langium").Stream<AstNodeDescription>;
14
+ uniqueDescedants(parent: Fqn): StreamImpl<IterableIterator<AstNodeDescription> | null, AstNodeDescription>;
15
+ private doIndexElements;
16
+ private cleanIndexedElements;
17
+ }