@likec4/language-server 1.21.1 → 1.22.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 (113) 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 +15 -2
  6. package/dist/bundled.d.ts +8 -0
  7. package/dist/bundled.js +25 -0
  8. package/dist/bundled.mjs +2555 -4022
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js +19 -2
  11. package/dist/logger.d.ts +10 -3
  12. package/dist/logger.js +56 -50
  13. package/dist/model/fqn-computation.js +2 -2
  14. package/dist/model/model-builder.js +13 -14
  15. package/dist/model-change/ModelChanges.js +2 -2
  16. package/dist/module.js +1 -4
  17. package/dist/references/scope-provider.js +3 -3
  18. package/dist/view-utils/manual-layout.js +2 -2
  19. package/dist/views/configurable-layouter.js +4 -4
  20. package/dist/views/likec4-views.d.ts +2 -1
  21. package/dist/views/likec4-views.js +2 -2
  22. package/package.json +14 -12
  23. package/dist/test/setup.d.ts +0 -1
  24. package/dist/test/setup.js +0 -7
  25. package/src/LikeC4FileSystem.ts +0 -38
  26. package/src/Rpc.ts +0 -134
  27. package/src/ast.ts +0 -556
  28. package/src/browser.ts +0 -35
  29. package/src/documentation/documentation-provider.ts +0 -52
  30. package/src/documentation/index.ts +0 -1
  31. package/src/formatting/LikeC4Formatter.ts +0 -639
  32. package/src/formatting/utils.ts +0 -26
  33. package/src/generated/ast.ts +0 -3735
  34. package/src/generated/grammar.ts +0 -10
  35. package/src/generated/module.ts +0 -33
  36. package/src/generated-lib/icons.ts +0 -1538
  37. package/src/index.ts +0 -30
  38. package/src/like-c4.langium +0 -901
  39. package/src/likec4lib.ts +0 -6
  40. package/src/logger.ts +0 -80
  41. package/src/lsp/CodeLensProvider.ts +0 -50
  42. package/src/lsp/CompletionProvider.ts +0 -147
  43. package/src/lsp/DocumentHighlightProvider.ts +0 -12
  44. package/src/lsp/DocumentLinkProvider.ts +0 -65
  45. package/src/lsp/DocumentSymbolProvider.ts +0 -313
  46. package/src/lsp/HoverProvider.ts +0 -92
  47. package/src/lsp/RenameProvider.ts +0 -8
  48. package/src/lsp/SemanticTokenProvider.ts +0 -383
  49. package/src/lsp/index.ts +0 -8
  50. package/src/model/deployments-index.ts +0 -209
  51. package/src/model/fqn-computation.ts +0 -83
  52. package/src/model/fqn-index.ts +0 -138
  53. package/src/model/index.ts +0 -6
  54. package/src/model/model-builder.ts +0 -724
  55. package/src/model/model-locator.ts +0 -146
  56. package/src/model/model-parser-where.ts +0 -84
  57. package/src/model/model-parser.ts +0 -86
  58. package/src/model/parser/Base.ts +0 -113
  59. package/src/model/parser/DeploymentModelParser.ts +0 -192
  60. package/src/model/parser/DeploymentViewParser.ts +0 -122
  61. package/src/model/parser/FqnRefParser.ts +0 -143
  62. package/src/model/parser/GlobalsParser.ts +0 -96
  63. package/src/model/parser/ModelParser.ts +0 -170
  64. package/src/model/parser/PredicatesParser.ts +0 -315
  65. package/src/model/parser/SpecificationParser.ts +0 -133
  66. package/src/model/parser/ViewsParser.ts +0 -428
  67. package/src/model-change/ModelChanges.ts +0 -101
  68. package/src/model-change/changeElementStyle.ts +0 -172
  69. package/src/model-change/changeViewLayout.ts +0 -47
  70. package/src/model-change/saveManualLayout.ts +0 -41
  71. package/src/module.ts +0 -255
  72. package/src/protocol.ts +0 -93
  73. package/src/references/index.ts +0 -3
  74. package/src/references/name-provider.ts +0 -37
  75. package/src/references/scope-computation.ts +0 -364
  76. package/src/references/scope-provider.ts +0 -201
  77. package/src/shared/NodeKindProvider.ts +0 -121
  78. package/src/shared/WorkspaceManager.ts +0 -48
  79. package/src/shared/WorkspaceSymbolProvider.ts +0 -3
  80. package/src/shared/index.ts +0 -3
  81. package/src/test/index.ts +0 -1
  82. package/src/test/setup.ts +0 -8
  83. package/src/test/testServices.ts +0 -152
  84. package/src/utils/disposable.ts +0 -30
  85. package/src/utils/elementRef.ts +0 -26
  86. package/src/utils/fqnRef.ts +0 -56
  87. package/src/utils/index.ts +0 -2
  88. package/src/utils/printDocs.ts +0 -3
  89. package/src/utils/stringHash.ts +0 -6
  90. package/src/validation/_shared.ts +0 -29
  91. package/src/validation/deployment-checks.ts +0 -131
  92. package/src/validation/dynamic-view-rule.ts +0 -23
  93. package/src/validation/dynamic-view-step.ts +0 -36
  94. package/src/validation/element.ts +0 -56
  95. package/src/validation/index.ts +0 -171
  96. package/src/validation/property-checks.ts +0 -52
  97. package/src/validation/relation.ts +0 -63
  98. package/src/validation/specification.ts +0 -205
  99. package/src/validation/view-predicates/element-with.ts +0 -36
  100. package/src/validation/view-predicates/expanded-element.ts +0 -16
  101. package/src/validation/view-predicates/expression-v2.ts +0 -101
  102. package/src/validation/view-predicates/incoming.ts +0 -20
  103. package/src/validation/view-predicates/index.ts +0 -6
  104. package/src/validation/view-predicates/outgoing.ts +0 -20
  105. package/src/validation/view-predicates/relation-with.ts +0 -17
  106. package/src/validation/view.ts +0 -37
  107. package/src/view-utils/assignNavigateTo.ts +0 -31
  108. package/src/view-utils/index.ts +0 -2
  109. package/src/view-utils/manual-layout.ts +0 -116
  110. package/src/view-utils/resolve-relative-paths.ts +0 -90
  111. package/src/views/configurable-layouter.ts +0 -65
  112. package/src/views/index.ts +0 -1
  113. 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
- }