@likec4/language-server 1.23.1 → 1.24.1

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 (73) hide show
  1. package/dist/LikeC4FileSystem.d.ts +1 -0
  2. package/dist/LikeC4FileSystem.js +7 -0
  3. package/dist/Rpc.js +13 -11
  4. package/dist/ast.d.ts +13 -29
  5. package/dist/ast.js +3 -70
  6. package/dist/bundled.mjs +2441 -2610
  7. package/dist/generated/ast.d.ts +36 -8
  8. package/dist/generated/ast.js +44 -2
  9. package/dist/generated/grammar.js +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.js +1 -0
  12. package/dist/likec4lib.d.ts +2 -0
  13. package/dist/likec4lib.js +3 -0
  14. package/dist/lsp/CodeLensProvider.js +10 -6
  15. package/dist/lsp/CompletionProvider.js +20 -2
  16. package/dist/lsp/DocumentLinkProvider.d.ts +3 -3
  17. package/dist/lsp/DocumentLinkProvider.js +5 -5
  18. package/dist/lsp/DocumentSymbolProvider.d.ts +1 -1
  19. package/dist/lsp/DocumentSymbolProvider.js +5 -2
  20. package/dist/lsp/HoverProvider.js +20 -7
  21. package/dist/lsp/SemanticTokenProvider.js +18 -1
  22. package/dist/model/builder/MergedExtends.d.ts +12 -0
  23. package/dist/model/builder/MergedExtends.js +67 -0
  24. package/dist/model/builder/MergedSpecification.d.ts +29 -0
  25. package/dist/model/builder/MergedSpecification.js +203 -0
  26. package/dist/model/builder/buildModel.d.ts +3 -0
  27. package/dist/model/builder/buildModel.js +194 -0
  28. package/dist/model/deployments-index.d.ts +5 -56
  29. package/dist/model/deployments-index.js +61 -137
  30. package/dist/model/fqn-index.d.ts +50 -19
  31. package/dist/model/fqn-index.js +176 -69
  32. package/dist/model/index.d.ts +0 -1
  33. package/dist/model/index.js +0 -1
  34. package/dist/model/model-builder.d.ts +10 -9
  35. package/dist/model/model-builder.js +102 -547
  36. package/dist/model/model-locator.d.ts +2 -1
  37. package/dist/model/model-locator.js +7 -9
  38. package/dist/model/model-parser.d.ts +156 -150
  39. package/dist/model/model-parser.js +68 -38
  40. package/dist/model/parser/Base.d.ts +3 -3
  41. package/dist/model/parser/Base.js +15 -9
  42. package/dist/model/parser/DeploymentModelParser.d.ts +4 -3
  43. package/dist/model/parser/DeploymentModelParser.js +54 -3
  44. package/dist/model/parser/DeploymentViewParser.d.ts +3 -2
  45. package/dist/model/parser/FqnRefParser.d.ts +2 -2
  46. package/dist/model/parser/GlobalsParser.d.ts +3 -2
  47. package/dist/model/parser/ModelParser.d.ts +4 -4
  48. package/dist/model/parser/ModelParser.js +45 -4
  49. package/dist/model/parser/PredicatesParser.d.ts +2 -2
  50. package/dist/model/parser/SpecificationParser.d.ts +2 -2
  51. package/dist/model/parser/ViewsParser.d.ts +3 -2
  52. package/dist/module.d.ts +2 -3
  53. package/dist/module.js +2 -3
  54. package/dist/references/scope-computation.d.ts +1 -1
  55. package/dist/references/scope-computation.js +14 -11
  56. package/dist/references/scope-provider.d.ts +16 -4
  57. package/dist/references/scope-provider.js +64 -30
  58. package/dist/test/testServices.d.ts +2 -1
  59. package/dist/test/testServices.js +23 -20
  60. package/dist/utils/elementRef.d.ts +1 -1
  61. package/dist/utils/elementRef.js +3 -3
  62. package/dist/validation/deployment-checks.d.ts +1 -0
  63. package/dist/validation/deployment-checks.js +12 -0
  64. package/dist/validation/index.d.ts +1 -1
  65. package/dist/validation/index.js +8 -1
  66. package/dist/views/configurable-layouter.js +3 -3
  67. package/dist/views/likec4-views.d.ts +1 -0
  68. package/dist/views/likec4-views.js +11 -11
  69. package/package.json +12 -13
  70. package/dist/bundled.d.ts +0 -8
  71. package/dist/bundled.js +0 -25
  72. package/dist/model/fqn-computation.d.ts +0 -3
  73. package/dist/model/fqn-computation.js +0 -72
