vendor tsgo
This commit is contained in:
161
tools/tsgo/internal/api/encoder/encoder_test.go
Normal file
161
tools/tsgo/internal/api/encoder/encoder_test.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package encoder_test
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/api/encoder"
|
||||
"github.com/microsoft/typescript-go/internal/ast"
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/parser"
|
||||
"github.com/microsoft/typescript-go/internal/repo"
|
||||
"github.com/microsoft/typescript-go/internal/testutil/baseline"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestEncodeSourceFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
|
||||
FileName: "/test.ts",
|
||||
Path: "/test.ts",
|
||||
}, "import { bar } from \"bar\";\nexport function foo<T, U>(a: string, b: string): any {}\nfoo();", core.ScriptKindTS)
|
||||
t.Run("baseline", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf, _, err := encoder.EncodeSourceFile(sourceFile)
|
||||
assert.NilError(t, err)
|
||||
|
||||
str := formatEncodedSourceFile(buf)
|
||||
baseline.Run(t, "encodeSourceFile.txt", str, baseline.Options{
|
||||
Subfolder: "api",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestEncodeSourceFileWithUnicodeEscapes(t *testing.T) {
|
||||
t.Parallel()
|
||||
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
|
||||
FileName: "/test.ts",
|
||||
Path: "/test.ts",
|
||||
}, `let a = "😃"; let b = "\ud83d\ude03"; let c = "\udc00\ud83d\ude03"; let d = "\ud83d\ud83d\ude03"`, core.ScriptKindTS)
|
||||
t.Run("baseline", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
buf, _, err := encoder.EncodeSourceFile(sourceFile)
|
||||
assert.NilError(t, err)
|
||||
|
||||
str := formatEncodedSourceFile(buf)
|
||||
baseline.Run(t, "encodeSourceFileWithUnicodeEscapes.txt", str, baseline.Options{
|
||||
Subfolder: "api",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuildNodeIndexTableMatchesEncode(t *testing.T) {
|
||||
t.Parallel()
|
||||
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
|
||||
FileName: "/test.ts",
|
||||
Path: "/test.ts",
|
||||
}, "import { bar } from \"bar\";\nexport function foo<T, U>(a: string, b: string): any {}\nfoo();", core.ScriptKindTS)
|
||||
|
||||
_, encodeTable, err := encoder.EncodeSourceFile(sourceFile)
|
||||
assert.NilError(t, err)
|
||||
|
||||
buildTable := encoder.BuildNodeIndexTable(sourceFile)
|
||||
|
||||
// Both tables should produce identical Nodes slices
|
||||
assert.Equal(t, len(buildTable.Nodes), len(encodeTable.Nodes), "Nodes slice length mismatch")
|
||||
|
||||
// Every index should map to the same node
|
||||
for i := range encodeTable.Nodes {
|
||||
assert.Equal(t, buildTable.Nodes[i], encodeTable.Nodes[i], "node mismatch at index %d", i)
|
||||
}
|
||||
|
||||
// GetIndex on both tables should agree for every non-nil node
|
||||
for i, node := range encodeTable.Nodes {
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
encIdx := encodeTable.GetIndex(node)
|
||||
buildIdx := buildTable.GetIndex(node)
|
||||
assert.Equal(t, encIdx, uint32(i), "encodeTable.GetIndex mismatch at index %d, node kind=%s", i, node.Kind.String())
|
||||
assert.Equal(t, buildIdx, encIdx, "buildTable.GetIndex mismatch for node kind=%s", node.Kind.String())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncodeSourceFile(b *testing.B) {
|
||||
repo.SkipIfNoTypeScriptSubmodule(b)
|
||||
filePath := filepath.Join(repo.TypeScriptSubmodulePath(), "src/compiler/checker.ts")
|
||||
fileContent, err := os.ReadFile(filePath)
|
||||
assert.NilError(b, err)
|
||||
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
|
||||
FileName: "/checker.ts",
|
||||
Path: "/checker.ts",
|
||||
}, string(fileContent), core.ScriptKindTS)
|
||||
|
||||
for b.Loop() {
|
||||
_, _, err := encoder.EncodeSourceFile(sourceFile)
|
||||
assert.NilError(b, err)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBuildNodeIndexTable(b *testing.B) {
|
||||
repo.SkipIfNoTypeScriptSubmodule(b)
|
||||
filePath := filepath.Join(repo.TypeScriptSubmodulePath(), "src/compiler/checker.ts")
|
||||
fileContent, err := os.ReadFile(filePath)
|
||||
assert.NilError(b, err)
|
||||
sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{
|
||||
FileName: "/checker.ts",
|
||||
Path: "/checker.ts",
|
||||
}, string(fileContent), core.ScriptKindTS)
|
||||
|
||||
for b.Loop() {
|
||||
encoder.BuildNodeIndexTable(sourceFile)
|
||||
}
|
||||
}
|
||||
|
||||
func readUint32(buf []byte, offset int) uint32 {
|
||||
return binary.LittleEndian.Uint32(buf[offset : offset+4])
|
||||
}
|
||||
|
||||
func formatEncodedSourceFile(encoded []byte) string {
|
||||
var result strings.Builder
|
||||
var getIndent func(parentIndex uint32) string
|
||||
offsetNodes := readUint32(encoded, encoder.HeaderOffsetNodes)
|
||||
offsetStringOffsets := readUint32(encoded, encoder.HeaderOffsetStringOffsets)
|
||||
offsetStrings := readUint32(encoded, encoder.HeaderOffsetStringData)
|
||||
getIndent = func(parentIndex uint32) string {
|
||||
if parentIndex == 0 {
|
||||
return ""
|
||||
}
|
||||
return " " + getIndent(readUint32(encoded, int(offsetNodes)+int(parentIndex)*encoder.NodeSize+encoder.NodeOffsetParent))
|
||||
}
|
||||
j := 1
|
||||
for i := int(offsetNodes) + encoder.NodeSize; i < len(encoded); i += encoder.NodeSize {
|
||||
kind := readUint32(encoded, i+encoder.NodeOffsetKind)
|
||||
pos := readUint32(encoded, i+encoder.NodeOffsetPos)
|
||||
end := readUint32(encoded, i+encoder.NodeOffsetEnd)
|
||||
parentIndex := readUint32(encoded, i+encoder.NodeOffsetParent)
|
||||
result.WriteString(getIndent(parentIndex))
|
||||
if kind == encoder.SyntaxKindNodeList {
|
||||
result.WriteString("NodeList")
|
||||
} else {
|
||||
result.WriteString(ast.Kind(kind).String())
|
||||
}
|
||||
data := readUint32(encoded, i+encoder.NodeOffsetData)
|
||||
dataType := data & encoder.NodeDataTypeMask
|
||||
if ast.Kind(kind) == ast.KindIdentifier || (dataType == encoder.NodeDataTypeString) {
|
||||
stringIndex := data & encoder.NodeDataStringIndexMask
|
||||
strStart := readUint32(encoded, int(offsetStringOffsets+stringIndex*4))
|
||||
strEnd := readUint32(encoded, int(offsetStringOffsets+stringIndex*4)+4)
|
||||
str := string(encoded[offsetStrings+strStart : offsetStrings+strEnd])
|
||||
result.WriteString(fmt.Sprintf(" \"%s\"", str))
|
||||
}
|
||||
fmt.Fprintf(&result, " [%d, %d), i=%d, next=%d", pos, end, j, encoded[i+encoder.NodeOffsetNext])
|
||||
result.WriteString("\n")
|
||||
j++
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
Reference in New Issue
Block a user