dot-language-support 2.1.1 → 2.2.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/lib/cjs/checker.js +40 -2
- package/lib/cjs/parser.js +1 -1
- package/lib/cjs/service/codeAction.js +2 -0
- package/lib/cjs/types.d.ts +2 -1
- package/lib/cjs/types.js +2 -2
- package/lib/esm/checker.js +40 -2
- package/lib/esm/service/codeAction.js +2 -0
- package/lib/esm/types.d.ts +2 -1
- package/package.json +4 -4
package/lib/cjs/checker.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.nodeContainsErrors = exports.getIdentifierText = exports.edgeStatementHa
|
|
|
4
4
|
const types_js_1 = require("./types.js");
|
|
5
5
|
const util_js_1 = require("./service/util.js");
|
|
6
6
|
const visitor_js_1 = require("./visitor.js");
|
|
7
|
+
const languageFacts_js_1 = require("./service/languageFacts.js");
|
|
7
8
|
function checkSourceFile(file) {
|
|
8
9
|
const g = file.graph;
|
|
9
10
|
if (g) {
|
|
@@ -48,9 +49,46 @@ exports.getAllowedEdgeOperation = getAllowedEdgeOperation;
|
|
|
48
49
|
function checkGraphSemantics(file, root) {
|
|
49
50
|
const expectedEdgeOp = getAllowedEdgeOperation(root);
|
|
50
51
|
const invalidEdgeRhses = findEdgeErrors(expectedEdgeOp, root);
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
const invalidShapes = checkShapeLabelValues(root);
|
|
53
|
+
const invalidEdgeDiagnostics = invalidEdgeRhses == undefined || invalidEdgeRhses.length === 0
|
|
54
|
+
? []
|
|
53
55
|
: createEdgeViolationDiagnostics(file, expectedEdgeOp, invalidEdgeRhses);
|
|
56
|
+
return [...invalidEdgeDiagnostics, ...invalidShapes];
|
|
57
|
+
}
|
|
58
|
+
function forEachAssignmentTransitive(root, cb) {
|
|
59
|
+
(0, visitor_js_1.forEachChild)(root, child => {
|
|
60
|
+
if (child.kind === types_js_1.SyntaxKind.Assignment) {
|
|
61
|
+
cb(child);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
(0, visitor_js_1.forEachChild)(child, c => forEachAssignmentTransitive(c, cb));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function checkShapeLabelValues(root) {
|
|
68
|
+
const invalidShapes = [];
|
|
69
|
+
forEachAssignmentTransitive(root, assignment => {
|
|
70
|
+
const { leftId, rightId } = assignment;
|
|
71
|
+
if (leftId.kind !== types_js_1.SyntaxKind.TextIdentifier || rightId.kind !== types_js_1.SyntaxKind.TextIdentifier) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const leftText = leftId.text.trim();
|
|
75
|
+
if (leftText.toLocaleLowerCase() !== "shape") {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const rightText = rightId.text.trim();
|
|
79
|
+
const shapeCandidate = rightText.toLowerCase();
|
|
80
|
+
if (languageFacts_js_1.shapes.includes(shapeCandidate)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
invalidShapes.push({
|
|
84
|
+
category: types_js_1.DiagnosticCategory.Warning,
|
|
85
|
+
code: createCheckerError(1),
|
|
86
|
+
message: `Unknown shape "${rightText}".`,
|
|
87
|
+
start: assignment.pos,
|
|
88
|
+
end: assignment.end,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
return invalidShapes;
|
|
54
92
|
}
|
|
55
93
|
function findAllEdges(node) {
|
|
56
94
|
const allEdges = [];
|
package/lib/cjs/parser.js
CHANGED
|
@@ -13,7 +13,7 @@ var ParsingContext;
|
|
|
13
13
|
ParsingContext[ParsingContext["EdgeRhsList"] = 4] = "EdgeRhsList";
|
|
14
14
|
ParsingContext[ParsingContext["QuotedTextIdentifierConcatenation"] = 5] = "QuotedTextIdentifierConcatenation";
|
|
15
15
|
ParsingContext[ParsingContext["Count"] = 6] = "Count";
|
|
16
|
-
})(ParsingContext
|
|
16
|
+
})(ParsingContext || (exports.ParsingContext = ParsingContext = {}));
|
|
17
17
|
class Parser {
|
|
18
18
|
constructor() {
|
|
19
19
|
this.currentToken = types_1.SyntaxKind.Unknown;
|
package/lib/cjs/types.d.ts
CHANGED
package/lib/cjs/types.js
CHANGED
|
@@ -7,7 +7,7 @@ var DiagnosticCategory;
|
|
|
7
7
|
DiagnosticCategory[DiagnosticCategory["Warning"] = 2] = "Warning";
|
|
8
8
|
DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message";
|
|
9
9
|
DiagnosticCategory[DiagnosticCategory["Suggestion"] = 4] = "Suggestion";
|
|
10
|
-
})(DiagnosticCategory
|
|
10
|
+
})(DiagnosticCategory || (exports.DiagnosticCategory = DiagnosticCategory = {}));
|
|
11
11
|
var SyntaxKind;
|
|
12
12
|
(function (SyntaxKind) {
|
|
13
13
|
SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
|
|
@@ -70,5 +70,5 @@ var SyntaxKind;
|
|
|
70
70
|
SyntaxKind[SyntaxKind["CompassBegin"] = 18] = "CompassBegin";
|
|
71
71
|
SyntaxKind[SyntaxKind["CompassEnd"] = 27] = "CompassEnd";
|
|
72
72
|
SyntaxKind[SyntaxKind["LastKeyword"] = 38] = "LastKeyword";
|
|
73
|
-
})(SyntaxKind
|
|
73
|
+
})(SyntaxKind || (exports.SyntaxKind = SyntaxKind = {}));
|
|
74
74
|
//# sourceMappingURL=types.js.map
|
package/lib/esm/checker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SyntaxKind, DiagnosticCategory, } from "./types.js";
|
|
2
2
|
import { assertNever, getStart } from "./service/util.js";
|
|
3
3
|
import { forEachChild } from "./visitor.js";
|
|
4
|
+
import { shapes as validShapes } from "./service/languageFacts.js";
|
|
4
5
|
export function checkSourceFile(file) {
|
|
5
6
|
const g = file.graph;
|
|
6
7
|
if (g) {
|
|
@@ -42,9 +43,46 @@ export function getAllowedEdgeOperation(graph) {
|
|
|
42
43
|
function checkGraphSemantics(file, root) {
|
|
43
44
|
const expectedEdgeOp = getAllowedEdgeOperation(root);
|
|
44
45
|
const invalidEdgeRhses = findEdgeErrors(expectedEdgeOp, root);
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
const invalidShapes = checkShapeLabelValues(root);
|
|
47
|
+
const invalidEdgeDiagnostics = invalidEdgeRhses == undefined || invalidEdgeRhses.length === 0
|
|
48
|
+
? []
|
|
47
49
|
: createEdgeViolationDiagnostics(file, expectedEdgeOp, invalidEdgeRhses);
|
|
50
|
+
return [...invalidEdgeDiagnostics, ...invalidShapes];
|
|
51
|
+
}
|
|
52
|
+
function forEachAssignmentTransitive(root, cb) {
|
|
53
|
+
forEachChild(root, child => {
|
|
54
|
+
if (child.kind === SyntaxKind.Assignment) {
|
|
55
|
+
cb(child);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
forEachChild(child, c => forEachAssignmentTransitive(c, cb));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function checkShapeLabelValues(root) {
|
|
62
|
+
const invalidShapes = [];
|
|
63
|
+
forEachAssignmentTransitive(root, assignment => {
|
|
64
|
+
const { leftId, rightId } = assignment;
|
|
65
|
+
if (leftId.kind !== SyntaxKind.TextIdentifier || rightId.kind !== SyntaxKind.TextIdentifier) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const leftText = leftId.text.trim();
|
|
69
|
+
if (leftText.toLocaleLowerCase() !== "shape") {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const rightText = rightId.text.trim();
|
|
73
|
+
const shapeCandidate = rightText.toLowerCase();
|
|
74
|
+
if (validShapes.includes(shapeCandidate)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
invalidShapes.push({
|
|
78
|
+
category: DiagnosticCategory.Warning,
|
|
79
|
+
code: createCheckerError(1),
|
|
80
|
+
message: `Unknown shape "${rightText}".`,
|
|
81
|
+
start: assignment.pos,
|
|
82
|
+
end: assignment.end,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
return invalidShapes;
|
|
48
86
|
}
|
|
49
87
|
export function findAllEdges(node) {
|
|
50
88
|
const allEdges = [];
|
package/lib/esm/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dot-language-support",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Parser and language service for graphviz (dot) files",
|
|
5
5
|
"author": "Niklas Mollenhauer",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"vscode-languageserver-types": "^3.17.3"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@vitest/coverage-
|
|
36
|
+
"@vitest/coverage-v8": "^0.32.4",
|
|
37
37
|
"rimraf": "^5.0.1",
|
|
38
|
-
"typescript": "^5.
|
|
39
|
-
"vitest": "^0.
|
|
38
|
+
"typescript": "^5.1.6",
|
|
39
|
+
"vitest": "^0.32.4"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=18"
|