@likec4/language-server 1.21.0 → 1.22.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 (114) hide show
  1. package/README.md +4 -1
  2. package/bin/likec4-language-server.mjs +5 -2
  3. package/dist/LikeC4FileSystem.js +2 -2
  4. package/dist/browser.d.ts +3 -3
  5. package/dist/browser.js +17 -2
  6. package/dist/bundled.d.ts +8 -0
  7. package/dist/bundled.js +25 -0
  8. package/dist/bundled.mjs +2587 -4306
  9. package/dist/generated-lib/icons.js +1 -0
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +23 -2
  12. package/dist/logger.d.ts +9 -3
  13. package/dist/logger.js +35 -55
  14. package/dist/model/fqn-computation.js +2 -2
  15. package/dist/model/model-builder.js +13 -14
  16. package/dist/model-change/ModelChanges.js +2 -2
  17. package/dist/module.js +1 -4
  18. package/dist/references/scope-provider.js +3 -3
  19. package/dist/view-utils/manual-layout.js +2 -2
  20. package/dist/views/configurable-layouter.js +4 -4
  21. package/dist/views/likec4-views.d.ts +2 -1
  22. package/dist/views/likec4-views.js +2 -2
  23. package/package.json +14 -14
  24. package/dist/test/setup.d.ts +0 -1
  25. package/dist/test/setup.js +0 -7
  26. package/src/LikeC4FileSystem.ts +0 -38
  27. package/src/Rpc.ts +0 -134
  28. package/src/ast.ts +0 -556
  29. package/src/browser.ts +0 -35
  30. package/src/documentation/documentation-provider.ts +0 -52
  31. package/src/documentation/index.ts +0 -1
  32. package/src/formatting/LikeC4Formatter.ts +0 -639
  33. package/src/formatting/utils.ts +0 -26
  34. package/src/generated/ast.ts +0 -3735
  35. package/src/generated/grammar.ts +0 -10
  36. package/src/generated/module.ts +0 -33
  37. package/src/generated-lib/icons.ts +0 -1537
  38. package/src/index.ts +0 -30
  39. package/src/like-c4.langium +0 -901
  40. package/src/likec4lib.ts +0 -6
  41. package/src/logger.ts +0 -80
  42. package/src/lsp/CodeLensProvider.ts +0 -50
  43. package/src/lsp/CompletionProvider.ts +0 -147
  44. package/src/lsp/DocumentHighlightProvider.ts +0 -12
  45. package/src/lsp/DocumentLinkProvider.ts +0 -65
  46. package/src/lsp/DocumentSymbolProvider.ts +0 -313
  47. package/src/lsp/HoverProvider.ts +0 -92
  48. package/src/lsp/RenameProvider.ts +0 -8
  49. package/src/lsp/SemanticTokenProvider.ts +0 -383
  50. package/src/lsp/index.ts +0 -8
  51. package/src/model/deployments-index.ts +0 -209
  52. package/src/model/fqn-computation.ts +0 -83
  53. package/src/model/fqn-index.ts +0 -138
  54. package/src/model/index.ts +0 -6
  55. package/src/model/model-builder.ts +0 -724
  56. package/src/model/model-locator.ts +0 -146
  57. package/src/model/model-parser-where.ts +0 -84
  58. package/src/model/model-parser.ts +0 -86
  59. package/src/model/parser/Base.ts +0 -113
  60. package/src/model/parser/DeploymentModelParser.ts +0 -192
  61. package/src/model/parser/DeploymentViewParser.ts +0 -122
  62. package/src/model/parser/FqnRefParser.ts +0 -143
  63. package/src/model/parser/GlobalsParser.ts +0 -96
  64. package/src/model/parser/ModelParser.ts +0 -170
  65. package/src/model/parser/PredicatesParser.ts +0 -315
  66. package/src/model/parser/SpecificationParser.ts +0 -133
  67. package/src/model/parser/ViewsParser.ts +0 -428
  68. package/src/model-change/ModelChanges.ts +0 -101
  69. package/src/model-change/changeElementStyle.ts +0 -172
  70. package/src/model-change/changeViewLayout.ts +0 -47
  71. package/src/model-change/saveManualLayout.ts +0 -41
  72. package/src/module.ts +0 -255
  73. package/src/protocol.ts +0 -93
  74. package/src/references/index.ts +0 -3
  75. package/src/references/name-provider.ts +0 -37
  76. package/src/references/scope-computation.ts +0 -364
  77. package/src/references/scope-provider.ts +0 -201
  78. package/src/shared/NodeKindProvider.ts +0 -121
  79. package/src/shared/WorkspaceManager.ts +0 -48
  80. package/src/shared/WorkspaceSymbolProvider.ts +0 -3
  81. package/src/shared/index.ts +0 -3
  82. package/src/test/index.ts +0 -1
  83. package/src/test/setup.ts +0 -8
  84. package/src/test/testServices.ts +0 -152
  85. package/src/utils/disposable.ts +0 -30
  86. package/src/utils/elementRef.ts +0 -26
  87. package/src/utils/fqnRef.ts +0 -56
  88. package/src/utils/index.ts +0 -2
  89. package/src/utils/printDocs.ts +0 -3
  90. package/src/utils/stringHash.ts +0 -6
  91. package/src/validation/_shared.ts +0 -29
  92. package/src/validation/deployment-checks.ts +0 -131
  93. package/src/validation/dynamic-view-rule.ts +0 -23
  94. package/src/validation/dynamic-view-step.ts +0 -36
  95. package/src/validation/element.ts +0 -56
  96. package/src/validation/index.ts +0 -171
  97. package/src/validation/property-checks.ts +0 -52
  98. package/src/validation/relation.ts +0 -63
  99. package/src/validation/specification.ts +0 -205
  100. package/src/validation/view-predicates/element-with.ts +0 -36
  101. package/src/validation/view-predicates/expanded-element.ts +0 -16
  102. package/src/validation/view-predicates/expression-v2.ts +0 -101
  103. package/src/validation/view-predicates/incoming.ts +0 -20
  104. package/src/validation/view-predicates/index.ts +0 -6
  105. package/src/validation/view-predicates/outgoing.ts +0 -20
  106. package/src/validation/view-predicates/relation-with.ts +0 -17
  107. package/src/validation/view.ts +0 -37
  108. package/src/view-utils/assignNavigateTo.ts +0 -31
  109. package/src/view-utils/index.ts +0 -2
  110. package/src/view-utils/manual-layout.ts +0 -116
  111. package/src/view-utils/resolve-relative-paths.ts +0 -90
  112. package/src/views/configurable-layouter.ts +0 -65
  113. package/src/views/index.ts +0 -1
  114. package/src/views/likec4-views.ts +0 -139
