816 lines
42 KiB
Go
816 lines
42 KiB
Go
package encoder
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"slices"
|
|
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
|
|
)
|
|
|
|
const (
|
|
NodeOffsetKind = iota * 4
|
|
NodeOffsetPos
|
|
NodeOffsetEnd
|
|
NodeOffsetNext
|
|
NodeOffsetParent
|
|
NodeOffsetData
|
|
// NodeSize is the number of bytes that represents a single node in the encoded format.
|
|
NodeSize
|
|
)
|
|
|
|
const (
|
|
NodeDataTypeChildren uint32 = iota << 30
|
|
NodeDataTypeString
|
|
NodeDataTypeExtendedData
|
|
)
|
|
|
|
const (
|
|
NodeDataTypeMask uint32 = 0xc0_00_00_00
|
|
NodeDataChildMask uint32 = 0x00_00_00_ff
|
|
NodeDataStringIndexMask uint32 = 0x00_ff_ff_ff
|
|
)
|
|
|
|
const (
|
|
SyntaxKindNodeList uint32 = 1<<32 - 1
|
|
)
|
|
|
|
const (
|
|
HeaderOffsetMetadata = iota * 4
|
|
HeaderOffsetStringOffsets
|
|
HeaderOffsetStringData
|
|
HeaderOffsetExtendedData
|
|
HeaderOffsetNodes
|
|
HeaderSize
|
|
)
|
|
|
|
const (
|
|
ProtocolVersion uint8 = 1
|
|
)
|
|
|
|
// Source File Binary Format
|
|
// =========================
|
|
//
|
|
// The following defines a protocol for serializing TypeScript SourceFile objects to a compact binary format. All integer
|
|
// values are little-endian.
|
|
//
|
|
// Overview
|
|
// --------
|
|
//
|
|
// The format comprises six sections:
|
|
//
|
|
// | Section | Length | Description |
|
|
// | ------------------ | ------------------ | ---------------------------------------------------------------------------------------- |
|
|
// | Header | 20 bytes | Contains byte offsets to the start of each section. |
|
|
// | String offsets | 8 bytes per string | Pairs of starting byte offsets and ending byte offsets into the **string data** section. |
|
|
// | String data | variable | UTF-8 encoded string data. |
|
|
// | Extended node data | variable | Extra data for some kinds of nodes. |
|
|
// | Nodes | 24 bytes per node | Defines the AST structure of the file, with references to strings and extended data. |
|
|
//
|
|
// Header (20 bytes)
|
|
// -----------------
|
|
//
|
|
// The header contains the following fields:
|
|
//
|
|
// | Byte offset | Type | Field |
|
|
// | ----------- | ------ | ----------------------------------------- |
|
|
// | 0 | uint8 | Protocol version |
|
|
// | 1-4 | | Reserved |
|
|
// | 4-8 | uint32 | Byte offset to string offsets section |
|
|
// | 8-12 | uint32 | Byte offset to string data section |
|
|
// | 12-16 | uint32 | Byte offset to extended node data section |
|
|
// | 16-20 | uint32 | Byte offset to nodes section |
|
|
//
|
|
// String offsets (8 bytes per string)
|
|
// -----------------------------------
|
|
//
|
|
// Each string offset entry consists of two 4-byte unsigned integers, representing the start and end byte offsets into the
|
|
// **string data** section.
|
|
//
|
|
// String data (variable)
|
|
// ----------------------
|
|
//
|
|
// The string data section contains UTF-8 encoded string data. In typical cases, the entirety of the string data is the
|
|
// source file text, and individual nodes with string properties reference their positional slice of the file text. In
|
|
// cases where a node's string property is not equal to the slice of file text at its position, the unique string is
|
|
// appended to the string data section after the file text.
|
|
//
|
|
// Extended node data (variable)
|
|
// -----------------------------
|
|
//
|
|
// The extended node data section contains additional data for specific node types. The length and meaning of each entry
|
|
// is defined by the node type.
|
|
//
|
|
// Currently, the only node types that use this section are `TemplateHead`, `TemplateMiddle`, `TemplateTail`, and
|
|
// `SourceFile`. The extended data format for the first three is:
|
|
//
|
|
// | Byte offset | Type | Field |
|
|
// | ----------- | ------ | ------------------------------------------------ |
|
|
// | 0-4 | uint32 | Index of `text` in the string offsets section |
|
|
// | 4-8 | uint32 | Index of `rawText` in the string offsets section |
|
|
// | 8-12 | uint32 | Value of `templateFlags` |
|
|
//
|
|
// and for `SourceFile` is:
|
|
//
|
|
// | Byte offset | Type | Field |
|
|
// | ----------- | ------ | ------------------------------------------------- |
|
|
// | 0-4 | uint32 | Index of `text` in the string offsets section |
|
|
// | 4-8 | uint32 | Index of `fileName` in the string offsets section |
|
|
// | 8-12 | uint32 | Index of `id` in the string offsets section |
|
|
//
|
|
// Nodes (24 bytes per node)
|
|
// -------------------------
|
|
//
|
|
// The nodes section contains the AST structure of the file. Nodes are represented in a flat array in source order,
|
|
// heavily inspired by https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-11/. Each node has the following
|
|
// structure:
|
|
//
|
|
// | Byte offset | Type | Field |
|
|
// | ----------- | ------ | -------------------------- |
|
|
// | 0-4 | uint32 | Kind |
|
|
// | 4-8 | uint32 | Pos |
|
|
// | 8-12 | uint32 | End |
|
|
// | 12-16 | uint32 | Node index of next sibling |
|
|
// | 16-20 | uint32 | Node index of parent |
|
|
// | 20-24 | | Node data |
|
|
//
|
|
// The first 24 bytes of the nodes section are zeros representing a nil node, such that nodes without a parent or next
|
|
// sibling can unambiuously use `0` for those indices.
|
|
//
|
|
// NodeLists are represented as normal nodes with the special `kind` value `0xff_ff_ff_ff`. They are considered the parent
|
|
// of their contents in the encoded format. A client reconstructing an AST similar to TypeScript's internal representation
|
|
// should instead set the `parent` pointers of a NodeList's children to the NodeList's parent. A NodeList's `data` field
|
|
// is the uint32 length of the list, and does not use one of the data types described below.
|
|
//
|
|
// For node types other than NodeList, the node data field encodes one of the following, determined by the first 2 bits of
|
|
// the field:
|
|
//
|
|
// | Value | Data type | Description |
|
|
// | ----- | --------- | ------------------------------------------------------------------------------------ |
|
|
// | 0b00 | Children | Disambiguates which named properties of the node its children should be assigned to. |
|
|
// | 0b01 | String | The index of the node's string property in the **string offsets** section. |
|
|
// | 0b10 | Extended | The byte offset of the node's extended data into the **extended node data** section. |
|
|
// | 0b11 | Reserved | Reserved for future use. |
|
|
//
|
|
// In all node data types, the remaining 6 bits of the first byte are used to encode booleans specific to the node type:
|
|
//
|
|
// | Node type | Bits 2-5 | Bit 1 | Bit 0 |
|
|
// | ------------------------- | -------- | ------------- | ------------------------------- |
|
|
// | `ImportSpecifier` | | | `isTypeOnly` |
|
|
// | `ImportClause` | | | `isTypeOnly` |
|
|
// | `ExportSpecifier` | | | `isTypeOnly` |
|
|
// | `ImportEqualsDeclaration` | | | `isTypeOnly` |
|
|
// | `ExportDeclaration` | | | `isTypeOnly` |
|
|
// | `ImportTypeNode` | | | `isTypeOf` |
|
|
// | `ExportAssignment` | | | `isExportEquals` |
|
|
// | `Block` | | | `multiline` |
|
|
// | `ArrayLiteralExpression` | | | `multiline` |
|
|
// | `ObjectLiteralExpression` | | | `multiline` |
|
|
// | `JsxText` | | | `containsOnlyTriviaWhiteSpaces` |
|
|
// | `JSDocTypeLiteral` | | | `isArrayType` |
|
|
// | `JsDocPropertyTag` | | `isNameFirst` | `isBracketed` |
|
|
// | `JsDocParameterTag` | | `isNameFirst` | `isBracketed` |
|
|
// | `VariableDeclarationList` | | is `const` | is `let` |
|
|
// | `ImportAttributes` | | is `assert` | `multiline` |
|
|
//
|
|
// The remaining 3 bytes of the node data field vary by data type:
|
|
//
|
|
// ### Children (0b00)
|
|
//
|
|
// If a node has fewer children than its type allows, additional data is needed to determine which properties the children
|
|
// correspond to. The last byte of the 4-byte data field is a bitmask representing the child properties of the node type,
|
|
// in visitor order, where `1` indicates that the child at that property is present and `0` indicates that the property is
|
|
// nil. For example, a `MethodDeclaration` has the following child properties:
|
|
//
|
|
// | Property name | Bit position |
|
|
// | -------------- | ------------ |
|
|
// | modifiers | 0 |
|
|
// | asteriskToken | 1 |
|
|
// | name | 2 |
|
|
// | postfixToken | 3 |
|
|
// | typeParameters | 4 |
|
|
// | parameters | 5 |
|
|
// | returnType | 6 |
|
|
// | body | 7 |
|
|
//
|
|
// A bitmask with value `0b01100101` would indicate that the next four direct descendants (i.e., node records that have a
|
|
// `parent` set to the node index of the `MethodDeclaration`) of the node are its `modifiers`, `name`, `parameters`, and
|
|
// `body` properties, in that order. The remaining properties are nil. (To reconstruct the node with named properties, the
|
|
// client must consult a static table of each node type's child property names.)
|
|
//
|
|
// The bitmask may be zero for node types that can only have a single child, since no disambiguation is needed.
|
|
// Additionally, the children data type may be used for nodes that can never have children, but do not require other
|
|
// data types.
|
|
//
|
|
// ### String (0b01)
|
|
//
|
|
// The string data type is used for nodes with a single string property. (Currently, the name of that property is always
|
|
// `text`.) The last three bytes of the 4-byte data field form a single 24-bit unsigned integer (i.e.,
|
|
// `uint32(0x00_ff_ff_ff & node.data)`) _N_ that is an index into the **string offsets** section. The *N*th 32-bit
|
|
// unsigned integer in the **string offsets** section is the byte offset of the start of the string in the **string data**
|
|
// section, and the *N+1*th 32-bit unsigned integer is the byte offset of the end of the string in the
|
|
// **string data** section.
|
|
//
|
|
// ### Extended (0b10)
|
|
//
|
|
// The extended data type is used for nodes with properties that don't fit into either the children or string data types.
|
|
// The last three bytes of the 4-byte data field form a single 24-bit unsigned integer (i.e.,
|
|
// `uint32(0x00_ff_ff_ff & node.data)`) _N_ that is a byte offset into the **extended node data** section. The length and
|
|
// meaning of the data at that offset is defined by the node type. See the **Extended node data** section for details on
|
|
// the format of the extended data for specific node types.
|
|
|
|
func EncodeSourceFile(sourceFile *ast.SourceFile, id string) ([]byte, error) {
|
|
var parentIndex, nodeCount, prevIndex uint32
|
|
var extendedData []byte
|
|
strs := newStringTable(sourceFile.Text(), sourceFile.TextCount)
|
|
nodes := make([]byte, 0, (sourceFile.NodeCount+1)*NodeSize)
|
|
|
|
visitor := &ast.NodeVisitor{
|
|
Hooks: ast.NodeVisitorHooks{
|
|
VisitNodes: func(nodeList *ast.NodeList, visitor *ast.NodeVisitor) *ast.NodeList {
|
|
if nodeList == nil || len(nodeList.Nodes) == 0 {
|
|
return nodeList
|
|
}
|
|
|
|
nodeCount++
|
|
if prevIndex != 0 {
|
|
// this is the next sibling of `prevNode`
|
|
b0, b1, b2, b3 := uint8(nodeCount), uint8(nodeCount>>8), uint8(nodeCount>>16), uint8(nodeCount>>24)
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+0] = b0
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+1] = b1
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+2] = b2
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+3] = b3
|
|
}
|
|
|
|
nodes = appendUint32s(nodes, SyntaxKindNodeList, uint32(nodeList.Pos()), uint32(nodeList.End()), 0, parentIndex, uint32(len(nodeList.Nodes)))
|
|
|
|
saveParentIndex := parentIndex
|
|
|
|
currentIndex := nodeCount
|
|
prevIndex = 0
|
|
parentIndex = currentIndex
|
|
visitor.VisitSlice(nodeList.Nodes)
|
|
prevIndex = currentIndex
|
|
parentIndex = saveParentIndex
|
|
|
|
return nodeList
|
|
},
|
|
VisitModifiers: func(modifiers *ast.ModifierList, visitor *ast.NodeVisitor) *ast.ModifierList {
|
|
if modifiers != nil && len(modifiers.Nodes) > 0 {
|
|
visitor.Hooks.VisitNodes(&modifiers.NodeList, visitor)
|
|
}
|
|
return modifiers
|
|
},
|
|
},
|
|
}
|
|
visitor.Visit = func(node *ast.Node) *ast.Node {
|
|
nodeCount++
|
|
if prevIndex != 0 {
|
|
// this is the next sibling of `prevNode`
|
|
b0, b1, b2, b3 := uint8(nodeCount), uint8(nodeCount>>8), uint8(nodeCount>>16), uint8(nodeCount>>24)
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+0] = b0
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+1] = b1
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+2] = b2
|
|
nodes[prevIndex*NodeSize+NodeOffsetNext+3] = b3
|
|
}
|
|
|
|
nodes = appendUint32s(nodes, uint32(node.Kind), uint32(node.Pos()), uint32(node.End()), 0, parentIndex, getNodeData(node, strs, &extendedData))
|
|
|
|
saveParentIndex := parentIndex
|
|
|
|
currentIndex := nodeCount
|
|
prevIndex = 0
|
|
parentIndex = currentIndex
|
|
visitor.VisitEachChild(node)
|
|
prevIndex = currentIndex
|
|
parentIndex = saveParentIndex
|
|
return node
|
|
}
|
|
|
|
nodes = appendUint32s(nodes, 0, 0, 0, 0, 0, 0)
|
|
|
|
nodeCount++
|
|
parentIndex++
|
|
nodes = appendUint32s(nodes, uint32(sourceFile.Kind), uint32(sourceFile.Pos()), uint32(sourceFile.End()), 0, 0, getSourceFileData(sourceFile, id, strs, &extendedData))
|
|
|
|
visitor.VisitEachChild(sourceFile.AsNode())
|
|
|
|
metadata := uint32(ProtocolVersion) << 24
|
|
offsetStringTableOffsets := HeaderSize
|
|
offsetStringTableData := HeaderSize + len(strs.offsets)*4
|
|
offsetExtendedData := offsetStringTableData + strs.stringLength()
|
|
offsetNodes := offsetExtendedData + len(extendedData)
|
|
|
|
header := []uint32{
|
|
metadata,
|
|
uint32(offsetStringTableOffsets),
|
|
uint32(offsetStringTableData),
|
|
uint32(offsetExtendedData),
|
|
uint32(offsetNodes),
|
|
}
|
|
|
|
var headerBytes, strsBytes []byte
|
|
headerBytes = appendUint32s(nil, header...)
|
|
strsBytes = strs.encode()
|
|
|
|
return slices.Concat(
|
|
headerBytes,
|
|
strsBytes,
|
|
extendedData,
|
|
nodes,
|
|
), nil
|
|
}
|
|
|
|
func appendUint32s(buf []byte, values ...uint32) []byte {
|
|
for _, value := range values {
|
|
var err error
|
|
if buf, err = binary.Append(buf, binary.LittleEndian, value); err != nil {
|
|
// The only error binary.Append can return is for values that are not fixed-size.
|
|
// This can never happen here, since we are always appending uint32.
|
|
panic(fmt.Sprintf("failed to append uint32: %v", err))
|
|
}
|
|
}
|
|
return buf
|
|
}
|
|
|
|
func getSourceFileData(sourceFile *ast.SourceFile, id string, strs *stringTable, extendedData *[]byte) uint32 {
|
|
t := NodeDataTypeExtendedData
|
|
extendedDataOffset := len(*extendedData)
|
|
textIndex := strs.add(sourceFile.Text(), sourceFile.Kind, sourceFile.Pos(), sourceFile.End())
|
|
fileNameIndex := strs.add(sourceFile.FileName(), 0, 0, 0)
|
|
idIndex := strs.add(id, 0, 0, 0)
|
|
*extendedData = appendUint32s(*extendedData, textIndex, fileNameIndex, idIndex)
|
|
return t | uint32(extendedDataOffset)
|
|
}
|
|
|
|
func getNodeData(node *ast.Node, strs *stringTable, extendedData *[]byte) uint32 {
|
|
t := getNodeDataType(node)
|
|
switch t {
|
|
case NodeDataTypeChildren:
|
|
return t | getNodeDefinedData(node) | uint32(getChildrenPropertyMask(node))
|
|
case NodeDataTypeString:
|
|
return t | getNodeDefinedData(node) | recordNodeStrings(node, strs)
|
|
case NodeDataTypeExtendedData:
|
|
return t | getNodeDefinedData(node) | recordExtendedData(node, strs, extendedData)
|
|
default:
|
|
panic("unreachable")
|
|
}
|
|
}
|
|
|
|
func getNodeDataType(node *ast.Node) uint32 {
|
|
switch node.Kind {
|
|
case ast.KindJsxText,
|
|
ast.KindIdentifier,
|
|
ast.KindPrivateIdentifier,
|
|
ast.KindStringLiteral,
|
|
ast.KindNumericLiteral,
|
|
ast.KindBigIntLiteral,
|
|
ast.KindRegularExpressionLiteral,
|
|
ast.KindNoSubstitutionTemplateLiteral,
|
|
ast.KindJSDocText:
|
|
return NodeDataTypeString
|
|
case ast.KindTemplateHead,
|
|
ast.KindTemplateMiddle,
|
|
ast.KindTemplateTail,
|
|
ast.KindSourceFile:
|
|
return NodeDataTypeExtendedData
|
|
default:
|
|
return NodeDataTypeChildren
|
|
}
|
|
}
|
|
|
|
// getChildrenPropertyMask returns a mask of which children properties are present in the node.
|
|
// It is defined for node kinds that have more than one property that is a pointer to a child node.
|
|
// Example: QualifiedName has two children properties: Left and Right, which are visited in that order.
|
|
// result&1 is non-zero if Left is present, and result&2 is non-zero if Right is present. If the client
|
|
// knows that QualifiedName has properties ["Left", "Right"] and sees an encoded node with only one
|
|
// child, it can use the mask to determine which property is present.
|
|
func getChildrenPropertyMask(node *ast.Node) uint8 {
|
|
switch node.Kind {
|
|
case ast.KindQualifiedName:
|
|
n := node.AsQualifiedName()
|
|
return (boolToByte(n.Left != nil) << 0) | (boolToByte(n.Right != nil) << 1)
|
|
case ast.KindTypeParameter:
|
|
n := node.AsTypeParameter()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.Constraint != nil) << 2) | (boolToByte(n.DefaultType != nil) << 3)
|
|
case ast.KindIfStatement:
|
|
n := node.AsIfStatement()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.ThenStatement != nil) << 1) | (boolToByte(n.ElseStatement != nil) << 2)
|
|
case ast.KindDoStatement:
|
|
n := node.AsDoStatement()
|
|
return (boolToByte(n.Statement != nil) << 0) | (boolToByte(n.Expression != nil) << 1)
|
|
case ast.KindWhileStatement:
|
|
n := node.AsWhileStatement()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.Statement != nil) << 1)
|
|
case ast.KindForStatement:
|
|
n := node.AsForStatement()
|
|
return (boolToByte(n.Initializer != nil) << 0) | (boolToByte(n.Condition != nil) << 1) | (boolToByte(n.Incrementor != nil) << 2) | (boolToByte(n.Statement != nil) << 3)
|
|
case ast.KindForInStatement, ast.KindForOfStatement:
|
|
n := node.AsForInOrOfStatement()
|
|
return (boolToByte(n.AwaitModifier != nil) << 0) | (boolToByte(n.Initializer != nil) << 1) | (boolToByte(n.Expression != nil) << 2) | (boolToByte(n.Statement != nil) << 3)
|
|
case ast.KindWithStatement:
|
|
n := node.AsWithStatement()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.Statement != nil) << 1)
|
|
case ast.KindSwitchStatement:
|
|
n := node.AsSwitchStatement()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.CaseBlock != nil) << 1)
|
|
case ast.KindCaseClause, ast.KindDefaultClause:
|
|
n := node.AsCaseOrDefaultClause()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.Statements != nil) << 1)
|
|
case ast.KindTryStatement:
|
|
n := node.AsTryStatement()
|
|
return (boolToByte(n.TryBlock != nil) << 0) | (boolToByte(n.CatchClause != nil) << 1) | (boolToByte(n.FinallyBlock != nil) << 2)
|
|
case ast.KindCatchClause:
|
|
n := node.AsCatchClause()
|
|
return (boolToByte(n.VariableDeclaration != nil) << 0) | (boolToByte(n.Block != nil) << 1)
|
|
case ast.KindLabeledStatement:
|
|
n := node.AsLabeledStatement()
|
|
return (boolToByte(n.Label != nil) << 0) | (boolToByte(n.Statement != nil) << 1)
|
|
case ast.KindVariableStatement:
|
|
n := node.AsVariableStatement()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.DeclarationList != nil) << 1)
|
|
case ast.KindVariableDeclaration:
|
|
n := node.AsVariableDeclaration()
|
|
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.ExclamationToken != nil) << 1) | (boolToByte(n.Type != nil) << 2) | (boolToByte(n.Initializer != nil) << 3)
|
|
case ast.KindParameter:
|
|
n := node.AsParameterDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.DotDotDotToken != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.QuestionToken != nil) << 3) | (boolToByte(n.Type != nil) << 4) | (boolToByte(n.Initializer != nil) << 5)
|
|
case ast.KindBindingElement:
|
|
n := node.AsBindingElement()
|
|
return (boolToByte(n.DotDotDotToken != nil) << 0) | (boolToByte(n.PropertyName != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.Initializer != nil) << 3)
|
|
case ast.KindFunctionDeclaration:
|
|
n := node.AsFunctionDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.AsteriskToken != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.TypeParameters != nil) << 3) | (boolToByte(n.Parameters != nil) << 4) | (boolToByte(n.Type != nil) << 5) | (boolToByte(n.Body != nil) << 6)
|
|
case ast.KindInterfaceDeclaration:
|
|
n := node.AsInterfaceDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.HeritageClauses != nil) << 3) | (boolToByte(n.Members != nil) << 4)
|
|
case ast.KindTypeAliasDeclaration:
|
|
n := node.AsTypeAliasDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.Type != nil) << 3)
|
|
case ast.KindEnumMember:
|
|
n := node.AsEnumMember()
|
|
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.Initializer != nil) << 1)
|
|
case ast.KindEnumDeclaration:
|
|
n := node.AsEnumDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.Members != nil) << 2)
|
|
case ast.KindModuleDeclaration:
|
|
n := node.AsModuleDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.Body != nil) << 2)
|
|
case ast.KindImportEqualsDeclaration:
|
|
n := node.AsImportEqualsDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.ModuleReference != nil) << 2)
|
|
case ast.KindImportDeclaration, ast.KindJSImportDeclaration:
|
|
n := node.AsImportDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.ImportClause != nil) << 1) | (boolToByte(n.ModuleSpecifier != nil) << 2) | (boolToByte(n.Attributes != nil) << 3)
|
|
case ast.KindImportSpecifier:
|
|
n := node.AsImportSpecifier()
|
|
return (boolToByte(n.PropertyName != nil) << 0) | (boolToByte(n.Name() != nil) << 1)
|
|
case ast.KindImportClause:
|
|
n := node.AsImportClause()
|
|
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.NamedBindings != nil) << 1)
|
|
case ast.KindExportAssignment, ast.KindJSExportAssignment:
|
|
n := node.AsExportAssignment()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Expression != nil) << 1)
|
|
case ast.KindNamespaceExportDeclaration:
|
|
n := node.AsNamespaceExportDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1)
|
|
case ast.KindExportDeclaration:
|
|
n := node.AsExportDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.ExportClause != nil) << 1) | (boolToByte(n.ModuleSpecifier != nil) << 2) | (boolToByte(n.Attributes != nil) << 3)
|
|
case ast.KindExportSpecifier:
|
|
n := node.AsExportSpecifier()
|
|
return (boolToByte(n.PropertyName != nil) << 0) | (boolToByte(n.Name() != nil) << 1)
|
|
case ast.KindCallSignature:
|
|
n := node.AsCallSignatureDeclaration()
|
|
return (boolToByte(n.TypeParameters != nil) << 0) | (boolToByte(n.Parameters != nil) << 1) | (boolToByte(n.Type != nil) << 2)
|
|
case ast.KindConstructSignature:
|
|
n := node.AsConstructSignatureDeclaration()
|
|
return (boolToByte(n.TypeParameters != nil) << 0) | (boolToByte(n.Parameters != nil) << 1) | (boolToByte(n.Type != nil) << 2)
|
|
case ast.KindConstructor:
|
|
n := node.AsConstructorDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.TypeParameters != nil) << 1) | (boolToByte(n.Parameters != nil) << 2) | (boolToByte(n.Type != nil) << 3) | (boolToByte(n.Body != nil) << 4)
|
|
case ast.KindGetAccessor:
|
|
n := node.AsGetAccessorDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.Parameters != nil) << 3) | (boolToByte(n.Type != nil) << 4) | (boolToByte(n.Body != nil) << 5)
|
|
case ast.KindSetAccessor:
|
|
n := node.AsSetAccessorDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.Parameters != nil) << 3) | (boolToByte(n.Type != nil) << 4) | (boolToByte(n.Body != nil) << 5)
|
|
case ast.KindIndexSignature:
|
|
n := node.AsIndexSignatureDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Parameters != nil) << 1) | (boolToByte(n.Type != nil) << 2)
|
|
case ast.KindMethodSignature:
|
|
n := node.AsMethodSignatureDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.PostfixToken != nil) << 2) | (boolToByte(n.TypeParameters != nil) << 3) | (boolToByte(n.Parameters != nil) << 4) | (boolToByte(n.Type != nil) << 5)
|
|
case ast.KindMethodDeclaration:
|
|
n := node.AsMethodDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.AsteriskToken != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.PostfixToken != nil) << 3) | (boolToByte(n.TypeParameters != nil) << 4) | (boolToByte(n.Parameters != nil) << 5) | (boolToByte(n.Type != nil) << 6) | (boolToByte(n.Body != nil) << 7)
|
|
case ast.KindPropertySignature:
|
|
n := node.AsPropertySignatureDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.PostfixToken != nil) << 2) | (boolToByte(n.Type != nil) << 3) | (boolToByte(n.Initializer != nil) << 4)
|
|
case ast.KindPropertyDeclaration:
|
|
n := node.AsPropertyDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.PostfixToken != nil) << 2) | (boolToByte(n.Type != nil) << 3) | (boolToByte(n.Initializer != nil) << 4)
|
|
case ast.KindBinaryExpression:
|
|
n := node.AsBinaryExpression()
|
|
return (boolToByte(n.Left != nil) << 0) | (boolToByte(n.OperatorToken != nil) << 1) | (boolToByte(n.Right != nil) << 2)
|
|
case ast.KindYieldExpression:
|
|
n := node.AsYieldExpression()
|
|
return (boolToByte(n.AsteriskToken != nil) << 0) | (boolToByte(n.Expression != nil) << 1)
|
|
case ast.KindArrowFunction:
|
|
n := node.AsArrowFunction()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.TypeParameters != nil) << 1) | (boolToByte(n.Parameters != nil) << 2) | (boolToByte(n.Type != nil) << 3) | (boolToByte(n.EqualsGreaterThanToken != nil) << 4) | (boolToByte(n.Body != nil) << 5)
|
|
case ast.KindFunctionExpression:
|
|
n := node.AsFunctionExpression()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.AsteriskToken != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.TypeParameters != nil) << 3) | (boolToByte(n.Parameters != nil) << 4) | (boolToByte(n.Type != nil) << 5) | (boolToByte(n.Body != nil) << 6)
|
|
case ast.KindAsExpression:
|
|
n := node.AsAsExpression()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.Type != nil) << 1)
|
|
case ast.KindSatisfiesExpression:
|
|
n := node.AsSatisfiesExpression()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.Type != nil) << 1)
|
|
case ast.KindConditionalExpression:
|
|
n := node.AsConditionalExpression()
|
|
return (boolToByte(n.Condition != nil) << 0) | (boolToByte(n.QuestionToken != nil) << 1) | (boolToByte(n.WhenTrue != nil) << 2) | (boolToByte(n.ColonToken != nil) << 3) | (boolToByte(n.WhenFalse != nil) << 4)
|
|
case ast.KindPropertyAccessExpression:
|
|
n := node.AsPropertyAccessExpression()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.QuestionDotToken != nil) << 1) | (boolToByte(n.Name() != nil) << 2)
|
|
case ast.KindElementAccessExpression:
|
|
n := node.AsElementAccessExpression()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.QuestionDotToken != nil) << 1) | (boolToByte(n.ArgumentExpression != nil) << 2)
|
|
case ast.KindCallExpression:
|
|
n := node.AsCallExpression()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.QuestionDotToken != nil) << 1) | (boolToByte(n.TypeArguments != nil) << 2) | (boolToByte(n.Arguments != nil) << 3)
|
|
case ast.KindNewExpression:
|
|
n := node.AsNewExpression()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.TypeArguments != nil) << 1) | (boolToByte(n.Arguments != nil) << 2)
|
|
case ast.KindTemplateExpression:
|
|
n := node.AsTemplateExpression()
|
|
return (boolToByte(n.Head != nil) << 0) | (boolToByte(n.TemplateSpans != nil) << 1)
|
|
case ast.KindTemplateSpan:
|
|
n := node.AsTemplateSpan()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.Literal != nil) << 1)
|
|
case ast.KindTaggedTemplateExpression:
|
|
n := node.AsTaggedTemplateExpression()
|
|
return (boolToByte(n.Tag != nil) << 0) | (boolToByte(n.QuestionDotToken != nil) << 1) | (boolToByte(n.TypeArguments != nil) << 2) | (boolToByte(n.Template != nil) << 3)
|
|
case ast.KindPropertyAssignment:
|
|
n := node.AsPropertyAssignment()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.PostfixToken != nil) << 2) | (boolToByte(n.Initializer != nil) << 3)
|
|
case ast.KindShorthandPropertyAssignment:
|
|
n := node.AsShorthandPropertyAssignment()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.PostfixToken != nil) << 2) | (boolToByte(n.EqualsToken != nil) << 3) | (boolToByte(n.ObjectAssignmentInitializer != nil) << 4)
|
|
case ast.KindTypeAssertionExpression:
|
|
n := node.AsTypeAssertion()
|
|
return (boolToByte(n.Type != nil) << 0) | (boolToByte(n.Expression != nil) << 1)
|
|
case ast.KindConditionalType:
|
|
n := node.AsConditionalTypeNode()
|
|
return (boolToByte(n.CheckType != nil) << 0) | (boolToByte(n.ExtendsType != nil) << 1) | (boolToByte(n.TrueType != nil) << 2) | (boolToByte(n.FalseType != nil) << 3)
|
|
case ast.KindIndexedAccessType:
|
|
n := node.AsIndexedAccessTypeNode()
|
|
return (boolToByte(n.ObjectType != nil) << 0) | (boolToByte(n.IndexType != nil) << 1)
|
|
case ast.KindTypeReference:
|
|
n := node.AsTypeReferenceNode()
|
|
return (boolToByte(n.TypeName != nil) << 0) | (boolToByte(n.TypeArguments != nil) << 1)
|
|
case ast.KindExpressionWithTypeArguments:
|
|
n := node.AsExpressionWithTypeArguments()
|
|
return (boolToByte(n.Expression != nil) << 0) | (boolToByte(n.TypeArguments != nil) << 1)
|
|
case ast.KindTypePredicate:
|
|
n := node.AsTypePredicateNode()
|
|
return (boolToByte(n.AssertsModifier != nil) << 0) | (boolToByte(n.ParameterName != nil) << 1) | (boolToByte(n.Type != nil) << 2)
|
|
case ast.KindImportType:
|
|
n := node.AsImportTypeNode()
|
|
return (boolToByte(n.Argument != nil) << 0) | (boolToByte(n.Attributes != nil) << 1) | (boolToByte(n.Qualifier != nil) << 2) | (boolToByte(n.TypeArguments != nil) << 3)
|
|
case ast.KindImportAttribute:
|
|
n := node.AsImportAttribute()
|
|
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.Value != nil) << 1)
|
|
case ast.KindTypeQuery:
|
|
n := node.AsTypeQueryNode()
|
|
return (boolToByte(n.ExprName != nil) << 0) | (boolToByte(n.TypeArguments != nil) << 1)
|
|
case ast.KindMappedType:
|
|
n := node.AsMappedTypeNode()
|
|
return (boolToByte(n.ReadonlyToken != nil) << 0) | (boolToByte(n.TypeParameter != nil) << 1) | (boolToByte(n.NameType != nil) << 2) | (boolToByte(n.QuestionToken != nil) << 3) | (boolToByte(n.Type != nil) << 4) | (boolToByte(n.Members != nil) << 5)
|
|
case ast.KindNamedTupleMember:
|
|
n := node.AsNamedTupleMember()
|
|
return (boolToByte(n.DotDotDotToken != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.QuestionToken != nil) << 2) | (boolToByte(n.Type != nil) << 3)
|
|
case ast.KindFunctionType:
|
|
n := node.AsFunctionTypeNode()
|
|
return (boolToByte(n.TypeParameters != nil) << 0) | (boolToByte(n.Parameters != nil) << 1) | (boolToByte(n.Type != nil) << 2)
|
|
case ast.KindConstructorType:
|
|
n := node.AsConstructorTypeNode()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.TypeParameters != nil) << 1) | (boolToByte(n.Parameters != nil) << 2) | (boolToByte(n.Type != nil) << 3)
|
|
case ast.KindTemplateLiteralType:
|
|
n := node.AsTemplateLiteralTypeNode()
|
|
return (boolToByte(n.Head != nil) << 0) | (boolToByte(n.TemplateSpans != nil) << 1)
|
|
case ast.KindTemplateLiteralTypeSpan:
|
|
n := node.AsTemplateLiteralTypeSpan()
|
|
return (boolToByte(n.Type != nil) << 0) | (boolToByte(n.Literal != nil) << 1)
|
|
case ast.KindJsxElement:
|
|
n := node.AsJsxElement()
|
|
return (boolToByte(n.OpeningElement != nil) << 0) | (boolToByte(n.Children != nil) << 1) | (boolToByte(n.ClosingElement != nil) << 2)
|
|
case ast.KindJsxNamespacedName:
|
|
n := node.AsJsxNamespacedName()
|
|
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.Namespace != nil) << 1)
|
|
case ast.KindJsxOpeningElement:
|
|
n := node.AsJsxOpeningElement()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeArguments != nil) << 1) | (boolToByte(n.Attributes != nil) << 2)
|
|
case ast.KindJsxSelfClosingElement:
|
|
n := node.AsJsxSelfClosingElement()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeArguments != nil) << 1) | (boolToByte(n.Attributes != nil) << 2)
|
|
case ast.KindJsxFragment:
|
|
n := node.AsJsxFragment()
|
|
return (boolToByte(n.OpeningFragment != nil) << 0) | (boolToByte(n.Children != nil) << 1) | (boolToByte(n.ClosingFragment != nil) << 2)
|
|
case ast.KindJsxAttribute:
|
|
n := node.AsJsxAttribute()
|
|
return (boolToByte(n.Name() != nil) << 0) | (boolToByte(n.Initializer != nil) << 1)
|
|
case ast.KindJsxExpression:
|
|
n := node.AsJsxExpression()
|
|
return (boolToByte(n.DotDotDotToken != nil) << 0) | (boolToByte(n.Expression != nil) << 1)
|
|
case ast.KindJSDoc:
|
|
n := node.AsJSDoc()
|
|
return (boolToByte(n.Comment != nil) << 0) | (boolToByte(n.Tags != nil) << 1)
|
|
case ast.KindJSDocTypeTag:
|
|
n := node.AsJSDocTypeTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocTag:
|
|
n := node.AsJSDocUnknownTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocTemplateTag:
|
|
n := node.AsJSDocTemplateTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Constraint != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
|
|
case ast.KindJSDocReturnTag:
|
|
n := node.AsJSDocReturnTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocPublicTag:
|
|
n := node.AsJSDocPublicTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocPrivateTag:
|
|
n := node.AsJSDocPrivateTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocProtectedTag:
|
|
n := node.AsJSDocProtectedTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocReadonlyTag:
|
|
n := node.AsJSDocReadonlyTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocOverrideTag:
|
|
n := node.AsJSDocOverrideTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocDeprecatedTag:
|
|
n := node.AsJSDocDeprecatedTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Comment != nil) << 1)
|
|
case ast.KindJSDocSeeTag:
|
|
n := node.AsJSDocSeeTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.NameExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocImplementsTag:
|
|
n := node.AsJSDocImplementsTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.ClassName != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocAugmentsTag:
|
|
n := node.AsJSDocAugmentsTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.ClassName != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocSatisfiesTag:
|
|
n := node.AsJSDocSatisfiesTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocThisTag:
|
|
n := node.AsJSDocThisTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocImportTag:
|
|
n := node.AsJSDocImportTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.ImportClause != nil) << 1) | (boolToByte(n.ModuleSpecifier != nil) << 2) | (boolToByte(n.Attributes != nil) << 3) | (boolToByte(n.Comment != nil) << 4)
|
|
case ast.KindJSDocCallbackTag:
|
|
n := node.AsJSDocCallbackTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.FullName != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
|
|
case ast.KindJSDocOverloadTag:
|
|
n := node.AsJSDocOverloadTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Comment != nil) << 2)
|
|
case ast.KindJSDocTypedefTag:
|
|
n := node.AsJSDocTypedefTag()
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
|
|
case ast.KindJSDocSignature:
|
|
n := node.AsJSDocSignature()
|
|
return (boolToByte(n.TypeParameters != nil) << 0) | (boolToByte(n.Parameters != nil) << 1) | (boolToByte(n.Type != nil) << 2)
|
|
case ast.KindClassStaticBlockDeclaration:
|
|
n := node.AsClassStaticBlockDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Body != nil) << 1)
|
|
case ast.KindClassDeclaration:
|
|
n := node.AsClassDeclaration()
|
|
return (boolToByte(n.Modifiers() != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.TypeParameters != nil) << 2) | (boolToByte(n.HeritageClauses != nil) << 3) | (boolToByte(n.Members != nil) << 4)
|
|
case ast.KindJSDocParameterTag, ast.KindJSDocPropertyTag:
|
|
n := node.AsJSDocParameterOrPropertyTag()
|
|
if n.IsNameFirst {
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.Name() != nil) << 1) | (boolToByte(n.TypeExpression != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
|
|
}
|
|
return (boolToByte(n.TagName != nil) << 0) | (boolToByte(n.TypeExpression != nil) << 1) | (boolToByte(n.Name() != nil) << 2) | (boolToByte(n.Comment != nil) << 3)
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func getNodeDefinedData(node *ast.Node) uint32 {
|
|
switch node.Kind {
|
|
case ast.KindJSDocTypeLiteral:
|
|
n := node.AsJSDocTypeLiteral()
|
|
return uint32(boolToByte(n.IsArrayType)) << 24
|
|
case ast.KindImportSpecifier:
|
|
n := node.AsImportSpecifier()
|
|
return uint32(boolToByte(n.IsTypeOnly)) << 24
|
|
case ast.KindImportClause:
|
|
n := node.AsImportClause()
|
|
return uint32(boolToByte(n.PhaseModifier == ast.KindTypeKeyword))<<24 | uint32(boolToByte(n.PhaseModifier == ast.KindDeferKeyword))<<25
|
|
case ast.KindExportSpecifier:
|
|
n := node.AsExportSpecifier()
|
|
return uint32(boolToByte(n.IsTypeOnly)) << 24
|
|
case ast.KindImportType:
|
|
n := node.AsImportTypeNode()
|
|
return uint32(boolToByte(n.IsTypeOf)) << 24
|
|
case ast.KindImportEqualsDeclaration:
|
|
n := node.AsImportEqualsDeclaration()
|
|
return uint32(boolToByte(n.IsTypeOnly)) << 24
|
|
case ast.KindExportAssignment:
|
|
n := node.AsExportAssignment()
|
|
return uint32(boolToByte(n.IsExportEquals)) << 24
|
|
case ast.KindExportDeclaration:
|
|
n := node.AsExportDeclaration()
|
|
return uint32(boolToByte(n.IsTypeOnly)) << 24
|
|
case ast.KindBlock:
|
|
n := node.AsBlock()
|
|
return uint32(boolToByte(n.Multiline)) << 24
|
|
case ast.KindArrayLiteralExpression:
|
|
n := node.AsArrayLiteralExpression()
|
|
return uint32(boolToByte(n.MultiLine)) << 24
|
|
case ast.KindObjectLiteralExpression:
|
|
n := node.AsObjectLiteralExpression()
|
|
return uint32(boolToByte(n.MultiLine)) << 24
|
|
case ast.KindJSDocParameterTag, ast.KindJSDocPropertyTag:
|
|
n := node.AsJSDocParameterOrPropertyTag()
|
|
return uint32(boolToByte(n.IsBracketed))<<24 | uint32(boolToByte(n.IsNameFirst))<<25
|
|
case ast.KindJsxText:
|
|
n := node.AsJsxText()
|
|
return uint32(boolToByte(n.ContainsOnlyTriviaWhiteSpaces)) << 24
|
|
case ast.KindVariableDeclarationList:
|
|
n := node.AsVariableDeclarationList()
|
|
return uint32(n.Flags & (ast.NodeFlagsLet | ast.NodeFlagsConst) << 24)
|
|
case ast.KindImportAttributes:
|
|
n := node.AsImportAttributes()
|
|
return uint32(boolToByte(n.MultiLine))<<24 | uint32(boolToByte(n.Token == ast.KindAssertKeyword))<<25
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func recordNodeStrings(node *ast.Node, strs *stringTable) uint32 {
|
|
switch node.Kind {
|
|
case ast.KindJsxText:
|
|
return strs.add(node.AsJsxText().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindIdentifier:
|
|
return strs.add(node.AsIdentifier().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindPrivateIdentifier:
|
|
return strs.add(node.AsPrivateIdentifier().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindStringLiteral:
|
|
return strs.add(node.AsStringLiteral().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindNumericLiteral:
|
|
return strs.add(node.AsNumericLiteral().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindBigIntLiteral:
|
|
return strs.add(node.AsBigIntLiteral().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindRegularExpressionLiteral:
|
|
return strs.add(node.AsRegularExpressionLiteral().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindNoSubstitutionTemplateLiteral:
|
|
return strs.add(node.AsNoSubstitutionTemplateLiteral().Text, node.Kind, node.Pos(), node.End())
|
|
case ast.KindJSDocText:
|
|
return strs.add(node.AsJSDocText().Text(), node.Kind, node.Pos(), node.End())
|
|
default:
|
|
panic(fmt.Sprintf("Unexpected node kind %v", node.Kind))
|
|
}
|
|
}
|
|
|
|
func recordExtendedData(node *ast.Node, strs *stringTable, extendedData *[]byte) uint32 {
|
|
offset := uint32(len(*extendedData))
|
|
var text, rawText string
|
|
var templateFlags uint32
|
|
switch node.Kind {
|
|
case ast.KindTemplateTail:
|
|
n := node.AsTemplateTail()
|
|
text = n.Text
|
|
rawText = n.RawText
|
|
templateFlags = uint32(n.TemplateFlags)
|
|
case ast.KindTemplateMiddle:
|
|
n := node.AsTemplateMiddle()
|
|
text = n.Text
|
|
rawText = n.RawText
|
|
templateFlags = uint32(n.TemplateFlags)
|
|
case ast.KindTemplateHead:
|
|
n := node.AsTemplateHead()
|
|
text = n.Text
|
|
rawText = n.RawText
|
|
templateFlags = uint32(n.TemplateFlags)
|
|
}
|
|
textIndex := strs.add(text, node.Kind, node.Pos(), node.End())
|
|
rawTextIndex := strs.add(rawText, node.Kind, node.Pos(), node.End())
|
|
*extendedData = appendUint32s(*extendedData, textIndex, rawTextIndex, templateFlags)
|
|
return offset
|
|
}
|
|
|
|
func boolToByte(b bool) byte {
|
|
if b {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|