@likec4/language-server 1.55.1 → 1.57.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/dist/_chunks/LikeC4FileSystem.mjs +2 -2
- package/dist/_chunks/common-exports.mjs +1 -0
- package/dist/_chunks/module.d.mts +98 -27
- package/dist/_chunks/module.mjs +34 -19
- package/dist/_chunks/protocol.d.mts +3 -1
- package/dist/_chunks/utils.mjs +1 -1
- package/dist/browser/index.d.mts +2 -3
- package/dist/browser/index.mjs +1 -1
- package/dist/browser/worker.mjs +1 -1
- package/dist/filesystem/index.d.mts +1 -2
- package/dist/filesystem/index.mjs +1 -1
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +1 -1
- package/dist/module.d.mts +1 -2
- package/dist/module.mjs +1 -1
- package/package.json +15 -13
- package/src/test/testServices.ts +7 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./icons.mjs";import{isLikeC4Builtin as t}from"../likec4lib.mjs";import{c as n,
|
|
1
|
+
import{t as e}from"./icons.mjs";import{isLikeC4Builtin as t}from"../likec4lib.mjs";import{c as n,l as r,n as i,o as a,oi as o,s,ui as c}from"./utils.mjs";import{compareNaturalHierarchically as l,onNextTick as u,stringHash as d}from"@likec4/core/utils";import{isLikeC4Config as f,loadConfig as p}from"@likec4/config/node";import{fdir as m}from"fdir";import{SimpleCache as h,URI as g,UriUtils as _}from"langium";import{NodeFileSystemProvider as v}from"langium/node";import{mkdirSync as y,statSync as b}from"node:fs";import{unlink as x,writeFile as S}from"node:fs/promises";import{basename as C,dirname as w}from"node:path";import T from"chokidar";import E from"p-queue";import{exact as D}from"@likec4/core";import O from"json5";import k from"p-limit";import{indexBy as A,prop as j}from"remeda";import{Position as M,Range as N}from"vscode-languageserver-types";const P=c.getChild(`manual-layouts`),F=`.likec4.snap`,isManualLayoutFile=e=>e!==F&&e.endsWith(F);function fileName(e){return`${e}${F}`}function viewIdFromURI(e){let t=_.basename(e);return isManualLayoutFile(t)?t.slice(0,-12):null}function getManualLayoutsOutDir(e){return _.resolvePath(e.folderUri,e.config.manualLayouts?.outDir??`.likec4`)}const I={manualLayouts:e=>new DefaultLikeC4ManualLayouts(e)},L=`file://./`;var DefaultLikeC4ManualLayouts=class{services;cache;listeners=[];#e=k(1);constructor(e){this.services=e,this.cache=new h,u(()=>{e.workspace.ProjectsManager.onProjectsUpdate(()=>{this.clearCaches()})})}async handleFileSystemUpdate(e){let t=e.update??e.delete,n=viewIdFromURI(t)??void 0,r=this.services.workspace.ProjectsManager.ownerProjectId(t);if(this.cache.delete(r),`delete`in e){this.triggerUpdate(D({removed:t,projectId:r,viewId:n}));return}let i=this.services.workspace.ProjectsManager.getProject(r);if(!n){let e=await this.readSnapshot(t,i);e?n=e.id:(P.error(`Snapshot ${t.fsPath} does not exist or is invalid`),n=`index`)}this.triggerUpdate({updated:t,projectId:r,viewId:n})}onManualLayoutUpdate(e){return this.listeners.push(e),{dispose:()=>{let t=this.listeners.indexOf(e);t!==-1&&this.listeners.splice(t,1)}}}async readManualLayouts(e){let t=P.getChild(e.id),n=this.services.workspace.FileSystemProvider,r=getManualLayoutsOutDir(e),i=[],a=`${r.toString()}`;try{let o=await n.scanDirectory(r,isManualLayoutFile);if(o.length===0)return null;o.sort((e,t)=>e.uri.path.localeCompare(t.uri.path));for(let r of o)try{let t=await n.readFile(r.uri),o=O.parse(t);a=d(a+r.uri.toString()+t);let s=this.resolveIconPathsAfterRead(o,e.folderUri);i.push({...s,_layout:`manual`})}catch(e){t.warn(`Failed to read view snapshot ${r.uri.fsPath}`,{err:e})}i.length&&t.trace`read manual layouts for ${e.id}, found ${i.length}`}catch(n){t.warn(`Failed to read manual layouts for ${e.folderUri.fsPath}`,{err:n})}if(i.length===0)return null;let o=A(i,j(`id`));return{hash:a,views:o}}async readSnapshot(e,t){let n=this.services.workspace.FileSystemProvider;try{let r=await n.readFile(e),i=O.parse(r);if(!t){let n=this.services.workspace.ProjectsManager.ownerProjectId(e);t=this.services.workspace.ProjectsManager.getProject(n)}return{...this.resolveIconPathsAfterRead(i,t.folderUri),_layout:`manual`}}catch(t){return P.warn(`Failed to read view snapshot ${e.fsPath}`,{err:t}),null}}async read(e){return await this.#e(async()=>{let t=this.cache.get(e.id);if(t!==void 0)return P.trace`cache hit project ${e.id}`,t;let n=await this.readManualLayouts(e);return this.cache.set(e.id,n),n})}async write(e,t){this.cache.delete(e.id);let n=P.getChild(e.id),r=getManualLayoutsOutDir(e),i=_.joinPath(r,fileName(t.id));if(`manualLayout`in t){let{manualLayout:e,...n}=t;t=n}let a=O.stringify(this.normalizeIconPathsForWrite(t,e.folderUri),{space:2,quote:`'`}),o={uri:i.toString(),range:N.create(M.create(0,0),M.create(a.split(`
|
|
2
2
|
`).length-1,1))};n.debug`write snapshot of ${t.id} in project ${e.id} to ${i.fsPath}`;let s=this.services.workspace.FileSystemProvider;try{await s.writeFile(i,a+`
|
|
3
|
-
`),this.triggerUpdate({updated:i,projectId:e.id,viewId:t.id})}catch(e){n.warn(`Failed to write snapshot ${t.id} to ${i.fsPath}`,{err:e})}return o}async remove(e,t){this.cache.delete(e.id);let n=
|
|
3
|
+
`),this.triggerUpdate({updated:i,projectId:e.id,viewId:t.id})}catch(e){n.warn(`Failed to write snapshot ${t.id} to ${i.fsPath}`,{err:e})}return o}async remove(e,t){this.cache.delete(e.id);let n=P.getChild(e.id),r=getManualLayoutsOutDir(e),i=_.joinPath(r,fileName(t));n.debug`delete snapshot of ${t} in project ${e.id}. File: ${i.fsPath}`;let a={uri:i.toString(),range:N.create(0,0,0,0)};try{if(!await this.services.workspace.FileSystemProvider.deleteFile(i))return n.warn`Snapshot ${t} did not exist at ${i.fsPath}`,null;this.triggerUpdate({removed:i,projectId:e.id,viewId:t})}catch(e){n.warn(`Failed to delete snapshot ${t} from ${i.fsPath}`,{err:e})}return a}clearCaches(){P.trace`clear caches`,this.cache.clear()}triggerUpdate(e){for(let t of this.listeners)i(()=>t(e))}normalizeIconPathsForWrite(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(`file://`)){let n=g.parse(e.icon),r=_.relative(t,n);return r.startsWith(`..`)?e:{...e,icon:`${L}${r}`}}return e});return{...e,nodes:n}}resolveIconPathsAfterRead(e,t){let n=e.nodes.map(e=>{if(!e.icon||typeof e.icon!=`string`)return e;if(e.icon.startsWith(L)){let n=e.icon.substring(9),r=_.joinPath(t,n);return{...e,icon:r.toString()}}return e});return{...e,nodes:n}}};const R=c.getChild(`chokidar`),z={fileSystemWatcher:e=>new ChokidarFileSystemWatcher(e)},isAnyLikeC4File=e=>{let t=C(e);return s(t)||f(t)||isManualLayoutFile(t)};var ChokidarFileSystemWatcher=class{services;watcher;queue=new E({concurrency:1,timeout:5e3});constructor(e){this.services=e,R.debug`ChokidarFileSystemWatcher created`}watch(e){if(this.watcher){R.debug`add watching folder: ${e}`,this.watcher.add(e);return}this.watcher=this.createWatcher(e)}async dispose(){if(this.watcher){let e=this.watcher;this.watcher=void 0,await e.close()}}createWatcher(e){R.debug`create watcher for folder: ${e}`;let t=T.watch(e,{ignored:[e=>n(e),(e,t)=>!!t&&t.isFile()&&!isAnyLikeC4File(e)],followSymlinks:!0,ignoreInitial:!0}),onAddOrChange=(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`addOrChange: `+e,async()=>{await this.onAddOrChange(e)})};return t.on(`add`,onAddOrChange).on(`change`,onAddOrChange).on(`unlink`,(e,t)=>{t?.isDirectory()||this.enqueueFileOp(`remove: `+e,async()=>{await this.onRemove(e)})}).on(`unlinkDir`,e=>{this.enqueueFileOp(`removeDir: `+e,async()=>{await this.onRemoveDir(e)})}),t}enqueueFileOp(e,t){this.queue.add(async()=>{try{await t()}catch(t){R.warn(`Failed on {fileop}`,{fileop:e,error:t})}}).catch(t=>{R.error(`Error on {fileop}`,{fileop:e,error:t})})}async onAddOrChange(e){let t=this.services.workspace,n=C(e),r=g.file(e);switch(!0){case f(n):R.debug`project config changed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.registerConfigFile(r);break;case isManualLayoutFile(n):R.debug`manual layout file changed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({update:r});break;case s(n):R.debug`file changed: ${e}`,await t.DocumentBuilder.update([r],[]);break;default:R.warn`Unknown file change: ${e}`}}async onRemove(e){let t=this.services.workspace,n=C(e),r=g.file(e);switch(!0){case f(n):R.debug`project file removed: ${e}`,t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects();break;case s(n):R.debug`file removed: ${e}`,await t.DocumentBuilder.update([],[r]);break;case isManualLayoutFile(n):R.debug`manual layout file removed: ${e}`,await t.ManualLayouts.handleFileSystemUpdate({delete:r});break;default:R.warn`Unknown file removal: ${e}`}}async onRemoveDir(e){R.debug`directory removed: ${e}`;let t=this.services.workspace;t.ProjectsManager.findOverlaped(e).length>0&&(t.ManualLayouts.clearCaches(),await t.ProjectsManager.reloadProjects())}};const B=c.getChild(`filesystem`);function isLikeC4ConfigFile(e,t=!1){return!t&&f(C(e))}function isLikeC4File(e,t=!1){return!t&&s(C(e))}const WithFileSystem=(e=!1)=>({fileSystemProvider:()=>new SymLinkTraversingFileSystemProvider,...e?z:o});var SymLinkTraversingFileSystemProvider=class extends v{async readFile(n){if(t(n))return Promise.resolve(e);try{return await super.readFile(n)}catch(e){return B.warn(`Failed to read file ${n.fsPath}`,{error:e}),``}}async readDirectory(e,t){let n=t?.recursive??!0,i=t?.maxDepth??1/0,o=[];try{let t=new m().withSymlinks({resolvePaths:!1}).exclude(r).withFullPaths().filter(isLikeC4File);n?i!==1/0&&(t=t.withMaxDepth(i)):t=t.withMaxDepth(1);let a=await t.crawl(e.fsPath).withPromise();for(let e of a)o.push({isFile:!0,isDirectory:!1,uri:g.file(e)})}catch(t){B.warn(`Failed to read directory ${e.fsPath}`,{error:t})}return o.sort(a)}async scanProjectFiles(e){let t=await this.scanDirectory(e,isLikeC4ConfigFile);if(t.length<=1)return t;let n=l(`/`,!0);return t.sort((e,t)=>n(e.uri.path,t.uri.path))}async scanDirectory(e,t){let n=[];try{let i=await new m().withSymlinks({resolvePaths:!1}).exclude(r).withFullPaths().filter(t).crawl(e.fsPath).withPromise();for(let e of i)n.push({isFile:!0,isDirectory:!1,uri:g.file(e)})}catch(t){B.warn(`Failed to scan directory {path}`,{path:e.fsPath,error:t})}return n}async loadProjectConfig(e){return await p(e)}async writeFile(e,t){let n=w(e.fsPath),r=b(n,{throwIfNoEntry:!1});if(r?.isFile())throw Error(`Cannot create directory ${n} because a file with the same name exists.`);return r||(B.debug(`creating directory {path}`,{path:n}),y(n,{recursive:!0})),B.debug(`writing file {path}`,{path:e.fsPath}),await S(e.fsPath,t,{encoding:`utf-8`})}async deleteFile(e){try{let t=e.fsPath,n=b(t,{throwIfNoEntry:!1});return n?.isFile()||n?.isSymbolicLink()?(await x(t),B.debug(`deleted file {path}`,{path:t}),!0):(B.warn(`deleteFile failed: {path} does not exist, or is not a file`,{path:t}),!1)}catch(t){B.warn(`Failed to delete file ${e.fsPath}`,{error:t})}return!1}};export{z as n,I as r,WithFileSystem as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./utils.mjs";import"./module.mjs";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { h as Locate, n as ChangeView, o as DidRequestOpenViewNotification } from "./protocol.mjs";
|
|
2
|
+
import { DefaultWeakMap, MultiMap } from "@likec4/core/utils";
|
|
2
3
|
import * as langium from "langium";
|
|
3
4
|
import { AstNode, AstNodeDescription, AsyncDisposable, BuildOptions, Cancellation, CstNode, DefaultAstNodeDescriptionProvider, DefaultDocumentValidator, DefaultIndexManager, DefaultLangiumDocuments, DefaultNameProvider, DefaultScopeComputation, DefaultScopeProvider, DefaultValueConverter, DefaultWorkspaceManager, DiagnosticInfo, Disposable, FileSelector, FileSystemNode, FileSystemProvider, GrammarAST, JSDocDocumentationProvider, LangiumDocument, LangiumDocumentFactory, MaybePromise, Module, PrecomputedScopes, Reference, ReferenceDescription, ReferenceInfo, Scope, SimpleCache, Stream, URI, ValidationOptions, ValueType, WorkspaceCache } from "langium";
|
|
4
|
-
import { DefaultWeakMap, MultiMap as MultiMap$1 } from "@likec4/core/utils";
|
|
5
5
|
import * as c4 from "@likec4/core";
|
|
6
6
|
import { ComputedView, DiagramView, LayoutType, LayoutedView, NonEmptyArray, NonEmptyReadonlyArray, ProjectId, Tag, UnknownComputed, UnknownLayouted, UnknownParsed, ViewChange, ViewId } from "@likec4/core";
|
|
7
7
|
import { CompletionItemKind, Diagnostic, DocumentSymbol, FormattingOptions, Hover, Location, Range, SymbolKind, TextEdit } from "vscode-languageserver-types";
|
|
@@ -18,6 +18,7 @@ import { Fqn as Fqn$1, GuardedBy, LayoutedView as LayoutedView$1, ProjectId as P
|
|
|
18
18
|
import { CancellationToken as CancellationToken$1 } from "vscode-jsonrpc";
|
|
19
19
|
import * as type_fest0 from "type-fest";
|
|
20
20
|
import { ConditionalPick, MergeExclusive, Simplify, Tagged, ValueOf, Writable } from "type-fest";
|
|
21
|
+
import { AILayoutHints } from "@likec4/layouts/ai";
|
|
21
22
|
|
|
22
23
|
//#region src/documentation/documentation-provider.d.ts
|
|
23
24
|
/**
|
|
@@ -41,6 +42,7 @@ declare class LikeC4DocumentationProvider extends JSDocDocumentationProvider {
|
|
|
41
42
|
}
|
|
42
43
|
//#endregion
|
|
43
44
|
//#region src/workspace/ProjectsManager.d.ts
|
|
45
|
+
type NormalizedUri = Tagged<string, 'NormalizedUri'>;
|
|
44
46
|
type DocOrUri = LangiumDocument | string | URI;
|
|
45
47
|
/**
|
|
46
48
|
* A tagged string that represents a project folder URI (with trailing slash).
|
|
@@ -91,6 +93,11 @@ declare class ProjectsManager {
|
|
|
91
93
|
*/
|
|
92
94
|
static readonly DefaultProjectId: ProjectId$1;
|
|
93
95
|
constructor(services: LikeC4SharedServices);
|
|
96
|
+
/**
|
|
97
|
+
* Checks if a document is excluded by workspace-level patterns.
|
|
98
|
+
* These patterns come from VS Code settings and take precedence over project-level excludes.
|
|
99
|
+
*/
|
|
100
|
+
isExcludedByWorkspace(uri: NormalizedUri | URI): boolean;
|
|
94
101
|
/**
|
|
95
102
|
* Updates the workspace-level exclude patterns from VS Code settings.
|
|
96
103
|
* Called during initial server startup; dynamic changes restart the server.
|
|
@@ -111,7 +118,7 @@ declare class ProjectsManager {
|
|
|
111
118
|
/**
|
|
112
119
|
* Returns all projects that overlap with the specified folder (is parent or child)
|
|
113
120
|
*/
|
|
114
|
-
findOverlaped(folder: URI | string): ProjectData
|
|
121
|
+
findOverlaped(folder: URI | string): ReadonlyArray<ProjectData>;
|
|
115
122
|
/**
|
|
116
123
|
* Validates and ensures the project ID.
|
|
117
124
|
* If no project ID is specified, returns default project ID
|
|
@@ -119,14 +126,22 @@ declare class ProjectsManager {
|
|
|
119
126
|
*/
|
|
120
127
|
ensureProjectId(projectId?: ProjectId$1 | undefined): ProjectId$1;
|
|
121
128
|
/**
|
|
122
|
-
* Validates and ensures the project.
|
|
129
|
+
* Validates and ensures the project data.
|
|
130
|
+
* If projectId is not specified, returns default project
|
|
131
|
+
*
|
|
132
|
+
* If there are multiple projects and default project is not set, throws an error
|
|
133
|
+
*
|
|
134
|
+
* @see ensureProjectId - to validate project ID only
|
|
123
135
|
*/
|
|
124
136
|
ensureProject(projectId?: ProjectId$1 | undefined): ProjectData;
|
|
125
137
|
hasMultipleProjects(): boolean;
|
|
126
138
|
/**
|
|
127
|
-
* Checks if
|
|
139
|
+
* Checks if given document (or URI) must be excluded from processing.
|
|
128
140
|
*/
|
|
129
141
|
isExcluded(document: DocOrUri): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Checks if given document (or URI) must be excluded in the context of the project.
|
|
144
|
+
*/
|
|
130
145
|
isExcluded(projectId: ProjectId$1, document: DocOrUri): boolean;
|
|
131
146
|
/**
|
|
132
147
|
* Checks if the specified document is included by the project:
|
|
@@ -148,6 +163,16 @@ declare class ProjectsManager {
|
|
|
148
163
|
* If the document does not belong to any project, returns the default project ID.
|
|
149
164
|
*/
|
|
150
165
|
ownerProjectId(document: LangiumDocument | URI | string): ProjectId$1;
|
|
166
|
+
/**
|
|
167
|
+
* Returns path to the document relative to the project folder.
|
|
168
|
+
* If the document does not belong to any project, returns the document URI as string.
|
|
169
|
+
*/
|
|
170
|
+
relativePath(document: LangiumDocument | URI | string): string;
|
|
171
|
+
/**
|
|
172
|
+
* Returns true if the manager is currently initializing or reloading projects.
|
|
173
|
+
* This is used to prevent duplicate reload operations.
|
|
174
|
+
*/
|
|
175
|
+
protected get isInitiatingOrReloading(): boolean;
|
|
151
176
|
reloadProjects(cancelToken?: Cancellation.CancellationToken): Promise<void>;
|
|
152
177
|
protected _reloadProjects(cancelToken?: Cancellation.CancellationToken): Promise<void>;
|
|
153
178
|
protected uniqueProjectId(name: string): ProjectId$1;
|
|
@@ -191,7 +216,8 @@ interface FileSystemProvider$1 extends FileSystemProvider {
|
|
|
191
216
|
*/
|
|
192
217
|
loadProjectConfig(filepath: URI): Promise<LikeC4ProjectConfig>;
|
|
193
218
|
/**
|
|
194
|
-
* Reads the directory
|
|
219
|
+
* Reads the directory and returns LikeC4 files.
|
|
220
|
+
*
|
|
195
221
|
* @param options.recursive If true, recursively reads the directory,
|
|
196
222
|
* @param options.maxDepth Maximum depth to traverse when recursive is true (default: Infinity)
|
|
197
223
|
*/
|
|
@@ -202,7 +228,7 @@ interface FileSystemProvider$1 extends FileSystemProvider {
|
|
|
202
228
|
/**
|
|
203
229
|
* Finds all files in the given directory, matching the given filter.
|
|
204
230
|
*/
|
|
205
|
-
scanDirectory(directory: URI, filter: (filepath: string) => boolean): Promise<FileNode[]>;
|
|
231
|
+
scanDirectory(directory: URI, filter: (filepath: string, isDirectory: boolean) => boolean): Promise<FileNode[]>;
|
|
206
232
|
/**
|
|
207
233
|
* Writes the content to the file system.
|
|
208
234
|
* Used by manual layouts.
|
|
@@ -358,7 +384,7 @@ type DeploymentElement = DeployedInstance | DeploymentNode;
|
|
|
358
384
|
declare const DeploymentElement = "DeploymentElement";
|
|
359
385
|
type DeploymentNodeOrElementKind = DeploymentNodeKind | ElementKind;
|
|
360
386
|
declare const DeploymentNodeOrElementKind = "DeploymentNodeOrElementKind";
|
|
361
|
-
type DeploymentViewRule = DeploymentViewRulePredicate | DeploymentViewRuleStyle | ViewRuleAutoLayout;
|
|
387
|
+
type DeploymentViewRule = DeploymentViewRulePredicate | DeploymentViewRuleStyle | ViewRuleAncestors | ViewRuleAutoLayout;
|
|
362
388
|
declare const DeploymentViewRule = "DeploymentViewRule";
|
|
363
389
|
type DynamicViewDisplayVariantValue = 'diagram' | 'sequence';
|
|
364
390
|
type DynamicViewProperty = DynamicViewDisplayVariantProperty | ViewProperty;
|
|
@@ -490,7 +516,7 @@ declare const CustomElementProperties = "CustomElementProperties";
|
|
|
490
516
|
interface CustomRelationProperties extends langium.AstNode {
|
|
491
517
|
readonly $container: AbstractDynamicStep | RelationExprWith;
|
|
492
518
|
readonly $type: 'CustomRelationProperties';
|
|
493
|
-
props: Array<NotationProperty | NotesProperty | RelationNavigateToProperty | RelationStringProperty | RelationshipStyleProperty>;
|
|
519
|
+
props: Array<MultipleProperty | NotationProperty | NotesProperty | RelationNavigateToProperty | RelationStringProperty | RelationshipStyleProperty>;
|
|
494
520
|
}
|
|
495
521
|
declare const CustomRelationProperties = "CustomRelationProperties";
|
|
496
522
|
interface DeployedInstance extends langium.AstNode {
|
|
@@ -969,7 +995,7 @@ interface MetadataAttribute extends langium.AstNode {
|
|
|
969
995
|
readonly $container: MetadataBody;
|
|
970
996
|
readonly $type: 'MetadataAttribute';
|
|
971
997
|
boolValue: boolean;
|
|
972
|
-
key:
|
|
998
|
+
key: Id;
|
|
973
999
|
value?: MetadataValue;
|
|
974
1000
|
}
|
|
975
1001
|
declare const MetadataAttribute = "MetadataAttribute";
|
|
@@ -1003,7 +1029,7 @@ interface ModelViews extends langium.AstNode {
|
|
|
1003
1029
|
}
|
|
1004
1030
|
declare const ModelViews = "ModelViews";
|
|
1005
1031
|
interface MultipleProperty extends langium.AstNode {
|
|
1006
|
-
readonly $container: CustomElementProperties | DeploymentViewRuleStyle | ElementStyleProperty | GlobalStyle | ViewRuleStyle;
|
|
1032
|
+
readonly $container: CustomElementProperties | CustomRelationProperties | DeploymentViewRuleStyle | ElementStyleProperty | GlobalStyle | SpecificationRelationshipKind | ViewRuleStyle;
|
|
1007
1033
|
readonly $type: 'MultipleProperty';
|
|
1008
1034
|
key: 'multiple';
|
|
1009
1035
|
value: boolean;
|
|
@@ -1178,7 +1204,7 @@ interface SpecificationRelationshipKind extends langium.AstNode {
|
|
|
1178
1204
|
readonly $container: SpecificationRule;
|
|
1179
1205
|
readonly $type: 'SpecificationRelationshipKind';
|
|
1180
1206
|
kind: RelationshipKind;
|
|
1181
|
-
props: Array<RelationshipStyleProperty | SpecificationRelationshipStringProperty>;
|
|
1207
|
+
props: Array<MultipleProperty | RelationshipStyleProperty | SpecificationRelationshipStringProperty>;
|
|
1182
1208
|
}
|
|
1183
1209
|
declare const SpecificationRelationshipKind = "SpecificationRelationshipKind";
|
|
1184
1210
|
interface SpecificationRelationshipStringProperty extends langium.AstNode {
|
|
@@ -1252,6 +1278,13 @@ interface ViewRef extends langium.AstNode {
|
|
|
1252
1278
|
view: langium.Reference<LikeC4View>;
|
|
1253
1279
|
}
|
|
1254
1280
|
declare const ViewRef = "ViewRef";
|
|
1281
|
+
interface ViewRuleAncestors extends langium.AstNode {
|
|
1282
|
+
readonly $container: DeploymentViewBody;
|
|
1283
|
+
readonly $type: 'ViewRuleAncestors';
|
|
1284
|
+
key: 'includeAncestors';
|
|
1285
|
+
value: boolean;
|
|
1286
|
+
}
|
|
1287
|
+
declare const ViewRuleAncestors = "ViewRuleAncestors";
|
|
1255
1288
|
interface ViewRuleAutoLayout extends langium.AstNode {
|
|
1256
1289
|
readonly $container: DeploymentViewBody | DynamicViewBody | ElementViewBody;
|
|
1257
1290
|
readonly $type: 'ViewRuleAutoLayout';
|
|
@@ -1569,6 +1602,7 @@ type LikeC4AstType = {
|
|
|
1569
1602
|
ViewProperty: ViewProperty;
|
|
1570
1603
|
ViewRef: ViewRef;
|
|
1571
1604
|
ViewRule: ViewRule;
|
|
1605
|
+
ViewRuleAncestors: ViewRuleAncestors;
|
|
1572
1606
|
ViewRuleAutoLayout: ViewRuleAutoLayout;
|
|
1573
1607
|
ViewRuleGlobalPredicateRef: ViewRuleGlobalPredicateRef;
|
|
1574
1608
|
ViewRuleGlobalStyle: ViewRuleGlobalStyle;
|
|
@@ -1678,6 +1712,7 @@ interface ParsedAstSpecification {
|
|
|
1678
1712
|
line?: c4.RelationshipLineType;
|
|
1679
1713
|
head?: c4.RelationshipArrowType;
|
|
1680
1714
|
tail?: c4.RelationshipArrowType;
|
|
1715
|
+
multiple?: boolean;
|
|
1681
1716
|
}>;
|
|
1682
1717
|
colors: Record<c4.CustomColor, {
|
|
1683
1718
|
color: c4.ColorLiteral;
|
|
@@ -1798,7 +1833,7 @@ interface LikeC4DocumentProps {
|
|
|
1798
1833
|
c4Views?: ParsedAstView[];
|
|
1799
1834
|
c4Deployments?: ParsedAstDeployment[];
|
|
1800
1835
|
c4DeploymentRelations?: ParsedAstDeploymentRelation[];
|
|
1801
|
-
c4Imports?: MultiMap
|
|
1836
|
+
c4Imports?: MultiMap<c4.ProjectId, c4.Fqn, Set<c4.Fqn>>;
|
|
1802
1837
|
}
|
|
1803
1838
|
type LikeC4GrammarDocument = Omit<LangiumDocument<LikeC4Grammar>, 'diagnostics'>;
|
|
1804
1839
|
interface LikeC4LangiumDocument extends LikeC4GrammarDocument, LikeC4DocumentProps {
|
|
@@ -1878,20 +1913,24 @@ declare class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
|
1878
1913
|
initialBuildOptions: BuildOptions;
|
|
1879
1914
|
constructor(services: LikeC4SharedServices);
|
|
1880
1915
|
/**
|
|
1881
|
-
*
|
|
1916
|
+
* Whether the workspace is ready, use {@link ready} promise to wait for it
|
|
1882
1917
|
*/
|
|
1883
|
-
|
|
1918
|
+
get isReady(): boolean;
|
|
1884
1919
|
/**
|
|
1885
|
-
*
|
|
1886
|
-
* Uses a timeout fallback for third-party IDEs that may not support workspace/configuration.
|
|
1920
|
+
* First load all project config files, then load all documents in the workspace.
|
|
1887
1921
|
*/
|
|
1888
|
-
|
|
1922
|
+
protected performStartup(folders: WorkspaceFolder[]): Promise<LangiumDocument[]>;
|
|
1889
1923
|
/**
|
|
1890
1924
|
* Load all additional documents that shall be visible in the context of the given workspace
|
|
1891
1925
|
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
1892
1926
|
* your language, which can be either loaded from provided files or constructed in memory.
|
|
1893
1927
|
*/
|
|
1894
1928
|
protected loadAdditionalDocuments(folders: WorkspaceFolder[], collector: (document: LangiumDocument) => void): Promise<void>;
|
|
1929
|
+
/**
|
|
1930
|
+
* Traverse the file system folder identified by the given URI and its subfolders. All
|
|
1931
|
+
* contained files that match the file extensions are added to the collector.
|
|
1932
|
+
*/
|
|
1933
|
+
protected traverseFolder(workspaceFolder: WorkspaceFolder, folderPath: URI$2, selector: FileSelector, collector: (document: LangiumDocument) => void): Promise<void>;
|
|
1895
1934
|
/**
|
|
1896
1935
|
* Determine whether the given folder entry shall be included while indexing the workspace.
|
|
1897
1936
|
*/
|
|
@@ -1908,6 +1947,11 @@ declare class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
|
1908
1947
|
* Register a listener to be called when caches are force cleaned
|
|
1909
1948
|
*/
|
|
1910
1949
|
onForceCleanCache(listener: () => void): Disposable;
|
|
1950
|
+
/**
|
|
1951
|
+
* Read workspace exclude patterns from configuration before workspace scan.
|
|
1952
|
+
* Uses a timeout fallback for third-party IDEs that may not support workspace/configuration.
|
|
1953
|
+
*/
|
|
1954
|
+
private readExcludeConfig;
|
|
1911
1955
|
}
|
|
1912
1956
|
//#endregion
|
|
1913
1957
|
//#region src/references/scope-provider.d.ts
|
|
@@ -2005,17 +2049,17 @@ declare class DocumentFqnIndex {
|
|
|
2005
2049
|
* direct children of elements
|
|
2006
2050
|
*/
|
|
2007
2051
|
|
|
2008
|
-
_children: MultiMap
|
|
2052
|
+
_children: MultiMap<Fqn$1, AstNodeDescriptionWithFqn>,
|
|
2009
2053
|
/**
|
|
2010
2054
|
* All descendants of an element (unique by name)
|
|
2011
2055
|
*/
|
|
2012
2056
|
|
|
2013
|
-
_descendants: MultiMap
|
|
2057
|
+
_descendants: MultiMap<Fqn$1, AstNodeDescriptionWithFqn>,
|
|
2014
2058
|
/**
|
|
2015
2059
|
* All elements by FQN
|
|
2016
2060
|
*/
|
|
2017
2061
|
|
|
2018
|
-
_byfqn: MultiMap
|
|
2062
|
+
_byfqn: MultiMap<Fqn$1, AstNodeDescriptionWithFqn>, projectId: ProjectId$1);
|
|
2019
2063
|
rootElements(): readonly AstNodeDescriptionWithFqn[];
|
|
2020
2064
|
byFqn(fqn: Fqn$1): readonly AstNodeDescriptionWithFqn[];
|
|
2021
2065
|
children(parent: Fqn$1): readonly AstNodeDescriptionWithFqn[];
|
|
@@ -2042,7 +2086,7 @@ declare class MergedSpecification {
|
|
|
2042
2086
|
readonly specs: Omit<ParsedAstSpecification, 'tags'>;
|
|
2043
2087
|
readonly tags: Readonly<Record<c4.Tag, c4.TagSpecification>>;
|
|
2044
2088
|
readonly globals: c4.ModelGlobals;
|
|
2045
|
-
readonly imports: MultiMap
|
|
2089
|
+
readonly imports: MultiMap<c4.ProjectId, c4.Fqn, Set<c4.Fqn>>;
|
|
2046
2090
|
readonly projectId: c4.ProjectId | undefined;
|
|
2047
2091
|
readonly inferTechFromIcon: boolean;
|
|
2048
2092
|
constructor(docs: ReadonlyArray<ParsedLikeC4LangiumDocument>, opts?: {
|
|
@@ -2233,7 +2277,8 @@ type LayoutViewParams = {
|
|
|
2233
2277
|
*/
|
|
2234
2278
|
layoutType?: LayoutType | undefined;
|
|
2235
2279
|
projectId?: ProjectId | undefined;
|
|
2236
|
-
cancelToken?: CancellationToken | undefined;
|
|
2280
|
+
cancelToken?: CancellationToken | undefined; /** Optional AI-generated layout hints */
|
|
2281
|
+
layoutHints?: AILayoutHints | undefined;
|
|
2237
2282
|
};
|
|
2238
2283
|
interface LikeC4Views {
|
|
2239
2284
|
readonly layouter: GraphvizLayouter;
|
|
@@ -2251,10 +2296,12 @@ interface LikeC4Views {
|
|
|
2251
2296
|
layoutAllViews(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<GraphvizOut[]>;
|
|
2252
2297
|
/**
|
|
2253
2298
|
* Layouts a view.
|
|
2254
|
-
* If layoutType is 'manual' - applies manual layout if any.
|
|
2255
|
-
* If layoutType is 'auto' - returns latest version with drifts from manual layout if any
|
|
2299
|
+
* If `layoutType` is 'manual' - applies manual layout if any.
|
|
2300
|
+
* If `layoutType` is 'auto' - returns latest version with drifts from manual layout if any
|
|
2256
2301
|
* If not specified - returns latest layout as is
|
|
2257
2302
|
*
|
|
2303
|
+
* If `layoutHints` are provided, they will be used, ignoring any manual snapshots, and the resulting layout will not be cached (i.e. it will be computed on every call)
|
|
2304
|
+
*
|
|
2258
2305
|
* If view not found in model, but there is a snapshot - it will be returned (with empty DOT)
|
|
2259
2306
|
*/
|
|
2260
2307
|
layoutView(params: LayoutViewParams): Promise<GraphvizOut | null>;
|
|
@@ -2379,6 +2426,10 @@ declare class BaseParser {
|
|
|
2379
2426
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2380
2427
|
readonly project: Project;
|
|
2381
2428
|
isValid: IsValidFn;
|
|
2429
|
+
/** Full URI of the document */
|
|
2430
|
+
docUri: string;
|
|
2431
|
+
/** Path of the document relative to the project root */
|
|
2432
|
+
docPathInProject: string;
|
|
2382
2433
|
constructor(services: LikeC4Services, doc: ParsedLikeC4LangiumDocument, project: Project);
|
|
2383
2434
|
logError(error: unknown, astNode?: AstNode | Reference<AstNode>, level?: ParserLevel): void;
|
|
2384
2435
|
tryParse<N extends AstNode, T>(level: ParserLevel, node: N | undefined, fn: (node: NoInfer<N>) => T | undefined): T | undefined;
|
|
@@ -2484,6 +2535,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2484
2535
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
2485
2536
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
2486
2537
|
isValid: IsValidFn;
|
|
2538
|
+
docUri: string;
|
|
2539
|
+
docPathInProject: string;
|
|
2487
2540
|
readonly services: LikeC4Services;
|
|
2488
2541
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2489
2542
|
readonly project: Project;
|
|
@@ -2587,6 +2640,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2587
2640
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
2588
2641
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
2589
2642
|
isValid: IsValidFn;
|
|
2643
|
+
docUri: string;
|
|
2644
|
+
docPathInProject: string;
|
|
2590
2645
|
readonly services: LikeC4Services;
|
|
2591
2646
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2592
2647
|
readonly project: Project;
|
|
@@ -2645,6 +2700,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2645
2700
|
parseElementSpecificationNode(specAst: SpecificationElementKind): {};
|
|
2646
2701
|
parseElementSpecificationNode(specAst: SpecificationDeploymentNodeKind): {};
|
|
2647
2702
|
isValid: IsValidFn;
|
|
2703
|
+
docUri: string;
|
|
2704
|
+
docPathInProject: string;
|
|
2648
2705
|
readonly services: LikeC4Services;
|
|
2649
2706
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2650
2707
|
readonly project: Project;
|
|
@@ -2718,6 +2775,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2718
2775
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
2719
2776
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
2720
2777
|
isValid: IsValidFn;
|
|
2778
|
+
docUri: string;
|
|
2779
|
+
docPathInProject: string;
|
|
2721
2780
|
readonly services: LikeC4Services;
|
|
2722
2781
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2723
2782
|
readonly project: Project;
|
|
@@ -2784,6 +2843,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2784
2843
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
2785
2844
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
2786
2845
|
isValid: IsValidFn;
|
|
2846
|
+
docUri: string;
|
|
2847
|
+
docPathInProject: string;
|
|
2787
2848
|
readonly services: LikeC4Services;
|
|
2788
2849
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2789
2850
|
readonly project: Project;
|
|
@@ -2858,6 +2919,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2858
2919
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
2859
2920
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
2860
2921
|
isValid: IsValidFn;
|
|
2922
|
+
docUri: string;
|
|
2923
|
+
docPathInProject: string;
|
|
2861
2924
|
readonly services: LikeC4Services;
|
|
2862
2925
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2863
2926
|
readonly project: Project;
|
|
@@ -2926,6 +2989,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2926
2989
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
2927
2990
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
2928
2991
|
isValid: IsValidFn;
|
|
2992
|
+
docUri: string;
|
|
2993
|
+
docPathInProject: string;
|
|
2929
2994
|
readonly services: LikeC4Services;
|
|
2930
2995
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2931
2996
|
readonly project: Project;
|
|
@@ -2972,6 +3037,8 @@ declare const DocumentParserFromMixins: {
|
|
|
2972
3037
|
new (...args: any[]): {
|
|
2973
3038
|
parseImports(): void;
|
|
2974
3039
|
isValid: IsValidFn;
|
|
3040
|
+
docUri: string;
|
|
3041
|
+
docPathInProject: string;
|
|
2975
3042
|
readonly services: LikeC4Services;
|
|
2976
3043
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
2977
3044
|
readonly project: Project;
|
|
@@ -3034,6 +3101,8 @@ declare const DocumentParserFromMixins: {
|
|
|
3034
3101
|
parseInlineKindCondition(astNode: OutgoingRelationExpr): ProjectId | null;
|
|
3035
3102
|
wrapInWhere(expr: ProjectId, condition: ProjectId | null): ProjectId;
|
|
3036
3103
|
isValid: IsValidFn;
|
|
3104
|
+
docUri: string;
|
|
3105
|
+
docPathInProject: string;
|
|
3037
3106
|
readonly services: LikeC4Services;
|
|
3038
3107
|
readonly doc: ParsedLikeC4LangiumDocument;
|
|
3039
3108
|
readonly project: Project;
|
|
@@ -3104,11 +3173,12 @@ declare class LikeC4ModelChanges {
|
|
|
3104
3173
|
change
|
|
3105
3174
|
}: {
|
|
3106
3175
|
lookup: ViewLocateResult;
|
|
3107
|
-
change: Exclude<ViewChange, ViewChange.SaveViewSnapshot | ViewChange.ResetManualLayout>;
|
|
3176
|
+
change: Exclude<ViewChange, ViewChange.SaveViewSnapshot | ViewChange.ResetManualLayout | ViewChange.ChangeProperty>;
|
|
3108
3177
|
}): {
|
|
3109
3178
|
modifiedRange: Range;
|
|
3110
3179
|
edits: TextEdit[];
|
|
3111
3180
|
};
|
|
3181
|
+
protected applyTextEdits(doc: ParsedLikeC4LangiumDocument, edits: TextEdit[]): Promise<boolean>;
|
|
3112
3182
|
}
|
|
3113
3183
|
//#endregion
|
|
3114
3184
|
//#region src/LikeC4LanguageServices.d.ts
|
|
@@ -3116,6 +3186,7 @@ interface LikeC4LanguageServices {
|
|
|
3116
3186
|
readonly views: LikeC4Views;
|
|
3117
3187
|
readonly builder: LikeC4ModelBuilder;
|
|
3118
3188
|
readonly workspaceUri: URI;
|
|
3189
|
+
readonly workspacePath: string;
|
|
3119
3190
|
readonly projectsManager: ProjectsManager;
|
|
3120
3191
|
readonly editor: LikeC4ModelChanges;
|
|
3121
3192
|
/**
|
|
@@ -3261,7 +3332,7 @@ declare class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
|
|
|
3261
3332
|
protected getSpecSymbol(astSpec: SpecificationRule): DocumentSymbol[];
|
|
3262
3333
|
protected getModelSymbol(astModel: Model): DocumentSymbol[];
|
|
3263
3334
|
protected getDeploymentModelSymbol(astModel: ModelDeployments): DocumentSymbol[];
|
|
3264
|
-
protected getElementsSymbol(el: Element | Relation | ExtendElement): DocumentSymbol[];
|
|
3335
|
+
protected getElementsSymbol(el: Element | Relation | ExtendElement, parentFqn?: string): DocumentSymbol[];
|
|
3265
3336
|
protected getExtendElementSymbol(astElement: ExtendElement): DocumentSymbol[];
|
|
3266
3337
|
protected getElementSymbol(astElement: Element): DocumentSymbol[];
|
|
3267
3338
|
protected getModelViewsSymbol(astViews: ModelViews): DocumentSymbol[];
|
|
@@ -3480,4 +3551,4 @@ declare function createLanguageServices<I1, I2, I3, I extends I1 & I2 & I3 & Lik
|
|
|
3480
3551
|
*/
|
|
3481
3552
|
declare function createSharedServices(context?: Partial<LanguageServicesContext>): LikeC4SharedServices;
|
|
3482
3553
|
//#endregion
|
|
3483
|
-
export {
|
|
3554
|
+
export { WithFileSystem as A, LikeC4ManualLayoutsModuleContext as B, ViewLocateResult as C, LangiumDocuments as D, LikeC4WorkspaceManager as E, FileSystemModuleContext as F, Project as H, FileSystemProvider$1 as I, FileSystemWatcher as L, NoFileSystemWatcher as M, NoLikeC4ManualLayouts as N, WithLikeC4ManualLayouts as O, FileNode as P, FileSystemWatcherModuleContext as R, LikeC4ModelLocator as S, FqnIndex as T, ProjectData as U, ManualLayoutsSnapshot as V, ProjectsManager as W, LikeC4ViewsModuleContext as _, LikeC4SharedModuleContext as a, LayoutViewParams as b, createLikeC4Module as c, LikeC4LanguageServices as d, DocumentParser as f, configureLanguageServerLogger as g, ConfigureLanguageServerLoggerOptions as h, LikeC4ServicesContext as i, NoFileSystem as j, WithChokidarWatcher as k, createSharedServices as l, startLanguageServer$1 as m, LikeC4AddedServices as n, LikeC4SharedServices as o, LikeC4ModelParser as p, LikeC4Services as r, createLanguageServices as s, LanguageServicesContext as t, FormatOptions as u, WithGraphviz as v, LikeC4ModelBuilder as w, LikeC4Views as x, WithWasmGraphviz as y, LikeC4ManualLayouts as z };
|