Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions compiler/override-registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,33 @@ func TestOverrideParityVerifierReportsBlockedGoUse(t *testing.T) {
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-blocked-use")
}

// TestOverrideParityVerifierBlocksJSONV2 checks that a program that uses
// encoding/json/v2, which compiled from Go source fails when it initializes,
// fails to compile instead.
func TestOverrideParityVerifierBlocksJSONV2(t *testing.T) {
moduleDir := writePackageGraphFixture(t, map[string]string{
"go.mod": "module example.test/jsonv2\n\ngo 1.27\n",
"main.go": strings.Join([]string{
"package main",
"import \"encoding/json/v2\"",
"func main() { json.Marshal(1) }",
"",
}, "\n"),
})
comp, err := NewCompiler(&Config{
Dir: moduleDir,
OutputPath: filepath.Join(t.TempDir(), "out"),
}, nil, nil)
if err != nil {
t.Fatal(err.Error())
}
result, err := comp.CompilePackages(context.Background(), ".")
if err == nil {
t.Fatalf("expected compile to fail")
}
requireDiagnosticCode(t, result.Diagnostics, "goscript/overrides:parity-blocked-use")
}

func TestOverrideParityVerifierAllowsDeferredMissingExports(t *testing.T) {
result, err := compileParityFixture(t, map[string]overrideParityEntry{
"Present": {Status: overrideParityStatusReal},
Expand Down
3 changes: 3 additions & 0 deletions gs-embed.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions gs/encoding/json/meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"dependencies": [
"encoding/json/jsontext",
"encoding/json/v2",
"io"
],
"asyncMethods": {
Expand Down
17 changes: 17 additions & 0 deletions gs/encoding/json/v2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// encoding/json/v2 is not supported: its implementation uses the internals of
// encoding/json/jsontext, which the jsontext override does not implement, so
// compiling it from Go source fails when the package initializes. parity.json
// blocks its exports, so a program that uses one fails to compile instead.
//
// Marshaler and Unmarshaler are the exceptions: encoding/json.Marshaler and
// encoding/json.Unmarshaler are aliases of them since Go 1.27, so code that
// uses those types refers to these, which have the same methods.
import type * as $ from '@goscript/builtin/index.js'

export interface Marshaler {
MarshalJSON(): [$.Slice<number>, $.GoError]
}

export interface Unmarshaler {
UnmarshalJSON(data: $.Slice<number>): $.GoError
}
1 change: 1 addition & 0 deletions gs/encoding/json/v2/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
39 changes: 39 additions & 0 deletions gs/encoding/json/v2/parity.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"schemaVersion": 1,
"strict": true,
"symbols": {
"DefaultOptionsV2": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Deterministic": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"ErrUnknownName": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"FormatNilMapAsNull": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"FormatNilSliceAsNull": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"GetOption": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"JoinMarshalers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"JoinOptions": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"JoinUnmarshalers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Marshal": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"MarshalEncode": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"MarshalFunc": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"MarshalToFunc": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"MarshalWrite": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Marshaler": { "status": "real" },
"MarshalerTo": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Marshalers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"MatchCaseInsensitiveNames": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"OmitZeroStructFields": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Options": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"RejectUnknownMembers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"SemanticError": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"StringifyNumbers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Unmarshal": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"UnmarshalDecode": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"UnmarshalFromFunc": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"UnmarshalFunc": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"UnmarshalRead": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Unmarshaler": { "status": "real" },
"UnmarshalerFrom": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"Unmarshalers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"WithMarshalers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" },
"WithUnmarshalers": { "status": "blocked", "reason": "encoding/json/v2 is not supported; it needs the internals of encoding/json/jsontext, which its override does not implement" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import * as $ from "@goscript/builtin/index.js"
import * as json from "@goscript/encoding/json/index.js"
import * as fmt from "@goscript/fmt/index.js"
import type * as v2 from "@goscript/encoding/json/v2/index.js"

export type Maps = $.Slice<MapItem>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<a title="x &lt; y">x &lt; y</a>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"html/template"
"os"
)

func main() {
// html/template, compiled from source, uses json.Marshaler, which is an
// alias of a type of encoding/json/v2 since Go 1.27.
t := template.Must(template.New("t").Parse(`<a title="{{.}}">{{.}}</a>` + "\n"))
if err := t.Execute(os.Stdout, "x < y"); err != nil {
println("error:", err.Error())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Generated file based on package_import_json_marshaler_alias.go
// Updated when compliance tests are re-run, DO NOT EDIT!

import * as $ from "@goscript/builtin/index.js"
import * as template from "@goscript/html/template/index.js"
import * as os from "@goscript/os/index.js"
import type * as io from "@goscript/io/index.js"
import "@goscript/os/index.js"

export async function main(): globalThis.Promise<void> {
// html/template, compiled from source, uses json.Marshaler, which is an
// alias of a type of encoding/json/v2 since Go 1.27.
let t = template.Must(...((await template.Template.prototype.Parse.call(template.New("t"), "<a title=\"{{.}}\">{{.}}</a>" + "\n")) as [template.Template | $.VarRef<template.Template> | null, $.GoError]))
{
let err = await (t !== null && (t as any).__isVarRef !== true && (t as any).__goValue === undefined ? ((t as any) as template.Template).Execute($.interfaceValue<io.Writer | null>(os.Stdout, "*os.File", __goscriptStatic0()), "x < y") : template.Template.prototype.Execute.call(t, $.interfaceValue<io.Writer | null>(os.Stdout, "*os.File", __goscriptStatic0()), "x < y"))
if (err != null) {
await $.println("error:", (__goscriptAwait = (err !== null && (err as any).__isVarRef !== true && ((err as any).__goValue === undefined || (err as any).__goType?.charCodeAt(0) !== 42) ? (err as Exclude<$.GoError, null>) : $.pointerValue<Exclude<$.GoError, null>>(err)).Error(), __goscriptAwait instanceof Promise ? await __goscriptAwait : __goscriptAwait))
}
}
}

var __goscriptStatic0$value: any
function __goscriptStatic0(): any {
return __goscriptStatic0$value ??= ($.overrideTypeMethods(/* @__PURE__ */ $.pointerType("os.File"), "os.File", () => [$.methodSignature("Chdir", [], ["error"], true), $.methodSignature("Chmod", [["mode", /* @__PURE__ */ $.basicType("uint32", "fs.FileMode")]], ["error"], true), $.methodSignature("Chown", [["uid", /* @__PURE__ */ $.basicType("int")], ["gid", /* @__PURE__ */ $.basicType("int")]], ["error"], true), $.methodSignature("Close", [], ["error"], true), $.methodSignature("Fd", [], [/* @__PURE__ */ $.basicType("uintptr")], true), $.methodSignature("Name", [], [/* @__PURE__ */ $.basicType("string")], true), $.methodSignature("Read", [["b", /* @__PURE__ */ $.sliceType(/* @__PURE__ */ $.basicType("uint8"))]], [["n", /* @__PURE__ */ $.basicType("int")], ["err", "error"]], true), $.methodSignature("ReadAt", [["b", /* @__PURE__ */ $.sliceType(/* @__PURE__ */ $.basicType("uint8"))], ["off", /* @__PURE__ */ $.basicType("int64")]], [["n", /* @__PURE__ */ $.basicType("int")], ["err", "error"]], true), $.methodSignature("ReadDir", [["n", /* @__PURE__ */ $.basicType("int")]], [/* @__PURE__ */ $.sliceType("fs.DirEntry"), "error"], true), $.methodSignature("ReadFrom", [["r", "io.Reader"]], [["n", /* @__PURE__ */ $.basicType("int64")], ["err", "error"]], true), $.methodSignature("Readdir", [["n", /* @__PURE__ */ $.basicType("int")]], [/* @__PURE__ */ $.sliceType("fs.FileInfo"), "error"], true), $.methodSignature("Readdirnames", [["n", /* @__PURE__ */ $.basicType("int")]], [["names", /* @__PURE__ */ $.sliceType(/* @__PURE__ */ $.basicType("string"))], ["err", "error"]], true), $.methodSignature("Seek", [["offset", /* @__PURE__ */ $.basicType("int64")], ["whence", /* @__PURE__ */ $.basicType("int")]], [["ret", /* @__PURE__ */ $.basicType("int64")], ["err", "error"]], true), $.methodSignature("SetDeadline", [["t", "time.Time"]], ["error"], true), $.methodSignature("SetReadDeadline", [["t", "time.Time"]], ["error"], true), $.methodSignature("SetWriteDeadline", [["t", "time.Time"]], ["error"], true), $.methodSignature("Stat", [], ["fs.FileInfo", "error"], true), $.methodSignature("Sync", [], ["error"], true), $.methodSignature("SyscallConn", [], ["syscall.RawConn", "error"], true), $.methodSignature("Truncate", [["size", /* @__PURE__ */ $.basicType("int64")]], ["error"], true), $.methodSignature("Write", [["b", /* @__PURE__ */ $.sliceType(/* @__PURE__ */ $.basicType("uint8"))]], [["n", /* @__PURE__ */ $.basicType("int")], ["err", "error"]], true), $.methodSignature("WriteAt", [["b", /* @__PURE__ */ $.sliceType(/* @__PURE__ */ $.basicType("uint8"))], ["off", /* @__PURE__ */ $.basicType("int64")]], [["n", /* @__PURE__ */ $.basicType("int")], ["err", "error"]], true), $.methodSignature("WriteString", [["s", /* @__PURE__ */ $.basicType("string")]], [["n", /* @__PURE__ */ $.basicType("int")], ["err", "error"]], true), $.methodSignature("WriteTo", [["w", "io.Writer"]], [["n", /* @__PURE__ */ $.basicType("int64")], ["err", "error"]], true)]))
}

var __goscriptAwait: any

if ($.isMainScript(import.meta)) {
await main()
}
25 changes: 25 additions & 0 deletions tests/tests/package_import_json_marshaler_alias/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"paths": {
"*": [
"./*"
],
"@go/github.com/s4wave/goscript/*": [
"../../../*"
],
"@goscript/*": [
"../../../tests/tests/package_import_json_marshaler_alias/run/output/@goscript/*",
"../../../gs/*",
"../../../tests/deps/*"
],
"@goscript/github.com/s4wave/goscript/tests/tests/package_import_json_marshaler_alias/*": [
"./*"
]
}
},
"extends": "../../../tests/tsconfig.base.json",
"include": [
"index.ts",
"package_import_json_marshaler_alias.gs.ts"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import * as $ from "@goscript/builtin/index.js"
import * as json from "@goscript/encoding/json/index.js"
import * as reflect from "@goscript/reflect/index.js"
import type * as v2 from "@goscript/encoding/json/v2/index.js"

export class Node {
public declare Name: string
Expand Down
Loading