@likec4/language-server 1.46.4 → 1.48.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.
- package/LICENSE +1 -1
- package/browser/package.json +2 -2
- package/browser-worker/package.json +2 -2
- package/bundled/package.json +4 -0
- package/dist/LikeC4LanguageServices.d.mts +4 -0
- package/dist/LikeC4LanguageServices.mjs +3 -0
- package/dist/_chunks/ConfigurableLayouter.mjs +1956 -0
- package/dist/_chunks/LikeC4LanguageServices.d.mts +1978 -0
- package/dist/_chunks/LikeC4LanguageServices.mjs +725 -0
- package/dist/_chunks/ast.d.mts +1444 -0
- package/dist/_chunks/ast.mjs +2375 -0
- package/dist/_chunks/ast2.mjs +176 -0
- package/dist/_chunks/common-exports.mjs +0 -0
- package/dist/_chunks/filesystem.mjs +58 -0
- package/dist/_chunks/grammar.mjs +8 -0
- package/dist/_chunks/icons.mjs +5211 -0
- package/dist/_chunks/libs/@hono/node-server.mjs +436 -0
- package/dist/_chunks/libs/@msgpack/msgpack.mjs +805 -0
- package/dist/_chunks/libs/eventemitter3.mjs +243 -0
- package/dist/_chunks/libs/fast-equals.mjs +446 -0
- package/dist/_chunks/libs/hono.mjs +1829 -0
- package/dist/_chunks/libs/p-queue.mjs +449 -0
- package/dist/_chunks/libs/parse-ms.mjs +36 -0
- package/dist/_chunks/libs/picomatch.mjs +1673 -0
- package/dist/_chunks/libs/pretty-ms.mjs +80 -0
- package/dist/_chunks/libs/remeda.mjs +482 -0
- package/dist/_chunks/libs/strip-indent.mjs +15 -0
- package/dist/_chunks/libs/ufo.mjs +166 -0
- package/dist/_chunks/likec4lib.mjs +9 -0
- package/dist/_chunks/mcp.mjs +33 -0
- package/dist/_chunks/module.mjs +28 -0
- package/dist/_chunks/module2.mjs +6576 -0
- package/dist/_chunks/protocol.d.mts +311 -0
- package/dist/_chunks/protocol.mjs +78 -0
- package/dist/_chunks/rolldown-runtime.mjs +42 -0
- package/dist/ast.d.mts +4 -0
- package/dist/ast.mjs +4 -0
- package/dist/browser-worker.d.mts +1 -0
- package/dist/browser-worker.mjs +6 -0
- package/dist/browser.d.mts +11 -0
- package/dist/browser.mjs +27 -0
- package/dist/bundled.d.mts +28 -0
- package/dist/bundled.mjs +51 -4681
- package/dist/common-exports.d.mts +4 -0
- package/dist/common-exports.mjs +5 -0
- package/dist/filesystem/index.d.mts +4 -0
- package/dist/filesystem/index.mjs +3 -0
- package/dist/generated/ast.d.mts +2 -0
- package/dist/generated/ast.mjs +3 -0
- package/dist/generated/grammar.d.mts +6 -0
- package/dist/generated/grammar.mjs +3 -0
- package/dist/generated/module.d.mts +14 -0
- package/dist/generated/module.mjs +3 -0
- package/dist/generated-lib/icons.d.mts +4 -0
- package/dist/generated-lib/icons.mjs +3 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +48 -0
- package/dist/likec4lib.d.mts +9 -0
- package/dist/likec4lib.mjs +4 -0
- package/dist/mcp/index.d.mts +4 -0
- package/dist/mcp/index.mjs +3 -0
- package/dist/module.d.mts +4 -0
- package/dist/module.mjs +3 -0
- package/dist/protocol.d.mts +2 -0
- package/dist/protocol.mjs +3 -0
- package/likec4lib/package.json +2 -2
- package/package.json +106 -62
- package/protocol/package.json +2 -2
- package/dist/LikeC4LanguageServices.d.ts +0 -109
- package/dist/LikeC4LanguageServices.js +0 -154
- package/dist/Rpc.d.ts +0 -9
- package/dist/Rpc.js +0 -270
- package/dist/ast.d.ts +0 -226
- package/dist/ast.js +0 -264
- package/dist/browser-worker.d.ts +0 -1
- package/dist/browser-worker.js +0 -4
- package/dist/browser.d.ts +0 -11
- package/dist/browser.js +0 -35
- package/dist/bundled.d.ts +0 -8
- package/dist/bundled.js +0 -44
- package/dist/documentation/documentation-provider.d.ts +0 -8
- package/dist/documentation/documentation-provider.js +0 -51
- package/dist/documentation/index.d.ts +0 -1
- package/dist/documentation/index.js +0 -1
- package/dist/empty.d.ts +0 -2
- package/dist/empty.js +0 -2
- package/dist/filesystem/ChokidarWatcher.d.ts +0 -16
- package/dist/filesystem/ChokidarWatcher.js +0 -108
- package/dist/filesystem/FileSystemWatcher.d.ts +0 -19
- package/dist/filesystem/FileSystemWatcher.js +0 -14
- package/dist/filesystem/LikeC4FileSystem.d.ts +0 -3
- package/dist/filesystem/LikeC4FileSystem.js +0 -130
- package/dist/filesystem/index.d.ts +0 -55
- package/dist/filesystem/index.js +0 -29
- package/dist/formatting/LikeC4Formatter.d.ts +0 -59
- package/dist/formatting/LikeC4Formatter.js +0 -637
- package/dist/formatting/utils.d.ts +0 -6
- package/dist/formatting/utils.js +0 -18
- package/dist/generated/ast.d.ts +0 -1411
- package/dist/generated/ast.js +0 -2207
- package/dist/generated/grammar.d.ts +0 -6
- package/dist/generated/grammar.js +0 -7
- package/dist/generated/module.d.ts +0 -14
- package/dist/generated/module.js +0 -27
- package/dist/generated-lib/icons.d.ts +0 -1
- package/dist/generated-lib/icons.js +0 -18
- package/dist/index.d.ts +0 -38
- package/dist/index.js +0 -55
- package/dist/likec4lib.d.ts +0 -6
- package/dist/likec4lib.js +0 -7
- package/dist/logger.d.ts +0 -17
- package/dist/logger.js +0 -81
- package/dist/lsp/CodeActionProvider.d.ts +0 -14
- package/dist/lsp/CodeActionProvider.js +0 -33
- package/dist/lsp/CodeLensProvider.d.ts +0 -9
- package/dist/lsp/CodeLensProvider.js +0 -44
- package/dist/lsp/CompletionProvider.d.ts +0 -11
- package/dist/lsp/CompletionProvider.js +0 -200
- package/dist/lsp/DocumentHighlightProvider.d.ts +0 -9
- package/dist/lsp/DocumentHighlightProvider.js +0 -10
- package/dist/lsp/DocumentLinkProvider.d.ts +0 -11
- package/dist/lsp/DocumentLinkProvider.js +0 -58
- package/dist/lsp/DocumentSymbolProvider.d.ts +0 -33
- package/dist/lsp/DocumentSymbolProvider.js +0 -317
- package/dist/lsp/HoverProvider.d.ts +0 -10
- package/dist/lsp/HoverProvider.js +0 -106
- package/dist/lsp/RenameProvider.d.ts +0 -5
- package/dist/lsp/RenameProvider.js +0 -6
- package/dist/lsp/SemanticTokenProvider.d.ts +0 -12
- package/dist/lsp/SemanticTokenProvider.js +0 -264
- package/dist/lsp/index.d.ts +0 -8
- package/dist/lsp/index.js +0 -9
- package/dist/mcp/MCPServerFactory.d.ts +0 -8
- package/dist/mcp/MCPServerFactory.js +0 -73
- package/dist/mcp/NoopLikeC4MCPServer.d.ts +0 -9
- package/dist/mcp/NoopLikeC4MCPServer.js +0 -17
- package/dist/mcp/interfaces.d.ts +0 -13
- package/dist/mcp/interfaces.js +0 -5
- package/dist/mcp/server/StdioLikeC4MCPServer.d.ts +0 -16
- package/dist/mcp/server/StdioLikeC4MCPServer.js +0 -51
- package/dist/mcp/server/StreamableLikeC4MCPServer.d.ts +0 -16
- package/dist/mcp/server/StreamableLikeC4MCPServer.js +0 -145
- package/dist/mcp/server/WithMCPServer.d.ts +0 -4
- package/dist/mcp/server/WithMCPServer.js +0 -54
- package/dist/mcp/tools/_common.d.ts +0 -88
- package/dist/mcp/tools/_common.js +0 -49
- package/dist/mcp/tools/find-relationships.d.ts +0 -12
- package/dist/mcp/tools/find-relationships.js +0 -150
- package/dist/mcp/tools/list-projects.d.ts +0 -6
- package/dist/mcp/tools/list-projects.js +0 -62
- package/dist/mcp/tools/open-view.d.ts +0 -10
- package/dist/mcp/tools/open-view.js +0 -52
- package/dist/mcp/tools/read-deployment.d.ts +0 -10
- package/dist/mcp/tools/read-deployment.js +0 -150
- package/dist/mcp/tools/read-element.d.ts +0 -10
- package/dist/mcp/tools/read-element.js +0 -218
- package/dist/mcp/tools/read-project-summary.d.ts +0 -8
- package/dist/mcp/tools/read-project-summary.js +0 -176
- package/dist/mcp/tools/read-view.d.ts +0 -10
- package/dist/mcp/tools/read-view.js +0 -203
- package/dist/mcp/tools/search-element.d.ts +0 -8
- package/dist/mcp/tools/search-element.js +0 -177
- package/dist/mcp/utils.d.ts +0 -18
- package/dist/mcp/utils.js +0 -48
- package/dist/model/builder/MergedExtends.d.ts +0 -13
- package/dist/model/builder/MergedExtends.js +0 -74
- package/dist/model/builder/MergedSpecification.d.ts +0 -32
- package/dist/model/builder/MergedSpecification.js +0 -175
- package/dist/model/builder/buildModel.d.ts +0 -16
- package/dist/model/builder/buildModel.js +0 -245
- package/dist/model/deployments-index.d.ts +0 -10
- package/dist/model/deployments-index.js +0 -102
- package/dist/model/fqn-index.d.ts +0 -61
- package/dist/model/fqn-index.js +0 -253
- package/dist/model/index.d.ts +0 -6
- package/dist/model/index.js +0 -6
- package/dist/model/model-builder.d.ts +0 -52
- package/dist/model/model-builder.js +0 -224
- package/dist/model/model-locator.d.ts +0 -39
- package/dist/model/model-locator.js +0 -240
- package/dist/model/model-parser-where.d.ts +0 -4
- package/dist/model/model-parser-where.js +0 -81
- package/dist/model/model-parser.d.ts +0 -645
- package/dist/model/model-parser.js +0 -133
- package/dist/model/parser/Base.d.ts +0 -69
- package/dist/model/parser/Base.js +0 -372
- package/dist/model/parser/DeploymentModelParser.d.ts +0 -71
- package/dist/model/parser/DeploymentModelParser.js +0 -176
- package/dist/model/parser/DeploymentViewParser.d.ts +0 -75
- package/dist/model/parser/DeploymentViewParser.js +0 -86
- package/dist/model/parser/FqnRefParser.d.ts +0 -66
- package/dist/model/parser/FqnRefParser.js +0 -382
- package/dist/model/parser/GlobalsParser.d.ts +0 -109
- package/dist/model/parser/GlobalsParser.js +0 -84
- package/dist/model/parser/ImportsParser.d.ts +0 -46
- package/dist/model/parser/ImportsParser.js +0 -24
- package/dist/model/parser/ModelParser.d.ts +0 -71
- package/dist/model/parser/ModelParser.js +0 -209
- package/dist/model/parser/PredicatesParser.d.ts +0 -75
- package/dist/model/parser/PredicatesParser.js +0 -45
- package/dist/model/parser/SpecificationParser.d.ts +0 -53
- package/dist/model/parser/SpecificationParser.js +0 -113
- package/dist/model/parser/ValueConverter.d.ts +0 -4
- package/dist/model/parser/ValueConverter.js +0 -12
- package/dist/model/parser/ViewsParser.d.ts +0 -112
- package/dist/model/parser/ViewsParser.js +0 -492
- package/dist/model-change/ModelChanges.d.ts +0 -18
- package/dist/model-change/ModelChanges.js +0 -129
- package/dist/model-change/changeElementStyle.d.ts +0 -16
- package/dist/model-change/changeElementStyle.js +0 -134
- package/dist/model-change/changeViewLayout.d.ts +0 -12
- package/dist/model-change/changeViewLayout.js +0 -28
- package/dist/model-change/removeManualLayoutV1.d.ts +0 -7
- package/dist/model-change/removeManualLayoutV1.js +0 -27
- package/dist/module.d.ts +0 -92
- package/dist/module.js +0 -143
- package/dist/protocol.d.ts +0 -284
- package/dist/protocol.js +0 -123
- package/dist/references/index.d.ts +0 -3
- package/dist/references/index.js +0 -3
- package/dist/references/name-provider.d.ts +0 -9
- package/dist/references/name-provider.js +0 -37
- package/dist/references/scope-computation.d.ts +0 -20
- package/dist/references/scope-computation.js +0 -288
- package/dist/references/scope-provider.d.ts +0 -40
- package/dist/references/scope-provider.js +0 -239
- package/dist/shared/NodeKindProvider.d.ts +0 -15
- package/dist/shared/NodeKindProvider.js +0 -57
- package/dist/shared/WorkspaceSymbolProvider.d.ts +0 -3
- package/dist/shared/WorkspaceSymbolProvider.js +0 -3
- package/dist/shared/index.d.ts +0 -2
- package/dist/shared/index.js +0 -2
- package/dist/test/index.d.ts +0 -1
- package/dist/test/index.js +0 -1
- package/dist/test/testServices.d.ts +0 -64
- package/dist/test/testServices.js +0 -210
- package/dist/utils/disposable.d.ts +0 -8
- package/dist/utils/disposable.js +0 -26
- package/dist/utils/elementRef.d.ts +0 -11
- package/dist/utils/elementRef.js +0 -27
- package/dist/utils/fqnRef.d.ts +0 -11
- package/dist/utils/fqnRef.js +0 -63
- package/dist/utils/index.d.ts +0 -11
- package/dist/utils/index.js +0 -35
- package/dist/utils/printDocs.d.ts +0 -2
- package/dist/utils/printDocs.js +0 -1
- package/dist/utils/projectId.d.ts +0 -4
- package/dist/utils/projectId.js +0 -16
- package/dist/utils/stringHash.d.ts +0 -1
- package/dist/utils/stringHash.js +0 -5
- package/dist/validation/DocumentValidator.d.ts +0 -11
- package/dist/validation/DocumentValidator.js +0 -17
- package/dist/validation/_shared.d.ts +0 -3
- package/dist/validation/_shared.js +0 -26
- package/dist/validation/deployment-checks.d.ts +0 -7
- package/dist/validation/deployment-checks.js +0 -140
- package/dist/validation/dynamic-view.d.ts +0 -6
- package/dist/validation/dynamic-view.js +0 -67
- package/dist/validation/element-ref.d.ts +0 -4
- package/dist/validation/element-ref.js +0 -12
- package/dist/validation/element.d.ts +0 -4
- package/dist/validation/element.js +0 -49
- package/dist/validation/imports.d.ts +0 -4
- package/dist/validation/imports.js +0 -46
- package/dist/validation/index.d.ts +0 -15
- package/dist/validation/index.js +0 -167
- package/dist/validation/property-checks.d.ts +0 -7
- package/dist/validation/property-checks.js +0 -108
- package/dist/validation/relation.d.ts +0 -6
- package/dist/validation/relation.js +0 -141
- package/dist/validation/specification.d.ts +0 -12
- package/dist/validation/specification.js +0 -190
- package/dist/validation/view-checks.d.ts +0 -4
- package/dist/validation/view-checks.js +0 -46
- package/dist/validation/view-predicates/fqn-expr-with.d.ts +0 -4
- package/dist/validation/view-predicates/fqn-expr-with.js +0 -43
- package/dist/validation/view-predicates/fqn-ref-expr.d.ts +0 -4
- package/dist/validation/view-predicates/fqn-ref-expr.js +0 -51
- package/dist/validation/view-predicates/incoming.d.ts +0 -4
- package/dist/validation/view-predicates/incoming.js +0 -16
- package/dist/validation/view-predicates/index.d.ts +0 -6
- package/dist/validation/view-predicates/index.js +0 -6
- package/dist/validation/view-predicates/outgoing.d.ts +0 -4
- package/dist/validation/view-predicates/outgoing.js +0 -20
- package/dist/validation/view-predicates/relation-expr.d.ts +0 -4
- package/dist/validation/view-predicates/relation-expr.js +0 -46
- package/dist/validation/view-predicates/relation-with.d.ts +0 -4
- package/dist/validation/view-predicates/relation-with.js +0 -16
- package/dist/validation/view.d.ts +0 -4
- package/dist/validation/view.js +0 -42
- package/dist/view-utils/assignNavigateTo.d.ts +0 -2
- package/dist/view-utils/assignNavigateTo.js +0 -27
- package/dist/view-utils/index.d.ts +0 -2
- package/dist/view-utils/index.js +0 -2
- package/dist/view-utils/manual-layout.d.ts +0 -13
- package/dist/view-utils/manual-layout.js +0 -149
- package/dist/views/ConfigurableLayouter.d.ts +0 -7
- package/dist/views/ConfigurableLayouter.js +0 -51
- package/dist/views/LikeC4ManualLayouts.d.ts +0 -42
- package/dist/views/LikeC4ManualLayouts.js +0 -209
- package/dist/views/LikeC4Views.d.ts +0 -89
- package/dist/views/LikeC4Views.js +0 -216
- package/dist/views/index.d.ts +0 -4
- package/dist/views/index.js +0 -11
- package/dist/workspace/AstNodeDescriptionProvider.d.ts +0 -7
- package/dist/workspace/AstNodeDescriptionProvider.js +0 -18
- package/dist/workspace/IndexManager.d.ts +0 -10
- package/dist/workspace/IndexManager.js +0 -26
- package/dist/workspace/LangiumDocuments.d.ts +0 -25
- package/dist/workspace/LangiumDocuments.js +0 -98
- package/dist/workspace/ProjectsManager.d.ts +0 -130
- package/dist/workspace/ProjectsManager.js +0 -605
- package/dist/workspace/WorkspaceManager.d.ts +0 -31
- package/dist/workspace/WorkspaceManager.js +0 -132
- package/dist/workspace/index.d.ts +0 -5
- package/dist/workspace/index.js +0 -5
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { type LayoutedView, type ProjectId, type UnknownComputed, type UnknownParsed, type ViewId } from '@likec4/core';
|
|
2
|
-
import { LikeC4Model } from '@likec4/core/model';
|
|
3
|
-
import type * as c4 from '@likec4/core/types';
|
|
4
|
-
import { type URI, Disposable } from 'langium';
|
|
5
|
-
import type { CancellationToken } from 'vscode-jsonrpc';
|
|
6
|
-
import type { LikeC4Services } from '../module';
|
|
7
|
-
import { ADisposable } from '../utils';
|
|
8
|
-
type ModelParsedListener = (docs: URI[]) => void;
|
|
9
|
-
type ManualLayouts = Record<ViewId, LayoutedView> | null;
|
|
10
|
-
export interface LikeC4ModelBuilder extends Disposable {
|
|
11
|
-
parseModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownParsed> | null>;
|
|
12
|
-
unsafeSyncComputeModel(projectId: ProjectId): LikeC4Model<UnknownComputed>;
|
|
13
|
-
computeModel(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownComputed>>;
|
|
14
|
-
onModelParsed(callback: ModelParsedListener): Disposable;
|
|
15
|
-
clearCache(): void;
|
|
16
|
-
}
|
|
17
|
-
export declare class DefaultLikeC4ModelBuilder extends ADisposable implements LikeC4ModelBuilder {
|
|
18
|
-
private projects;
|
|
19
|
-
private parser;
|
|
20
|
-
private listeners;
|
|
21
|
-
private cache;
|
|
22
|
-
private DocumentBuilder;
|
|
23
|
-
private manualLayouts;
|
|
24
|
-
private mutex;
|
|
25
|
-
constructor(services: LikeC4Services);
|
|
26
|
-
/**
|
|
27
|
-
* WARNING:
|
|
28
|
-
* This method is internal and should to be called only when all documents are known to be parsed.
|
|
29
|
-
* Otherwise, the model may be incomplete.
|
|
30
|
-
*
|
|
31
|
-
* To avoid circular dependencies, we do not resolve imports here.
|
|
32
|
-
*/
|
|
33
|
-
private unsafeSyncParseModelData;
|
|
34
|
-
/**
|
|
35
|
-
* To avoid circular dependencies, first we parse all documents and then we join them.
|
|
36
|
-
*/
|
|
37
|
-
private unsafeSyncJoinedModel;
|
|
38
|
-
parseModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownParsed> | null>;
|
|
39
|
-
private previousViews;
|
|
40
|
-
/**
|
|
41
|
-
* WARNING:
|
|
42
|
-
* This method is internal and should to be called only when all documents are known to be parsed.
|
|
43
|
-
* Otherwise, the model may be incomplete.
|
|
44
|
-
*/
|
|
45
|
-
unsafeSyncComputeModel(projectId: c4.ProjectId, manualLayouts?: ManualLayouts): LikeC4Model<UnknownComputed>;
|
|
46
|
-
computeModel(projectId?: c4.ProjectId | undefined, cancelToken?: CancellationToken): Promise<LikeC4Model<UnknownComputed>>;
|
|
47
|
-
onModelParsed(callback: ModelParsedListener): Disposable;
|
|
48
|
-
clearCache(): void;
|
|
49
|
-
private documents;
|
|
50
|
-
private notifyListeners;
|
|
51
|
-
}
|
|
52
|
-
export {};
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { _stage, } from '@likec4/core';
|
|
2
|
-
import { computeView } from '@likec4/core/compute-view';
|
|
3
|
-
import { LikeC4Model } from '@likec4/core/model';
|
|
4
|
-
import { loggable } from '@likec4/log';
|
|
5
|
-
import { deepEqual as eq } from 'fast-equals';
|
|
6
|
-
import { Disposable, DocumentState, interruptAndCheck, WorkspaceCache, } from 'langium';
|
|
7
|
-
import { flatMap, hasAtLeast, isEmpty, mapToObj, pipe, values, } from 'remeda';
|
|
8
|
-
import { isLikeC4Builtin } from '../likec4lib';
|
|
9
|
-
import { logger as mainLogger } from '../logger';
|
|
10
|
-
import { ADisposable, performanceMark } from '../utils';
|
|
11
|
-
import { assignNavigateTo } from '../view-utils';
|
|
12
|
-
import { buildModelData } from './builder/buildModel';
|
|
13
|
-
const parsedWithoutImportsCacheKey = (projectId) => `parsed-without-imports-${projectId}`;
|
|
14
|
-
const parsedModelCacheKey = (projectId) => `parsed-model-${projectId}`;
|
|
15
|
-
const computedModelCacheKey = (projectId) => `computed-model-${projectId}`;
|
|
16
|
-
const builderLogger = mainLogger.getChild('model-builder');
|
|
17
|
-
export class DefaultLikeC4ModelBuilder extends ADisposable {
|
|
18
|
-
projects;
|
|
19
|
-
parser;
|
|
20
|
-
listeners = [];
|
|
21
|
-
cache;
|
|
22
|
-
DocumentBuilder;
|
|
23
|
-
manualLayouts;
|
|
24
|
-
mutex;
|
|
25
|
-
constructor(services) {
|
|
26
|
-
super();
|
|
27
|
-
this.projects = services.shared.workspace.ProjectsManager;
|
|
28
|
-
this.parser = services.likec4.ModelParser;
|
|
29
|
-
this.cache = services.shared.workspace.Cache;
|
|
30
|
-
this.DocumentBuilder = services.shared.workspace.DocumentBuilder;
|
|
31
|
-
this.mutex = services.shared.workspace.WorkspaceLock;
|
|
32
|
-
this.manualLayouts = services.likec4.ManualLayouts;
|
|
33
|
-
this.onDispose(this.DocumentBuilder.onUpdate((_changed, deleted) => {
|
|
34
|
-
if (deleted.length > 0) {
|
|
35
|
-
this.notifyListeners(deleted);
|
|
36
|
-
}
|
|
37
|
-
}));
|
|
38
|
-
this.onDispose(this.DocumentBuilder.onBuildPhase(DocumentState.Validated, (docs, _cancelToken) => {
|
|
39
|
-
const validated = docs.flatMap(d => isLikeC4Builtin(d.uri) || this.projects.isExcluded(d) ? [] : d.uri);
|
|
40
|
-
if (validated.length > 0) {
|
|
41
|
-
this.notifyListeners(validated);
|
|
42
|
-
}
|
|
43
|
-
}));
|
|
44
|
-
builderLogger.debug `created`;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* WARNING:
|
|
48
|
-
* This method is internal and should to be called only when all documents are known to be parsed.
|
|
49
|
-
* Otherwise, the model may be incomplete.
|
|
50
|
-
*
|
|
51
|
-
* To avoid circular dependencies, we do not resolve imports here.
|
|
52
|
-
*/
|
|
53
|
-
unsafeSyncParseModelData(projectId) {
|
|
54
|
-
const cache = this.cache;
|
|
55
|
-
const logger = builderLogger.getChild(projectId);
|
|
56
|
-
const key = parsedWithoutImportsCacheKey(projectId);
|
|
57
|
-
if (cache.has(key)) {
|
|
58
|
-
logger.debug `unsafeSyncParseModelData: from cache`;
|
|
59
|
-
}
|
|
60
|
-
return cache.get(key, () => {
|
|
61
|
-
try {
|
|
62
|
-
const project = this.projects.getProject(projectId);
|
|
63
|
-
const docs = this.documents(projectId);
|
|
64
|
-
if (docs.length === 0) {
|
|
65
|
-
logger.debug `unsafeSyncParseModelData: skipped due to no documents`;
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
logger.debug `unsafeSyncParseModelData: completed`;
|
|
69
|
-
return buildModelData(project, docs);
|
|
70
|
-
}
|
|
71
|
-
catch (err) {
|
|
72
|
-
builderLogger.warn(`unsafeSyncParseModelData failed for project ${projectId}`, { err });
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* To avoid circular dependencies, first we parse all documents and then we join them.
|
|
79
|
-
*/
|
|
80
|
-
unsafeSyncJoinedModel(projectId) {
|
|
81
|
-
const logger = builderLogger.getChild(projectId);
|
|
82
|
-
const cache = this.cache;
|
|
83
|
-
const key = parsedModelCacheKey(projectId);
|
|
84
|
-
if (cache.has(key)) {
|
|
85
|
-
logger.debug `unsafeSyncJoinedModel from cache`;
|
|
86
|
-
}
|
|
87
|
-
return cache.get(key, () => {
|
|
88
|
-
const result = this.unsafeSyncParseModelData(projectId);
|
|
89
|
-
if (!result) {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
let parsedData = result.data;
|
|
93
|
-
if (result.imports.size > 0) {
|
|
94
|
-
logger.debug `processing imports of ${projectId}`;
|
|
95
|
-
const imports = [...result.imports.associations()].reduce((acc, [projectId, fqns]) => {
|
|
96
|
-
const anotherProject = this.unsafeSyncParseModelData(projectId);
|
|
97
|
-
if (anotherProject) {
|
|
98
|
-
const imported = pipe([...fqns], flatMap(fqn => anotherProject.data.elements[fqn] ?? []));
|
|
99
|
-
if (hasAtLeast(imported, 1)) {
|
|
100
|
-
acc[projectId] = imported;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return acc;
|
|
104
|
-
}, {});
|
|
105
|
-
parsedData = {
|
|
106
|
-
...result.data,
|
|
107
|
-
imports,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
return LikeC4Model.create(parsedData);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
async parseModel(projectId, cancelToken) {
|
|
114
|
-
projectId = this.projects.ensureProjectId(projectId);
|
|
115
|
-
const logger = builderLogger.getChild(projectId);
|
|
116
|
-
const t0 = performanceMark();
|
|
117
|
-
return await this.mutex.read(async () => {
|
|
118
|
-
if (cancelToken?.isCancellationRequested) {
|
|
119
|
-
await interruptAndCheck(cancelToken);
|
|
120
|
-
}
|
|
121
|
-
const parsedModel = this.unsafeSyncJoinedModel(projectId);
|
|
122
|
-
logger.debug `parseModel in ${t0.pretty}`;
|
|
123
|
-
return parsedModel;
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
previousViews = {};
|
|
127
|
-
/**
|
|
128
|
-
* WARNING:
|
|
129
|
-
* This method is internal and should to be called only when all documents are known to be parsed.
|
|
130
|
-
* Otherwise, the model may be incomplete.
|
|
131
|
-
*/
|
|
132
|
-
unsafeSyncComputeModel(projectId, manualLayouts) {
|
|
133
|
-
const logger = builderLogger.getChild(projectId);
|
|
134
|
-
const cache = this.cache;
|
|
135
|
-
const hasManualLayouts = !!manualLayouts && !isEmpty(manualLayouts);
|
|
136
|
-
const key = computedModelCacheKey(projectId) + (hasManualLayouts ? '+manualLayouts' : '');
|
|
137
|
-
if (cache.has(key)) {
|
|
138
|
-
logger.debug `unsafeSyncBuildModel: from cache`;
|
|
139
|
-
}
|
|
140
|
-
return cache.get(key, () => {
|
|
141
|
-
const parsedModel = this.unsafeSyncJoinedModel(projectId);
|
|
142
|
-
if (!parsedModel) {
|
|
143
|
-
return LikeC4Model.EMPTY.asComputed;
|
|
144
|
-
}
|
|
145
|
-
const allViews = [];
|
|
146
|
-
for (const view of values(parsedModel.$data.views)) {
|
|
147
|
-
const result = computeView(view, parsedModel);
|
|
148
|
-
if (!result.isSuccess) {
|
|
149
|
-
logger.warn(loggable(result.error));
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
if (manualLayouts?.[view.id]) {
|
|
153
|
-
Object.assign(result.view,
|
|
154
|
-
// satisfies enforces that the object has the property
|
|
155
|
-
{ hasManualLayout: true });
|
|
156
|
-
}
|
|
157
|
-
allViews.push(result.view);
|
|
158
|
-
}
|
|
159
|
-
assignNavigateTo(allViews);
|
|
160
|
-
const views = mapToObj(allViews, v => {
|
|
161
|
-
const key = computedViewKey(projectId, v.id);
|
|
162
|
-
const previous = this.previousViews[key];
|
|
163
|
-
const view = previous && eq(v, previous) ? previous : v;
|
|
164
|
-
this.previousViews[key] = view;
|
|
165
|
-
return [v.id, view];
|
|
166
|
-
});
|
|
167
|
-
const data = {
|
|
168
|
-
...parsedModel.$data,
|
|
169
|
-
[_stage]: 'computed',
|
|
170
|
-
views,
|
|
171
|
-
};
|
|
172
|
-
if (hasManualLayouts) {
|
|
173
|
-
data.manualLayouts = manualLayouts;
|
|
174
|
-
}
|
|
175
|
-
logger.debug `unsafeSyncBuildModel: completed`;
|
|
176
|
-
return LikeC4Model.create(data);
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
async computeModel(projectId, cancelToken) {
|
|
180
|
-
projectId = this.projects.ensureProjectId(projectId);
|
|
181
|
-
const logger = builderLogger.getChild(projectId);
|
|
182
|
-
const t0 = performanceMark();
|
|
183
|
-
return await this.mutex.read(async () => {
|
|
184
|
-
if (cancelToken?.isCancellationRequested) {
|
|
185
|
-
await interruptAndCheck(cancelToken);
|
|
186
|
-
}
|
|
187
|
-
const project = this.projects.getProject(projectId);
|
|
188
|
-
const manualLayouts = await this.manualLayouts.read(project);
|
|
189
|
-
const result = this.unsafeSyncComputeModel(projectId, manualLayouts);
|
|
190
|
-
logger.debug(`computeModel in ${t0.pretty}`);
|
|
191
|
-
return result;
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
onModelParsed(callback) {
|
|
195
|
-
this.listeners.push(callback);
|
|
196
|
-
return Disposable.create(() => {
|
|
197
|
-
const index = this.listeners.indexOf(callback);
|
|
198
|
-
if (index >= 0) {
|
|
199
|
-
this.listeners.splice(index, 1);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
clearCache() {
|
|
204
|
-
builderLogger.debug(`clearCache`);
|
|
205
|
-
this.cache.clear();
|
|
206
|
-
this.previousViews = {};
|
|
207
|
-
}
|
|
208
|
-
documents(projectId) {
|
|
209
|
-
return this.parser.documents(projectId).toArray();
|
|
210
|
-
}
|
|
211
|
-
notifyListeners(docs) {
|
|
212
|
-
for (const listener of this.listeners) {
|
|
213
|
-
try {
|
|
214
|
-
listener(docs);
|
|
215
|
-
}
|
|
216
|
-
catch (e) {
|
|
217
|
-
builderLogger.warn(loggable(e));
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
function computedViewKey(projectId, viewId) {
|
|
223
|
-
return `computed-view-${projectId}-${viewId}`;
|
|
224
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type * as c4 from '@likec4/core';
|
|
2
|
-
import type { Cancellation } from 'langium';
|
|
3
|
-
import type { Location, Range } from 'vscode-languageserver-types';
|
|
4
|
-
import { URI } from 'vscode-uri';
|
|
5
|
-
import type { ParsedAstElement, ParsedAstView, ParsedLikeC4LangiumDocument } from '../ast';
|
|
6
|
-
import { ast } from '../ast';
|
|
7
|
-
import type { LikeC4Services } from '../module';
|
|
8
|
-
export type ViewLocateResult = {
|
|
9
|
-
doc: ParsedLikeC4LangiumDocument;
|
|
10
|
-
view: ParsedAstView;
|
|
11
|
-
viewAst: ast.LikeC4View;
|
|
12
|
-
};
|
|
13
|
-
export declare class LikeC4ModelLocator {
|
|
14
|
-
private services;
|
|
15
|
-
private fqnIndex;
|
|
16
|
-
private deploymentsIndex;
|
|
17
|
-
private langiumDocuments;
|
|
18
|
-
private parser;
|
|
19
|
-
private projects;
|
|
20
|
-
constructor(services: LikeC4Services);
|
|
21
|
-
private documents;
|
|
22
|
-
getParsedElement(...args: [ast.Element] | [c4.Fqn] | [c4.Fqn, c4.ProjectId]): ParsedAstElement | null;
|
|
23
|
-
locateElement(fqn: c4.Fqn, projectId?: c4.ProjectId | undefined): Location | null;
|
|
24
|
-
locateDeploymentElement(deploymentFqn: c4.DeploymentFqn, projectId?: c4.ProjectId | undefined): Location | null;
|
|
25
|
-
locateRelation(relationId: c4.RelationId, projectId?: c4.ProjectId): Location | null;
|
|
26
|
-
locateViewAst(viewId: c4.ViewId, projectId?: c4.ProjectId | undefined): null | ViewLocateResult;
|
|
27
|
-
locateView(viewId: c4.ViewId, projectId?: c4.ProjectId): Location | null;
|
|
28
|
-
locateDocumentTags(documentUri: URI, cancelToken?: Cancellation.CancellationToken): Promise<Array<{
|
|
29
|
-
name: string;
|
|
30
|
-
color: string;
|
|
31
|
-
range: Range;
|
|
32
|
-
isSpecification: boolean;
|
|
33
|
-
}>>;
|
|
34
|
-
locateDynamicViewStep(params: {
|
|
35
|
-
view: c4.ViewId;
|
|
36
|
-
astPath: string;
|
|
37
|
-
projectId?: c4.ProjectId | undefined;
|
|
38
|
-
}): Location | null;
|
|
39
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
import { splitGlobalFqn } from '@likec4/core';
|
|
2
|
-
import { ifilter, invariant, toArray } from '@likec4/core/utils';
|
|
3
|
-
import { loggable } from '@likec4/log';
|
|
4
|
-
import { AstUtils, DocumentState, GrammarUtils } from 'langium';
|
|
5
|
-
import { flatMap, isString, pipe } from 'remeda';
|
|
6
|
-
import { URI } from 'vscode-uri';
|
|
7
|
-
import { ast, isLikeC4LangiumDocument } from '../ast';
|
|
8
|
-
import { logger as serverLogger } from '../logger';
|
|
9
|
-
import { projectIdFrom } from '../utils';
|
|
10
|
-
import { MergedSpecification } from './builder/MergedSpecification';
|
|
11
|
-
const { findNodeForKeyword, findNodeForProperty } = GrammarUtils;
|
|
12
|
-
const { getDocument, streamAllContents } = AstUtils;
|
|
13
|
-
const logger = serverLogger.getChild('ModelLocator');
|
|
14
|
-
export class LikeC4ModelLocator {
|
|
15
|
-
services;
|
|
16
|
-
fqnIndex;
|
|
17
|
-
deploymentsIndex;
|
|
18
|
-
langiumDocuments;
|
|
19
|
-
parser;
|
|
20
|
-
projects;
|
|
21
|
-
constructor(services) {
|
|
22
|
-
this.services = services;
|
|
23
|
-
this.fqnIndex = services.likec4.FqnIndex;
|
|
24
|
-
this.deploymentsIndex = services.likec4.DeploymentsIndex;
|
|
25
|
-
this.langiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
26
|
-
this.parser = services.likec4.ModelParser;
|
|
27
|
-
this.projects = services.shared.workspace.ProjectsManager;
|
|
28
|
-
}
|
|
29
|
-
documents(projectId) {
|
|
30
|
-
return this.parser.documents(projectId);
|
|
31
|
-
}
|
|
32
|
-
// public getParsedElement(astNodeOrFqn: ast.Element): ParsedAstElement | null
|
|
33
|
-
// public getParsedElement(astNodeOrFqn: c4.Fqn, projectId?: c4.ProjectId): ParsedAstElement | null
|
|
34
|
-
getParsedElement(...args) {
|
|
35
|
-
let astNodeOrFqn;
|
|
36
|
-
let projectId;
|
|
37
|
-
if (args.length === 2) {
|
|
38
|
-
astNodeOrFqn = args[0];
|
|
39
|
-
projectId = args[1];
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
astNodeOrFqn = args[0];
|
|
43
|
-
projectId = isString(astNodeOrFqn) ? this.projects.ensureProjectId() : projectIdFrom(astNodeOrFqn);
|
|
44
|
-
}
|
|
45
|
-
if (isString(astNodeOrFqn)) {
|
|
46
|
-
const fqn = astNodeOrFqn;
|
|
47
|
-
const entry = this.fqnIndex.byFqn(projectId, fqn).head();
|
|
48
|
-
if (!entry) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
const doc = this.langiumDocuments.getDocument(entry.documentUri);
|
|
52
|
-
if (!doc) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
return this.parser.parse(doc).c4Elements.find(e => e.id === fqn) ?? null;
|
|
56
|
-
}
|
|
57
|
-
const fqn = this.fqnIndex.getFqn(astNodeOrFqn);
|
|
58
|
-
const doc = this.parser.parse(getDocument(astNodeOrFqn));
|
|
59
|
-
return doc.c4Elements.find(e => e.id === fqn) ?? null;
|
|
60
|
-
}
|
|
61
|
-
locateElement(fqn, projectId) {
|
|
62
|
-
let [_projectId, _fqn] = splitGlobalFqn(fqn);
|
|
63
|
-
_projectId ??= this.projects.ensureProjectId(projectId);
|
|
64
|
-
const entry = this.fqnIndex.byFqn(_projectId, _fqn).head();
|
|
65
|
-
const docsegment = entry?.nameSegment ?? entry?.selectionSegment;
|
|
66
|
-
if (!entry || !docsegment) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
return {
|
|
70
|
-
uri: entry.documentUri.toString(),
|
|
71
|
-
range: docsegment.range,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
locateDeploymentElement(deploymentFqn, projectId) {
|
|
75
|
-
// let [_projectId, _fqn] = splitGlobalFqn(fqn)
|
|
76
|
-
const _projectId = this.projects.ensureProjectId(projectId);
|
|
77
|
-
// TODO: remove this cast to Fqn
|
|
78
|
-
const fqn = deploymentFqn;
|
|
79
|
-
const entry = this.deploymentsIndex.byFqn(_projectId, fqn).head();
|
|
80
|
-
const docsegment = entry?.nameSegment ?? entry?.selectionSegment;
|
|
81
|
-
if (!entry || !docsegment) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
uri: entry.documentUri.toString(),
|
|
86
|
-
range: docsegment.range,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
locateRelation(relationId, projectId) {
|
|
90
|
-
const project = this.projects.ensureProjectId(projectId);
|
|
91
|
-
for (const doc of this.documents(project)) {
|
|
92
|
-
const relation = doc.c4Relations.find(r => r.id === relationId)
|
|
93
|
-
?? doc.c4DeploymentRelations.find(r => r.id === relationId);
|
|
94
|
-
if (!relation) {
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
const node = this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, relation.astPath);
|
|
98
|
-
if (!ast.isRelation(node) && !ast.isDeploymentRelation(node)) {
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
let targetNode = node.kind ? findNodeForProperty(node.$cstNode, 'kind') : undefined;
|
|
102
|
-
targetNode ??= node.dotKind ? findNodeForProperty(node.$cstNode, 'dotKind') : undefined;
|
|
103
|
-
targetNode ??= findNodeForKeyword(node.$cstNode, '->');
|
|
104
|
-
targetNode ??= findNodeForProperty(node.$cstNode, 'title');
|
|
105
|
-
targetNode ??= findNodeForProperty(node.$cstNode, 'target');
|
|
106
|
-
targetNode ??= node.$cstNode;
|
|
107
|
-
if (!targetNode) {
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
uri: doc.uri.toString(),
|
|
112
|
-
range: {
|
|
113
|
-
start: targetNode.range.start,
|
|
114
|
-
end: targetNode.range.start,
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
locateViewAst(viewId, projectId) {
|
|
121
|
-
const project = this.projects.ensureProjectId(projectId);
|
|
122
|
-
for (const doc of this.documents(project)) {
|
|
123
|
-
const view = doc.c4Views.find(r => r.id === viewId);
|
|
124
|
-
if (!view) {
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
const viewAst = this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, view.astPath);
|
|
128
|
-
if (ast.isLikeC4View(viewAst)) {
|
|
129
|
-
return {
|
|
130
|
-
doc,
|
|
131
|
-
view,
|
|
132
|
-
viewAst,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
locateView(viewId, projectId) {
|
|
139
|
-
const res = this.locateViewAst(viewId, projectId);
|
|
140
|
-
if (!res) {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
const node = res.viewAst;
|
|
144
|
-
let targetNode = node.name ? findNodeForProperty(node.$cstNode, 'name') : undefined;
|
|
145
|
-
targetNode ??= findNodeForKeyword(node.$cstNode, 'view');
|
|
146
|
-
targetNode ??= node.$cstNode;
|
|
147
|
-
if (!targetNode) {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
return {
|
|
151
|
-
uri: res.doc.uri.toString(),
|
|
152
|
-
range: {
|
|
153
|
-
start: targetNode.range.start,
|
|
154
|
-
end: targetNode.range.start,
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
async locateDocumentTags(documentUri, cancelToken) {
|
|
159
|
-
const doc = this.langiumDocuments.getDocument(documentUri);
|
|
160
|
-
if (!doc || !isLikeC4LangiumDocument(doc)) {
|
|
161
|
-
return [];
|
|
162
|
-
}
|
|
163
|
-
if (doc.state < DocumentState.Validated) {
|
|
164
|
-
logger.debug(`Waiting for document ${doc.uri.path} to be Validated`);
|
|
165
|
-
await this.services.shared.workspace.DocumentBuilder.waitUntil(DocumentState.Validated, doc.uri, cancelToken);
|
|
166
|
-
}
|
|
167
|
-
const projectId = projectIdFrom(doc);
|
|
168
|
-
logger.debug(`locate document tags for ${doc.uri.path} in project ${projectId}`);
|
|
169
|
-
try {
|
|
170
|
-
const tagSpecs = new MergedSpecification(this.documents(projectId).toArray()).tags;
|
|
171
|
-
logger.debug(`Assigned colors to tags`, { tagSpecs });
|
|
172
|
-
const tags = pipe(streamAllContents(doc.parseResult.value), ifilter(astNode => ast.isTag(astNode) || ast.isTagRef(astNode)), toArray(), flatMap(tagRef => {
|
|
173
|
-
let name;
|
|
174
|
-
let $cstNode;
|
|
175
|
-
try {
|
|
176
|
-
if (ast.isTag(tagRef)) {
|
|
177
|
-
name = tagRef.name;
|
|
178
|
-
$cstNode = tagRef.$cstNode;
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
name = tagRef.tag.$refText;
|
|
182
|
-
$cstNode = tagRef.tag.$refNode;
|
|
183
|
-
}
|
|
184
|
-
const specification = tagSpecs[name];
|
|
185
|
-
invariant(specification, `Tag ${name} not found in merged specification`);
|
|
186
|
-
invariant($cstNode, `Tag ${name} does not have a $cstNode`);
|
|
187
|
-
return {
|
|
188
|
-
name,
|
|
189
|
-
color: specification.color,
|
|
190
|
-
range: $cstNode.range,
|
|
191
|
-
isSpecification: ast.isTag(tagRef),
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
catch (err) {
|
|
195
|
-
logger.warn(`Fail on tag ${name}`, { err });
|
|
196
|
-
return [];
|
|
197
|
-
}
|
|
198
|
-
}));
|
|
199
|
-
logger.debug(`Found ${tags.length} tags in document ${doc.uri.path}`);
|
|
200
|
-
return tags;
|
|
201
|
-
}
|
|
202
|
-
catch (e) {
|
|
203
|
-
logger.warn(loggable(e));
|
|
204
|
-
return [];
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
locateDynamicViewStep(params) {
|
|
208
|
-
const { doc, viewAst } = this.locateViewAst(params.view, params.projectId) ?? {};
|
|
209
|
-
if (!doc || !viewAst) {
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
if (!ast.isDynamicView(viewAst) || !viewAst.body) {
|
|
213
|
-
logger.warn(`View ${params.view} is not a dynamic view`);
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
216
|
-
const astPath = this.services.workspace.AstNodeLocator.getAstNodePath(viewAst.body) + params.astPath;
|
|
217
|
-
const node = this.services.workspace.AstNodeLocator.getAstNode(doc.parseResult.value, astPath);
|
|
218
|
-
if (!node || !ast.isDynamicViewStep(node)) {
|
|
219
|
-
logger.warn(`Failed to locate dynamic view step ${astPath} in view ${params.view}`);
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
let targetNode = node.kind ? findNodeForProperty(node.$cstNode, 'kind') : undefined;
|
|
223
|
-
targetNode ??= node.dotKind ? findNodeForProperty(node.$cstNode, 'dotKind') : undefined;
|
|
224
|
-
targetNode ??= findNodeForKeyword(node.$cstNode, '->');
|
|
225
|
-
targetNode ??= findNodeForKeyword(node.$cstNode, '<-');
|
|
226
|
-
targetNode ??= findNodeForProperty(node.$cstNode, 'title');
|
|
227
|
-
targetNode ??= findNodeForProperty(node.$cstNode, 'target');
|
|
228
|
-
targetNode ??= node.$cstNode;
|
|
229
|
-
if (!targetNode) {
|
|
230
|
-
return null;
|
|
231
|
-
}
|
|
232
|
-
return {
|
|
233
|
-
uri: doc.uri.toString(),
|
|
234
|
-
range: {
|
|
235
|
-
start: targetNode.range.start,
|
|
236
|
-
end: targetNode.range.start,
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type * as c4 from '@likec4/core';
|
|
2
|
-
import { ast } from '../ast';
|
|
3
|
-
export declare function parseWhereClause(astNode: ast.WhereExpression): c4.WhereOperator;
|
|
4
|
-
export declare function createBinaryOperator(operator: Lowercase<ast.WhereBinaryExpression['operator']>, left: c4.WhereOperator, right: c4.WhereOperator | null): c4.WhereOperator;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { invariant, isAndOperator, isNonEmptyArray, isOrOperator, nonexhaustive } from '@likec4/core';
|
|
2
|
-
import { ast } from '../ast';
|
|
3
|
-
const parseEquals = ({ operator, not }, value) => {
|
|
4
|
-
if (operator.startsWith('!=')) {
|
|
5
|
-
return {
|
|
6
|
-
neq: value,
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
if (operator.startsWith('=')) {
|
|
10
|
-
return {
|
|
11
|
-
eq: value,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
return not ? { neq: value } : { eq: value };
|
|
15
|
-
};
|
|
16
|
-
function parseParticipant(astNode) {
|
|
17
|
-
if (!ast.isWhereRelationParticipantKind(astNode) && !ast.isWhereRelationParticipantTag(astNode)) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
return astNode.participant;
|
|
21
|
-
}
|
|
22
|
-
export function parseWhereClause(astNode) {
|
|
23
|
-
switch (true) {
|
|
24
|
-
case ast.isWhereTagEqual(astNode): {
|
|
25
|
-
const tag = astNode.value.tag.ref?.name;
|
|
26
|
-
const participant = parseParticipant(astNode);
|
|
27
|
-
invariant(tag, 'Expected tag name');
|
|
28
|
-
const tagOperator = { tag: parseEquals(astNode, tag) };
|
|
29
|
-
return participant ? { participant, operator: tagOperator } : tagOperator;
|
|
30
|
-
}
|
|
31
|
-
case ast.isWhereKindEqual(astNode): {
|
|
32
|
-
const kind = astNode.value?.ref?.name;
|
|
33
|
-
const participant = parseParticipant(astNode);
|
|
34
|
-
invariant(kind, 'Expected kind name');
|
|
35
|
-
const kindOperator = { kind: parseEquals(astNode, kind) };
|
|
36
|
-
return participant ? { participant, operator: kindOperator } : kindOperator;
|
|
37
|
-
}
|
|
38
|
-
case ast.isWhereElementNegation(astNode) || ast.isWhereRelationNegation(astNode): {
|
|
39
|
-
return {
|
|
40
|
-
not: parseWhereClause(astNode.value),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
case ast.isWhereBinaryExpression(astNode): {
|
|
44
|
-
const left = parseWhereClause(astNode.left);
|
|
45
|
-
const right = parseWhereClause(astNode.right);
|
|
46
|
-
const operator = astNode.operator.toLowerCase();
|
|
47
|
-
return createBinaryOperator(operator, left, right);
|
|
48
|
-
}
|
|
49
|
-
default:
|
|
50
|
-
nonexhaustive(astNode);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
export function createBinaryOperator(operator, left, right) {
|
|
54
|
-
if (right === null) {
|
|
55
|
-
return left;
|
|
56
|
-
}
|
|
57
|
-
switch (operator) {
|
|
58
|
-
case 'and': {
|
|
59
|
-
const operands = [
|
|
60
|
-
isAndOperator(left) ? left.and : left,
|
|
61
|
-
isAndOperator(right) ? right.and : right,
|
|
62
|
-
].flat();
|
|
63
|
-
invariant(isNonEmptyArray(operands), 'Expected non-empty array');
|
|
64
|
-
return {
|
|
65
|
-
and: operands,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
case 'or': {
|
|
69
|
-
const operands = [
|
|
70
|
-
isOrOperator(left) ? left.or : left,
|
|
71
|
-
isOrOperator(right) ? right.or : right,
|
|
72
|
-
].flat();
|
|
73
|
-
invariant(isNonEmptyArray(operands), 'Expected non-empty array');
|
|
74
|
-
return {
|
|
75
|
-
or: operands,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
default:
|
|
79
|
-
nonexhaustive(operator);
|
|
80
|
-
}
|
|
81
|
-
}
|