@likec4/language-server 0.6.2 → 0.8.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/contrib/likec4.monarch.ts +31 -0
- package/contrib/likec4.tmLanguage.json +73 -0
- package/dist/ast.d.ts +75 -0
- package/dist/ast.js +143 -0
- package/dist/builtin.d.ts +5 -0
- package/dist/builtin.js +9 -0
- package/dist/elementRef.d.ts +7 -0
- package/dist/elementRef.js +40 -0
- package/dist/generated/ast.d.ts +364 -0
- package/dist/generated/ast.js +389 -0
- package/dist/generated/grammar.d.ts +7 -0
- package/dist/generated/grammar.js +2548 -0
- package/dist/generated/module.d.ts +10 -0
- package/dist/generated/module.js +27 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +21 -0
- package/dist/lsp/DocumentSymbolProvider.d.ts +22 -0
- package/dist/lsp/DocumentSymbolProvider.js +167 -0
- package/dist/lsp/HoverProvider.d.ts +9 -0
- package/dist/lsp/HoverProvider.js +55 -0
- package/dist/lsp/SemanticTokenProvider.d.ts +7 -0
- package/dist/lsp/SemanticTokenProvider.js +222 -0
- package/dist/lsp/index.d.ts +4 -0
- package/dist/lsp/index.js +4 -0
- package/dist/model/fqn-index.d.ts +41 -0
- package/dist/model/fqn-index.js +119 -0
- package/dist/model/index.d.ts +4 -0
- package/dist/model/index.js +4 -0
- package/dist/model/model-builder.d.ts +27 -0
- package/dist/model/model-builder.js +339 -0
- package/dist/model/model-locator.d.ts +17 -0
- package/dist/model/model-locator.js +116 -0
- package/dist/module.d.ts +21 -0
- package/dist/module.js +66 -0
- package/dist/protocol.d.ts +37 -0
- package/dist/protocol.js +20 -0
- package/dist/references/fqn-computation.d.ts +4 -0
- package/dist/references/fqn-computation.js +41 -0
- package/dist/references/index.d.ts +3 -0
- package/dist/references/index.js +3 -0
- package/dist/references/scope-computation.d.ts +14 -0
- package/dist/references/scope-computation.js +86 -0
- package/dist/references/scope-provider.d.ts +19 -0
- package/dist/references/scope-provider.js +120 -0
- package/dist/registerProtocolHandlers.d.ts +3 -0
- package/dist/registerProtocolHandlers.js +65 -0
- package/dist/shared/CodeLensProvider.d.ts +9 -0
- package/dist/shared/CodeLensProvider.js +36 -0
- package/dist/shared/WorkspaceManager.d.ts +14 -0
- package/dist/shared/WorkspaceManager.js +18 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.js +3 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.js +2 -0
- package/dist/test/testServices.d.ts +16 -0
- package/dist/test/testServices.js +58 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +8 -0
- package/dist/validation/element.d.ts +6 -0
- package/dist/validation/element.js +21 -0
- package/dist/validation/index.d.ts +3 -0
- package/dist/validation/index.js +23 -0
- package/dist/validation/relation.d.ts +5 -0
- package/dist/validation/relation.js +54 -0
- package/dist/validation/specification.d.ts +6 -0
- package/dist/validation/specification.js +34 -0
- package/dist/validation/view.d.ts +5 -0
- package/dist/validation/view.js +21 -0
- package/package.json +26 -31
package/dist/module.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createDefaultModule, createDefaultSharedModule, EmptyFileSystem, inject } from 'langium';
|
|
2
|
+
import { LikeC4GeneratedModule, LikeC4GeneratedSharedModule } from './generated/module';
|
|
3
|
+
import { LikeC4DocumentSymbolProvider, LikeC4HoverProvider, LikeC4SemanticTokenProvider } from './lsp';
|
|
4
|
+
import { FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator } from './model';
|
|
5
|
+
import { LikeC4ScopeComputation, LikeC4ScopeProvider } from './references';
|
|
6
|
+
import { registerProtocolHandlers } from './registerProtocolHandlers';
|
|
7
|
+
import { LikeC4CodeLensProvider, LikeC4WorkspaceManager } from './shared';
|
|
8
|
+
import { registerValidationChecks } from './validation';
|
|
9
|
+
function bind(Type) {
|
|
10
|
+
return (services) => new Type(services);
|
|
11
|
+
}
|
|
12
|
+
export const LikeC4Module = {
|
|
13
|
+
likec4: {
|
|
14
|
+
FqnIndex: bind(FqnIndex),
|
|
15
|
+
ModelBuilder: bind(LikeC4ModelBuilder),
|
|
16
|
+
ModelLocator: bind(LikeC4ModelLocator)
|
|
17
|
+
// Model: bind(LikeC4Model),
|
|
18
|
+
// Model: bind(LikeC4Model),
|
|
19
|
+
// SpecIndex: bind(LikeC4SpecIndex),
|
|
20
|
+
// Validator: bind(LikeC4Validator)
|
|
21
|
+
},
|
|
22
|
+
lsp: {
|
|
23
|
+
DocumentSymbolProvider: bind(LikeC4DocumentSymbolProvider),
|
|
24
|
+
SemanticTokenProvider: bind(LikeC4SemanticTokenProvider),
|
|
25
|
+
HoverProvider: bind(LikeC4HoverProvider)
|
|
26
|
+
},
|
|
27
|
+
//
|
|
28
|
+
// // Formatter: bind(LikeC4Formatter),
|
|
29
|
+
//
|
|
30
|
+
// },
|
|
31
|
+
references: {
|
|
32
|
+
ScopeComputation: bind(LikeC4ScopeComputation),
|
|
33
|
+
ScopeProvider: bind(LikeC4ScopeProvider)
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const LikeC4SharedModule = {
|
|
37
|
+
...LikeC4GeneratedSharedModule,
|
|
38
|
+
workspace: {
|
|
39
|
+
WorkspaceManager: services => new LikeC4WorkspaceManager(services)
|
|
40
|
+
},
|
|
41
|
+
lsp: {
|
|
42
|
+
CodeLensProvider: services => new LikeC4CodeLensProvider(services)
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export function createLanguageServices(context) {
|
|
46
|
+
// const connection = context.connection
|
|
47
|
+
// if (connection) {
|
|
48
|
+
// logger.log = connection.console.log.bind(connection.console)
|
|
49
|
+
// logger.info = connection.console.info.bind(connection.console)
|
|
50
|
+
// logger.warn = connection.console.warn.bind(connection.console)
|
|
51
|
+
// logger.error = connection.console.error.bind(connection.console)
|
|
52
|
+
// logger.debug = connection.tracer.log.bind(connection.tracer)
|
|
53
|
+
// logger.trace = connection.tracer.log.bind(connection.tracer)
|
|
54
|
+
// }
|
|
55
|
+
const moduleContext = {
|
|
56
|
+
...EmptyFileSystem,
|
|
57
|
+
...context
|
|
58
|
+
};
|
|
59
|
+
const shared = inject(createDefaultSharedModule(moduleContext), LikeC4SharedModule);
|
|
60
|
+
const likec4 = inject(createDefaultModule({ shared }), LikeC4GeneratedModule, LikeC4Module);
|
|
61
|
+
shared.ServiceRegistry.register(likec4);
|
|
62
|
+
registerValidationChecks(likec4);
|
|
63
|
+
registerProtocolHandlers(likec4);
|
|
64
|
+
return { shared, likec4 };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Fqn, LikeC4Model, RelationID, ViewID } from '@likec4/core';
|
|
2
|
+
import type { DocumentUri, Location } from 'vscode-languageserver-protocol';
|
|
3
|
+
import { NotificationType0, RequestType0, RequestType } from 'vscode-languageserver-protocol';
|
|
4
|
+
export declare const onDidChangeModel: NotificationType0;
|
|
5
|
+
export declare const fetchModel: RequestType0<{
|
|
6
|
+
model: LikeC4Model | null;
|
|
7
|
+
}, void>;
|
|
8
|
+
export interface BuildDocumentsParams {
|
|
9
|
+
docs: DocumentUri[];
|
|
10
|
+
}
|
|
11
|
+
export declare const buildDocuments: RequestType<BuildDocumentsParams, void, void>;
|
|
12
|
+
export interface LocateElementParams {
|
|
13
|
+
element: Fqn;
|
|
14
|
+
property?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const locateElement: RequestType<LocateElementParams, Location | null, void>;
|
|
17
|
+
export declare const locateRelation: RequestType<{
|
|
18
|
+
id: RelationID;
|
|
19
|
+
}, Location | null, void>;
|
|
20
|
+
export declare const locateView: RequestType<{
|
|
21
|
+
id: ViewID;
|
|
22
|
+
}, Location | null, void>;
|
|
23
|
+
export declare const Rpc: {
|
|
24
|
+
readonly onDidChangeModel: NotificationType0;
|
|
25
|
+
readonly fetchModel: RequestType0<{
|
|
26
|
+
model: LikeC4Model | null;
|
|
27
|
+
}, void>;
|
|
28
|
+
readonly buildDocuments: RequestType<BuildDocumentsParams, void, void>;
|
|
29
|
+
readonly locateElement: RequestType<LocateElementParams, Location | null, void>;
|
|
30
|
+
readonly locateRelation: RequestType<{
|
|
31
|
+
id: RelationID;
|
|
32
|
+
}, Location | null, void>;
|
|
33
|
+
readonly locateView: RequestType<{
|
|
34
|
+
id: ViewID;
|
|
35
|
+
}, Location | null, void>;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=protocol.d.ts.map
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { NotificationType0, RequestType0, RequestType } from 'vscode-languageserver-protocol';
|
|
2
|
+
//#region From server
|
|
3
|
+
export const onDidChangeModel = new NotificationType0('likec4/onDidChangeModel');
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region To server
|
|
6
|
+
export const fetchModel = new RequestType0('likec4/fetchModel');
|
|
7
|
+
export const buildDocuments = new RequestType('likec4/buildDocuments');
|
|
8
|
+
export const locateElement = new RequestType('likec4/locateElement');
|
|
9
|
+
export const locateRelation = new RequestType('likec4/locateRelation');
|
|
10
|
+
export const locateView = new RequestType('likec4/locateView');
|
|
11
|
+
//#endregion
|
|
12
|
+
export const Rpc = {
|
|
13
|
+
onDidChangeModel,
|
|
14
|
+
fetchModel,
|
|
15
|
+
buildDocuments,
|
|
16
|
+
locateElement,
|
|
17
|
+
locateRelation,
|
|
18
|
+
locateView
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { failExpectedNever } from '@likec4/core';
|
|
2
|
+
import { Fqn } from '@likec4/core/types';
|
|
3
|
+
import { MultiMap } from 'langium';
|
|
4
|
+
import { isEmpty, isNil } from 'rambdax';
|
|
5
|
+
import { ElementOps, ast } from '../ast';
|
|
6
|
+
import { strictElementRefFqn } from '../elementRef';
|
|
7
|
+
export function computeDocumentFqn(document, services) {
|
|
8
|
+
const { model } = document.parseResult.value;
|
|
9
|
+
if (!model?.elements) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const c4fqns = document.c4fqns = new MultiMap();
|
|
13
|
+
const locator = services.workspace.AstNodeLocator;
|
|
14
|
+
const traverseStack = model.elements.map(el => [el, null]);
|
|
15
|
+
let pair;
|
|
16
|
+
while ((pair = traverseStack.shift())) {
|
|
17
|
+
const [el, parent] = pair;
|
|
18
|
+
if (ast.isRelation(el)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (ast.isExtendElement(el)) {
|
|
22
|
+
if (!isNil(el.body) && !isEmpty(el.body.elements)) {
|
|
23
|
+
const fqn = strictElementRefFqn(el.element);
|
|
24
|
+
el.body.elements.forEach(child => traverseStack.push([child, fqn]));
|
|
25
|
+
}
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (ast.isElement(el)) {
|
|
29
|
+
const fqn = Fqn(el.name, parent);
|
|
30
|
+
const path = locator.getAstNodePath(el);
|
|
31
|
+
c4fqns.add(fqn, path);
|
|
32
|
+
ElementOps.writeId(el, fqn);
|
|
33
|
+
if (!isNil(el.body) && !isEmpty(el.body.elements)) {
|
|
34
|
+
el.body.elements.forEach(child => traverseStack.push([child, fqn]));
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
failExpectedNever(el);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=fqn-computation.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DefaultScopeComputation, MultiMap, type AstNodeDescription, type PrecomputedScopes } from 'langium';
|
|
2
|
+
import type { CancellationToken } from 'vscode-languageserver';
|
|
3
|
+
import { ast, type LikeC4LangiumDocument } from '../ast';
|
|
4
|
+
import type { LikeC4Services } from '../module';
|
|
5
|
+
type ElementsContainer = ast.Model | ast.ElementBody | ast.ExtendElementBody;
|
|
6
|
+
export declare class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
7
|
+
private services;
|
|
8
|
+
constructor(services: LikeC4Services);
|
|
9
|
+
computeExports(document: LikeC4LangiumDocument, _cancelToken: CancellationToken): Promise<AstNodeDescription[]>;
|
|
10
|
+
computeLocalScopes(document: LikeC4LangiumDocument, _cancelToken: CancellationToken): Promise<PrecomputedScopes>;
|
|
11
|
+
protected processContainer(container: ElementsContainer, scopes: PrecomputedScopes, document: LikeC4LangiumDocument): MultiMap<string, AstNodeDescription>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=scope-computation.d.ts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { DefaultScopeComputation, MultiMap } from 'langium';
|
|
2
|
+
import { ast } from '../ast';
|
|
3
|
+
import { computeDocumentFqn } from './fqn-computation';
|
|
4
|
+
export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
5
|
+
services;
|
|
6
|
+
constructor(services) {
|
|
7
|
+
super(services);
|
|
8
|
+
this.services = services;
|
|
9
|
+
}
|
|
10
|
+
computeExports(document, _cancelToken) {
|
|
11
|
+
const { specification, model, views } = document.parseResult.value;
|
|
12
|
+
const docExports = [];
|
|
13
|
+
if (specification) {
|
|
14
|
+
for (const { kind } of specification.elementKinds) {
|
|
15
|
+
docExports.push(this.descriptions.createDescription(kind, kind.name, document));
|
|
16
|
+
}
|
|
17
|
+
for (const { tag } of specification.tags) {
|
|
18
|
+
docExports.push(this.descriptions.createDescription(tag, tag.name, document));
|
|
19
|
+
docExports.push(this.descriptions.createDescription(tag, '#' + tag.name, document));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
document.c4fqns = undefined;
|
|
23
|
+
if (model) {
|
|
24
|
+
for (const elAst of model.elements) {
|
|
25
|
+
if (ast.isElement(elAst)) {
|
|
26
|
+
docExports.push(this.descriptions.createDescription(elAst, elAst.name, document));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
computeDocumentFqn(document, this.services);
|
|
30
|
+
}
|
|
31
|
+
// const c4fqns = document.c4fqns
|
|
32
|
+
// logger.debug(`doc ${document.uri.path}:
|
|
33
|
+
// fqns: ${c4fqns ? Array.from(c4fqns.keys()).join(', ') : '--'}
|
|
34
|
+
// `)
|
|
35
|
+
if (views) {
|
|
36
|
+
for (const viewAst of views.views) {
|
|
37
|
+
if ('name' in viewAst) {
|
|
38
|
+
docExports.push(this.descriptions.createDescription(viewAst, viewAst.name, document));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return Promise.resolve(docExports);
|
|
43
|
+
}
|
|
44
|
+
async computeLocalScopes(document, _cancelToken) {
|
|
45
|
+
const root = document.parseResult.value;
|
|
46
|
+
const scopes = new MultiMap();
|
|
47
|
+
if (root.model) {
|
|
48
|
+
const nested = this.processContainer(root.model, scopes, document);
|
|
49
|
+
scopes.addAll(root, nested.values());
|
|
50
|
+
}
|
|
51
|
+
return Promise.resolve(scopes);
|
|
52
|
+
}
|
|
53
|
+
processContainer(container, scopes, document) {
|
|
54
|
+
const localScope = new MultiMap();
|
|
55
|
+
const nestedScopes = new MultiMap();
|
|
56
|
+
for (const el of container.elements) {
|
|
57
|
+
if (ast.isRelation(el)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
let subcontainer;
|
|
61
|
+
if (ast.isElement(el)) {
|
|
62
|
+
localScope.add(el.name, this.descriptions.createDescription(el, el.name, document));
|
|
63
|
+
subcontainer = el.body;
|
|
64
|
+
}
|
|
65
|
+
else if (ast.isExtendElement(el)) {
|
|
66
|
+
subcontainer = el.body;
|
|
67
|
+
}
|
|
68
|
+
if (subcontainer && subcontainer.elements.length > 0) {
|
|
69
|
+
const nested = this.processContainer(subcontainer, scopes, document);
|
|
70
|
+
for (const [nestedName, desc] of nested) {
|
|
71
|
+
nestedScopes.add(nestedName, desc);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const [name, descriptions] of nestedScopes.entriesGroupedByKey()) {
|
|
76
|
+
// If name is unique for current scope
|
|
77
|
+
if (!localScope.has(name) && descriptions.length === 1) {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
79
|
+
localScope.add(name, descriptions[0]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
scopes.addAll(container, localScope.values());
|
|
83
|
+
return localScope;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=scope-computation.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AstNode } from 'langium';
|
|
2
|
+
import { DefaultScopeProvider, type ReferenceInfo, type Scope } from 'langium';
|
|
3
|
+
import type { LikeC4Services } from '../module';
|
|
4
|
+
export declare class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
5
|
+
private fqnIndex;
|
|
6
|
+
constructor(services: LikeC4Services);
|
|
7
|
+
private directChildrenOf;
|
|
8
|
+
private uniqueDescedants;
|
|
9
|
+
private scopeElementRef;
|
|
10
|
+
private scopeExtendElement;
|
|
11
|
+
private scopeElementView;
|
|
12
|
+
getScope(context: ReferenceInfo): Scope;
|
|
13
|
+
protected computeScope(node: AstNode, referenceType: string): Scope;
|
|
14
|
+
/**
|
|
15
|
+
* Create a global scope filtered for the given reference type.
|
|
16
|
+
*/
|
|
17
|
+
protected getGlobalScope(referenceType: string): Scope;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=scope-provider.d.ts.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { DONE_RESULT, DefaultScopeProvider, EMPTY_STREAM, StreamImpl, StreamScope, getDocument, stream } from 'langium';
|
|
2
|
+
import { ast } from '../ast';
|
|
3
|
+
import { elementRef, isElementRefHead, parentStrictElementRef } from '../elementRef';
|
|
4
|
+
import { logger } from '../logger';
|
|
5
|
+
function toAstNodeDescription(entry) {
|
|
6
|
+
return {
|
|
7
|
+
documentUri: entry.doc.uri,
|
|
8
|
+
name: entry.name,
|
|
9
|
+
path: entry.path,
|
|
10
|
+
type: ast.Element
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export class LikeC4ScopeProvider extends DefaultScopeProvider {
|
|
14
|
+
fqnIndex;
|
|
15
|
+
constructor(services) {
|
|
16
|
+
super(services);
|
|
17
|
+
this.fqnIndex = services.likec4.FqnIndex;
|
|
18
|
+
}
|
|
19
|
+
directChildrenOf(parent) {
|
|
20
|
+
return this.fqnIndex
|
|
21
|
+
.directChildrenOf(parent)
|
|
22
|
+
.map(toAstNodeDescription);
|
|
23
|
+
}
|
|
24
|
+
uniqueDescedants(of) {
|
|
25
|
+
return new StreamImpl(() => {
|
|
26
|
+
const element = of();
|
|
27
|
+
const fqn = element && this.fqnIndex.get(element);
|
|
28
|
+
if (fqn) {
|
|
29
|
+
return this.fqnIndex.uniqueDescedants(fqn)
|
|
30
|
+
.map(toAstNodeDescription)
|
|
31
|
+
.iterator();
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}, iterator => {
|
|
35
|
+
if (iterator) {
|
|
36
|
+
return iterator.next();
|
|
37
|
+
}
|
|
38
|
+
return DONE_RESULT;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
scopeElementRef(ref) {
|
|
42
|
+
const parentNode = ref.$container;
|
|
43
|
+
if (!ast.isElementRef(parentNode)) {
|
|
44
|
+
throw new Error('Expected be inside ElementRef');
|
|
45
|
+
}
|
|
46
|
+
return this.uniqueDescedants(() => parentNode.el.ref);
|
|
47
|
+
}
|
|
48
|
+
scopeExtendElement(extend) {
|
|
49
|
+
return this.uniqueDescedants(() => elementRef(extend.element));
|
|
50
|
+
}
|
|
51
|
+
scopeElementView({ viewOf }) {
|
|
52
|
+
if (!viewOf) {
|
|
53
|
+
return EMPTY_STREAM;
|
|
54
|
+
}
|
|
55
|
+
return this.uniqueDescedants(() => elementRef(viewOf));
|
|
56
|
+
}
|
|
57
|
+
getScope(context) {
|
|
58
|
+
const referenceType = this.reflection.getReferenceType(context);
|
|
59
|
+
try {
|
|
60
|
+
const node = context.container;
|
|
61
|
+
// const path = this.services.workspace.AstNodeLocator.getAstNodePath(node)
|
|
62
|
+
if (referenceType === ast.Element) {
|
|
63
|
+
if (ast.isStrictElementRef(node)) {
|
|
64
|
+
if (isElementRefHead(node)) {
|
|
65
|
+
return this.getGlobalScope(referenceType);
|
|
66
|
+
}
|
|
67
|
+
const parent = parentStrictElementRef(node);
|
|
68
|
+
return new StreamScope(this.directChildrenOf(parent));
|
|
69
|
+
}
|
|
70
|
+
if (ast.isElementRef(node) && !isElementRefHead(node)) {
|
|
71
|
+
return new StreamScope(this.scopeElementRef(node));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return this.computeScope(node, referenceType);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
// console.error(e)
|
|
78
|
+
logger.error(e);
|
|
79
|
+
return this.getGlobalScope(referenceType);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
computeScope(node, referenceType) {
|
|
83
|
+
const scopes = [];
|
|
84
|
+
const doc = getDocument(node);
|
|
85
|
+
const precomputed = doc.precomputedScopes;
|
|
86
|
+
const byReferenceType = (desc) => this.reflection.isSubtype(desc.type, referenceType);
|
|
87
|
+
if (precomputed) {
|
|
88
|
+
const elements = precomputed.get(node).filter(byReferenceType);
|
|
89
|
+
if (elements.length > 0) {
|
|
90
|
+
scopes.push(stream(elements));
|
|
91
|
+
}
|
|
92
|
+
let container = node.$container;
|
|
93
|
+
while (container) {
|
|
94
|
+
const elements = precomputed.get(container).filter(byReferenceType);
|
|
95
|
+
if (elements.length > 0) {
|
|
96
|
+
scopes.push(stream(elements));
|
|
97
|
+
}
|
|
98
|
+
if (referenceType === ast.Element) {
|
|
99
|
+
if (ast.isExtendElementBody(container)) {
|
|
100
|
+
scopes.push(this.scopeExtendElement(container.$container));
|
|
101
|
+
}
|
|
102
|
+
if (ast.isViewRule(container)) {
|
|
103
|
+
scopes.push(this.scopeElementView(container.$container));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
container = container.$container;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return scopes.reduceRight((outerScope, elements) => {
|
|
110
|
+
return this.createScope(elements, outerScope);
|
|
111
|
+
}, this.getGlobalScope(referenceType));
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create a global scope filtered for the given reference type.
|
|
115
|
+
*/
|
|
116
|
+
getGlobalScope(referenceType) {
|
|
117
|
+
return new StreamScope(this.indexManager.allElements(referenceType));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=scope-provider.js.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { logger } from './logger';
|
|
2
|
+
import { Rpc } from './protocol';
|
|
3
|
+
export function registerProtocolHandlers(services) {
|
|
4
|
+
const connection = services.shared.lsp.Connection;
|
|
5
|
+
if (!connection) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const modelBuilder = services.likec4.ModelBuilder;
|
|
9
|
+
const modelLocator = services.likec4.ModelLocator;
|
|
10
|
+
const LangiumDocuments = services.shared.workspace.LangiumDocuments;
|
|
11
|
+
connection.onRequest(Rpc.fetchModel, async (_cancelToken) => {
|
|
12
|
+
let model;
|
|
13
|
+
try {
|
|
14
|
+
model = modelBuilder.buildModel() ?? null;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
model = null;
|
|
18
|
+
logger.error(e);
|
|
19
|
+
}
|
|
20
|
+
return Promise.resolve({
|
|
21
|
+
model: model ?? null
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
connection.onRequest(Rpc.buildDocuments, async ({ docs }, cancelToken) => {
|
|
25
|
+
const changed = [];
|
|
26
|
+
for (const d of docs) {
|
|
27
|
+
const uri = d;
|
|
28
|
+
if (LangiumDocuments.hasDocument(uri)) {
|
|
29
|
+
changed.push(uri);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
logger.error(`LangiumDocuments does not have document: ${uri.toString()}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
logger.debug(`Received request to rebuild: [
|
|
36
|
+
${changed.map(d => d.toString()).join('\n ')}
|
|
37
|
+
]`);
|
|
38
|
+
await services.shared.workspace.DocumentBuilder.update(changed, [], cancelToken);
|
|
39
|
+
});
|
|
40
|
+
connection.onRequest(Rpc.locateElement, async ({ element, property }, _cancelToken) => {
|
|
41
|
+
try {
|
|
42
|
+
return Promise.resolve(modelLocator.locateElement(element, property ?? 'name'));
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
return Promise.reject(e);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
connection.onRequest(Rpc.locateRelation, ({ id }, _cancelToken) => {
|
|
49
|
+
try {
|
|
50
|
+
return Promise.resolve(modelLocator.locateRelation(id));
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
return Promise.reject(e);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
connection.onRequest(Rpc.locateView, ({ id }, _cancelToken) => {
|
|
57
|
+
try {
|
|
58
|
+
return Promise.resolve(modelLocator.locateView(id));
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return Promise.reject(e);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=registerProtocolHandlers.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LangiumDocument, LangiumSharedServices, MaybePromise } from 'langium';
|
|
2
|
+
import type { CodeLensProvider } from 'langium/lib/lsp/code-lens-provider';
|
|
3
|
+
import type { CancellationToken, CodeLens, CodeLensParams } from 'vscode-languageserver';
|
|
4
|
+
export declare class LikeC4CodeLensProvider implements CodeLensProvider {
|
|
5
|
+
private services;
|
|
6
|
+
constructor(services: LangiumSharedServices);
|
|
7
|
+
provideCodeLens(doc: LangiumDocument, _params: CodeLensParams, _cancelToken?: CancellationToken): MaybePromise<CodeLens[] | undefined>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=CodeLensProvider.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ElementViewOps, isParsedLikeC4LangiumDocument } from '../ast';
|
|
2
|
+
export class LikeC4CodeLensProvider {
|
|
3
|
+
services;
|
|
4
|
+
constructor(services) {
|
|
5
|
+
this.services = services;
|
|
6
|
+
//
|
|
7
|
+
}
|
|
8
|
+
provideCodeLens(doc, _params, _cancelToken) {
|
|
9
|
+
if (!isParsedLikeC4LangiumDocument(doc)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
return doc.parseResult.value.views?.views.flatMap(ast => {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
+
const viewId = ElementViewOps.readId(ast);
|
|
15
|
+
const range = ast.$cstNode?.range;
|
|
16
|
+
if (!range || !viewId) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
range: {
|
|
21
|
+
start: range.start,
|
|
22
|
+
end: {
|
|
23
|
+
line: range.start.line,
|
|
24
|
+
character: range.start.character + 4
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
command: {
|
|
28
|
+
command: 'likec4.open-preview',
|
|
29
|
+
arguments: [viewId],
|
|
30
|
+
title: 'open preview'
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=CodeLensProvider.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { LangiumDocument, LangiumDocumentFactory, LangiumSharedServices } from 'langium';
|
|
2
|
+
import { DefaultWorkspaceManager } from 'langium';
|
|
3
|
+
import type { WorkspaceFolder } from 'vscode-languageserver';
|
|
4
|
+
export declare class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
5
|
+
protected readonly documentFactory: LangiumDocumentFactory;
|
|
6
|
+
constructor(services: LangiumSharedServices);
|
|
7
|
+
/**
|
|
8
|
+
* Load all additional documents that shall be visible in the context of the given workspace
|
|
9
|
+
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
10
|
+
* your language, which can be either loaded from provided files or constructed in memory.
|
|
11
|
+
*/
|
|
12
|
+
protected loadAdditionalDocuments(_folders: WorkspaceFolder[], _collector: (document: LangiumDocument) => void): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=WorkspaceManager.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DefaultWorkspaceManager } from 'langium';
|
|
2
|
+
export class LikeC4WorkspaceManager extends DefaultWorkspaceManager {
|
|
3
|
+
documentFactory;
|
|
4
|
+
constructor(services) {
|
|
5
|
+
super(services);
|
|
6
|
+
this.documentFactory = services.workspace.LangiumDocumentFactory;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Load all additional documents that shall be visible in the context of the given workspace
|
|
10
|
+
* folders and add them to the collector. This can be used to include built-in libraries of
|
|
11
|
+
* your language, which can be either loaded from provided files or constructed in memory.
|
|
12
|
+
*/
|
|
13
|
+
loadAdditionalDocuments(_folders, _collector) {
|
|
14
|
+
// collector(this.documentFactory.fromString(builtin.specification.document, URI.parse(builtin.specification.uri)))
|
|
15
|
+
return Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=WorkspaceManager.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LikeC4LangiumDocument } from '../ast';
|
|
2
|
+
export declare function createTestServices(): {
|
|
3
|
+
services: import("../module").LikeC4Services;
|
|
4
|
+
parse: (input: string, uri?: string) => Promise<LikeC4LangiumDocument>;
|
|
5
|
+
validate: (input: string | LikeC4LangiumDocument) => Promise<{
|
|
6
|
+
document: LikeC4LangiumDocument;
|
|
7
|
+
diagnostics: import("vscode-languageserver-types").Diagnostic[];
|
|
8
|
+
errors: string[];
|
|
9
|
+
}>;
|
|
10
|
+
validateAll: () => Promise<{
|
|
11
|
+
diagnostics: import("vscode-languageserver-types").Diagnostic[];
|
|
12
|
+
errors: string[];
|
|
13
|
+
}>;
|
|
14
|
+
buildModel: () => Promise<import("@likec4/core").LikeC4Model>;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=testServices.d.ts.map
|