@likec4/language-server 0.26.0 → 0.27.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 +3 -1
- package/contrib/likec4.tmLanguage.json +1 -1
- package/dist/ast.d.ts +1 -1
- package/dist/generated/ast.d.ts +14 -4
- package/dist/generated/ast.js +10 -3
- package/dist/generated/grammar.js +278 -134
- package/dist/lsp/DocumentSymbolProvider.js +16 -22
- package/dist/model/fqn-computation.js +1 -1
- package/dist/model/fqn-index.js +2 -2
- package/dist/model/model-builder.js +4 -4
- package/dist/module.js +3 -2
- package/dist/references/scope-computation.js +15 -12
- package/dist/shared/DocumentLinkProvider.d.ts +8 -0
- package/dist/shared/DocumentLinkProvider.js +37 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* This program and the accompanying materials are made available under the
|
|
4
4
|
* terms of the MIT License, which is available in the project root.
|
|
5
5
|
******************************************************************************/
|
|
6
|
-
import invariant from 'tiny-invariant';
|
|
7
6
|
import { findNodeForProperty } from 'langium';
|
|
8
7
|
import { SymbolKind } from 'vscode-languageserver-protocol';
|
|
9
8
|
import { ast } from '../ast';
|
|
10
9
|
import { logger } from '../logger';
|
|
10
|
+
import { isEmpty } from 'remeda';
|
|
11
11
|
export class LikeC4DocumentSymbolProvider {
|
|
12
12
|
services;
|
|
13
13
|
constructor(services) {
|
|
@@ -28,10 +28,20 @@ export class LikeC4DocumentSymbolProvider {
|
|
|
28
28
|
const specKeywordNode = findNodeForProperty(cstModel, 'name');
|
|
29
29
|
if (!specKeywordNode)
|
|
30
30
|
return [];
|
|
31
|
-
const specSymbols =
|
|
31
|
+
const specSymbols = astSpec.specs.flatMap(nd => {
|
|
32
|
+
if (ast.isSpecificationElementKind(nd)) {
|
|
33
|
+
return getElementKindSymbol(nd) ?? [];
|
|
34
|
+
}
|
|
35
|
+
else if (ast.isSpecificationTag(nd)) {
|
|
36
|
+
return getTagSymbol(nd) ?? [];
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
});
|
|
32
42
|
const getElementKindSymbol = (astKind) => {
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
if (!astKind.$cstNode || !astKind.kind.$cstNode || isEmpty(astKind.kind.name))
|
|
44
|
+
return null;
|
|
35
45
|
return {
|
|
36
46
|
kind: SymbolKind.Class,
|
|
37
47
|
name: astKind.kind.name,
|
|
@@ -39,17 +49,9 @@ export class LikeC4DocumentSymbolProvider {
|
|
|
39
49
|
selectionRange: astKind.kind.$cstNode.range
|
|
40
50
|
};
|
|
41
51
|
};
|
|
42
|
-
for (const astKind of astSpec.elementKinds) {
|
|
43
|
-
try {
|
|
44
|
-
specSymbols.push(getElementKindSymbol(astKind));
|
|
45
|
-
}
|
|
46
|
-
catch (e) {
|
|
47
|
-
logger.error(e);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
52
|
const getTagSymbol = (astTag) => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
if (!astTag.$cstNode || !astTag.tag.$cstNode || isEmpty(astTag.tag.name))
|
|
54
|
+
return null;
|
|
53
55
|
return {
|
|
54
56
|
kind: SymbolKind.EnumMember,
|
|
55
57
|
name: '#' + astTag.tag.name,
|
|
@@ -57,14 +59,6 @@ export class LikeC4DocumentSymbolProvider {
|
|
|
57
59
|
selectionRange: astTag.tag.$cstNode.range
|
|
58
60
|
};
|
|
59
61
|
};
|
|
60
|
-
for (const astTag of astSpec.tags) {
|
|
61
|
-
try {
|
|
62
|
-
specSymbols.push(getTagSymbol(astTag));
|
|
63
|
-
}
|
|
64
|
-
catch (e) {
|
|
65
|
-
logger.error(e);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
62
|
if (specSymbols.length === 0)
|
|
69
63
|
return [];
|
|
70
64
|
return [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { failExpectedNever } from '@likec4/core';
|
|
2
2
|
import { Fqn } from '@likec4/core/types';
|
|
3
3
|
import { MultiMap } from 'langium';
|
|
4
|
-
import { isEmpty, isNil } from '
|
|
4
|
+
import { isEmpty, isNil } from 'remeda';
|
|
5
5
|
import { ElementOps, ast } from '../ast';
|
|
6
6
|
import { strictElementRefFqn } from '../elementRef';
|
|
7
7
|
export function computeDocumentFqn(document, services) {
|
package/dist/model/fqn-index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { nameFromFqn, parentFqn } from '@likec4/core/utils';
|
|
2
|
-
import {
|
|
2
|
+
import { DONE_RESULT, DocumentState, MultiMap, StreamImpl } from 'langium';
|
|
3
3
|
import { isNil } from 'remeda';
|
|
4
4
|
import { ElementOps, isLikeC4LangiumDocument } from '../ast';
|
|
5
5
|
import { logger } from '../logger';
|
|
6
6
|
import { computeDocumentFqn } from './fqn-computation';
|
|
7
7
|
export function isFqnIndexedDocument(doc) {
|
|
8
|
-
return isLikeC4LangiumDocument(doc) && !isNil(doc.c4fqns);
|
|
8
|
+
return isLikeC4LangiumDocument(doc) && doc.state >= DocumentState.IndexedContent && !isNil(doc.c4fqns);
|
|
9
9
|
}
|
|
10
10
|
export class FqnIndex {
|
|
11
11
|
services;
|
|
@@ -5,13 +5,13 @@ import { DocumentState, getDocument } from 'langium';
|
|
|
5
5
|
import objectHash from 'object-hash';
|
|
6
6
|
import { clone } from 'rambdax';
|
|
7
7
|
import * as R from 'remeda';
|
|
8
|
+
import stripIndent from 'strip-indent';
|
|
8
9
|
import invariant from 'tiny-invariant';
|
|
9
10
|
import { ElementViewOps, ast, cleanParsedModel, isLikeC4LangiumDocument, isValidLikeC4LangiumDocument, resolveRelationPoints, streamModel, toAutoLayout, toElementStyle } from '../ast';
|
|
10
11
|
import { elementRef, strictElementRefFqn } from '../elementRef';
|
|
11
12
|
import { logger } from '../logger';
|
|
12
13
|
import { Rpc } from '../protocol';
|
|
13
14
|
import { failExpectedNever } from '../utils';
|
|
14
|
-
import stripIndent from 'strip-indent';
|
|
15
15
|
export class LikeC4ModelBuilder {
|
|
16
16
|
services;
|
|
17
17
|
fqnIndex;
|
|
@@ -129,9 +129,9 @@ export class LikeC4ModelBuilder {
|
|
|
129
129
|
*/
|
|
130
130
|
parseDocument(doc) {
|
|
131
131
|
const { elements, relations, views, specification } = cleanParsedModel(doc);
|
|
132
|
-
const
|
|
133
|
-
if (
|
|
134
|
-
for (const { kind, style } of
|
|
132
|
+
const specs = doc.parseResult.value.specification?.specs.filter(ast.isSpecificationElementKind);
|
|
133
|
+
if (specs) {
|
|
134
|
+
for (const { kind, style } of specs) {
|
|
135
135
|
try {
|
|
136
136
|
const styleProps = toElementStyle(style?.props);
|
|
137
137
|
specification.kinds[kind.name] = {
|
package/dist/module.js
CHANGED
|
@@ -4,7 +4,7 @@ import { LikeC4DocumentSymbolProvider, LikeC4HoverProvider, LikeC4SemanticTokenP
|
|
|
4
4
|
import { FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator } from './model';
|
|
5
5
|
import { LikeC4ScopeComputation, LikeC4ScopeProvider } from './references';
|
|
6
6
|
import { registerProtocolHandlers } from './registerProtocolHandlers';
|
|
7
|
-
import { LikeC4CodeLensProvider, LikeC4WorkspaceManager } from './shared';
|
|
7
|
+
import { LikeC4CodeLensProvider, LikeC4DocumentLinkProvider, LikeC4WorkspaceManager } from './shared';
|
|
8
8
|
import { registerValidationChecks } from './validation';
|
|
9
9
|
import { logger } from './logger';
|
|
10
10
|
function bind(Type) {
|
|
@@ -36,7 +36,8 @@ const LikeC4SharedModule = {
|
|
|
36
36
|
WorkspaceManager: services => new LikeC4WorkspaceManager(services)
|
|
37
37
|
},
|
|
38
38
|
lsp: {
|
|
39
|
-
CodeLensProvider: services => new LikeC4CodeLensProvider(services)
|
|
39
|
+
CodeLensProvider: services => new LikeC4CodeLensProvider(services),
|
|
40
|
+
DocumentLinkProvider: services => new LikeC4DocumentLinkProvider(services)
|
|
40
41
|
}
|
|
41
42
|
};
|
|
42
43
|
export function createLanguageServices(context) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DefaultScopeComputation, MultiMap } from 'langium';
|
|
2
2
|
import { ast } from '../ast';
|
|
3
|
+
import { isEmpty } from 'remeda';
|
|
3
4
|
export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
4
5
|
services;
|
|
5
6
|
constructor(services) {
|
|
@@ -9,28 +10,30 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
9
10
|
computeExports(document, _cancelToken) {
|
|
10
11
|
const { specification, model, views } = document.parseResult.value;
|
|
11
12
|
const docExports = [];
|
|
12
|
-
if (specification) {
|
|
13
|
-
for (const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
if (specification && specification.specs.length > 0) {
|
|
14
|
+
for (const spec of specification.specs) {
|
|
15
|
+
if (ast.isSpecificationElementKind(spec) && spec.kind && !isEmpty(spec.kind.name)) {
|
|
16
|
+
docExports.push(this.descriptions.createDescription(spec.kind, spec.kind.name, document));
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (ast.isSpecificationTag(spec) && spec.tag && !isEmpty(spec.tag.name)) {
|
|
20
|
+
docExports.push(this.descriptions.createDescription(spec.tag, spec.tag.name, document));
|
|
21
|
+
docExports.push(this.descriptions.createDescription(spec.tag, '#' + spec.tag.name, document));
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
19
24
|
}
|
|
20
25
|
}
|
|
21
|
-
// Filled later by FqnIndex (on IndexedContent phase)
|
|
22
|
-
document.c4fqns = undefined;
|
|
23
26
|
// Only root model elements are exported
|
|
24
27
|
if (model && model.elements.length > 0) {
|
|
25
28
|
for (const elAst of model.elements) {
|
|
26
|
-
if (ast.isElement(elAst)) {
|
|
29
|
+
if (ast.isElement(elAst) && !isEmpty(elAst.name)) {
|
|
27
30
|
docExports.push(this.descriptions.createDescription(elAst, elAst.name, document));
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
if (views && views.views.length > 0) {
|
|
32
35
|
for (const viewAst of views.views) {
|
|
33
|
-
if (
|
|
36
|
+
if (viewAst.name && !isEmpty(viewAst.name)) {
|
|
34
37
|
docExports.push(this.descriptions.createDescription(viewAst, viewAst.name, document));
|
|
35
38
|
}
|
|
36
39
|
}
|
|
@@ -54,7 +57,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
|
|
|
54
57
|
continue;
|
|
55
58
|
}
|
|
56
59
|
let subcontainer;
|
|
57
|
-
if (ast.isElement(el)) {
|
|
60
|
+
if (ast.isElement(el) && !isEmpty(el.name)) {
|
|
58
61
|
localScope.add(el.name, this.descriptions.createDescription(el, el.name, document));
|
|
59
62
|
subcontainer = el.body;
|
|
60
63
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LangiumDocument, LangiumSharedServices, MaybePromise, DocumentLinkProvider } from 'langium';
|
|
2
|
+
import type { DocumentLink, DocumentLinkParams } from 'vscode-languageserver-protocol';
|
|
3
|
+
export declare class LikeC4DocumentLinkProvider implements DocumentLinkProvider {
|
|
4
|
+
private services;
|
|
5
|
+
constructor(services: LangiumSharedServices);
|
|
6
|
+
getDocumentLinks(doc: LangiumDocument, _params: DocumentLinkParams): MaybePromise<DocumentLink[]>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=DocumentLinkProvider.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { findNodeForProperty, streamAllContents } from 'langium/lib/utils';
|
|
2
|
+
import { ast, isParsedLikeC4LangiumDocument } from '../ast';
|
|
3
|
+
import { logger } from '../logger';
|
|
4
|
+
export class LikeC4DocumentLinkProvider {
|
|
5
|
+
services;
|
|
6
|
+
constructor(services) {
|
|
7
|
+
this.services = services;
|
|
8
|
+
//
|
|
9
|
+
}
|
|
10
|
+
getDocumentLinks(doc, _params) {
|
|
11
|
+
if (!isParsedLikeC4LangiumDocument(doc)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const base = new URL(doc.uri.toString());
|
|
15
|
+
return streamAllContents(doc.parseResult.value)
|
|
16
|
+
.filter(ast.isLinkProperty)
|
|
17
|
+
.flatMap((n) => {
|
|
18
|
+
try {
|
|
19
|
+
const u = new URL(n.value, base);
|
|
20
|
+
const valueCst = findNodeForProperty(n.$cstNode, 'value');
|
|
21
|
+
if (!valueCst) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
range: valueCst.range,
|
|
26
|
+
target: u.toString()
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
logger.error(e);
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.toArray();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=DocumentLinkProvider.js.map
|
package/dist/shared/index.d.ts
CHANGED
package/dist/shared/index.js
CHANGED