@@ -8,6 +8,7 @@ export declare const LikeC4FileSystem: {
8
8
  * @see https://github.com/likec4/likec4/pull/1213
9
9
  */
10
10
  declare class SymLinkTraversingFileSystemProvider extends NodeFileSystemProvider {
11
+ readFile(uri: URI): Promise<string>;
11
12
  readDirectory(folderPath: URI): Promise<FileSystemNode[]>;
12
13
  }
13
14
  export {};
@@ -2,12 +2,19 @@ import { fdir } from "fdir";
2
2
  import { URI } from "langium";
3
3
  import { NodeFileSystemProvider } from "langium/node";
4
4
  import { LikeC4LanguageMetaData } from "./generated/module.js";
5
+ import { Content, isLikeC4Builtin } from "./likec4lib.js";
5
6
  import { logError } from "./logger.js";
6
7
  export const LikeC4FileSystem = {
7
8
  fileSystemProvider: () => new SymLinkTraversingFileSystemProvider()
8
9
  };
9
10
  const hasExtension = (path) => LikeC4LanguageMetaData.fileExtensions.some((ext) => path.endsWith(ext));
10
11
  class SymLinkTraversingFileSystemProvider extends NodeFileSystemProvider {
12
+ async readFile(uri) {
13
+ if (isLikeC4Builtin(uri)) {
14
+ return Promise.resolve(Content);
15
+ }
16
+ return await super.readFile(uri);
17
+ }
11
18
  async readDirectory(folderPath) {
12
19
  const entries = [];
13
20
  try {
package/dist/Rpc.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { filter, funnel, map, pipe } from "remeda";
2
2
  import { logger } from "./logger.js";
3
- import { nonexhaustive } from "@likec4/core";
3
+ import { LikeC4Model, nonexhaustive } from "@likec4/core";
4
4
  import { Disposable, interruptAndCheck, URI, UriUtils } from "langium";
5
5
  import { DiagnosticSeverity } from "vscode-languageserver";
6
6
  import { isLikeC4LangiumDocument } from "./ast.js";
7
- import { Scheme } from "./likec4lib.js";
7
+ import { isLikeC4Builtin } from "./likec4lib.js";
8
8
  import {
9
9
  buildDocuments,
10
10
  changeView,
@@ -43,9 +43,8 @@ export class Rpc extends ADisposable {
43
43
  });
44
44
  },
45
45
  {
46
- minQuietPeriodMs: 250,
47
- maxBurstDurationMs: 1e3,
48
- minGapMs: 200
46
+ triggerAt: "both",
47
+ minGapMs: 350
49
48
  }
50
49
  );
51
50
  let isFirstBuild = true;
@@ -53,14 +52,17 @@ export class Rpc extends ADisposable {
53
52
  modelBuilder.onModelParsed(() => notifyModelParsed.call()),
54
53
  connection.onRequest(fetchComputedModel, async ({ cleanCaches }, cancelToken) => {
55
54
  if (cleanCaches) {
56
- this.services.WorkspaceCache.clear();
57
- this.services.DocumentCache.clear();
55
+ const all = LangiumDocuments.all.map((d) => d.uri).toArray();
56
+ await DocumentBuilder.update(all, [], cancelToken);
58
57
  }
59
- const model = await modelBuilder.buildComputedModel(cancelToken);
60
- return { model };
58
+ const likec4model = await modelBuilder.buildLikeC4Model(cancelToken);
59
+ if (likec4model !== LikeC4Model.EMPTY) {
60
+ return { model: likec4model.$model };
61
+ }
62
+ return { model: null };
61
63
  }),
62
64
  connection.onRequest(fetchModel, async (cancelToken) => {
63
- const model = await modelBuilder.buildModel(cancelToken);
65
+ const model = await modelBuilder.parseModel(cancelToken);
64
66
  return { model };
65
67
  }),
66
68
  connection.onRequest(computeView, async ({ viewId }, cancelToken) => {
@@ -79,7 +81,7 @@ export class Rpc extends ADisposable {
79
81
  connection.onRequest(buildDocuments, async ({ docs }, cancelToken) => {
80
82
  const changed = docs.map((d) => URI.parse(d));
81
83
  const notChanged = (uri) => changed.every((c) => !UriUtils.equals(c, uri));
82
- const deleted = LangiumDocuments.all.filter((d) => isLikeC4LangiumDocument(d) && notChanged(d.uri) && d.uri.scheme !== Scheme).map((d) => d.uri).toArray();
84
+ const deleted = LangiumDocuments.all.toArray().filter((d) => !isLikeC4Builtin(d.uri) && isLikeC4LangiumDocument(d) && notChanged(d.uri)).map((d) => d.uri);
83
85
  logger.debug(
84
86
  `[ServerRpc] received request to build:
85
87
  changed (total ${changed.length}):${docs.map((d) => "\n - " + d).join("")}
package/dist/ast.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type * as c4 from '@likec4/core';
2
- import type { AstNode, AstNodeDescription, DiagnosticInfo, LangiumDocument, MultiMap } from 'langium';
3
- import type { ConditionalPick, SetRequired, ValueOf, Writable } from 'type-fest';
2
+ import type { AstNode, AstNodeDescription, DiagnosticInfo, LangiumDocument } from 'langium';
3
+ import type { ConditionalPick, ValueOf, Writable } from 'type-fest';
4
4
  import type { Diagnostic } from 'vscode-languageserver-types';
5
5
  import type { LikeC4Grammar } from './generated/ast';
6
6
  import * as ast from './generated/ast';
@@ -66,17 +66,17 @@ export interface ParsedAstElement {
66
66
  description?: string;
67
67
  technology?: string;
68
68
  tags?: c4.NonEmptyArray<c4.Tag>;
69
- links?: c4.NonEmptyArray<ParsedLink>;
69
+ links?: c4.NonEmptyArray<c4.Link>;
70
70
  style: ParsedElementStyle;
71
71
  metadata?: {
72
72
  [key: string]: string;
73
73
  };
74
74
  }
75
- export interface ParsedAstExtendElement {
75
+ export interface ParsedAstExtend {
76
76
  id: c4.Fqn;
77
77
  astPath: string;
78
78
  tags?: c4.NonEmptyArray<c4.Tag>;
79
- links?: c4.NonEmptyArray<ParsedLink>;
79
+ links?: c4.NonEmptyArray<c4.Link>;
80
80
  metadata?: {
81
81
  [key: string]: string;
82
82
  };
@@ -95,7 +95,7 @@ export interface ParsedAstRelation {
95
95
  line?: c4.RelationshipLineType;
96
96
  head?: c4.RelationshipArrowType;
97
97
  tail?: c4.RelationshipArrowType;
98
- links?: c4.NonEmptyArray<ParsedLink>;
98
+ links?: c4.NonEmptyArray<c4.Link>;
99
99
  navigateTo?: c4.ViewId;
100
100
  metadata?: {
101
101
  [key: string]: string;
@@ -119,7 +119,7 @@ export interface ParsedAstElementView {
119
119
  title: string | null;
120
120
  description: string | null;
121
121
  tags: c4.NonEmptyArray<c4.Tag> | null;
122
- links: c4.NonEmptyArray<ParsedLink> | null;
122
+ links: c4.NonEmptyArray<c4.Link> | null;
123
123
  rules: c4.ViewRule[];
124
124
  manualLayout?: c4.ViewManualLayout;
125
125
  }
@@ -130,7 +130,7 @@ export interface ParsedAstDynamicView {
130
130
  title: string | null;
131
131
  description: string | null;
132
132
  tags: c4.NonEmptyArray<c4.Tag> | null;
133
- links: c4.NonEmptyArray<ParsedLink> | null;
133
+ links: c4.NonEmptyArray<c4.Link> | null;
134
134
  steps: c4.DynamicViewStepOrParallel[];
135
135
  rules: Array<c4.DynamicViewRule>;
136
136
  manualLayout?: c4.ViewManualLayout;
@@ -142,7 +142,7 @@ export interface ParsedAstDeploymentView {
142
142
  title: string | null;
143
143
  description: string | null;
144
144
  tags: c4.NonEmptyArray<c4.Tag> | null;
145
- links: c4.NonEmptyArray<ParsedLink> | null;
145
+ links: c4.NonEmptyArray<c4.Link> | null;
146
146
  rules: Array<c4.DeploymentViewRule>;
147
147
  }
148
148
  export type ParsedAstView = ParsedAstElementView | ParsedAstDynamicView | ParsedAstDeploymentView;
@@ -150,19 +150,12 @@ export declare const ViewOps: {
150
150
  writeId<T extends ast.LikeC4View>(node: T, id: c4.ViewId): T;
151
151
  readId(node: ast.LikeC4View): c4.ViewId | undefined;
152
152
  };
153
- export interface ParsedLink {
154
- title?: string;
155
- url: string;
156
- }
157
153
  export declare const ElementOps: {
158
154
  writeId(node: ast.Element | ast.DeploymentElement, id: c4.Fqn | null): ast.DeploymentElement | ast.Element;
159
155
  readId(node: ast.Element | ast.DeploymentElement): any;
160
156
  };
161
- export interface DocFqnIndexAstNodeDescription extends AstNodeDescription {
162
- fqn: c4.Fqn;
163
- }
164
- export interface DeploymentAstNodeDescription extends AstNodeDescription {
165
- fqn: string;
157
+ export interface AstNodeDescriptionWithFqn extends AstNodeDescription {
158
+ id: c4.Fqn;
166
159
  }
167
160
  export type LikeC4AstNode = ValueOf<ConditionalPick<ast.LikeC4AstType, AstNode>>;
168
161
  type LikeC4DocumentDiagnostic = Diagnostic & DiagnosticInfo<LikeC4AstNode>;
@@ -170,30 +163,21 @@ export interface LikeC4DocumentProps {
170
163
  diagnostics?: Array<LikeC4DocumentDiagnostic>;
171
164
  c4Specification?: ParsedAstSpecification;
172
165
  c4Elements?: ParsedAstElement[];
173
- c4ExtendElements?: ParsedAstExtendElement[];
166
+ c4ExtendElements?: ParsedAstExtend[];
167
+ c4ExtendDeployments?: ParsedAstExtend[];
174
168
  c4Relations?: ParsedAstRelation[];
175
169
  c4Globals?: ParsedAstGlobals;
176
170
  c4Views?: ParsedAstView[];
177
171
  c4Deployments?: ParsedAstDeployment[];
178
172
  c4DeploymentRelations?: ParsedAstDeploymentRelation[];
179
- c4fqnIndex?: MultiMap<c4.Fqn, DocFqnIndexAstNodeDescription>;
180
173
  }
181
174
  type LikeC4GrammarDocument = Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>;
182
175
  export interface LikeC4LangiumDocument extends LikeC4GrammarDocument, LikeC4DocumentProps {
183
176
  }
184
- export interface FqnIndexedDocument extends SetRequired<LikeC4LangiumDocument, 'c4fqnIndex'> {
185
- }
186
177
  export interface ParsedLikeC4LangiumDocument extends LikeC4GrammarDocument, Required<LikeC4DocumentProps> {
187
178
  }
188
179
  export declare function isLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument;
189
- export declare function isFqnIndexedDocument(doc: LangiumDocument): doc is FqnIndexedDocument;
190
180
  export declare function isParsedLikeC4LangiumDocument(doc: LangiumDocument): doc is ParsedLikeC4LangiumDocument;
191
- export declare function streamModel(doc: LikeC4LangiumDocument): Generator<any, void, unknown>;
192
- export declare function streamDeploymentModel(doc: LikeC4LangiumDocument): Generator<any, void, unknown>;
193
- export declare function resolveRelationPoints(node: ast.Relation): {
194
- source: ast.Element;
195
- target: ast.Element;
196
- };
197
181
  export declare function parseAstOpacityProperty({ value }: ast.OpacityProperty): number;
198
182
  export declare function parseAstSizeValue({ value }: {
199
183
  value: ast.SizeValue;
package/dist/ast.js CHANGED
@@ -1,9 +1,8 @@
1
- import { DefaultArrowType, DefaultLineStyle, DefaultRelationshipColor, LinkedList, nonexhaustive } from "@likec4/core";
1
+ import { DefaultArrowType, DefaultLineStyle, DefaultRelationshipColor, nonexhaustive } from "@likec4/core";
2
2
  import { DocumentState } from "langium";
3
- import { clamp, isBoolean, isDefined, isNullish, isTruthy } from "remeda";
3
+ import { clamp, isBoolean, isNullish, isTruthy } from "remeda";
4
4
  import * as ast from "./generated/ast.js";
5
5
  import { LikeC4LanguageMetaData } from "./generated/module.js";
6
- import { elementRef } from "./utils/elementRef.js";
7
6
  export { ast };
8
7
  const idattr = Symbol.for("idattr");
9
8
  export const ViewOps = {
@@ -31,74 +30,8 @@ export const ElementOps = {
31
30
  export function isLikeC4LangiumDocument(doc) {
32
31
  return doc.textDocument.languageId === LikeC4LanguageMetaData.languageId;
33
32
  }
34
- export function isFqnIndexedDocument(doc) {
35
- return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !!doc.c4fqnIndex;
36
- }
37
33
  export function isParsedLikeC4LangiumDocument(doc) {
38
- return isLikeC4LangiumDocument(doc) && doc.state == DocumentState.Validated && !!doc.c4Specification && !!doc.c4Elements && !!doc.c4ExtendElements && !!doc.c4Relations && !!doc.c4Views && !!doc.c4fqnIndex && !!doc.c4Deployments && !!doc.c4DeploymentRelations;
39
- }
40
- export function* streamModel(doc) {
41
- const traverseStack = LinkedList.from(doc.parseResult.value.models.flatMap((m) => m.elements));
42
- const relations = [];
43
- let el;
44
- while (el = traverseStack.shift()) {
45
- if (ast.isRelation(el)) {
46
- relations.push(el);
47
- continue;
48
- }
49
- if (el.body && el.body.elements && el.body.elements.length > 0) {
50
- for (const child of el.body.elements) {
51
- traverseStack.push(child);
52
- }
53
- }
54
- yield el;
55
- }
56
- yield* relations;
57
- return;
58
- }
59
- export function* streamDeploymentModel(doc) {
60
- const traverseStack = LinkedList.from(
61
- doc.parseResult.value.deployments.flatMap((m) => m.elements)
62
- );
63
- const relations = [];
64
- let el;
65
- while (el = traverseStack.shift()) {
66
- if (ast.isDeploymentRelation(el)) {
67
- relations.push(el);
68
- continue;
69
- }
70
- if (ast.isDeploymentNode(el) && el.body && el.body.elements.length > 0) {
71
- for (const child of el.body.elements) {
72
- traverseStack.push(child);
73
- }
74
- }
75
- yield el;
76
- }
77
- yield* relations;
78
- return;
79
- }
80
- export function resolveRelationPoints(node) {
81
- const target = elementRef(node.target);
82
- if (!target) {
83
- throw new Error("RelationRefError: Invalid reference to target");
84
- }
85
- if (isDefined(node.source)) {
86
- const source = elementRef(node.source);
87
- if (!source) {
88
- throw new Error("RelationRefError: Invalid reference to source");
89
- }
90
- return {
91
- source,
92
- target
93
- };
94
- }
95
- if (!ast.isElementBody(node.$container)) {
96
- throw new Error("RelationRefError: Invalid container for sourceless relation");
97
- }
98
- return {
99
- source: node.$container.$container,
100
- target
101
- };
34
+ return isLikeC4LangiumDocument(doc) && doc.state == DocumentState.Validated && !!doc.c4Specification && !!doc.c4Elements && !!doc.c4ExtendElements && !!doc.c4ExtendDeployments && !!doc.c4Relations && !!doc.c4Views && !!doc.c4Deployments && !!doc.c4DeploymentRelations;
102
35
  }
103
36
  export function parseAstOpacityProperty({ value }) {
104
37
  const opacity = parseFloat(value);