@@ -21,8 +21,8 @@ const (
21
21
22
22
const (
23
23
NodeDataTypeChildren uint32 = iota << 30
24
- NodeDataTypeStringIndex
25
- NodeDataTypeExtendedDataIndex
24
+ NodeDataTypeString
25
+ NodeDataTypeExtendedData
26
26
)
27
27
28
28
const (
@@ -36,20 +36,22 @@ const (
36
36
)
37
37
38
38
const (
39
- HeaderOffsetReserved = iota * 4
40
- HeaderOffsetStringTableOffsets
41
- HeaderOffsetStringTable
42
- HeaderOffsetExtendedDataOffsets
39
+ HeaderOffsetMetadata = iota * 4
40
+ HeaderOffsetStringOffsets
41
+ HeaderOffsetStringData
43
42
HeaderOffsetExtendedData
44
43
HeaderOffsetNodes
45
44
HeaderSize
46
45
)
47
46
48
- // EncodeSourceFile encodes a source file into a byte slice.
47
+ const (
48
+ ProtocolVersion uint8 = 1
49
+ )
50
+
51
+ // EncodeSourceFile encodes a source file into a byte slice. The protocol
49
52
func EncodeSourceFile (sourceFile * ast.SourceFile ) ([]byte , error ) {
50
- var err error
51
53
var parentIndex , nodeCount , prevIndex uint32
52
-
54
+ var extendedData [] byte
53
55
strs := newStringTable (sourceFile .Text , sourceFile .TextCount )
54
56
nodes := make ([]byte , 0 , (sourceFile .NodeCount + 1 )* NodeSize )
55
57
@@ -70,9 +72,7 @@ func EncodeSourceFile(sourceFile *ast.SourceFile) ([]byte, error) {
70
72
nodes [prevIndex * NodeSize + NodeOffsetNext + 3 ] = b3
71
73
}
72
74
73
- if nodes , err = appendUint32s (nodes , SyntaxKindNodeList , uint32 (nodeList .Pos ()), uint32 (nodeList .End ()), 0 , parentIndex , uint32 (len (nodeList .Nodes ))); err != nil {
74
- return nil
75
- }
75
+ nodes = appendUint32s (nodes , SyntaxKindNodeList , uint32 (nodeList .Pos ()), uint32 (nodeList .End ()), 0 , parentIndex , uint32 (len (nodeList .Nodes )))
76
76
77
77
saveParentIndex := parentIndex
78
78
@@ -104,10 +104,7 @@ func EncodeSourceFile(sourceFile *ast.SourceFile) ([]byte, error) {
104
104
nodes [prevIndex * NodeSize + NodeOffsetNext + 3 ] = b3
105
105
}
106
106
107
- if nodes , err = appendUint32s (nodes , uint32 (node .Kind ), uint32 (node .Pos ()), uint32 (node .End ()), 0 , parentIndex , getNodeData (node , strs )); err != nil {
108
- visitor .Visit = nil
109
- return nil
110
- }
107
+ nodes = appendUint32s (nodes , uint32 (node .Kind ), uint32 (node .Pos ()), uint32 (node .End ()), 0 , parentIndex , getNodeData (node , strs , & extendedData ))
111
108
112
109
saveParentIndex := parentIndex
113
110
@@ -120,70 +117,61 @@ func EncodeSourceFile(sourceFile *ast.SourceFile) ([]byte, error) {
120
117
return node
121
118
}
122
119
123
- if nodes , err = appendUint32s (nodes , 0 , 0 , 0 , 0 , 0 , 0 ); err != nil {
124
- return nil , err
125
- }
120
+ nodes = appendUint32s (nodes , 0 , 0 , 0 , 0 , 0 , 0 )
126
121
127
122
nodeCount ++
128
123
parentIndex ++
129
- if nodes , err = appendUint32s (nodes , uint32 (sourceFile .Kind ), uint32 (sourceFile .Pos ()), uint32 (sourceFile .End ()), 0 , 0 , 0 ); err != nil {
130
- return nil , err
131
- }
124
+ nodes = appendUint32s (nodes , uint32 (sourceFile .Kind ), uint32 (sourceFile .Pos ()), uint32 (sourceFile .End ()), 0 , 0 , 0 )
132
125
133
126
visitor .VisitEachChild (sourceFile .AsNode ())
134
- if err != nil {
135
- return nil , err
136
- }
137
127
128
+ metadata := uint32 (ProtocolVersion ) << 24
138
129
offsetStringTableOffsets := HeaderSize
139
130
offsetStringTableData := HeaderSize + len (strs .offsets )* 4
140
- offsetNodes := offsetStringTableData + strs .stringLength ()
141
- offsetExtendedDataOffsets := 0
142
- offsetExtendedDataData := 0
131
+ offsetExtendedData := offsetStringTableData + strs .stringLength ()
132
+ offsetNodes := offsetExtendedData + len (extendedData )
143
133
144
134
header := []uint32 {
145
- 0 ,
135
+ metadata ,
146
136
uint32 (offsetStringTableOffsets ),
147
137
uint32 (offsetStringTableData ),
148
- uint32 (offsetExtendedDataOffsets ),
149
- uint32 (offsetExtendedDataData ),
138
+ uint32 (offsetExtendedData ),
150
139
uint32 (offsetNodes ),
151
140
}
152
141
153
142
var headerBytes , strsBytes []byte
154
- if headerBytes , err = appendUint32s (nil , header ... ); err != nil {
155
- return nil , err
156
- }
157
- if strsBytes , err = strs .encode (); err != nil {
158
- return nil , err
159
- }
143
+ headerBytes = appendUint32s (nil , header ... )
144
+ strsBytes = strs .encode ()
160
145
161
146
return slices .Concat (
162
147
headerBytes ,
163
148
strsBytes ,
149
+ extendedData ,
164
150
nodes ,
165
151
), nil
166
152
}
167
153
168
- func appendUint32s (buf []byte , values ... uint32 ) ( []byte , error ) {
154
+ func appendUint32s (buf []byte , values ... uint32 ) []byte {
169
155
for _ , value := range values {
170
156
var err error
171
157
if buf , err = binary .Append (buf , binary .LittleEndian , value ); err != nil {
172
- return nil , err
158
+ // The only error binary.Append can return is for values that are not fixed-size.
159
+ // This can never happen here, since we are always appending uint32.
160
+ panic (fmt .Sprintf ("failed to append uint32: %v" , err ))
173
161
}
174
162
}
175
- return buf , nil
163
+ return buf
176
164
}
177
165
178
- func getNodeData (node * ast.Node , strs * stringTable ) uint32 {
166
+ func getNodeData (node * ast.Node , strs * stringTable , extendedData * [] byte ) uint32 {
179
167
t := getNodeDataType (node )
180
168
switch t {
181
169
case NodeDataTypeChildren :
182
170
return t | getNodeDefinedData (node ) | uint32 (getChildrenPropertyMask (node ))
183
- case NodeDataTypeStringIndex :
171
+ case NodeDataTypeString :
184
172
return t | getNodeDefinedData (node ) | recordNodeStrings (node , strs )
185
- case NodeDataTypeExtendedDataIndex :
186
- return t | getNodeDefinedData (node ) /* | TODO */
173
+ case NodeDataTypeExtendedData :
174
+ return t | getNodeDefinedData (node ) | recordExtendedData ( node , strs , extendedData )
187
175
default :
188
176
panic ("unreachable" )
189
177
}
@@ -200,11 +188,11 @@ func getNodeDataType(node *ast.Node) uint32 {
200
188
ast .KindRegularExpressionLiteral ,
201
189
ast .KindNoSubstitutionTemplateLiteral ,
202
190
ast .KindJSDocText :
203
- return NodeDataTypeStringIndex
191
+ return NodeDataTypeString
204
192
case ast .KindTemplateHead ,
205
193
ast .KindTemplateMiddle ,
206
194
ast .KindTemplateTail :
207
- return NodeDataTypeExtendedDataIndex
195
+ return NodeDataTypeExtendedData
208
196
default :
209
197
return NodeDataTypeChildren
210
198
}
@@ -558,9 +546,6 @@ func getNodeDefinedData(node *ast.Node) uint32 {
558
546
case ast .KindImportType :
559
547
n := node .AsImportTypeNode ()
560
548
return uint32 (boolToByte (n .IsTypeOf )) << 24
561
- case ast .KindBlock :
562
- n := node .AsBlock ()
563
- return uint32 (boolToByte (n .Multiline )) << 24
564
549
case ast .KindImportEqualsDeclaration :
565
550
n := node .AsImportEqualsDeclaration ()
566
551
return uint32 (boolToByte (n .IsTypeOnly )) << 24
@@ -570,6 +555,9 @@ func getNodeDefinedData(node *ast.Node) uint32 {
570
555
case ast .KindExportDeclaration :
571
556
n := node .AsExportDeclaration ()
572
557
return uint32 (boolToByte (n .IsTypeOnly )) << 24
558
+ case ast .KindBlock :
559
+ n := node .AsBlock ()
560
+ return uint32 (boolToByte (n .Multiline )) << 24
573
561
case ast .KindArrayLiteralExpression :
574
562
n := node .AsArrayLiteralExpression ()
575
563
return uint32 (boolToByte (n .MultiLine )) << 24
@@ -620,6 +608,33 @@ func recordNodeStrings(node *ast.Node, strs *stringTable) uint32 {
620
608
}
621
609
}
622
610
611
+ func recordExtendedData (node * ast.Node , strs * stringTable , extendedData * []byte ) uint32 {
612
+ offset := uint32 (len (* extendedData ))
613
+ var text , rawText string
614
+ var templateFlags uint32
615
+ switch node .Kind {
616
+ case ast .KindTemplateTail :
617
+ n := node .AsTemplateTail ()
618
+ text = n .Text
619
+ rawText = n .RawText
620
+ templateFlags = uint32 (n .TemplateFlags )
621
+ case ast .KindTemplateMiddle :
622
+ n := node .AsTemplateMiddle ()
623
+ text = n .Text
624
+ rawText = n .RawText
625
+ templateFlags = uint32 (n .TemplateFlags )
626
+ case ast .KindTemplateHead :
627
+ n := node .AsTemplateHead ()
628
+ text = n .Text
629
+ rawText = n .RawText
630
+ templateFlags = uint32 (n .TemplateFlags )
631
+ }
632
+ textIndex := strs .add (text , node .Kind , node .Pos (), node .End ())
633
+ rawTextIndex := strs .add (rawText , node .Kind , node .Pos (), node .End ())
634
+ * extendedData = appendUint32s (* extendedData , textIndex , rawTextIndex , templateFlags )
635
+ return offset
636
+ }
637
+
623
638
func boolToByte (b bool ) byte {
624
639
if b {
625
640
return 1
0 commit comments