@@ -1,48 +0,0 @@
1
- import { hasAtLeast, invariant } from '@likec4/core'
2
- import type { LangiumDocument, LangiumDocumentFactory } from 'langium'
3
- import { DefaultWorkspaceManager } from 'langium'
4
- import type { LangiumSharedServices } from 'langium/lsp'
5
- import type { WorkspaceFolder } from 'vscode-languageserver'
6
- import { URI } from 'vscode-uri'
7
- import * as BuiltIn from '../likec4lib'
8
-
9
- export class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
10
- private documentFactory: LangiumDocumentFactory
11
-
12
- constructor(services: LangiumSharedServices) {
13
- super(services)
14
- this.documentFactory = services.workspace.LangiumDocumentFactory
15
- }
16
-
17
- /**
18
- * Load all additional documents that shall be visible in the context of the given workspace
19
- * folders and add them to the collector. This can be used to include built-in libraries of
20
- * your language, which can be either loaded from provided files or constructed in memory.
21
- */
22
- protected override async loadAdditionalDocuments(
23
- folders: WorkspaceFolder[],
24
- collector: (document: LangiumDocument) => void
25
- ): Promise<void> {
26
- collector(this.documentFactory.fromString(BuiltIn.Content, URI.parse(BuiltIn.Uri)))
27
- await super.loadAdditionalDocuments(folders, collector)
28
- }
29
-
30
- public workspace() {
31
- if (this.folders && hasAtLeast(this.folders, 1)) {
32
- return this.folders[0]
33
- }
34
- return null
35
- }
36
-
37
- public get workspaceUri() {
38
- const workspace = this.workspace()
39
- invariant(workspace, 'Workspace not initialized')
40
- return URI.parse(workspace.uri)
41
- }
42
-
43
- public get workspaceURL() {
44
- const workspace = this.workspace()
45
- invariant(workspace, 'Workspace not initialized')
46
- return new URL(workspace.uri)
47
- }
48
- }
@@ -1,3 +0,0 @@
1
- import { DefaultWorkspaceSymbolProvider } from 'langium/lsp'
2
-
3
- export class WorkspaceSymbolProvider extends DefaultWorkspaceSymbolProvider {}
@@ -1,3 +0,0 @@
1
- export * from './NodeKindProvider'
2
- export * from './WorkspaceManager'
3
- export * from './WorkspaceSymbolProvider'
package/src/test/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './testServices'
package/src/test/setup.ts DELETED
@@ -1,8 +0,0 @@
1
- import { consola } from '@likec4/log'
2
- import { beforeEach, vi } from 'vitest'
3
- import { logger } from '../logger'
4
- beforeEach(() => {
5
- // Vitest
6
- consola.mockTypes(() => vi.fn())
7
- logger.mockTypes(() => vi.fn())
8
- })
@@ -1,152 +0,0 @@
1
- import { LikeC4Model } from '@likec4/core'
2
- import { DocumentState, EmptyFileSystem, TextDocument } from 'langium'
3
- import * as assert from 'node:assert'
4
- import stripIndent from 'strip-indent'
5
- import { type Diagnostic, DiagnosticSeverity } from 'vscode-languageserver-types'
6
- import { URI, Utils } from 'vscode-uri'
7
- import type { LikeC4LangiumDocument } from '../ast'
8
- import { createLanguageServices } from '../module'
9
-
10
- export function createTestServices(workspace = 'file:///test/workspace') {
11
- const services = createLanguageServices(EmptyFileSystem).likec4
12
- const metaData = services.LanguageMetaData
13
- const langiumDocuments = services.shared.workspace.LangiumDocuments
14
- const documentBuilder = services.shared.workspace.DocumentBuilder
15
- const modelBuilder = services.likec4.ModelBuilder
16
- const workspaceUri = URI.parse(workspace)
17
- const formatter = services.lsp.Formatter
18
- const workspaceFolder = {
19
- name: 'test',
20
- uri: workspaceUri.toString(),
21
- }
22
- let isInitialized = false
23
- let documentIndex = 1
24
-
25
- const parse = async (input: string, uri?: string) => {
26
- if (!isInitialized) {
27
- await services.shared.workspace.WorkspaceLock.write(async (_cancelToken) => {
28
- if (isInitialized) {
29
- return
30
- }
31
- isInitialized = true
32
- services.shared.workspace.WorkspaceManager.initialize({
33
- capabilities: {},
34
- processId: null,
35
- rootUri: null,
36
- workspaceFolders: [workspaceFolder],
37
- })
38
- await services.shared.workspace.WorkspaceManager.initializeWorkspace([workspaceFolder])
39
- })
40
- }
41
- const docUri = Utils.resolvePath(
42
- workspaceUri,
43
- './src/',
44
- uri ?? `${documentIndex++}${metaData.fileExtensions[0]}`,
45
- )
46
- const document = services.shared.workspace.LangiumDocumentFactory.fromString(
47
- stripIndent(input),
48
- docUri,
49
- )
50
- langiumDocuments.addDocument(document)
51
- await services.shared.workspace.WorkspaceLock.write(async (_cancelToken) => {
52
- await documentBuilder.build([document], { validation: false })
53
- })
54
- return document as LikeC4LangiumDocument
55
- }
56
-
57
- const validate = async (input: string | LikeC4LangiumDocument, uri?: string) => {
58
- const document = typeof input === 'string' ? await parse(input, uri) : input
59
- await services.shared.workspace.WorkspaceLock.write(async (_cancelToken) => {
60
- await documentBuilder.build([document], { validation: true })
61
- })
62
- const diagnostics = document.diagnostics ?? []
63
- const warnings = diagnostics.flatMap(d => d.severity === DiagnosticSeverity.Warning ? d.message : [])
64
- const errors = diagnostics.flatMap(d => d.severity === DiagnosticSeverity.Error ? d.message : [])
65
- return {
66
- document,
67
- diagnostics,
68
- warnings,
69
- errors,
70
- }
71
- }
72
-
73
- const format = async (input: string | LikeC4LangiumDocument, uri?: string) => {
74
- const document = typeof input === 'string' ? await parse(input, uri) : input
75
- await services.shared.workspace.WorkspaceLock.write(async (_cancelToken) => {
76
- await documentBuilder.build([document], { validation: true })
77
- })
78
-
79
- const edits = await formatter?.formatDocument(
80
- document,
81
- {
82
- options: { tabSize: 2, insertSpaces: true },
83
- textDocument: { uri: document.uri.toString() },
84
- },
85
- )
86
-
87
- return TextDocument.applyEdits(document.textDocument, edits ?? [])
88
- }
89
-
90
- type ValidateAllResult = {
91
- diagnostics: Diagnostic[]
92
- errors: string[]
93
- warnings: string[]
94
- }
95
-
96
- const validateAll = async () => {
97
- await services.shared.workspace.WorkspaceLock.write(async (_cancelToken) => {
98
- const docs = langiumDocuments.all.toArray()
99
- await documentBuilder.build(docs, { validation: true })
100
- })
101
- await documentBuilder.waitUntil(DocumentState.Validated)
102
- const docs = langiumDocuments.all.toArray()
103
- assert.ok(docs.length > 0, 'no documents to validate')
104
- const diagnostics = docs.flatMap(doc => doc.diagnostics ?? [])
105
- const warnings = diagnostics.flatMap(d => d.severity === DiagnosticSeverity.Warning ? d.message : [])
106
- const errors = diagnostics.flatMap(d => d.severity === DiagnosticSeverity.Error ? d.message : [])
107
- return {
108
- diagnostics,
109
- errors,
110
- warnings,
111
- }
112
- }
113
-
114
- const buildModel = async () => {
115
- await validateAll()
116
- const model = await modelBuilder.buildComputedModel()
117
- if (!model) throw new Error('No model found')
118
- return model
119
- }
120
-
121
- const buildLikeC4Model = async () => {
122
- await validateAll()
123
- const model = await modelBuilder.buildComputedModel()
124
- if (!model) throw new Error('No model found')
125
- return LikeC4Model.create(model)
126
- }
127
-
128
- /**
129
- * This will clear all documents
130
- */
131
- const resetState = async () => {
132
- await services.shared.workspace.WorkspaceLock.write(async (cancelToken) => {
133
- const docs = langiumDocuments.all.toArray().map(doc => doc.uri)
134
- await documentBuilder.update([], docs, cancelToken)
135
- })
136
- }
137
-
138
- return {
139
- services,
140
- parse,
141
- validate,
142
- validateAll,
143
- buildModel,
144
- buildLikeC4Model,
145
- resetState,
146
- format,
147
- }
148
- }
149
-
150
- export type TestServices = ReturnType<typeof createTestServices>
151
- export type TestParseFn = TestServices['validate']
152
- export type TestValidateFn = TestServices['validate']
@@ -1,30 +0,0 @@
1
- import { Disposable } from 'langium'
2
- import { logError } from '../logger'
3
-
4
- export abstract class ADisposable implements Disposable {
5
- protected toDispose: Disposable[] = []
6
- protected isDisposed = false
7
-
8
- onDispose(...disposable: Disposable[]): void {
9
- this.toDispose.push(...disposable)
10
- }
11
-
12
- dispose(): void {
13
- this.throwIfDisposed()
14
- this.isDisposed = true
15
- let item: Disposable | undefined
16
- while (item = this.toDispose.pop()) {
17
- try {
18
- item.dispose()
19
- } catch (e) {
20
- logError(e)
21
- }
22
- }
23
- }
24
-
25
- protected throwIfDisposed(): void {
26
- if (this.isDisposed) {
27
- throw new Error('This has already been disposed')
28
- }
29
- }
30
- }
@@ -1,26 +0,0 @@
1
- import type * as c4 from '@likec4/core'
2
- import type { ast } from '../ast'
3
- /**
4
- * Returns referenced AST Element
5
- */
6
- export function elementRef(node: ast.ElementRef | ast.StrictFqnElementRef) {
7
- return node.el.ref
8
- }
9
-
10
- /**
11
- * Returns FQN of StrictFqnElementRef
12
- * a.b.c.d - for c node returns a.b.c
13
- */
14
- export function getFqnElementRef(node: ast.StrictFqnElementRef): c4.Fqn {
15
- // invariant(isElementRefHead(node), 'Expected head StrictElementRef')
16
- const name = [node.el.$refText]
17
- let parent = node.parent
18
- while (parent) {
19
- name.push(parent.el.$refText)
20
- parent = parent.parent
21
- }
22
- if (name.length === 1) {
23
- return name[0] as c4.Fqn
24
- }
25
- return name.reverse().join('.') as c4.Fqn
26
- }
@@ -1,56 +0,0 @@
1
- import { AstUtils } from 'langium'
2
- import { isNullish } from 'remeda'
3
- import { ast } from '../ast'
4
-
5
- export function instanceRef(deploymentRef: ast.FqnRef): ast.DeployedInstance | null {
6
- let referenceable
7
- while ((referenceable = deploymentRef.value?.ref)) {
8
- if (ast.isDeploymentNode(referenceable)) {
9
- return null
10
- }
11
- if (ast.isDeployedInstance(referenceable)) {
12
- return referenceable
13
- }
14
- if (isNullish(deploymentRef.parent)) {
15
- return null
16
- }
17
- deploymentRef = deploymentRef.parent
18
- }
19
- return null
20
- }
21
-
22
- export function deploymentNodeRef(deploymentRef: ast.FqnRef): ast.DeploymentNode | null {
23
- let referenceable = deploymentRef.value.ref ?? null
24
- if (!referenceable || ast.isDeploymentNode(referenceable)) {
25
- return referenceable
26
- }
27
- const artifact = instanceRef(deploymentRef)
28
- // Because path in deploymentRef may be omitted,
29
- // we find artifact first and then its container
30
- return artifact ? AstUtils.getContainerOfType(artifact, ast.isDeploymentNode) ?? null : null
31
- }
32
-
33
- export function isReferenceToLogicalModel(node: ast.FqnRef) {
34
- // iterate up the root parent
35
- while (node.parent) {
36
- node = node.parent
37
- }
38
- return ast.isElement(node.value.ref)
39
- }
40
-
41
- /**
42
- * Returns true if node references deployment model
43
- */
44
- export function isReferenceToDeploymentModel(node: ast.FqnRef) {
45
- let referenceable
46
- while ((referenceable = node.value?.ref)) {
47
- if (ast.isDeploymentElement(referenceable)) {
48
- return true
49
- }
50
- if (isNullish(node.parent)) {
51
- return false
52
- }
53
- node = node.parent
54
- }
55
- return false
56
- }
@@ -1,2 +0,0 @@
1
- export * from './disposable'
2
- export * from './stringHash'
@@ -1,3 +0,0 @@
1
- import type { LangiumDocument } from 'langium'
2
-
3
- export const printDocs = (docs: LangiumDocument[]) => docs.map(d => ' - ' + d.uri.toString(true)).join('\n')
@@ -1,6 +0,0 @@
1
- import { stringHash as hash } from '@likec4/core'
2
-
3
- export function stringHash(...str: [string, ...string[]]): string {
4
- var s = str.length > 1 ? str.join(':::') : str[0]
5
- return hash(s)
6
- }
@@ -1,29 +0,0 @@
1
- import { type AstNode, type ValidationAcceptor, type ValidationCheck } from 'langium'
2
- import { isPromise } from 'remeda'
3
- import type { CancellationToken } from 'vscode-jsonrpc'
4
- import { logWarnError } from '../logger'
5
-
6
- export const RESERVED_WORDS = [
7
- 'this',
8
- 'it',
9
- 'self',
10
- 'super',
11
- 'likec4lib',
12
- 'global',
13
- ]
14
-
15
- export function tryOrLog<T extends AstNode>(fn: ValidationCheck<T>): ValidationCheck<T> {
16
- return async function tryOrLogFn(node: T, accept: ValidationAcceptor, cancelToken: CancellationToken) {
17
- try {
18
- const result = fn(node, accept, cancelToken)
19
- if (isPromise(result)) {
20
- await result
21
- }
22
- return
23
- } catch (e) {
24
- const message = e instanceof Error ? e.message : String(e)
25
- accept('error', `Validation failed: ${message}`, { node })
26
- logWarnError(e)
27
- }
28
- }
29
- }
@@ -1,131 +0,0 @@
1
- import { FqnRef, isSameHierarchy, nonNullable } from '@likec4/core'
2
- import { type ValidationCheck, AstUtils } from 'langium'
3
- import { ast } from '../ast'
4
- import type { LikeC4Services } from '../module'
5
- import type { LikeC4NameProvider } from '../references'
6
- import { RESERVED_WORDS, tryOrLog } from './_shared'
7
-
8
- const { getDocument } = AstUtils
9
-
10
- export const deploymentNodeChecks = (services: LikeC4Services): ValidationCheck<ast.DeploymentNode> => {
11
- const DeploymentsIndex = services.likec4.DeploymentsIndex
12
- const Names = services.references.NameProvider
13
- return tryOrLog((el, accept) => {
14
- const nodeName = Names.getName(el)
15
- if (!nodeName) {
16
- accept('error', 'DeploymentNode must be named', {
17
- node: el,
18
- })
19
- return
20
- }
21
- const range = nonNullable(Names.getNameNode(el), 'name CstNode not found').range
22
-
23
- if (RESERVED_WORDS.includes(nodeName)) {
24
- accept('error', `Reserved word: ${nodeName}`, {
25
- node: el,
26
- range,
27
- })
28
- }
29
- const fqnName = DeploymentsIndex.getFqn(el)
30
-
31
- const withSameName = DeploymentsIndex.byFqn(fqnName).limit(2).toArray()
32
- if (withSameName.length > 1) {
33
- accept(
34
- 'error',
35
- `Duplicate node name "${fqnName}"`,
36
- {
37
- node: el,
38
- range,
39
- },
40
- )
41
- }
42
- })
43
- }
44
-
45
- export const deployedInstanceChecks = (services: LikeC4Services): ValidationCheck<ast.DeployedInstance> => {
46
- const DeploymentsIndex = services.likec4.DeploymentsIndex
47
- const Names = services.references.NameProvider as LikeC4NameProvider
48
- // const Locator = services.workspace.AstNodeLocator
49
- return tryOrLog((el, accept) => {
50
- const artifactName = Names.getName(el)
51
- if (!artifactName) {
52
- accept('error', 'Deployed instance must be named, unique inside node', {
53
- node: el,
54
- })
55
- return
56
- }
57
- const range = nonNullable(Names.getNameNode(el), 'name CstNode not found').range
58
-
59
- if (RESERVED_WORDS.includes(artifactName)) {
60
- accept('error', `Reserved word: ${artifactName}`, {
61
- node: el,
62
- range,
63
- })
64
- }
65
-
66
- const fqnName = DeploymentsIndex.getFqn(el)
67
-
68
- const withSameName = DeploymentsIndex.byFqn(fqnName).limit(2).toArray()
69
- if (withSameName.length > 1) {
70
- accept(
71
- 'error',
72
- `Duplicate instance name "${fqnName}"`,
73
- {
74
- node: el,
75
- range,
76
- },
77
- )
78
- }
79
- })
80
- }
81
-
82
- export const deploymentRelationChecks = (services: LikeC4Services): ValidationCheck<ast.DeploymentRelation> => {
83
- const ModelParser = services.likec4.ModelParser
84
- return tryOrLog((el, accept) => {
85
- const source = el.source?.value?.ref
86
- if (!source) {
87
- let sourceCstText = el.source?.$cstNode?.text ?? ''
88
- accept('error', `DeploymentRelation source '${sourceCstText}' not resolved`, {
89
- node: el,
90
- property: 'source',
91
- })
92
- return
93
- }
94
- const target = el.target?.value?.ref
95
- if (!target) {
96
- let targetCstText = el.target?.$cstNode?.text ?? ''
97
- accept('error', `DeploymentRelation target '${targetCstText}' not resolved`, {
98
- node: el,
99
- property: 'target',
100
- })
101
- return
102
- }
103
-
104
- const doc = getDocument(el)
105
- const parser = ModelParser.forDocument(doc)
106
-
107
- const sourceFqnRef = parser.parseFqnRef(el.source)
108
- if (FqnRef.isModelRef(sourceFqnRef)) {
109
- accept('error', 'DeploymentRelation must refer deployment element', {
110
- node: el,
111
- property: 'source',
112
- })
113
- return
114
- }
115
-
116
- const targetFqnRef = parser.parseFqnRef(el.target)
117
- if (FqnRef.isModelRef(targetFqnRef)) {
118
- accept('error', 'DeploymentRelation must refer deployment element', {
119
- node: el,
120
- property: 'target',
121
- })
122
- return
123
- }
124
-
125
- if (isSameHierarchy(sourceFqnRef.deployment, targetFqnRef.deployment)) {
126
- accept('error', 'Invalid parent-child relationship', {
127
- node: el,
128
- })
129
- }
130
- })
131
- }
@@ -1,23 +0,0 @@
1
- import { nonexhaustive } from '@likec4/core'
2
- import type { ValidationCheck } from 'langium'
3
- import { ast, elementExpressionFromPredicate } from '../ast'
4
- import type { LikeC4Services } from '../module'
5
- import { tryOrLog } from './_shared'
6
-
7
- export const dynamicViewRulePredicate = (
8
- _services: LikeC4Services,
9
- ): ValidationCheck<ast.DynamicViewPredicateIterator> => {
10
- return tryOrLog((predicate, accept) => {
11
- const expr = elementExpressionFromPredicate(predicate.value)
12
- switch (true) {
13
- case ast.isElementKindExpression(expr):
14
- case ast.isElementTagExpression(expr):
15
- case ast.isWildcardExpression(expr): {
16
- accept('warning', `Predicate is ignored, as not supported in dynamic views`, {
17
- node: predicate,
18
- })
19
- return
20
- }
21
- }
22
- })
23
- }
@@ -1,36 +0,0 @@
1
- import { isAncestor } from '@likec4/core'
2
- import type { ValidationCheck } from 'langium'
3
- import { ast } from '../ast'
4
- import { logError } from '../logger'
5
- import type { LikeC4Services } from '../module'
6
- import { elementRef } from '../utils/elementRef'
7
- import { tryOrLog } from './_shared'
8
-
9
- export const dynamicViewStep = (services: LikeC4Services): ValidationCheck<ast.DynamicViewStep> => {
10
- const fqnIndex = services.likec4.FqnIndex
11
- return tryOrLog((el, accept) => {
12
- const sourceEl: ast.Element | undefined = elementRef(el.source)
13
- const source = sourceEl && fqnIndex.getFqn(sourceEl)
14
- if (!source) {
15
- accept('error', 'Source not found (not parsed/indexed yet)', {
16
- node: el,
17
- property: 'source',
18
- })
19
- }
20
-
21
- const targetEl: ast.Element | undefined = elementRef(el.target)
22
- const target = targetEl && fqnIndex.getFqn(targetEl)
23
- if (!target) {
24
- accept('error', 'Target not found (not parsed/indexed yet)', {
25
- node: el,
26
- property: 'target',
27
- })
28
- }
29
-
30
- if (source && target && (isAncestor(source, target) || isAncestor(target, source))) {
31
- accept('error', 'Invalid parent-child relationship', {
32
- node: el,
33
- })
34
- }
35
- })
36
- }
@@ -1,56 +0,0 @@
1
- import { AstUtils, type ValidationCheck } from 'langium'
2
- import type { ast } from '../ast'
3
- import type { LikeC4Services } from '../module'
4
- import { RESERVED_WORDS, tryOrLog } from './_shared'
5
-
6
- const { getDocument } = AstUtils
7
-
8
- export const elementChecks = (services: LikeC4Services): ValidationCheck<ast.Element> => {
9
- const fqnIndex = services.likec4.FqnIndex
10
- const locator = services.workspace.AstNodeLocator
11
- return tryOrLog((el, accept) => {
12
- const fqn = fqnIndex.getFqn(el)
13
- if (!fqn) {
14
- accept('error', 'Not indexed element', {
15
- node: el,
16
- property: 'name'
17
- })
18
- return
19
- }
20
- if (RESERVED_WORDS.includes(el.name)) {
21
- accept('error', `Reserved word: ${el.name}`, {
22
- node: el,
23
- property: 'name'
24
- })
25
- }
26
- const doc = getDocument(el)
27
- const docUri = doc.uri
28
- const elPath = locator.getAstNodePath(el)
29
- const withSameFqn = fqnIndex
30
- .byFqn(fqn)
31
- .filter(v => v.documentUri !== docUri || v.path !== elPath)
32
- .head()
33
- if (withSameFqn) {
34
- const isAnotherDoc = withSameFqn.documentUri !== docUri
35
- accept(
36
- 'error',
37
- `Duplicate element name ${el.name !== fqn ? el.name + ' (' + fqn + ')' : el.name}`,
38
- {
39
- node: el,
40
- property: 'name',
41
- ...isAnotherDoc && {
42
- relatedInformation: [
43
- {
44
- location: {
45
- range: (withSameFqn.nameSegment?.range ?? withSameFqn.selectionSegment?.range)!,
46
- uri: withSameFqn.documentUri.toString()
47
- },
48
- message: `conflicting element`
49
- }
50
- ]
51
- }
52
- }
53
- )
54
- }
55
- })
56
- }