@likec4/language-server 1.8.1 → 1.9.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.
Files changed (76) hide show
  1. package/dist/browser.cjs +21 -0
  2. package/dist/browser.d.cts +22 -0
  3. package/dist/browser.d.mts +22 -0
  4. package/dist/browser.d.ts +22 -0
  5. package/dist/browser.mjs +19 -0
  6. package/dist/index.cjs +10 -0
  7. package/dist/index.d.cts +18 -0
  8. package/dist/index.d.mts +18 -0
  9. package/dist/index.d.ts +18 -0
  10. package/dist/index.mjs +1 -0
  11. package/dist/likec4lib.cjs +961 -0
  12. package/dist/likec4lib.d.cts +6 -0
  13. package/dist/likec4lib.d.mts +6 -0
  14. package/dist/likec4lib.d.ts +6 -0
  15. package/dist/likec4lib.mjs +957 -0
  16. package/dist/model-graph/index.cjs +10 -0
  17. package/dist/model-graph/index.d.cts +79 -0
  18. package/dist/model-graph/index.d.mts +79 -0
  19. package/dist/model-graph/index.d.ts +79 -0
  20. package/dist/model-graph/index.mjs +1 -0
  21. package/dist/node.cjs +18 -0
  22. package/dist/node.d.cts +20 -0
  23. package/dist/node.d.mts +20 -0
  24. package/dist/node.d.ts +20 -0
  25. package/dist/node.mjs +16 -0
  26. package/dist/protocol.cjs +25 -0
  27. package/dist/protocol.d.cts +43 -0
  28. package/dist/protocol.d.mts +43 -0
  29. package/dist/protocol.d.ts +43 -0
  30. package/dist/protocol.mjs +17 -0
  31. package/dist/shared/language-server.86lmJ8ZN.d.cts +1194 -0
  32. package/dist/shared/language-server.B1TZgyoH.cjs +5371 -0
  33. package/dist/shared/language-server.CCB4ESN5.mjs +1606 -0
  34. package/dist/shared/language-server.CFTY6j4e.d.mts +1194 -0
  35. package/dist/shared/language-server.D0bOlrCi.cjs +1619 -0
  36. package/dist/shared/language-server.Q-wtPShM.mjs +5360 -0
  37. package/dist/shared/language-server.RjhrBZS0.d.ts +1194 -0
  38. package/package.json +35 -20
  39. package/src/ast.ts +40 -30
  40. package/src/browser.ts +0 -3
  41. package/src/elementRef.ts +1 -1
  42. package/src/generated/ast.ts +67 -3
  43. package/src/generated/grammar.ts +1 -1
  44. package/src/generated-lib/icons.ts +1 -1
  45. package/src/like-c4.langium +16 -2
  46. package/src/likec4lib.ts +2 -3
  47. package/src/logger.ts +9 -1
  48. package/src/lsp/RenameProvider.ts +8 -0
  49. package/src/lsp/SemanticTokenProvider.ts +19 -1
  50. package/src/lsp/index.ts +1 -0
  51. package/src/model/fqn-computation.ts +33 -23
  52. package/src/model/fqn-index.ts +5 -20
  53. package/src/model/model-builder.ts +147 -90
  54. package/src/model/model-locator.ts +1 -1
  55. package/src/model/model-parser-where.ts +3 -2
  56. package/src/model/model-parser.ts +57 -19
  57. package/src/model-graph/LikeC4ModelGraph.ts +42 -21
  58. package/src/model-graph/compute-view/__test__/fixture.ts +16 -14
  59. package/src/model-graph/compute-view/compute.ts +9 -6
  60. package/src/model-graph/compute-view/predicates.ts +3 -3
  61. package/src/model-graph/dynamic-view/__test__/fixture.ts +1 -0
  62. package/src/model-graph/dynamic-view/compute.ts +2 -1
  63. package/src/model-graph/utils/elementExpressionToPredicate.ts +1 -1
  64. package/src/model-graph/utils/sortNodes.ts +2 -6
  65. package/src/module.ts +23 -3
  66. package/src/protocol.ts +4 -5
  67. package/src/references/scope-computation.ts +10 -1
  68. package/src/references/scope-provider.ts +2 -1
  69. package/src/shared/NodeKindProvider.ts +73 -34
  70. package/src/test/setup.ts +3 -8
  71. package/src/utils/graphlib.ts +11 -0
  72. package/src/view-utils/manual-layout.ts +1 -1
  73. package/src/view-utils/resolve-extended-views.ts +19 -10
  74. package/src/view-utils/resolve-relative-paths.ts +5 -7
  75. package/src/view-utils/view-hash.ts +1 -1
  76. package/src/reset.d.ts +0 -2
