dot-language-support 4.2.0 → 4.3.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/README.md +1 -1
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +106 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# dot-language-support [](https://github.com/nikeee/dot-language-support/actions/workflows/CD.yaml) [](https://github.com/nikeee/dot-language-support/actions/workflows/CI.yaml)  [](https://www.npmjs.com/package/dot-language-support)
|
|
2
2
|
|
|
3
3
|
A language service library, written in TypeScript. Used by [dot-language-server](https://github.com/nikeee/dot-language-server) and [edotor.net](https://edotor.net).
|
|
4
4
|
|
package/dist/index.d.mts
CHANGED
|
@@ -553,8 +553,10 @@ interface LanguageService {
|
|
|
553
553
|
hover(doc: DocumentLike, sourceFile: SourceFile, position: lst.Position): lst.Hover | undefined;
|
|
554
554
|
findReferences(doc: DocumentLike, sourceFile: SourceFile, position: lst.Position, context: lst.ReferenceContext): lst.Location[];
|
|
555
555
|
findDefinition(doc: DocumentLike, sourceFile: SourceFile, position: lst.Position): lst.Location | undefined;
|
|
556
|
+
findDeclaration(doc: DocumentLike, sourceFile: SourceFile, position: lst.Position): lst.Location | undefined;
|
|
556
557
|
renameSymbol(doc: DocumentLike, sourceFile: SourceFile, position: lst.Position, newName: string): lst.WorkspaceEdit | undefined;
|
|
557
558
|
getCompletions(doc: DocumentLike, sourceFile: SourceFile, position: lst.Position): lst.CompletionItem[];
|
|
559
|
+
getSelectionRanges(doc: DocumentLike, sourceFile: SourceFile, positions: lst.Position[]): lst.SelectionRange[];
|
|
558
560
|
getDocumentColors(doc: DocumentLike, sourceFile: SourceFile): ColorInformation[] | undefined;
|
|
559
561
|
getColorRepresentations(doc: DocumentLike, sourceFile: SourceFile, color: Color$1, range: lst.Range): ColorPresentation[] | undefined;
|
|
560
562
|
getCodeActions(doc: DocumentLike, sourceFile: SourceFile, range: lst.Range, context: lst.CodeActionContext): lst.Command[] | undefined;
|
package/dist/index.mjs
CHANGED
|
@@ -295,6 +295,13 @@ const characterCodes = {
|
|
|
295
295
|
};
|
|
296
296
|
//#endregion
|
|
297
297
|
//#region src/service/util.ts
|
|
298
|
+
function posRangeToRange(doc, sourceFile, pos, end) {
|
|
299
|
+
const start = pos === end ? pos : skipTrivia(sourceFile.content, pos);
|
|
300
|
+
return {
|
|
301
|
+
start: doc.positionAt(start),
|
|
302
|
+
end: doc.positionAt(end)
|
|
303
|
+
};
|
|
304
|
+
}
|
|
298
305
|
function getStart(sourceFile, node) {
|
|
299
306
|
return getTokenPosOfNode(sourceFile, node);
|
|
300
307
|
}
|
|
@@ -3268,11 +3275,17 @@ function hover(doc, sourceFile, position) {
|
|
|
3268
3275
|
return getNodeHover(doc, sourceFile, node);
|
|
3269
3276
|
}
|
|
3270
3277
|
function getNodeHover(doc, sf, n) {
|
|
3271
|
-
const
|
|
3272
|
-
if (
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3278
|
+
const result = getHoverContents(n);
|
|
3279
|
+
if (result) {
|
|
3280
|
+
const { pos, end } = result.range ?? {
|
|
3281
|
+
pos: n.pos,
|
|
3282
|
+
end: n.end
|
|
3283
|
+
};
|
|
3284
|
+
return {
|
|
3285
|
+
contents: result.contents,
|
|
3286
|
+
range: posRangeToRange(doc, sf, pos, end)
|
|
3287
|
+
};
|
|
3288
|
+
}
|
|
3276
3289
|
}
|
|
3277
3290
|
function getAssignedLabel(statement) {
|
|
3278
3291
|
const assignedLabel = statement.attributes.flatMap((a) => a.assignments)?.find((a) => getIdentifierText(a.leftId) === "label");
|
|
@@ -3288,37 +3301,63 @@ function getHoverContents(n) {
|
|
|
3288
3301
|
const labelMentions = (n.symbol?.references).map((e) => e.symbol?.members?.get("label")?.firstMention.parent);
|
|
3289
3302
|
for (let i = labelMentions.length; i >= 0; i--) {
|
|
3290
3303
|
const s = labelMentions[i];
|
|
3291
|
-
if (s?.rightId) return `(node) ${getIdentifierText(n)}: ${getIdentifierText(s.rightId)}
|
|
3304
|
+
if (s?.rightId) return { contents: `(node) ${getIdentifierText(n)}: ${getIdentifierText(s.rightId)}` };
|
|
3292
3305
|
}
|
|
3293
3306
|
} else if (parent.parent?.kind === syntaxKind.NodeStatement) {
|
|
3294
3307
|
const label = getAssignedLabel(parent.parent);
|
|
3295
|
-
if (label) return `(node) ${getIdentifierText(n)}: ${label}
|
|
3308
|
+
if (label) return { contents: `(node) ${getIdentifierText(n)}: ${label}` };
|
|
3296
3309
|
}
|
|
3297
|
-
return `(node) ${getIdentifierText(n)}
|
|
3310
|
+
return { contents: `(node) ${getIdentifierText(n)}` };
|
|
3298
3311
|
case syntaxKind.Assignment: {
|
|
3299
3312
|
const assignment = parent;
|
|
3300
|
-
return
|
|
3313
|
+
return {
|
|
3314
|
+
contents: `(assignment) \`${getIdentifierText(assignment.leftId)}\` = \`${getIdentifierText(assignment.rightId)}\``,
|
|
3315
|
+
range: {
|
|
3316
|
+
pos: assignment.pos,
|
|
3317
|
+
end: assignment.end
|
|
3318
|
+
}
|
|
3319
|
+
};
|
|
3301
3320
|
}
|
|
3302
3321
|
case syntaxKind.DirectedGraph: return getGraphHover(parent);
|
|
3303
3322
|
case syntaxKind.UndirectedGraph: return getGraphHover(parent);
|
|
3304
3323
|
case syntaxKind.SubGraphStatement: {
|
|
3305
|
-
const
|
|
3306
|
-
|
|
3324
|
+
const sgs = parent;
|
|
3325
|
+
const sg = sgs.subgraph;
|
|
3326
|
+
return {
|
|
3327
|
+
contents: sg.id ? `(sub graph) ${getIdentifierText(sg.id)}` : "(sub graph)",
|
|
3328
|
+
range: {
|
|
3329
|
+
pos: sgs.pos,
|
|
3330
|
+
end: sgs.end
|
|
3331
|
+
}
|
|
3332
|
+
};
|
|
3307
3333
|
}
|
|
3308
3334
|
case syntaxKind.SubGraph: {
|
|
3309
3335
|
const sg = parent;
|
|
3310
|
-
return
|
|
3336
|
+
return {
|
|
3337
|
+
contents: sg.id ? `(sub graph) ${getIdentifierText(sg.id)}` : "(sub graph)",
|
|
3338
|
+
range: {
|
|
3339
|
+
pos: sg.pos,
|
|
3340
|
+
end: sg.end
|
|
3341
|
+
}
|
|
3342
|
+
};
|
|
3311
3343
|
}
|
|
3312
3344
|
case syntaxKind.IdEqualsIdStatement: {
|
|
3313
3345
|
const idEqId = parent;
|
|
3314
|
-
return
|
|
3346
|
+
return {
|
|
3347
|
+
contents: `(graph property) \`${getIdentifierText(idEqId.leftId)}\` = \`${getIdentifierText(idEqId.rightId)}\``,
|
|
3348
|
+
range: {
|
|
3349
|
+
pos: idEqId.pos,
|
|
3350
|
+
end: idEqId.end
|
|
3351
|
+
}
|
|
3352
|
+
};
|
|
3315
3353
|
}
|
|
3316
3354
|
case syntaxKind.EdgeRhs: return getEdgeHover(parent);
|
|
3317
3355
|
}
|
|
3318
|
-
|
|
3356
|
+
const fallbackParent = syntaxKindNames[parent.kind];
|
|
3357
|
+
return fallbackParent ? { contents: fallbackParent } : void 0;
|
|
3319
3358
|
}
|
|
3320
3359
|
const fallback = syntaxKindNames[n.kind];
|
|
3321
|
-
return fallback ? `(${fallback.toLowerCase()})` : void 0;
|
|
3360
|
+
return fallback ? { contents: `(${fallback.toLowerCase()})` } : void 0;
|
|
3322
3361
|
}
|
|
3323
3362
|
switch (n.kind) {
|
|
3324
3363
|
case syntaxKind.GraphKeyword:
|
|
@@ -3335,7 +3374,13 @@ function getGraphHover(g) {
|
|
|
3335
3374
|
const direction = g.kind === syntaxKind.DirectedGraph ? "directed" : "undirected";
|
|
3336
3375
|
const graphId = g.id;
|
|
3337
3376
|
const strict = g.strict ? "strict " : "";
|
|
3338
|
-
return
|
|
3377
|
+
return {
|
|
3378
|
+
contents: graphId ? `(${strict}${direction} graph) ${getIdentifierText(graphId)}` : `(${strict}${direction} graph)`,
|
|
3379
|
+
range: {
|
|
3380
|
+
pos: g.pos,
|
|
3381
|
+
end: g.end
|
|
3382
|
+
}
|
|
3383
|
+
};
|
|
3339
3384
|
}
|
|
3340
3385
|
function getEdgeHover(n) {
|
|
3341
3386
|
const p = n.parent;
|
|
@@ -3346,8 +3391,15 @@ function getEdgeHover(n) {
|
|
|
3346
3391
|
source = curr.target;
|
|
3347
3392
|
}
|
|
3348
3393
|
if (source === void 0) source = p.source;
|
|
3394
|
+
if (source === void 0) return void 0;
|
|
3349
3395
|
const edgeOpStr = getEdgeStr(n.operation.kind);
|
|
3350
|
-
return
|
|
3396
|
+
return {
|
|
3397
|
+
contents: `(edge) ${getEdgeSourceOrTargetText(source)} ${edgeOpStr} ${getEdgeSourceOrTargetText(n.target)}`,
|
|
3398
|
+
range: {
|
|
3399
|
+
pos: source.pos,
|
|
3400
|
+
end: n.target.end
|
|
3401
|
+
}
|
|
3402
|
+
};
|
|
3351
3403
|
}
|
|
3352
3404
|
function getEdgeSourceOrTargetText(n) {
|
|
3353
3405
|
return n.kind === syntaxKind.NodeId ? getIdentifierText(n.id) : n.id !== void 0 ? `${getIdentifierText(n.id)}` : "sub graph";
|
|
@@ -3399,6 +3451,7 @@ function findDefinition(doc, sourceFile, position) {
|
|
|
3399
3451
|
}
|
|
3400
3452
|
debugger;
|
|
3401
3453
|
}
|
|
3454
|
+
const findDeclaration = findDefinition;
|
|
3402
3455
|
//#endregion
|
|
3403
3456
|
//#region src/service/rename.ts
|
|
3404
3457
|
function renameSymbol(doc, sourceFile, position, newName) {
|
|
@@ -3424,6 +3477,40 @@ function isRenameableNode(node) {
|
|
|
3424
3477
|
function isRenamableIdentifier(node) {
|
|
3425
3478
|
return node.kind !== syntaxKind.QuotedTextIdentifier;
|
|
3426
3479
|
}
|
|
3480
|
+
//#endregion
|
|
3481
|
+
//#region src/service/selectionRange.ts
|
|
3482
|
+
function getSelectionRanges(doc, sourceFile, positions) {
|
|
3483
|
+
return positions.map((p) => buildSelectionRange(doc, sourceFile, p));
|
|
3484
|
+
}
|
|
3485
|
+
function buildSelectionRange(doc, sourceFile, position) {
|
|
3486
|
+
const empty = { range: {
|
|
3487
|
+
start: position,
|
|
3488
|
+
end: position
|
|
3489
|
+
} };
|
|
3490
|
+
const g = sourceFile.graph;
|
|
3491
|
+
if (!g) return empty;
|
|
3492
|
+
const leaf = findNodeAtOffset(g, doc.offsetAt(position), true);
|
|
3493
|
+
const chain = [];
|
|
3494
|
+
let curr = leaf;
|
|
3495
|
+
while (curr) {
|
|
3496
|
+
chain.push(curr);
|
|
3497
|
+
curr = curr.parent;
|
|
3498
|
+
}
|
|
3499
|
+
if (chain.length === 0) return empty;
|
|
3500
|
+
let result;
|
|
3501
|
+
let lastKey;
|
|
3502
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
3503
|
+
const range = syntaxNodeToRange(doc, sourceFile, chain[i]);
|
|
3504
|
+
const key = `${range.start.line}:${range.start.character}-${range.end.line}:${range.end.character}`;
|
|
3505
|
+
if (key === lastKey) continue;
|
|
3506
|
+
lastKey = key;
|
|
3507
|
+
result = {
|
|
3508
|
+
range,
|
|
3509
|
+
parent: result
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
return result ?? empty;
|
|
3513
|
+
}
|
|
3427
3514
|
const subErrorCodeLength = 3;
|
|
3428
3515
|
function formatError(error) {
|
|
3429
3516
|
const subCode = (error.sub | 0).toString().padStart(subErrorCodeLength, "0");
|
|
@@ -3465,8 +3552,10 @@ function createService() {
|
|
|
3465
3552
|
hover,
|
|
3466
3553
|
findReferences,
|
|
3467
3554
|
findDefinition,
|
|
3555
|
+
findDeclaration,
|
|
3468
3556
|
renameSymbol,
|
|
3469
3557
|
getCompletions,
|
|
3558
|
+
getSelectionRanges,
|
|
3470
3559
|
getDocumentColors,
|
|
3471
3560
|
getColorRepresentations,
|
|
3472
3561
|
getCodeActions,
|