1
1
import { writeFile } from 'node:fs/promises' ;
2
- import { AST_NODES , astNodeNamesWithFieldOrder } from './ast-types.js' ;
3
- import { getNode } from './generate-buffer-to-ast.js' ;
2
+ import { astNodeNamesWithFieldOrder } from './ast-types.js' ;
4
3
import { firstLetterLowercase , lintTsFile } from './helpers.js' ;
5
4
6
5
const bufferParsersFile = new URL ( '../src/ast/bufferParsers.ts' , import . meta. url ) ;
7
6
8
- const nodeTypes = astNodeNamesWithFieldOrder . map ( ( { name } ) => getNode ( name ) . astType || name ) ;
7
+ const nodeTypes = astNodeNamesWithFieldOrder . map ( ( { name, node } ) => node . astType || name ) ;
9
8
10
9
const nodeTypeImports = nodeTypes . map ( name => `import ${ name } from './nodes/${ name } ';` ) ;
11
10
const nodeTypeStrings = nodeTypes . map ( name => `\t'${ name } '` ) ;
12
11
13
- const jsConverters = astNodeNamesWithFieldOrder . map (
14
- ( { name, inlinedVariableField, reservedFields, allFields } ) => {
15
- const node = getNode ( name ) ;
16
- const readStringArgument = allFields . some ( ( [ , fieldType ] ) =>
17
- [ 'Node' , 'OptionalNode' , 'NodeList' , 'String' , 'FixedString' , 'OptionalString' ] . includes (
18
- fieldType
19
- )
12
+ const jsConverters = astNodeNamesWithFieldOrder . map ( ( { name, fields, node, originalNode } ) => {
13
+ const readStringArgument = fields . some ( ( [ , fieldType ] ) =>
14
+ [ 'Node' , 'OptionalNode' , 'NodeList' , 'String' , 'FixedString' , 'OptionalString' ] . includes (
15
+ fieldType
20
16
)
21
- ? ', readString'
22
- : '' ;
23
- /** @type {string[] } */
24
- const definitions = [ ] ;
25
- let offset = 0 ;
26
- let needsBuffer = false ;
27
- let needsScope = false ;
28
- if ( node . flags ) {
29
- offset ++ ;
30
- needsBuffer = true ;
31
- definitions . push (
32
- 'const flags = buffer[position];\n' ,
33
- ...node . flags . map ( ( flagName , index ) => {
34
- let assignmentLeftHand = node . baseForAdditionalFields ?. includes ( flagName )
35
- ? `const ${ flagName } = `
36
- : '' ;
37
- if ( ! node . hiddenFields ?. includes ( flagName ) ) {
38
- assignmentLeftHand += `node.${ flagName } = ` ;
39
- }
40
- return `${ assignmentLeftHand } (flags & ${ 1 << index } ) === ${ 1 << index } ;` ;
41
- } )
42
- ) ;
43
- }
44
- for ( const [ index , field ] of reservedFields . entries ( ) ) {
45
- const fieldDefinition = getFieldDefinition ( field , name , offset + index , false ) ;
46
- needsBuffer = true ;
47
- needsScope ||= fieldDefinition . needsScope ;
48
- definitions . push ( `${ fieldDefinition . definition } \n` ) ;
49
- }
50
- offset += reservedFields . length ;
51
- if ( inlinedVariableField ) {
52
- const fieldDefinition = getFieldDefinition ( inlinedVariableField , name , offset , true ) ;
53
- needsBuffer = true ;
54
- needsScope ||= fieldDefinition . needsScope ;
55
- definitions . push ( `${ fieldDefinition . definition } \n` ) ;
56
- }
57
- for ( const [ fieldName , fieldValue ] of Object . entries ( node . additionalFields || { } ) ) {
58
- definitions . push ( `node.${ fieldName } = ${ fieldValue } ;\n` ) ;
59
- }
60
- for ( const [ fieldName , fallbackName ] of Object . entries ( node . optionalFallback || { } ) ) {
61
- needsScope = true ;
62
- definitions . push (
63
- `node.${ fieldName } = ${ fieldName } Position === 0 ? node.${ fallbackName } : convertNode(node, scope, ${ fieldName } Position, buffer, readString);\n`
64
- ) ;
65
- }
66
- if ( needsScope ) {
67
- definitions . unshift ( 'const {scope} = node;' ) ;
68
- }
69
- /** @type {string[] } */
70
- const parameters = [ ] ;
71
- if ( definitions . length > 0 ) {
72
- parameters . push ( `node: ${ node . astType || name } ` ) ;
73
- if ( needsBuffer ) {
74
- parameters . push ( `position, buffer${ readStringArgument } ` ) ;
75
- }
17
+ )
18
+ ? ', readString'
19
+ : '' ;
20
+ /** @type {string[] } */
21
+ const definitions = [ ] ;
22
+ let offset = 0 ;
23
+ let needsBuffer = false ;
24
+ let needsScope = false ;
25
+ if ( node . flags ) {
26
+ offset ++ ;
27
+ needsBuffer = true ;
28
+ definitions . push (
29
+ 'const flags = buffer[position];\n' ,
30
+ ...node . flags . map ( ( flagName , index ) => {
31
+ let assignmentLeftHand = node . baseForAdditionalFields ?. includes ( flagName )
32
+ ? `const ${ flagName } = `
33
+ : '' ;
34
+ if ( ! node . hiddenFields ?. includes ( flagName ) ) {
35
+ assignmentLeftHand += `node.${ flagName } = ` ;
36
+ }
37
+ return `${ assignmentLeftHand } (flags & ${ 1 << index } ) === ${ 1 << index } ;` ;
38
+ } )
39
+ ) ;
40
+ }
41
+ for ( const [ index , field ] of fields . entries ( ) ) {
42
+ const fieldDefinition = getFieldDefinition ( field , node , originalNode , offset + index ) ;
43
+ needsBuffer = true ;
44
+ needsScope ||= fieldDefinition . needsScope ;
45
+ definitions . push ( `${ fieldDefinition . definition } \n` ) ;
46
+ }
47
+ offset += fields . length ;
48
+ for ( const [ fieldName , fieldValue ] of Object . entries ( node . additionalFields || { } ) ) {
49
+ definitions . push ( `node.${ fieldName } = ${ fieldValue } ;\n` ) ;
50
+ }
51
+ for ( const [ fieldName , fallbackName ] of Object . entries ( node . optionalFallback || { } ) ) {
52
+ needsScope = true ;
53
+ definitions . push (
54
+ `node.${ fieldName } = ${ fieldName } Position === 0 ? node.${ fallbackName } : convertNode(node, scope, ${ fieldName } Position, buffer, readString);\n`
55
+ ) ;
56
+ }
57
+ if ( needsScope ) {
58
+ definitions . unshift ( 'const {scope} = node;' ) ;
59
+ }
60
+ /** @type {string[] } */
61
+ const parameters = [ ] ;
62
+ if ( definitions . length > 0 ) {
63
+ parameters . push ( `node: ${ node . astType || name } ` ) ;
64
+ if ( needsBuffer ) {
65
+ parameters . push ( `position, buffer${ readStringArgument } ` ) ;
76
66
}
77
- return `function ${ firstLetterLowercase ( name ) } (${ parameters . join ( ', ' ) } ) {
78
- ${ definitions . join ( '' ) } }` ;
79
67
}
80
- ) ;
68
+ return `function ${ firstLetterLowercase ( name ) } (${ parameters . join ( ', ' ) } ) {
69
+ ${ definitions . join ( '' ) } }` ;
70
+ } ) ;
81
71
82
72
/**
83
- * @param {import('./ast-types.js').FieldWithType } field
84
- * @param {string } name
73
+ * @param {import("./ast-types.js").FieldWithType } field
74
+ * @param {import("./ast-types.js").NodeDescription } node
75
+ * @param {import("./ast-types.js").NodeDescription } originalNode
85
76
* @param {number } offset
86
- * @param {boolean } isInlined
87
77
* @returns {{definition: string, needsScope: boolean} }
88
78
*/
89
- function getFieldDefinition ( [ fieldName , fieldType ] , name , offset , isInlined ) {
90
- const originalNode = AST_NODES [ name ] ;
91
- const node = getNode ( name ) ;
79
+ function getFieldDefinition ( [ fieldName , fieldType ] , node , originalNode , offset ) {
92
80
const getPosition = offset > 0 ? `position + ${ offset } ` : 'position' ;
93
- const dataStart = isInlined ? getPosition : `buffer[${ getPosition } ]` ;
81
+ const dataStart = `buffer[${ getPosition } ]` ;
94
82
if ( node . scriptedFields ?. [ fieldName ] ) {
95
83
return {
96
84
definition : node . scriptedFields ?. [ fieldName ] . replace ( / \$ p o s i t i o n / g, dataStart ) ,
@@ -114,7 +102,7 @@ function getFieldDefinition([fieldName, fieldType], name, offset, isInlined) {
114
102
} ;
115
103
}
116
104
case 'OptionalNode' : {
117
- let definition = `const ${ fieldName } Position = buffer[ ${ getPosition } ] ;` ;
105
+ let definition = `const ${ fieldName } Position = ${ dataStart } ;` ;
118
106
let needsScope = false ;
119
107
if ( ! node . optionalFallback ?. [ fieldName ] ) {
120
108
needsScope = true ;
@@ -158,13 +146,13 @@ function getFieldDefinition([fieldName, fieldType], name, offset, isInlined) {
158
146
}
159
147
case 'OptionalString' : {
160
148
return {
161
- definition : `const ${ fieldName } Position = buffer[ ${ getPosition } ] ;\n${ assignmentLeftHand } ${ fieldName } Position === 0 ? undefined : convertString(${ fieldName } Position, buffer, readString)${ typeCastString } ;` ,
149
+ definition : `const ${ fieldName } Position = ${ dataStart } ;\n${ assignmentLeftHand } ${ fieldName } Position === 0 ? undefined : convertString(${ fieldName } Position, buffer, readString)${ typeCastString } ;` ,
162
150
needsScope : false
163
151
} ;
164
152
}
165
153
case 'FixedString' : {
166
154
return {
167
- definition : `${ assignmentLeftHand } FIXED_STRINGS[buffer[ ${ getPosition } ] ]${ typeCastString } ;` ,
155
+ definition : `${ assignmentLeftHand } FIXED_STRINGS[${ dataStart } ]${ typeCastString } ;` ,
168
156
needsScope : false
169
157
} ;
170
158
}
@@ -186,6 +174,7 @@ const bufferParsers = `// This file is generated by scripts/generate-ast-convert
186
174
import type * as estree from 'estree';
187
175
import type { AstContext } from '../Module';
188
176
import { convertAnnotations, convertString } from '../utils/astConverterHelpers';
177
+ import { EMPTY_ARRAY } from '../utils/blank';
189
178
import { convertNode as convertJsonNode } from '../utils/bufferToAst';
190
179
import FIXED_STRINGS from '../utils/convert-ast-strings';
191
180
import type { ReadString } from '../utils/getReadStringFunction';
@@ -242,6 +231,7 @@ function convertNode(parent: Node | { context: AstContext; type: string }, paren
242
231
}
243
232
244
233
function convertNodeList(parent: Node | { context: AstContext; type: string }, parentScope: ChildScope, position: number, buffer: Uint32Array, readString: ReadString): any[] {
234
+ if (position === 0) return EMPTY_ARRAY as never[];
245
235
const length = buffer[position++];
246
236
const list: any[] = [];
247
237
for (let index = 0; index < length; index++) {
0 commit comments