@@ -1,4 +1,4 @@
1
- export const LibIcons = `likec4lib {
1
+ export const LibIcons: string = `likec4lib {
2
2
  icons {
3
3
  aws:activate
4
4
  aws:alexa-for-business
@@ -31,12 +31,16 @@ Tag:
31
31
  RelationshipKind:
32
32
  name=Id;
33
33
 
34
+ CustomColor:
35
+ name=CustomColorId;
36
+
34
37
  SpecificationRule:
35
38
  name='specification' '{'
36
39
  (
37
40
  elements+=SpecificationElementKind |
38
41
  tags+=SpecificationTag |
39
- relationships+=SpecificationRelationshipKind
42
+ relationships+=SpecificationRelationshipKind |
43
+ colors+=SpecificationColor
40
44
  )*
41
45
  '}';
42
46
 
@@ -54,6 +58,9 @@ SpecificationElementStringProperty:
54
58
  SpecificationTag:
55
59
  'tag' tag=Tag;
56
60
 
61
+ SpecificationColor:
62
+ 'color' name=CustomColor color=CustomColorValue;
63
+
57
64
  SpecificationRelationshipKind:
58
65
  'relationship' kind=RelationshipKind ('{'
59
66
  props+=(
@@ -447,7 +454,7 @@ NavigateToProperty:
447
454
  LinkProperty:
448
455
  key='link' ':'? value=Uri title=String? ';'?;
449
456
  ColorProperty:
450
- key='color' ':'? value=ThemeColor ';'?;
457
+ key='color' ':'? (themeColor=ThemeColor | customColor=[CustomColor:CustomColorId]) ';'?;
451
458
 
452
459
  OpacityProperty:
453
460
  key='opacity' ':'? value=Percent ';'?;
@@ -513,6 +520,9 @@ ThemeColor returns string:
513
520
  ElementShape returns string:
514
521
  'rectangle' | 'person' | 'browser' | 'mobile' | 'cylinder' | 'storage' | 'queue';
515
522
 
523
+ CustomColorValue returns string:
524
+ Hash (Id | Hex);
525
+
516
526
  IconId returns string:
517
527
  LIB_ICON;
518
528
 
@@ -525,6 +535,9 @@ TagId returns string:
525
535
  DotId returns string:
526
536
  Dot Id;
527
537
 
538
+ CustomColorId returns string:
539
+ IdTerminal | ElementShape | ArrowType | LineOptions | 'element' | 'model';
540
+
528
541
  Id returns string:
529
542
  IdTerminal | ElementShape | ThemeColor | ArrowType | LineOptions | 'element' | 'model';
530
543
 
@@ -580,3 +593,4 @@ terminal String: /"[^"]*"|'[^']*'/;
580
593
  // terminal TagId: HASH LETTER (LETTER | DIGIT | UNDERSCORE | DASH)*;
581
594
  // terminal IdTerminal: (LETTER | UNDERSCORE+ (LETTER | DIGIT)) (LETTER | DIGIT | UNDERSCORE | DASH)*;
582
595
  terminal IdTerminal: /[_]*[a-zA-Z][-\w]*/;
596
+ terminal Hex: /[a-zA-Z0-9]+/;
package/src/likec4lib.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { LibIcons } from './generated-lib/icons'
2
2
 
3
- export const Scheme = 'likec4-lib'
4
- export const Path = `/icons.c4`
5
- export const Uri = `${Scheme}://${Path}`
3
+ export const Scheme = 'likec4builtin'
4
+ export const Uri = `${Scheme}:///likec4/lib/icons.c4`
6
5
 
7
6
  export { LibIcons as Content }
package/src/logger.ts CHANGED
@@ -65,14 +65,22 @@ export function logToLspConnection(connection: Connection): void {
65
65
  }
66
66
  const message = parts.join(' ')
67
67
  switch (true) {
68
+ case level >= LogLevels.trace: {
69
+ connection.tracer.log(message)
70
+ break
71
+ }
68
72
  case level >= LogLevels.debug: {
69
73
  connection.console.debug(message)
70
74
  break
71
75
  }
72
- case level >= LogLevels.log: {
76
+ case level >= LogLevels.info: {
73
77
  connection.console.info(message)
74
78
  break
75
79
  }
80
+ case level >= LogLevels.log: {
81
+ connection.console.log(message)
82
+ break
83
+ }
76
84
  case level >= LogLevels.warn: {
77
85
  connection.console.warn(message)
78
86
  break
@@ -0,0 +1,8 @@
1
+ import { DefaultRenameProvider } from 'langium/lsp'
2
+ import type { LikeC4Services } from '../module'
3
+
4
+ export class LikeC4RenameProvider extends DefaultRenameProvider {
5
+ constructor(services: LikeC4Services) {
6
+ super(services)
7
+ }
8
+ }
@@ -118,6 +118,23 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
118
118
  })
119
119
  return !node.parent ? 'prune' : undefined
120
120
  }
121
+ if (ast.isSpecificationColor(node)) {
122
+ acceptor({
123
+ node,
124
+ keyword: 'color',
125
+ type: SemanticTokenTypes.keyword
126
+ })
127
+ acceptor({
128
+ node,
129
+ property: 'name',
130
+ type: SemanticTokenTypes.type,
131
+ modifier: [
132
+ SemanticTokenModifiers.declaration,
133
+ SemanticTokenModifiers.readonly
134
+ ]
135
+ })
136
+ return
137
+ }
121
138
  if (ast.isSpecificationElementKind(node) || ast.isSpecificationRelationshipKind(node)) {
122
139
  acceptor({
123
140
  node,
@@ -188,7 +205,8 @@ export class LikeC4SemanticTokenProvider extends AbstractSemanticTokenProvider {
188
205
  acceptor({
189
206
  node,
190
207
  property: 'libicon',
191
- type: SemanticTokenTypes.enum
208
+ type: SemanticTokenTypes.enum,
209
+ modifier: [SemanticTokenModifiers.defaultLibrary]
192
210
  })
193
211
  }
194
212
  return 'prune'
package/src/lsp/index.ts CHANGED
@@ -4,4 +4,5 @@ export * from './DocumentHighlightProvider'
4
4
  export * from './DocumentLinkProvider'
5
5
  export * from './DocumentSymbolProvider'
6
6
  export * from './HoverProvider'
7
+ export * from './RenameProvider'
7
8
  export * from './SemanticTokenProvider'
@@ -1,8 +1,10 @@
1
- import { AsFqn, type c4, nonexhaustive } from '@likec4/core'
1
+ import { AsFqn, nonexhaustive } from '@likec4/core'
2
+ import type * as c4 from '@likec4/core'
2
3
  import { type AstNodeDescription, type AstNodeLocator, AstUtils, CstUtils, GrammarUtils, MultiMap } from 'langium'
3
- import { isEmpty, isNullish as isNil } from 'remeda'
4
+ import { isDefined, isEmpty } from 'remeda'
4
5
  import { ast, ElementOps, type LikeC4LangiumDocument } from '../ast'
5
6
  import { getFqnElementRef } from '../elementRef'
7
+ import { logError } from '../logger'
6
8
  import type { LikeC4Services } from '../module'
7
9
 
8
10
  const { findNodeForProperty } = GrammarUtils
@@ -41,29 +43,37 @@ export function computeDocumentFqn(document: LikeC4LangiumDocument, services: Li
41
43
  const traverseStack: TraversePair[] = elements.map(el => [el, null])
42
44
  let pair
43
45
  while ((pair = traverseStack.shift())) {
44
- const [el, parent] = pair
45
- if (ast.isRelation(el)) {
46
- continue
47
- }
48
- if (ast.isExtendElement(el)) {
49
- if (!isNil(el.body) && !isEmpty(el.body.elements)) {
50
- const fqn = getFqnElementRef(el.element)
51
- el.body.elements.forEach(child => traverseStack.push([child, fqn]))
46
+ try {
47
+ const [el, parent] = pair
48
+ if (ast.isRelation(el)) {
49
+ continue
52
50
  }
53
- continue
54
- }
55
- if (ast.isElement(el)) {
56
- const fqn = AsFqn(el.name, parent)
57
- c4fqnIndex.add(fqn, {
58
- ...toAstNodeDescription(locator, el, document),
59
- fqn
60
- })
61
- ElementOps.writeId(el, fqn)
62
- if (!isNil(el.body) && !isEmpty(el.body.elements)) {
63
- el.body.elements.forEach(child => traverseStack.push([child, fqn]))
51
+ if (ast.isExtendElement(el)) {
52
+ if (isDefined(el.body) && !isEmpty(el.body.elements)) {
53
+ const fqn = getFqnElementRef(el.element)
54
+ for (const child of el.body.elements) {
55
+ traverseStack.push([child, fqn])
56
+ }
57
+ }
58
+ continue
59
+ }
60
+ if (ast.isElement(el)) {
61
+ const fqn = AsFqn(el.name, parent)
62
+ c4fqnIndex.add(fqn, {
63
+ ...toAstNodeDescription(locator, el, document),
64
+ fqn
65
+ })
66
+ ElementOps.writeId(el, fqn)
67
+ if (isDefined(el.body) && !isEmpty(el.body.elements)) {
68
+ for (const child of el.body.elements) {
69
+ traverseStack.push([child, fqn])
70
+ }
71
+ }
72
+ continue
64
73
  }
65
- continue
74
+ nonexhaustive(el)
75
+ } catch (e) {
76
+ logError(e)
66
77
  }
67
- nonexhaustive(el)
68
78
  }
69
79
  }
@@ -4,7 +4,7 @@ import type { AstNodeDescription, LangiumDocuments, Stream } from 'langium'
4
4
  import { DocumentState, DONE_RESULT, MultiMap, stream, StreamImpl } from 'langium'
5
5
  import type { ast, DocFqnIndexAstNodeDescription, FqnIndexedDocument } from '../ast'
6
6
  import { ElementOps, isFqnIndexedDocument, isLikeC4LangiumDocument } from '../ast'
7
- import { logError, logger } from '../logger'
7
+ import { logger, logWarnError } from '../logger'
8
8
  import type { LikeC4Services } from '../module'
9
9
  import { printDocs } from '../utils/printDocs'
10
10
  import { computeDocumentFqn } from './fqn-computation'
@@ -37,11 +37,11 @@ export class FqnIndex {
37
37
  try {
38
38
  computeDocumentFqn(doc, services)
39
39
  } catch (e) {
40
- logError(e)
40
+ logWarnError(e)
41
41
  }
42
42
  }
43
43
  }
44
- return Promise.resolve()
44
+ return await Promise.resolve()
45
45
  }
46
46
  )
47
47
  logger.debug(`[FqnIndex] Created`)
@@ -51,29 +51,14 @@ export class FqnIndex {
51
51
  return this.langiumDocuments.all.filter(isFqnIndexedDocument)
52
52
  }
53
53
 
54
- private entries(filterByFqn?: (fqn: Fqn) => boolean): Stream<DocFqnIndexAstNodeDescription> {
54
+ private entries(filterByFqn: (fqn: Fqn) => boolean): Stream<DocFqnIndexAstNodeDescription> {
55
55
  return this.documents.flatMap(doc => {
56
- if (filterByFqn) {
57
- return doc.c4fqnIndex.keys().filter(filterByFqn).flatMap(fqn => doc.c4fqnIndex.get(fqn))
58
- }
59
- return doc.c4fqnIndex.values()
56
+ return doc.c4fqnIndex.keys().filter(filterByFqn).flatMap(fqn => doc.c4fqnIndex.get(fqn))
60
57
  })
61
58
  }
62
59
 
63
60
  public getFqn(el: ast.Element): Fqn | null {
64
61
  return ElementOps.readId(el) ?? null
65
- // let fqn = ElementOps.readId(el) ?? null
66
- // if (fqn) {
67
- // const doc = getDocument(el)
68
- // if (isFqnIndexedDocument(doc) && doc.c4fqns.has(fqn)) {
69
- // return fqn
70
- // }
71
- // const path = this.services.workspace.AstNodeLocator.getAstNodePath(el)
72
- // logError(`Clean cached FQN ${fqn} at ${path}`)
73
- // ElementOps.writeId(el, null)
74
- // fqn = null
75
- // }
76
- // return fqn
77
62
  }
78
63
 
79
64
  public byFqn(fqn: Fqn): Stream<AstNodeDescription> {