Skip to content

Commit 8d7293d

Browse files
committed
build: replace dts-tree-sitter with custom node type generator script
1 parent a7d2728 commit 8d7293d

22 files changed

Lines changed: 442 additions & 551 deletions

.github/workflows/github-ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ jobs:
88
strategy:
99
matrix:
1010
node_version:
11-
- 20.x
1211
- 22.x
12+
- 24.x
1313
steps:
1414
- uses: actions/checkout@v4
1515
- uses: actions/setup-node@v3
@@ -33,15 +33,15 @@ jobs:
3333
test_repository:
3434
- e2e-jhipster1
3535
- e2e-jhipster2
36-
node_version: [22.x]
36+
node_version: [24.x]
3737
steps:
3838
- uses: actions/checkout@v4
3939
- uses: actions/setup-node@v3
4040
with:
4141
node-version: ${{ matrix.node_version }}
4242
- uses: actions/setup-java@v3
4343
with:
44-
java-version: 21.x
44+
java-version: 25.x
4545
distribution: zulu
4646
- name: Install dependencies
4747
run: yarn

.github/workflows/github-pages-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
fetch-depth: 0
2020
- uses: actions/setup-node@v4
2121
with:
22-
node-version: 20
22+
node-version: 24
2323
cache: yarn
2424

2525
- name: Install prettier-plugin-java dependencies

.github/workflows/github-pages-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
fetch-depth: 0
2020
- uses: actions/setup-node@v4
2121
with:
22-
node-version: 20
22+
node-version: 24
2323
cache: yarn
2424

2525
- name: Install prettier-plugin-java dependencies

.prettierignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/.nx/workspace-data
2-
/src/tree-sitter-java.d.ts
32
/website/.docusaurus
43
/website/build
54
/CHANGELOG.md

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"clone-samples": "node scripts/clone-samples.js",
2020
"format:fix": "prettier --write \"**/*.@(js|json|ts)\"",
2121
"format:validate": "prettier --list-different \"**/*.@(js|json|ts)\"",
22-
"postinstall": "cp node_modules/tree-sitter-java-orchard/tree-sitter-java_orchard.wasm src/ && dts-tree-sitter node_modules/tree-sitter-java-orchard > src/tree-sitter-java.d.ts",
22+
"postinstall": "cp node_modules/tree-sitter-java-orchard/tree-sitter-java_orchard.wasm src/ && node scripts/generate-node-types.ts && prettier --write src/node-types.ts",
2323
"lerna:publish": "lerna publish from-git --yes",
2424
"lerna:version": "lerna version --exact --no-private",
2525
"lint": "eslint src/**/*.ts",
@@ -46,7 +46,6 @@
4646
"web-tree-sitter": "0.26.6"
4747
},
4848
"devDependencies": {
49-
"@asgerf/dts-tree-sitter": "^0.21.0",
5049
"@eslint/js": "^10.0.1",
5150
"@types/chai": "^5.0.1",
5251
"@types/emscripten": "^1.41.5",

scripts/generate-node-types.ts

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import fs from "node:fs";
2+
import nodeTypeInfo from "tree-sitter-java-orchard/src/node-types.json" with { type: "json" };
3+
4+
fs.writeFileSync(
5+
"src/node-types.ts",
6+
`interface Point {
7+
index: number;
8+
row: number;
9+
column: number;
10+
}
11+
12+
interface SyntaxNodeBase {
13+
value: string;
14+
start: Point;
15+
end: Point;
16+
comments?: CommentNode[];
17+
}
18+
19+
interface NamedNodeBase extends SyntaxNodeBase {
20+
isNamed: true;
21+
fieldName: string | null;
22+
children: SyntaxNode[];
23+
namedChildren: NamedNode[];
24+
}
25+
26+
export interface UnnamedNode<T extends UnnamedType = UnnamedType> extends SyntaxNodeBase {
27+
type: T;
28+
isNamed: false;
29+
fieldName: string | null;
30+
}
31+
32+
export interface CommentNode extends SyntaxNodeBase {
33+
type: SyntaxType.BlockComment | SyntaxType.LineComment;
34+
leading: boolean;
35+
trailing: boolean;
36+
printed: boolean;
37+
enclosingNode?: SyntaxNode;
38+
precedingNode?: SyntaxNode;
39+
followingNode?: SyntaxNode;
40+
}
41+
42+
type PickNamedType<Node, T extends SyntaxType> = Node extends { type: T; isNamed: true } ? Node : never;
43+
44+
export type NamedNode<T extends NamedType = NamedType> = PickNamedType<SyntaxNode, T>;
45+
46+
export const enum SyntaxType {
47+
ERROR = "ERROR",
48+
${nodeTypeInfo
49+
.filter(({ named, subtypes }) => named && !subtypes?.length)
50+
.map(
51+
({ type }) =>
52+
` ${getSyntaxKindFromString(type)} = ${JSON.stringify(type)},`
53+
)
54+
.join("\n")}
55+
};
56+
57+
export type NamedType = Exclude<SyntaxType, SyntaxType.BlockComment | SyntaxType.LineComment>;
58+
59+
export type UnnamedType = ${nodeTypeInfo
60+
.filter(({ named }) => !named)
61+
.map(({ type }) => JSON.stringify(type))
62+
.join(" | ")};
63+
64+
export type TypeString = NamedType | UnnamedType;
65+
66+
export type SyntaxNode = ErrorNode | ${nodeTypeInfo
67+
.filter(({ type }) => !type.endsWith("_comment"))
68+
.map(getTypeExprFromRef)
69+
.join(" | ")};
70+
71+
export interface ErrorNode extends NamedNodeBase {
72+
type: SyntaxType.ERROR;
73+
}
74+
75+
${nodeTypeInfo
76+
.filter(({ named }) => named)
77+
.map(({ type, subtypes, fields }) =>
78+
subtypes?.length
79+
? `export type ${getTypeNameFromString(type)} = ${subtypes.map(getTypeExprFromRef).join(" | ")};`
80+
: `export interface ${getTypeNameFromString(type)} extends NamedNodeBase {
81+
type: SyntaxType.${getSyntaxKindFromString(type)};
82+
${
83+
fields && Object.keys(fields).length
84+
? `${Object.entries(fields as unknown as Record<string, NodeTypeChildren>)
85+
.map(([field, children]) => {
86+
let fieldName = `${field}Node`;
87+
let type = children.types.length
88+
? children.types.map(t => getTypeExprFromRef(t)).join(" | ")
89+
: "UnnamedNode";
90+
if (children.multiple) {
91+
if (children.types.length > 1) {
92+
type = `(${type})`;
93+
}
94+
type += "[]";
95+
fieldName += "s";
96+
}
97+
const opt = children.required || children.multiple ? "" : "?";
98+
return ` ${fieldName}${opt}: ${type};`;
99+
})
100+
.join("\n")}
101+
}`
102+
: "}"
103+
}`
104+
)
105+
.join("\n\n")}
106+
`
107+
);
108+
109+
interface NodeTypeRef {
110+
type: string;
111+
named: boolean;
112+
isError?: boolean;
113+
}
114+
115+
interface NodeTypeChildren {
116+
multiple: boolean;
117+
required: boolean;
118+
types: NodeTypeRef[];
119+
}
120+
121+
function isIdentifier(str: string) {
122+
return /^[a-z$_][a-z0-9$_]*$/i.test(str);
123+
}
124+
125+
function mangleNameToIdentifier(str: string) {
126+
let sb = "$";
127+
for (let i = 0; i < str.length; ++i) {
128+
const char = str.charAt(i);
129+
if (/[a-z0-9_]/i.test(char)) {
130+
sb += char;
131+
} else {
132+
sb += "$" + str.charCodeAt(i) + "$";
133+
}
134+
}
135+
return sb;
136+
}
137+
138+
function toCapitalCase(str: string) {
139+
return str
140+
.replace(/^[a-z]/, t => t.toUpperCase())
141+
.replace(/_[a-zA-Z]/g, t => t.substring(1).toUpperCase());
142+
}
143+
144+
function getTypePrefixFromString(str: string) {
145+
return isIdentifier(str) ? toCapitalCase(str) : mangleNameToIdentifier(str);
146+
}
147+
148+
function getTypeNameFromString(str: string) {
149+
return getTypePrefixFromString(str) + "Node";
150+
}
151+
152+
function getSyntaxKindFromString(str: string) {
153+
return getTypePrefixFromString(str);
154+
}
155+
156+
function getTypeExprFromRef({ type, named }: { type: string; named: boolean }) {
157+
return named
158+
? getTypeNameFromString(type)
159+
: `UnnamedNode<${JSON.stringify(type)}>`;
160+
}

0 commit comments

Comments
 (0)