Skip to content

Commit d880992

Browse files
authored
Merge pull request #199 from DTStack/feat/tree-visual
feat(website): #171, add parse tree visualizer in panel
2 parents b344f7c + c37dd9b commit d880992

File tree

8 files changed

+703
-35
lines changed

8 files changed

+703
-35
lines changed

src/baseSQLWorker.ts

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { worker } from './fillers/monaco-editor-core';
33
import { Suggestions, ParseError, EntityContext } from 'dt-sql-parser';
44
import { Position } from './fillers/monaco-editor-core';
55
import { SemanticContext } from 'dt-sql-parser/dist/parser/common/types';
6+
import type { SerializedTreeNode } from './languageService';
67

78
export interface ICreateData {
89
languageId: string;
@@ -24,14 +25,43 @@ export abstract class BaseSQLWorker {
2425
return Promise.resolve([]);
2526
}
2627

27-
async parserTreeToString(code: string): Promise<string> {
28-
if (code) {
29-
const parser = this.parser.createParser(code);
30-
const parseTree = parser.program();
31-
const result = parseTree.toStringTree(parser);
32-
return Promise.resolve(result);
28+
async getSerializedParseTree(code: string): Promise<SerializedTreeNode | null> {
29+
if (!code) return Promise.resolve(null);
30+
31+
const parser = this.parser.createParser(code);
32+
const parseTree = parser.program();
33+
const ruleNames = parser.ruleNames;
34+
const tokenTypeMap = parser.getTokenTypeMap();
35+
const tokenNameMap = new Map();
36+
37+
for (const [name, tokenType] of tokenTypeMap.entries()) {
38+
tokenNameMap.set(tokenType, name);
39+
}
40+
41+
function serializeNode(node: any): SerializedTreeNode | null {
42+
if (!node) return null;
43+
44+
const isRuleNode = !node.symbol;
45+
46+
const serializedNode: SerializedTreeNode = {
47+
ruleName: isRuleNode ? ruleNames[node.ruleIndex] : node.constructor.name,
48+
text: isRuleNode
49+
? ''
50+
: tokenNameMap.get(node.symbol.tokenSource?.type) + ': ' + node.symbol.text,
51+
children: []
52+
};
53+
54+
for (let i = 0; i < node.getChildCount(); i++) {
55+
const child = node.getChild(i);
56+
if (child) {
57+
serializedNode.children.push(serializeNode(child)!);
58+
}
59+
}
60+
61+
return serializedNode;
3362
}
34-
return Promise.resolve('');
63+
64+
return Promise.resolve(serializeNode(parseTree));
3565
}
3666

3767
async doCompletion(code: string, position: Position): Promise<Suggestions | null> {

src/languageService.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ import { WorkerManager } from './workerManager';
77
import { BaseSQLWorker } from './baseSQLWorker';
88
import { Position, Uri, editor } from './fillers/monaco-editor-core';
99

10+
export interface SerializedTreeNode {
11+
ruleName: string;
12+
text?: string;
13+
children: SerializedTreeNode[];
14+
}
15+
1016
export class LanguageService<T extends BaseSQLWorker = BaseSQLWorker> {
1117
private workerClients: Map<string, WorkerManager<T>> = new Map();
1218

@@ -20,13 +26,13 @@ export class LanguageService<T extends BaseSQLWorker = BaseSQLWorker> {
2026
});
2127
}
2228

23-
public parserTreeToString(language: string, model: editor.IReadOnlyModel | string) {
29+
public getSerializedParseTree(language: string, model: editor.IReadOnlyModel | string) {
2430
const text = typeof model === 'string' ? model : model.getValue();
2531
const uri = typeof model === 'string' ? void 0 : model.uri;
2632

2733
const clientWorker = this.getClientWorker(language, uri as Uri);
2834
return clientWorker.then((worker) => {
29-
return worker.parserTreeToString(text);
35+
return worker.getSerializedParseTree(text);
3036
});
3137
}
3238

website/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@
2323
"react-dom": "^18.2.0",
2424
"reflect-metadata": "^0.1.13",
2525
"tsyringe": "^4.8.0",
26+
"html-to-image": "^1.11.13",
2627
"vscode-oniguruma": "^2.0.1",
27-
"vscode-textmate": "^9.2.0"
28+
"vscode-textmate": "^9.2.0",
29+
"@xyflow/react": "^12.4.2",
30+
"dagre": "^0.8.5"
2831
},
2932
"devDependencies": {
33+
"@types/dagre": "^0.7.52",
3034
"@types/node": "^20.2.5",
3135
"@types/react": "^18.0.37",
3236
"@types/react-dom": "^18.0.11",

0 commit comments

Comments
 (0)