dot-language-support 1.6.2 → 2.0.2
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/.github/workflows/CD.yml +3 -3
- package/.github/workflows/CI.yml +2 -2
- package/README.md +5 -4
- package/jest.config.mjs +19 -0
- package/lib/{binder.d.ts → cjs/binder.d.ts} +1 -1
- package/lib/{binder.js → cjs/binder.js} +34 -34
- package/lib/{checker.d.ts → cjs/checker.d.ts} +1 -1
- package/lib/{checker.js → cjs/checker.js} +28 -28
- package/lib/{core.d.ts → cjs/core.d.ts} +0 -0
- package/lib/{core.js → cjs/core.js} +0 -0
- package/lib/{error.d.ts → cjs/error.d.ts} +1 -1
- package/lib/{error.js → cjs/error.js} +0 -0
- package/lib/cjs/index.d.ts +5 -0
- package/lib/{index.js → cjs/index.js} +5 -5
- package/lib/{parser.d.ts → cjs/parser.d.ts} +2 -2
- package/lib/{parser.js → cjs/parser.js} +14 -12
- package/lib/{scanner.d.ts → cjs/scanner.d.ts} +1 -1
- package/lib/{scanner.js → cjs/scanner.js} +67 -67
- package/lib/{service → cjs/service}/codeAction.d.ts +3 -3
- package/lib/cjs/service/codeAction.js +237 -0
- package/lib/cjs/service/colorProvider.d.ts +5 -0
- package/lib/cjs/service/colorProvider.js +92 -0
- package/lib/{service → cjs/service}/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.d.ts +4 -4
- package/lib/{service → cjs/service}/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.js +7 -7
- package/lib/{service → cjs/service}/command/ChangeEdgeOpCommand.d.ts +4 -4
- package/lib/cjs/service/command/ChangeEdgeOpCommand.js +60 -0
- package/lib/{service → cjs/service}/command/ConsolidateDescendantsCommand.d.ts +3 -3
- package/lib/{service → cjs/service}/command/ConsolidateDescendantsCommand.js +7 -25
- package/lib/{service → cjs/service}/command/RemoveSemicolons.d.ts +3 -3
- package/lib/{service → cjs/service}/command/RemoveSemicolons.js +4 -4
- package/lib/{service → cjs/service}/command/common.d.ts +4 -4
- package/lib/cjs/service/command/common.js +31 -0
- package/lib/{service → cjs/service}/completion.d.ts +2 -2
- package/lib/{service → cjs/service}/completion.js +49 -26
- package/lib/{service → cjs/service}/hover.d.ts +2 -2
- package/lib/{service → cjs/service}/hover.js +38 -38
- package/lib/{service → cjs/service}/languageFacts.d.ts +0 -0
- package/lib/{service → cjs/service}/languageFacts.js +0 -0
- package/lib/{service → cjs/service}/reference.d.ts +2 -2
- package/lib/{service → cjs/service}/reference.js +9 -11
- package/lib/{service → cjs/service}/rename.d.ts +2 -2
- package/lib/{service → cjs/service}/rename.js +11 -11
- package/lib/{service → cjs/service}/service.d.ts +2 -2
- package/lib/cjs/service/service.js +39 -0
- package/lib/cjs/service/util.d.ts +11 -0
- package/lib/{service → cjs/service}/util.js +7 -7
- package/lib/{service → cjs/service}/validation.d.ts +2 -2
- package/lib/{service → cjs/service}/validation.js +3 -3
- package/lib/cjs/tester.d.ts +1 -0
- package/lib/cjs/tester.js +23 -0
- package/lib/{types.d.ts → cjs/types.d.ts} +0 -0
- package/lib/{types.js → cjs/types.js} +0 -0
- package/lib/{visitor.d.ts → cjs/visitor.d.ts} +1 -1
- package/lib/{visitor.js → cjs/visitor.js} +17 -17
- package/lib/esm/binder.d.ts +2 -0
- package/lib/esm/binder.js +296 -0
- package/lib/esm/checker.d.ts +14 -0
- package/lib/esm/checker.js +169 -0
- package/lib/esm/core.d.ts +1 -0
- package/lib/esm/core.js +10 -0
- package/lib/esm/error.d.ts +3 -0
- package/lib/esm/error.js +10 -0
- package/lib/esm/index.d.ts +5 -0
- package/lib/esm/index.js +6 -0
- package/lib/esm/parser.d.ts +84 -0
- package/lib/esm/parser.js +700 -0
- package/lib/esm/scanner.d.ts +52 -0
- package/lib/esm/scanner.js +581 -0
- package/lib/esm/service/codeAction.d.ts +12 -0
- package/lib/{service → esm/service}/codeAction.js +40 -46
- package/lib/esm/service/colorProvider.d.ts +5 -0
- package/lib/{service → esm/service}/colorProvider.js +8 -18
- package/lib/esm/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.d.ts +10 -0
- package/lib/esm/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.js +38 -0
- package/lib/esm/service/command/ChangeEdgeOpCommand.d.ts +10 -0
- package/lib/{service → esm/service}/command/ChangeEdgeOpCommand.js +6 -11
- package/lib/esm/service/command/ConsolidateDescendantsCommand.d.ts +10 -0
- package/lib/esm/service/command/ConsolidateDescendantsCommand.js +83 -0
- package/lib/esm/service/command/RemoveSemicolons.d.ts +10 -0
- package/lib/esm/service/command/RemoveSemicolons.js +37 -0
- package/lib/esm/service/command/common.d.ts +31 -0
- package/lib/esm/service/command/common.js +22 -0
- package/lib/esm/service/completion.d.ts +4 -0
- package/lib/esm/service/completion.js +137 -0
- package/lib/esm/service/hover.d.ts +4 -0
- package/lib/esm/service/hover.js +119 -0
- package/lib/esm/service/languageFacts.d.ts +683 -0
- package/lib/esm/service/languageFacts.js +997 -0
- package/lib/esm/service/reference.d.ts +5 -0
- package/lib/esm/service/reference.js +66 -0
- package/lib/esm/service/rename.d.ts +4 -0
- package/lib/esm/service/rename.js +45 -0
- package/lib/esm/service/service.d.ts +28 -0
- package/lib/esm/service/service.js +35 -0
- package/lib/esm/service/util.d.ts +11 -0
- package/lib/esm/service/util.js +44 -0
- package/lib/esm/service/validation.d.ts +4 -0
- package/lib/esm/service/validation.js +20 -0
- package/lib/esm/tester.d.ts +1 -0
- package/lib/esm/tester.js +21 -0
- package/lib/esm/types.d.ts +396 -0
- package/lib/esm/types.js +71 -0
- package/lib/esm/visitor.d.ts +2 -0
- package/lib/esm/visitor.js +74 -0
- package/package.json +13 -11
- package/lib/index.d.ts +0 -5
- package/lib/service/colorProvider.d.ts +0 -6
- package/lib/service/command/common.js +0 -31
- package/lib/service/polyfill.d.ts +0 -16
- package/lib/service/polyfill.js +0 -3
- package/lib/service/service.js +0 -39
- package/lib/service/util.d.ts +0 -11
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findDefinition = exports.findReferences = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const index_js_1 = require("../index.js");
|
|
5
|
+
const checker_js_1 = require("../checker.js");
|
|
6
|
+
const util_js_1 = require("./util.js");
|
|
7
7
|
function findReferences(doc, sourceFile, position, context) {
|
|
8
8
|
if (!sourceFile.symbols)
|
|
9
9
|
throw "sourceFile is not bound";
|
|
@@ -11,10 +11,10 @@ function findReferences(doc, sourceFile, position, context) {
|
|
|
11
11
|
if (!g)
|
|
12
12
|
return [];
|
|
13
13
|
const offset = doc.offsetAt(position);
|
|
14
|
-
const node = (0,
|
|
14
|
+
const node = (0, checker_js_1.findNodeAtOffset)(g, offset);
|
|
15
15
|
if (!node)
|
|
16
16
|
return [];
|
|
17
|
-
if ((0,
|
|
17
|
+
if ((0, index_js_1.isIdentifierNode)(node)) {
|
|
18
18
|
const nodeSymbol = node.symbol;
|
|
19
19
|
if (!nodeSymbol)
|
|
20
20
|
throw "node.symbol is not bound";
|
|
@@ -34,7 +34,7 @@ function findReferences(doc, sourceFile, position, context) {
|
|
|
34
34
|
];
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
const ranges = (0,
|
|
37
|
+
const ranges = (0, util_js_1.syntaxNodesToRanges)(doc, sourceFile, symbolRefs);
|
|
38
38
|
const uri = doc.uri;
|
|
39
39
|
return ranges.map(range => {
|
|
40
40
|
return { uri, range };
|
|
@@ -51,19 +51,17 @@ function findDefinition(doc, sourceFile, position) {
|
|
|
51
51
|
if (!g)
|
|
52
52
|
return undefined;
|
|
53
53
|
const offset = doc.offsetAt(position);
|
|
54
|
-
const node = (0,
|
|
54
|
+
const node = (0, checker_js_1.findNodeAtOffset)(g, offset);
|
|
55
55
|
if (!node)
|
|
56
56
|
return undefined;
|
|
57
|
-
if ((0,
|
|
57
|
+
if ((0, index_js_1.isIdentifierNode)(node)) {
|
|
58
58
|
const nodeSymbol = node.symbol;
|
|
59
59
|
if (!nodeSymbol)
|
|
60
60
|
throw "node.symbol is not bound";
|
|
61
|
-
const refs = nodeSymbol.references || [];
|
|
62
|
-
let symbolRefs;
|
|
63
61
|
const firstMention = nodeSymbol.firstMention;
|
|
64
62
|
if (!firstMention)
|
|
65
63
|
return undefined;
|
|
66
|
-
const range = (0,
|
|
64
|
+
const range = (0, util_js_1.syntaxNodeToRange)(doc, sourceFile, firstMention);
|
|
67
65
|
return { uri: doc.uri, range };
|
|
68
66
|
}
|
|
69
67
|
debugger;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Position, WorkspaceEdit } from "vscode-languageserver-types";
|
|
2
|
-
import { SourceFile } from "../types";
|
|
3
|
-
import { DocumentLike } from "../";
|
|
2
|
+
import { SourceFile } from "../types.js";
|
|
3
|
+
import { DocumentLike } from "../index.js";
|
|
4
4
|
export declare function renameSymbol(doc: DocumentLike, sourceFile: SourceFile, position: Position, newName: string): WorkspaceEdit | undefined;
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.renameSymbol = void 0;
|
|
4
4
|
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
5
|
+
const types_js_1 = require("../types.js");
|
|
6
|
+
const checker_js_1 = require("../checker.js");
|
|
7
|
+
const index_js_1 = require("../index.js");
|
|
8
|
+
const util_js_1 = require("./util.js");
|
|
9
9
|
function renameSymbol(doc, sourceFile, position, newName) {
|
|
10
10
|
if (!sourceFile.symbols)
|
|
11
11
|
throw "sourceFile is not bound";
|
|
@@ -15,17 +15,17 @@ function renameSymbol(doc, sourceFile, position, newName) {
|
|
|
15
15
|
if (!g)
|
|
16
16
|
return undefined;
|
|
17
17
|
const offset = doc.offsetAt(position);
|
|
18
|
-
const node = (0,
|
|
18
|
+
const node = (0, checker_js_1.findNodeAtOffset)(g, offset);
|
|
19
19
|
if (!node)
|
|
20
20
|
return undefined;
|
|
21
21
|
const parent = node.parent;
|
|
22
|
-
if ((0,
|
|
22
|
+
if ((0, index_js_1.isIdentifierNode)(node) && isRenamableIdentifier(node) && !!parent && isRenameableNode(parent)) {
|
|
23
23
|
const nodeSymbol = node.symbol;
|
|
24
24
|
if (!nodeSymbol)
|
|
25
25
|
throw "node.symbol is not bound";
|
|
26
26
|
const r = nodeSymbol.references;
|
|
27
27
|
const refs = r ? [nodeSymbol.firstMention, ...r] : [nodeSymbol.firstMention];
|
|
28
|
-
const ranges = (0,
|
|
28
|
+
const ranges = (0, util_js_1.syntaxNodesToRanges)(doc, sourceFile, refs);
|
|
29
29
|
const uri = doc.uri;
|
|
30
30
|
const res = {
|
|
31
31
|
changes: {
|
|
@@ -39,11 +39,11 @@ function renameSymbol(doc, sourceFile, position, newName) {
|
|
|
39
39
|
}
|
|
40
40
|
exports.renameSymbol = renameSymbol;
|
|
41
41
|
function isRenameableNode(node) {
|
|
42
|
-
return node.kind ===
|
|
43
|
-
|| node.kind ===
|
|
44
|
-
|| node.kind ===
|
|
42
|
+
return node.kind === types_js_1.SyntaxKind.NodeId
|
|
43
|
+
|| node.kind === types_js_1.SyntaxKind.DirectedGraph
|
|
44
|
+
|| node.kind === types_js_1.SyntaxKind.UndirectedGraph;
|
|
45
45
|
}
|
|
46
46
|
function isRenamableIdentifier(node) {
|
|
47
|
-
return node.kind !==
|
|
47
|
+
return node.kind !== types_js_1.SyntaxKind.QuotedTextIdentifier;
|
|
48
48
|
}
|
|
49
49
|
//# sourceMappingURL=rename.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as lst from "vscode-languageserver-types";
|
|
2
|
+
import type { ColorInformation, Color, ColorPresentation } from "vscode-languageserver-types";
|
|
2
3
|
import type { TextDocument } from "vscode-languageserver-textdocument";
|
|
3
|
-
import {
|
|
4
|
-
import { SourceFile, Omit } from "../types";
|
|
4
|
+
import { SourceFile, Omit } from "../types.js";
|
|
5
5
|
export interface DocumentLike {
|
|
6
6
|
positionAt(offset: number): lst.Position;
|
|
7
7
|
offsetAt(position: lst.Position): number;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createService = void 0;
|
|
4
|
+
const index_js_1 = require("../index.js");
|
|
5
|
+
const binder_js_1 = require("../binder.js");
|
|
6
|
+
const hover_js_1 = require("./hover.js");
|
|
7
|
+
const validation_js_1 = require("./validation.js");
|
|
8
|
+
const reference_js_1 = require("./reference.js");
|
|
9
|
+
const rename_js_1 = require("./rename.js");
|
|
10
|
+
const completion_js_1 = require("./completion.js");
|
|
11
|
+
const checker_js_1 = require("../checker.js");
|
|
12
|
+
const codeAction_js_1 = require("./codeAction.js");
|
|
13
|
+
const colorProvider_js_1 = require("./colorProvider.js");
|
|
14
|
+
function parseDocument(doc) {
|
|
15
|
+
const parser = new index_js_1.Parser();
|
|
16
|
+
const content = typeof doc === "string" ? doc : doc.getText();
|
|
17
|
+
const sourceFile = parser.parse(content);
|
|
18
|
+
(0, binder_js_1.bindSourceFile)(sourceFile);
|
|
19
|
+
(0, checker_js_1.checkSourceFile)(sourceFile);
|
|
20
|
+
return sourceFile;
|
|
21
|
+
}
|
|
22
|
+
function createService() {
|
|
23
|
+
return {
|
|
24
|
+
parseDocument,
|
|
25
|
+
validateDocument: validation_js_1.validateDocument,
|
|
26
|
+
hover: hover_js_1.hover,
|
|
27
|
+
findReferences: reference_js_1.findReferences,
|
|
28
|
+
findDefinition: reference_js_1.findDefinition,
|
|
29
|
+
renameSymbol: rename_js_1.renameSymbol,
|
|
30
|
+
getCompletions: completion_js_1.getCompletions,
|
|
31
|
+
getDocumentColors: colorProvider_js_1.getDocumentColors,
|
|
32
|
+
getColorRepresentations: colorProvider_js_1.getColorRepresentations,
|
|
33
|
+
getCodeActions: codeAction_js_1.getCodeActions,
|
|
34
|
+
executeCommand: codeAction_js_1.executeCommand,
|
|
35
|
+
getAvailableCommands: codeAction_js_1.getAvailableCommands,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
exports.createService = createService;
|
|
39
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Range } from "vscode-languageserver-types";
|
|
2
|
+
import { SourceFile, SyntaxNode } from "../types.js";
|
|
3
|
+
import type { DocumentLike } from "../index.js";
|
|
4
|
+
export declare function getStart(sourceFile: SourceFile, node: SyntaxNode): number;
|
|
5
|
+
export declare function syntaxNodesToRanges(doc: DocumentLike, sourceFile: SourceFile, nodes: SyntaxNode[]): Range[];
|
|
6
|
+
export declare function syntaxNodeToRange(doc: DocumentLike, sourceFile: SourceFile, node: SyntaxNode): {
|
|
7
|
+
start: import("vscode-languageserver-types").Position;
|
|
8
|
+
end: import("vscode-languageserver-types").Position;
|
|
9
|
+
};
|
|
10
|
+
export declare function escapeIdentifierText(text: string): string;
|
|
11
|
+
export declare function assertNever(v: never): never;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.assertNever = exports.escapeIdentifierText = exports.syntaxNodeToRange = exports.syntaxNodesToRanges = exports.getStart = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const types_js_1 = require("../types.js");
|
|
5
|
+
const scanner_js_1 = require("../scanner.js");
|
|
6
6
|
function getStart(sourceFile, node) {
|
|
7
7
|
return getTokenPosOfNode(sourceFile, node);
|
|
8
8
|
}
|
|
@@ -10,12 +10,12 @@ exports.getStart = getStart;
|
|
|
10
10
|
function getTokenPosOfNode(sourceFile, node) {
|
|
11
11
|
if (nodeIsMissing(node))
|
|
12
12
|
return node.pos;
|
|
13
|
-
return (0,
|
|
13
|
+
return (0, scanner_js_1.skipTrivia)(sourceFile.content, node.pos);
|
|
14
14
|
}
|
|
15
15
|
function nodeIsMissing(node) {
|
|
16
16
|
return node === undefined
|
|
17
17
|
? true
|
|
18
|
-
: node.pos === node.end && node.pos >= 0 && node.kind !==
|
|
18
|
+
: node.pos === node.end && node.pos >= 0 && node.kind !== types_js_1.SyntaxKind.EndOfFileToken;
|
|
19
19
|
}
|
|
20
20
|
function syntaxNodesToRanges(doc, sourceFile, nodes) {
|
|
21
21
|
return nodes.map(node => syntaxNodeToRange(doc, sourceFile, node));
|
|
@@ -39,14 +39,14 @@ function escapeIdentifierText(text) {
|
|
|
39
39
|
return quote(esc);
|
|
40
40
|
}
|
|
41
41
|
const ch = text.charCodeAt(0);
|
|
42
|
-
if (!(0,
|
|
42
|
+
if (!(0, scanner_js_1.isIdentifierStart)(ch) || text.includes(" "))
|
|
43
43
|
return quote(text);
|
|
44
44
|
return text;
|
|
45
45
|
}
|
|
46
46
|
exports.escapeIdentifierText = escapeIdentifierText;
|
|
47
47
|
const quote = (s) => "\"" + s + "\"";
|
|
48
|
-
function assertNever(
|
|
49
|
-
throw new Error("
|
|
48
|
+
function assertNever(v) {
|
|
49
|
+
throw new Error("Should not have reached this. Value: " + (v !== null && v !== void 0 ? v : ""));
|
|
50
50
|
}
|
|
51
51
|
exports.assertNever = assertNever;
|
|
52
52
|
//# sourceMappingURL=util.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as lst from "vscode-languageserver-types";
|
|
2
|
-
import { SourceFile } from "../types";
|
|
3
|
-
import { DocumentLike } from "../";
|
|
2
|
+
import { SourceFile } from "../types.js";
|
|
3
|
+
import { DocumentLike } from "../index.js";
|
|
4
4
|
export declare function validateDocument(doc: DocumentLike, sourceFile: SourceFile): lst.Diagnostic[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateDocument = void 0;
|
|
4
|
-
const
|
|
4
|
+
const error_js_1 = require("../error.js");
|
|
5
5
|
function convertDiagnostic(document, source) {
|
|
6
6
|
return {
|
|
7
7
|
range: {
|
|
@@ -9,8 +9,8 @@ function convertDiagnostic(document, source) {
|
|
|
9
9
|
end: document.positionAt(source.end),
|
|
10
10
|
},
|
|
11
11
|
severity: source.category,
|
|
12
|
-
code: (0,
|
|
13
|
-
source:
|
|
12
|
+
code: (0, error_js_1.formatError)(source.code),
|
|
13
|
+
source: error_js_1.diagnosicSource,
|
|
14
14
|
message: source.message,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
|
|
4
|
+
const parser_js_1 = require("./parser.js");
|
|
5
|
+
const binder_js_1 = require("./binder.js");
|
|
6
|
+
const checker_js_1 = require("./checker.js");
|
|
7
|
+
const completion_js_1 = require("./service/completion.js");
|
|
8
|
+
const text = `graph {
|
|
9
|
+
node_name_a -- node_name_b [color=blue,
|
|
10
|
+
];
|
|
11
|
+
}`;
|
|
12
|
+
function main() {
|
|
13
|
+
const parser = new parser_js_1.Parser();
|
|
14
|
+
const sf = parser.parse(text);
|
|
15
|
+
(0, binder_js_1.bindSourceFile)(sf);
|
|
16
|
+
(0, checker_js_1.checkSourceFile)(sf);
|
|
17
|
+
const doc = vscode_languageserver_textdocument_1.TextDocument.create("inmemory://model.json", "DOT", 0, text);
|
|
18
|
+
const requestOffset = text.indexOf("color=blue,\n\t") + "color=blue,\n\t".length;
|
|
19
|
+
const completions = (0, completion_js_1.getCompletions)(doc, sf, doc.positionAt(requestOffset));
|
|
20
|
+
console.dir(completions);
|
|
21
|
+
}
|
|
22
|
+
main();
|
|
23
|
+
//# sourceMappingURL=tester.js.map
|
|
File without changes
|
|
File without changes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { SyntaxNode, SyntaxNodeArray } from "./types";
|
|
1
|
+
import { SyntaxNode, SyntaxNodeArray } from "./types.js";
|
|
2
2
|
export declare function forEachChild<TReturn>(node: SyntaxNode, cbNode: (node: SyntaxNode) => TReturn, cbNodes?: (nodes: SyntaxNodeArray<SyntaxNode>) => TReturn): TReturn | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.forEachChild = void 0;
|
|
4
|
-
const
|
|
4
|
+
const types_js_1 = require("./types.js");
|
|
5
5
|
function visitNode(cbNode, node) {
|
|
6
6
|
return node && cbNode(node);
|
|
7
7
|
}
|
|
@@ -18,56 +18,56 @@ function visitNodes(cbNode, cbNodes, nodes) {
|
|
|
18
18
|
return undefined;
|
|
19
19
|
}
|
|
20
20
|
function forEachChild(node, cbNode, cbNodes) {
|
|
21
|
-
if (!node || node.kind <=
|
|
21
|
+
if (!node || node.kind <= types_js_1.SyntaxKind.LastKeyword)
|
|
22
22
|
return;
|
|
23
23
|
switch (node.kind) {
|
|
24
|
-
case
|
|
25
|
-
case
|
|
24
|
+
case types_js_1.SyntaxKind.DirectedGraph:
|
|
25
|
+
case types_js_1.SyntaxKind.UndirectedGraph:
|
|
26
26
|
return visitNodes(cbNode, cbNodes, node.statements)
|
|
27
27
|
|| visitNode(cbNode, node.strict)
|
|
28
28
|
|| visitNode(cbNode, node.id);
|
|
29
|
-
case
|
|
29
|
+
case types_js_1.SyntaxKind.AttributeStatement:
|
|
30
30
|
return visitNodes(cbNode, cbNodes, node.attributes)
|
|
31
31
|
|| visitNode(cbNode, node.subject)
|
|
32
32
|
|| visitNode(cbNode, node.terminator);
|
|
33
|
-
case
|
|
33
|
+
case types_js_1.SyntaxKind.EdgeStatement:
|
|
34
34
|
return visitNodes(cbNode, cbNodes, node.attributes)
|
|
35
35
|
|| visitNodes(cbNode, cbNodes, node.rhs)
|
|
36
36
|
|| visitNode(cbNode, node.source)
|
|
37
37
|
|| visitNode(cbNode, node.terminator);
|
|
38
|
-
case
|
|
38
|
+
case types_js_1.SyntaxKind.NodeStatement:
|
|
39
39
|
return visitNodes(cbNode, cbNodes, node.attributes)
|
|
40
40
|
|| visitNode(cbNode, node.id)
|
|
41
41
|
|| visitNode(cbNode, node.terminator);
|
|
42
|
-
case
|
|
42
|
+
case types_js_1.SyntaxKind.SubGraph:
|
|
43
43
|
return visitNodes(cbNode, cbNodes, node.statements)
|
|
44
44
|
|| visitNode(cbNode, node.id);
|
|
45
|
-
case
|
|
45
|
+
case types_js_1.SyntaxKind.SubGraphStatement:
|
|
46
46
|
return visitNode(cbNode, node.subgraph)
|
|
47
47
|
|| visitNode(cbNode, node.terminator);
|
|
48
|
-
case
|
|
48
|
+
case types_js_1.SyntaxKind.IdEqualsIdStatement:
|
|
49
49
|
return visitNode(cbNode, node.leftId)
|
|
50
50
|
|| visitNode(cbNode, node.rightId)
|
|
51
51
|
|| visitNode(cbNode, node.terminator);
|
|
52
|
-
case
|
|
52
|
+
case types_js_1.SyntaxKind.QuotedTextIdentifier:
|
|
53
53
|
return visitNodes(cbNode, cbNodes, node.values);
|
|
54
|
-
case
|
|
54
|
+
case types_js_1.SyntaxKind.EdgeRhs:
|
|
55
55
|
return visitNode(cbNode, node.operation)
|
|
56
56
|
|| visitNode(cbNode, node.target);
|
|
57
|
-
case
|
|
57
|
+
case types_js_1.SyntaxKind.AttributeContainer:
|
|
58
58
|
return visitNodes(cbNode, cbNodes, node.assignments);
|
|
59
|
-
case
|
|
59
|
+
case types_js_1.SyntaxKind.Assignment:
|
|
60
60
|
return visitNode(cbNode, node.leftId)
|
|
61
61
|
|| visitNode(cbNode, node.rightId)
|
|
62
62
|
|| visitNode(cbNode, node.terminator);
|
|
63
|
-
case
|
|
63
|
+
case types_js_1.SyntaxKind.NormalPortDeclaration:
|
|
64
64
|
return visitNode(cbNode, node.colon)
|
|
65
65
|
|| visitNode(cbNode, node.id)
|
|
66
66
|
|| visitNode(cbNode, node.compassPt);
|
|
67
|
-
case
|
|
67
|
+
case types_js_1.SyntaxKind.CompassPortDeclaration:
|
|
68
68
|
return visitNode(cbNode, node.colon)
|
|
69
69
|
|| visitNode(cbNode, node.compassPt);
|
|
70
|
-
case
|
|
70
|
+
case types_js_1.SyntaxKind.NodeId:
|
|
71
71
|
return visitNode(cbNode, node.port)
|
|
72
72
|
|| visitNode(cbNode, node.id);
|
|
73
73
|
default:
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { SyntaxKind, } from "./types.js";
|
|
2
|
+
import { getIdentifierText, nodeContainsErrors } from "./checker.js";
|
|
3
|
+
import { isIdentifierNode } from "./parser.js";
|
|
4
|
+
const binder = createBinder();
|
|
5
|
+
export function bindSourceFile(file) {
|
|
6
|
+
binder.bind(file);
|
|
7
|
+
}
|
|
8
|
+
function createBinder() {
|
|
9
|
+
let parent = undefined;
|
|
10
|
+
let symbolTable = undefined;
|
|
11
|
+
let colorTable = undefined;
|
|
12
|
+
let graphContext = 0;
|
|
13
|
+
function bind(node) {
|
|
14
|
+
if (!node)
|
|
15
|
+
return;
|
|
16
|
+
const saveParent = parent;
|
|
17
|
+
const saveContext = graphContext;
|
|
18
|
+
node.parent = saveParent;
|
|
19
|
+
node.graphContext = saveContext;
|
|
20
|
+
parent = node;
|
|
21
|
+
innerBind(node);
|
|
22
|
+
parent = saveParent;
|
|
23
|
+
graphContext = saveContext;
|
|
24
|
+
}
|
|
25
|
+
function innerBind(node) {
|
|
26
|
+
switch (node.kind) {
|
|
27
|
+
case SyntaxKind.DirectedGraph:
|
|
28
|
+
case SyntaxKind.UndirectedGraph:
|
|
29
|
+
return bindGraph(node);
|
|
30
|
+
case SyntaxKind.AttributeStatement:
|
|
31
|
+
return bindAttributeStatement(node);
|
|
32
|
+
case SyntaxKind.EdgeStatement:
|
|
33
|
+
return bindEdgeStatement(node);
|
|
34
|
+
case SyntaxKind.NodeStatement:
|
|
35
|
+
return bindNodeStatement(node);
|
|
36
|
+
case SyntaxKind.SubGraph:
|
|
37
|
+
return bindSubGraph(node);
|
|
38
|
+
case SyntaxKind.SubGraphStatement:
|
|
39
|
+
return bindSubGraphStatement(node);
|
|
40
|
+
case SyntaxKind.IdEqualsIdStatement:
|
|
41
|
+
return bindIdEqualsIdStatement(node);
|
|
42
|
+
case SyntaxKind.QuotedTextIdentifier:
|
|
43
|
+
return bindQuotedTextIdentifier(node);
|
|
44
|
+
case SyntaxKind.EdgeRhs:
|
|
45
|
+
return bindEdgeRhs(node);
|
|
46
|
+
case SyntaxKind.AttributeContainer:
|
|
47
|
+
return bindAttributeContainer(node);
|
|
48
|
+
case SyntaxKind.Assignment:
|
|
49
|
+
return bindAssignment(node);
|
|
50
|
+
case SyntaxKind.NormalPortDeclaration:
|
|
51
|
+
return bindNormalPortDeclaration(node);
|
|
52
|
+
case SyntaxKind.CompassPortDeclaration:
|
|
53
|
+
return bindCompassPortDeclaration(node);
|
|
54
|
+
case SyntaxKind.NodeId:
|
|
55
|
+
return bindNodeId(node);
|
|
56
|
+
default:
|
|
57
|
+
if (node.kind >= SyntaxKind.FirstNode)
|
|
58
|
+
throw "TODO";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function bindGraph(node) {
|
|
62
|
+
if (node.strict) {
|
|
63
|
+
graphContext |= 2;
|
|
64
|
+
}
|
|
65
|
+
switch (node.kind) {
|
|
66
|
+
case SyntaxKind.DirectedGraph:
|
|
67
|
+
graphContext |= 4;
|
|
68
|
+
break;
|
|
69
|
+
case SyntaxKind.UndirectedGraph:
|
|
70
|
+
graphContext |= 8;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
if (node.id) {
|
|
74
|
+
ensureGlobalSymbol(node.id);
|
|
75
|
+
bind(node.id);
|
|
76
|
+
}
|
|
77
|
+
;
|
|
78
|
+
if (node.strict)
|
|
79
|
+
bind(node.strict);
|
|
80
|
+
bindChildren(node.statements);
|
|
81
|
+
}
|
|
82
|
+
function bindAttributeStatement(node) {
|
|
83
|
+
bind(node.subject);
|
|
84
|
+
bindChildren(node.attributes);
|
|
85
|
+
if (node.terminator)
|
|
86
|
+
bind(node.terminator);
|
|
87
|
+
}
|
|
88
|
+
function bindEdgeStatement(node) {
|
|
89
|
+
bindChildren(node.attributes);
|
|
90
|
+
bindChildren(node.rhs);
|
|
91
|
+
bind(node.source);
|
|
92
|
+
if (node.terminator)
|
|
93
|
+
bind(node.terminator);
|
|
94
|
+
}
|
|
95
|
+
function bindNodeStatement(node) {
|
|
96
|
+
bind(node.id);
|
|
97
|
+
bindChildren(node.attributes);
|
|
98
|
+
if (node.terminator)
|
|
99
|
+
bind(node.terminator);
|
|
100
|
+
}
|
|
101
|
+
function bindSubGraph(node) {
|
|
102
|
+
if (node.id) {
|
|
103
|
+
bind(node.id);
|
|
104
|
+
}
|
|
105
|
+
;
|
|
106
|
+
bindChildren(node.statements);
|
|
107
|
+
}
|
|
108
|
+
function bindSubGraphStatement(node) {
|
|
109
|
+
bind(node.subgraph);
|
|
110
|
+
if (node.terminator)
|
|
111
|
+
bind(node.terminator);
|
|
112
|
+
}
|
|
113
|
+
function bindIdEqualsIdStatement(node) {
|
|
114
|
+
bind(node.leftId);
|
|
115
|
+
bind(node.rightId);
|
|
116
|
+
if (node.rightId && !nodeContainsErrors(node.rightId)) {
|
|
117
|
+
if (isAttributeName("color", node.leftId)) {
|
|
118
|
+
ensureGlobalColor(node.rightId);
|
|
119
|
+
}
|
|
120
|
+
else if (isAttributeName("fillcolor", node.leftId)) {
|
|
121
|
+
ensureGlobalColor(node.rightId);
|
|
122
|
+
}
|
|
123
|
+
else if (isAttributeName("bgcolor", node.leftId)) {
|
|
124
|
+
ensureGlobalColor(node.rightId);
|
|
125
|
+
}
|
|
126
|
+
else if (isAttributeName("fontcolor", node.leftId)) {
|
|
127
|
+
ensureGlobalColor(node.rightId);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (node.terminator)
|
|
131
|
+
bind(node.terminator);
|
|
132
|
+
}
|
|
133
|
+
function bindQuotedTextIdentifier(node) {
|
|
134
|
+
bindChildren(node.values);
|
|
135
|
+
node.concatenation = node.values.map(v => v.text).join("");
|
|
136
|
+
}
|
|
137
|
+
function bindEdgeRhs(node) {
|
|
138
|
+
bind(node.operation);
|
|
139
|
+
bind(node.target);
|
|
140
|
+
}
|
|
141
|
+
function bindAttributeContainer(node) {
|
|
142
|
+
bind(node.openBracket);
|
|
143
|
+
bindChildren(node.assignments);
|
|
144
|
+
bind(node.closeBracket);
|
|
145
|
+
}
|
|
146
|
+
function bindAssignment(node) {
|
|
147
|
+
const attrContainer = node.parent;
|
|
148
|
+
console.assert(!!attrContainer);
|
|
149
|
+
const superParentStatement = attrContainer.parent;
|
|
150
|
+
console.assert(!!superParentStatement);
|
|
151
|
+
bind(node.leftId);
|
|
152
|
+
let carrierIdentifier = undefined;
|
|
153
|
+
switch (superParentStatement.kind) {
|
|
154
|
+
case SyntaxKind.NodeStatement:
|
|
155
|
+
carrierIdentifier = superParentStatement.id.id;
|
|
156
|
+
break;
|
|
157
|
+
case SyntaxKind.EdgeStatement:
|
|
158
|
+
break;
|
|
159
|
+
case SyntaxKind.SubGraphStatement:
|
|
160
|
+
break;
|
|
161
|
+
case SyntaxKind.AttributeStatement:
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
if (carrierIdentifier)
|
|
165
|
+
ensureMemberSymbol(node.leftId, carrierIdentifier);
|
|
166
|
+
bind(node.rightId);
|
|
167
|
+
if (node.rightId && !nodeContainsErrors(node.rightId)) {
|
|
168
|
+
if (isAttributeName("color", node.leftId)) {
|
|
169
|
+
ensureGlobalColor(node.rightId);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (node.terminator)
|
|
173
|
+
bind(node.terminator);
|
|
174
|
+
}
|
|
175
|
+
function bindNormalPortDeclaration(node) {
|
|
176
|
+
bind(node.colon);
|
|
177
|
+
ensureGlobalSymbol(node.id);
|
|
178
|
+
bind(node.id);
|
|
179
|
+
if (node.compassPt)
|
|
180
|
+
bind(node.compassPt);
|
|
181
|
+
}
|
|
182
|
+
function bindCompassPortDeclaration(node) {
|
|
183
|
+
bind(node.colon);
|
|
184
|
+
if (node.compassPt)
|
|
185
|
+
bind(node.compassPt);
|
|
186
|
+
}
|
|
187
|
+
function bindNodeId(node) {
|
|
188
|
+
ensureGlobalSymbol(node.id);
|
|
189
|
+
bind(node.id);
|
|
190
|
+
if (node.port)
|
|
191
|
+
bind(node.port);
|
|
192
|
+
}
|
|
193
|
+
function bindChildren(nodes) {
|
|
194
|
+
for (const n of nodes)
|
|
195
|
+
bind(n);
|
|
196
|
+
}
|
|
197
|
+
function createSymbolTable() {
|
|
198
|
+
return new Map();
|
|
199
|
+
}
|
|
200
|
+
function createColorTable() {
|
|
201
|
+
return new Map();
|
|
202
|
+
}
|
|
203
|
+
function ensureMemberSymbol(node, carrier) {
|
|
204
|
+
if (node && carrier && isIdentifierNode(node)) {
|
|
205
|
+
const name = getIdentifierText(node);
|
|
206
|
+
if (name === undefined)
|
|
207
|
+
return;
|
|
208
|
+
const carrierSymbol = carrier.symbol;
|
|
209
|
+
if (carrierSymbol === undefined)
|
|
210
|
+
throw "carrierSymbol is undefined";
|
|
211
|
+
let symbols = carrierSymbol.members;
|
|
212
|
+
if (symbols === undefined)
|
|
213
|
+
carrierSymbol.members = symbols = createSymbolTable();
|
|
214
|
+
ensureSymbolOnTable(name, node, symbols);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
console.warn("ensureSymbol called on non-identifier node");
|
|
218
|
+
debugger;
|
|
219
|
+
}
|
|
220
|
+
function ensureGlobalSymbol(node) {
|
|
221
|
+
if (node && isIdentifierNode(node)) {
|
|
222
|
+
const symbols = symbolTable;
|
|
223
|
+
const name = getIdentifierText(node);
|
|
224
|
+
if (name === undefined)
|
|
225
|
+
return;
|
|
226
|
+
if (symbols === undefined)
|
|
227
|
+
throw "symbolTable is undefined";
|
|
228
|
+
ensureSymbolOnTable(name, node, symbols);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
console.warn("ensureSymbol called on non-identifier node");
|
|
232
|
+
debugger;
|
|
233
|
+
}
|
|
234
|
+
function ensureSymbolOnTable(name, node, symbols) {
|
|
235
|
+
if (!name)
|
|
236
|
+
return;
|
|
237
|
+
let sym = symbols.get(name);
|
|
238
|
+
if (sym === undefined) {
|
|
239
|
+
sym = createSymbol(name, node);
|
|
240
|
+
symbols.set(name, sym);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
if (!sym.references)
|
|
244
|
+
sym.references = [node];
|
|
245
|
+
else
|
|
246
|
+
sym.references.push(node);
|
|
247
|
+
}
|
|
248
|
+
node.symbol = sym;
|
|
249
|
+
}
|
|
250
|
+
function ensureGlobalColor(node) {
|
|
251
|
+
if (node && isIdentifierNode(node)) {
|
|
252
|
+
const colors = colorTable;
|
|
253
|
+
const name = getIdentifierText(node);
|
|
254
|
+
if (name === undefined)
|
|
255
|
+
return;
|
|
256
|
+
if (colors === undefined)
|
|
257
|
+
throw "symbolTable is undefined";
|
|
258
|
+
const color = createColor(node);
|
|
259
|
+
colors.set(name, color);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
console.warn("ensureSymbol called on non-identifier node");
|
|
263
|
+
debugger;
|
|
264
|
+
}
|
|
265
|
+
function createSymbol(name, node) {
|
|
266
|
+
if (!name)
|
|
267
|
+
throw "name is falsy";
|
|
268
|
+
if (!node)
|
|
269
|
+
throw "node is undefined or null";
|
|
270
|
+
return {
|
|
271
|
+
name,
|
|
272
|
+
firstMention: node,
|
|
273
|
+
references: undefined,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function createColor(node) {
|
|
277
|
+
return {
|
|
278
|
+
node,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function isAttributeName(name, id) {
|
|
282
|
+
return id ? getIdentifierText(id).trim().toLowerCase() === name : false;
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
bind: file => {
|
|
286
|
+
symbolTable = createSymbolTable();
|
|
287
|
+
colorTable = createColorTable();
|
|
288
|
+
const { graph } = file;
|
|
289
|
+
if (graph)
|
|
290
|
+
bind(graph);
|
|
291
|
+
file.symbols = symbolTable;
|
|
292
|
+
file.colors = colorTable;
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=binder.js.map
|