From e9f9495f57b841046b88daae57c22a72fac81a0e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 4 Mar 2025 09:42:03 -0800 Subject: [PATCH 1/3] Remove jsonv2 --- go.mod | 1 - go.sum | 2 - internal/collections/ordered_map.go | 39 +----------- internal/collections/ordered_map_test.go | 5 -- internal/packagejson/exportsorimports.go | 11 +--- internal/packagejson/exportsorimports_test.go | 5 -- internal/packagejson/jsonvalue.go | 63 +------------------ internal/packagejson/jsonvalue_test.go | 5 -- internal/packagejson/packagejson.go | 6 +- internal/packagejson/packagejson_test.go | 12 ---- 10 files changed, 5 insertions(+), 144 deletions(-) diff --git a/go.mod b/go.mod index 067f388aa4..9c786a6384 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.24.0 require ( github.com/dlclark/regexp2 v1.11.5 - github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 github.com/google/go-cmp v0.7.0 github.com/pkg/diff v0.0.0-20241224192749-4e6772a4315c golang.org/x/sys v0.31.0 diff --git a/go.sum b/go.sum index 1a460f2534..7ebec643b9 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= -github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/matryer/moq v0.5.3 h1:4femQCFmBUwFPYs8VfM5ID7AI67/DTEDRBbTtSWy7GU= diff --git a/internal/collections/ordered_map.go b/internal/collections/ordered_map.go index f95273a5bf..c9653bb9de 100644 --- a/internal/collections/ordered_map.go +++ b/internal/collections/ordered_map.go @@ -11,9 +11,6 @@ import ( "reflect" "slices" "strconv" - - json2 "github.com/go-json-experiment/json" - "github.com/go-json-experiment/json/jsontext" ) // OrderedMap is an insertion ordered map. @@ -244,10 +241,7 @@ func resolveKeyName(k reflect.Value) (string, error) { panic("unexpected map key type") } -var ( - _ json.Unmarshaler = (*OrderedMap[string, string])(nil) - _ json2.UnmarshalerFrom = (*OrderedMap[string, string])(nil) -) +var _ json.Unmarshaler = (*OrderedMap[string, string])(nil) func (m *OrderedMap[K, V]) UnmarshalJSON(data []byte) error { if string(data) == "null" { @@ -288,34 +282,3 @@ func (m *OrderedMap[K, V]) UnmarshalJSON(data []byte) error { } return nil } - -func (m *OrderedMap[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { - token, err := dec.ReadToken() - if err != nil { - return err - } - if token.Kind() == 'n' { // jsontext.Null.Kind() - // By convention, to approximate the behavior of Unmarshal itself, - // Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. - // https://pkg.go.dev/encoding/json#Unmarshaler - return nil - } - if token.Kind() != '{' { // jsontext.ObjectStart.Kind() - return errors.New("cannot unmarshal non-object JSON value into Map") - } - for dec.PeekKind() != '}' { // jsontext.ObjectEnd.Kind() - var key K - var value V - if err := json2.UnmarshalDecode(dec, &key); err != nil { - return err - } - if err := json2.UnmarshalDecode(dec, &value); err != nil { - return err - } - m.Set(key, value) - } - if _, err := dec.ReadToken(); err != nil { - return err - } - return nil -} diff --git a/internal/collections/ordered_map_test.go b/internal/collections/ordered_map_test.go index e4ac2f2d5b..27461a374a 100644 --- a/internal/collections/ordered_map_test.go +++ b/internal/collections/ordered_map_test.go @@ -6,7 +6,6 @@ import ( "slices" "testing" - json2 "github.com/go-json-experiment/json" "github.com/microsoft/typescript-go/internal/collections" "gotest.tools/v3/assert" ) @@ -166,10 +165,6 @@ func TestOrderedMapUnmarshalJSON(t *testing.T) { t.Parallel() testOrderedMapUnmarshalJSON(t, json.Unmarshal) }) - t.Run("UnmarshalJSONV2", func(t *testing.T) { - t.Parallel() - testOrderedMapUnmarshalJSON(t, func(in []byte, out any) error { return json2.Unmarshal(in, out) }) - }) } func testOrderedMapUnmarshalJSON(t *testing.T, unmarshal func([]byte, any) error) { diff --git a/internal/packagejson/exportsorimports.go b/internal/packagejson/exportsorimports.go index 01f17234fc..6853e41de8 100644 --- a/internal/packagejson/exportsorimports.go +++ b/internal/packagejson/exportsorimports.go @@ -3,8 +3,6 @@ package packagejson import ( "encoding/json" - json2 "github.com/go-json-experiment/json" - "github.com/go-json-experiment/json/jsontext" "github.com/microsoft/typescript-go/internal/collections" ) @@ -23,19 +21,12 @@ type ExportsOrImports struct { objectKind objectKind } -var ( - _ json.Unmarshaler = (*ExportsOrImports)(nil) - _ json2.UnmarshalerFrom = (*ExportsOrImports)(nil) -) +var _ json.Unmarshaler = (*ExportsOrImports)(nil) func (e *ExportsOrImports) UnmarshalJSON(data []byte) error { return unmarshalJSONValue[ExportsOrImports](&e.JSONValue, data) } -func (e *ExportsOrImports) UnmarshalJSONFrom(dec *jsontext.Decoder) error { - return unmarshalJSONValueV2[ExportsOrImports](&e.JSONValue, dec) -} - func (e ExportsOrImports) AsObject() *collections.OrderedMap[string, ExportsOrImports] { if e.Type != JSONValueTypeObject { panic("expected object") diff --git a/internal/packagejson/exportsorimports_test.go b/internal/packagejson/exportsorimports_test.go index 4c7f608978..ff352ef33c 100644 --- a/internal/packagejson/exportsorimports_test.go +++ b/internal/packagejson/exportsorimports_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "testing" - json2 "github.com/go-json-experiment/json" "github.com/microsoft/typescript-go/internal/packagejson" "gotest.tools/v3/assert" ) @@ -16,10 +15,6 @@ func TestExports(t *testing.T) { t.Parallel() testExports(t, json.Unmarshal) }) - t.Run("UnmarshalJSONV2", func(t *testing.T) { - t.Parallel() - testExports(t, func(in []byte, out any) error { return json2.Unmarshal(in, out) }) - }) } func testExports(t *testing.T, unmarshal func([]byte, any) error) { diff --git a/internal/packagejson/jsonvalue.go b/internal/packagejson/jsonvalue.go index 63f0548f41..320ee16c4f 100644 --- a/internal/packagejson/jsonvalue.go +++ b/internal/packagejson/jsonvalue.go @@ -4,8 +4,6 @@ import ( "encoding/json" "fmt" - json2 "github.com/go-json-experiment/json" - "github.com/go-json-experiment/json/jsontext" "github.com/microsoft/typescript-go/internal/collections" ) @@ -74,19 +72,12 @@ func (v JSONValue) AsArray() []JSONValue { return v.Value.([]JSONValue) } -var ( - _ json.Unmarshaler = (*JSONValue)(nil) - _ json2.UnmarshalerFrom = (*JSONValue)(nil) -) +var _ json.Unmarshaler = (*JSONValue)(nil) func (v *JSONValue) UnmarshalJSON(data []byte) error { return unmarshalJSONValue[JSONValue](v, data) } -func (v *JSONValue) UnmarshalJSONFrom(dec *jsontext.Decoder) error { - return unmarshalJSONValueV2[JSONValue](v, dec) -} - func unmarshalJSONValue[T any](v *JSONValue, data []byte) error { if string(data) == "null" { *v = JSONValue{Type: JSONValueTypeNull} @@ -119,55 +110,3 @@ func unmarshalJSONValue[T any](v *JSONValue, data []byte) error { } return nil } - -func unmarshalJSONValueV2[T any](v *JSONValue, dec *jsontext.Decoder) error { - switch dec.PeekKind() { - case 'n': // jsontext.Null.Kind() - if _, err := dec.ReadToken(); err != nil { - return err - } - v.Value = nil - v.Type = JSONValueTypeNull - return nil - case '"': - v.Type = JSONValueTypeString - if err := json2.UnmarshalDecode(dec, &v.Value); err != nil { - return err - } - case '[': - if _, err := dec.ReadToken(); err != nil { - return err - } - var elements []T - for dec.PeekKind() != jsontext.EndArray.Kind() { - var element T - if err := json2.UnmarshalDecode(dec, &element); err != nil { - return err - } - elements = append(elements, element) - } - if _, err := dec.ReadToken(); err != nil { - return err - } - v.Type = JSONValueTypeArray - v.Value = elements - case '{': - var object collections.OrderedMap[string, T] - if err := json2.UnmarshalDecode(dec, &object); err != nil { - return err - } - v.Type = JSONValueTypeObject - v.Value = &object - case 't', 'f': // jsontext.True.Kind(), jsontext.False.Kind() - v.Type = JSONValueTypeBoolean - if err := json2.UnmarshalDecode(dec, &v.Value); err != nil { - return err - } - default: - v.Type = JSONValueTypeNumber - if err := json2.UnmarshalDecode(dec, &v.Value); err != nil { - return err - } - } - return nil -} diff --git a/internal/packagejson/jsonvalue_test.go b/internal/packagejson/jsonvalue_test.go index 13d750dc1e..08980f14c2 100644 --- a/internal/packagejson/jsonvalue_test.go +++ b/internal/packagejson/jsonvalue_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "testing" - json2 "github.com/go-json-experiment/json" "github.com/microsoft/typescript-go/internal/packagejson" "gotest.tools/v3/assert" ) @@ -16,10 +15,6 @@ func TestJSONValue(t *testing.T) { t.Parallel() testJSONValue(t, json.Unmarshal) }) - t.Run("UnmarshalJSONV2", func(t *testing.T) { - t.Parallel() - testJSONValue(t, func(in []byte, out any) error { return json2.Unmarshal(in, out) }) - }) } func testJSONValue(t *testing.T, unmarshal func([]byte, any) error) { diff --git a/internal/packagejson/packagejson.go b/internal/packagejson/packagejson.go index 41c994ad88..1f789be82e 100644 --- a/internal/packagejson/packagejson.go +++ b/internal/packagejson/packagejson.go @@ -1,8 +1,6 @@ package packagejson -import ( - json2 "github.com/go-json-experiment/json" -) +import "encoding/json" type HeaderFields struct { Name Expected[string] `json:"name"` @@ -34,7 +32,7 @@ type Fields struct { func Parse(data []byte) (Fields, error) { var f Fields - if err := json2.Unmarshal(data, &f); err != nil { + if err := json.Unmarshal(data, &f); err != nil { return f, err } return f, nil diff --git a/internal/packagejson/packagejson_test.go b/internal/packagejson/packagejson_test.go index 389580490d..0ba8259a88 100644 --- a/internal/packagejson/packagejson_test.go +++ b/internal/packagejson/packagejson_test.go @@ -5,7 +5,6 @@ import ( "path/filepath" "testing" - json2 "github.com/go-json-experiment/json" "github.com/microsoft/typescript-go/internal/packagejson" "github.com/microsoft/typescript-go/internal/parser" "github.com/microsoft/typescript-go/internal/repo" @@ -33,17 +32,6 @@ func BenchmarkPackageJSON(b *testing.B) { }) }) - b.Run("UnmarshalJSONV2", func(b *testing.B) { - b.Run(f.Name(), func(b *testing.B) { - for b.Loop() { - var p packagejson.Fields - if err := json2.Unmarshal(content, &p); err != nil { - b.Fatal(err) - } - } - }) - }) - b.Run("ParseJSONText", func(b *testing.B) { b.Run(f.Name(), func(b *testing.B) { fileName := "/" + f.Name() From af89e943b418a5e658be24bb5b3e80e2fa005b50 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:11:33 -0700 Subject: [PATCH 2/3] Hack it to work in tinygo --- internal/jsnum/string.go | 7 ++++--- internal/module/resolver.go | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/jsnum/string.go b/internal/jsnum/string.go index 3789052e5a..a0e694cf3c 100644 --- a/internal/jsnum/string.go +++ b/internal/jsnum/string.go @@ -1,7 +1,6 @@ package jsnum import ( - "encoding/json" "errors" "math" "math/big" @@ -32,9 +31,11 @@ func (n Number) String() string { } } + return strconv.FormatFloat(float64(n), 'g', -1, 64) + // Otherwise, the Go json package handles this correctly. - b, _ := json.Marshal(float64(n)) //nolint:errchkjson - return string(b) + // b, _ := json.Marshal(float64(n)) //nolint:errchkjson + // return string(b) } // https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-stringtonumber diff --git a/internal/module/resolver.go b/internal/module/resolver.go index ed3bd0d859..cae8110bfb 100644 --- a/internal/module/resolver.go +++ b/internal/module/resolver.go @@ -1416,8 +1416,9 @@ func (r *resolutionState) getPackageJsonInfo(packageDirectory string, onlyRecord directoryExists := r.resolver.host.FS().DirectoryExists(packageDirectory) if directoryExists && r.resolver.host.FS().FileExists(packageJsonPath) { // Ignore error - contents, _ := r.resolver.host.FS().ReadFile(packageJsonPath) - packageJsonContent, _ := packagejson.Parse([]byte(contents)) + // contents, _ := r.resolver.host.FS().ReadFile(packageJsonPath) + // packageJsonContent, _ := packagejson.Parse([]byte(contents)) + var packageJsonContent packagejson.Fields if r.resolver.traceEnabled() { r.resolver.host.Trace(diagnostics.Found_package_json_at_0.Format(packageJsonPath)) } From 3787a64d8aba8ac416cb53725618049b76deac5b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 22 Apr 2025 10:39:19 -0700 Subject: [PATCH 3/3] Add benchmark file --- benchmark-wasm.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 benchmark-wasm.sh diff --git a/benchmark-wasm.sh b/benchmark-wasm.sh new file mode 100755 index 0000000000..e507744a58 --- /dev/null +++ b/benchmark-wasm.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -exo pipefail +cd "$(dirname "$0")" + +[[ -f ./tsgo ]] || go build ./cmd/tsgo +[[ -f ./tsgo.wasm ]] || GOOS=wasip1 GOARCH=wasm go build -o tsgo.wasm ./cmd/tsgo +[[ -f ./tsgo-tinygo.wasm ]] || GOOS=wasip1 GOARCH=wasm tinygo build -o tsgo-tinygo.wasm ./cmd/tsgo + +hyperfine -w 1 \ + -n 'native' \ + './tsgo -p $PWD/_submodules/TypeScript/src/compiler --singleThreaded --listFilesOnly' \ + -n 'go wasm' \ + 'wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=1048576 ./tsgo.wasm -p $PWD/_submodules/TypeScript/src/compiler --singleThreaded --listFilesOnly' \ + -n 'tinygo wasm' \ + 'wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=1048576 ./tsgo-tinygo.wasm -p $PWD/_submodules/TypeScript/src/compiler --singleThreaded --listFilesOnly'