goscript 0.1.4 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +7 -0
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript-wasm/main.go +38 -6
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/diagnostic.go +104 -12
- package/compiler/diagnostic_test.go +106 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +354 -44
- package/compiler/gotest/runner_test.go +293 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/index.test.ts +23 -0
- package/compiler/lowered-program.go +33 -24
- package/compiler/lowering.go +746 -194
- package/compiler/lowering_bench_test.go +42 -27
- package/compiler/lowering_internal_test.go +18 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/protobuf-ts-binding.go +567 -0
- package/compiler/protobuf-ts-binding_test.go +402 -0
- package/compiler/runtime-contract.go +4 -0
- package/compiler/runtime-contract_test.go +2 -0
- package/compiler/semantic-model-types.go +9 -4
- package/compiler/semantic-model.go +282 -70
- package/compiler/semantic-model_test.go +82 -1
- package/compiler/service.go +21 -1
- package/compiler/skeleton_test.go +118 -10
- package/compiler/typescript-emitter.go +128 -13
- package/compiler/wasm/compile_test.go +37 -4
- package/compiler/{wasm_api.go → wasm-api.go} +57 -7
- package/dist/gs/builtin/hostio.js +5 -0
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +13 -2
- package/dist/gs/builtin/slice.js +187 -6
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +13 -5
- package/dist/gs/builtin/type.js +153 -60
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +10 -3
- package/dist/gs/compress/zlib/index.js +50 -16
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +101 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +589 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.d.ts +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js +17 -11
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +4 -2
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +2 -0
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +5 -0
- package/dist/gs/math/bits/index.js +16 -4
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +300 -5
- package/dist/gs/net/http/index.js +1598 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.js +1 -1
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +25 -6
- package/dist/gs/reflect/type.js +1475 -228
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.js +9 -5
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/doc_64.gs.js +7 -6
- package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/testing/testing.js +55 -13
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/hostio.test.ts +16 -0
- package/gs/builtin/hostio.ts +7 -0
- package/gs/builtin/runtime-contract.test.ts +246 -21
- package/gs/builtin/slice.ts +269 -24
- package/gs/builtin/type.ts +226 -59
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +62 -1
- package/gs/compress/zlib/index.ts +53 -16
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +373 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +893 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.test.ts +18 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/json/index.ts +17 -11
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/byteorder/index.test.ts +2 -2
- package/gs/internal/byteorder/index.ts +2 -2
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.ts +4 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.ts +1 -0
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +23 -4
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +781 -12
- package/gs/net/http/index.ts +1860 -139
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +1 -1
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1961 -317
- package/gs/reflect/typefor.test.ts +530 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.ts +9 -5
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/doc_64.gs.ts +6 -7
- package/gs/sync/atomic/doc_64.test.ts +43 -0
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/syscall/env.ts +29 -14
- package/gs/testing/testing.test.ts +67 -0
- package/gs/testing/testing.ts +87 -19
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -926
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -38
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1361
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
package/compiler/lowering.go
CHANGED
|
@@ -24,6 +24,18 @@ type LoweringOwner struct {
|
|
|
24
24
|
overrideOwner *OverrideRegistryOwner
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// LoweringOptions are request-scoped lowering switches.
|
|
28
|
+
type LoweringOptions struct {
|
|
29
|
+
// SourceRoot is the request source root that may contain sibling protobuf TypeScript files.
|
|
30
|
+
SourceRoot string
|
|
31
|
+
// DisplayRoot is the request root used to format source file names in diagnostics.
|
|
32
|
+
DisplayRoot string
|
|
33
|
+
// OutputPath is the TypeScript output root used for generated relative imports.
|
|
34
|
+
OutputPath string
|
|
35
|
+
// ProtobufTypeScriptBinding binds .pb.go files to sibling .pb.ts files.
|
|
36
|
+
ProtobufTypeScriptBinding bool
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
// NewLoweringOwner creates the lowering owner.
|
|
28
40
|
func NewLoweringOwner(runtimeOwner *RuntimeContractOwner, overrideOwner *OverrideRegistryOwner) *LoweringOwner {
|
|
29
41
|
if runtimeOwner == nil {
|
|
@@ -39,7 +51,7 @@ func NewLoweringOwner(runtimeOwner *RuntimeContractOwner, overrideOwner *Overrid
|
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
// Build converts the semantic model into the compiler IR.
|
|
42
|
-
func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*LoweredProgram, []Diagnostic) {
|
|
54
|
+
func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel, opts ...LoweringOptions) (*LoweredProgram, []Diagnostic) {
|
|
43
55
|
if err := ctx.Err(); err != nil {
|
|
44
56
|
return nil, []Diagnostic{{
|
|
45
57
|
Severity: DiagnosticSeverityError,
|
|
@@ -55,7 +67,14 @@ func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*Lower
|
|
|
55
67
|
}}
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
var options LoweringOptions
|
|
71
|
+
if len(opts) != 0 {
|
|
72
|
+
options = opts[0]
|
|
73
|
+
}
|
|
74
|
+
|
|
58
75
|
program := &LoweredProgram{}
|
|
76
|
+
lazyPackageVars := make(map[string]map[types.Object]bool, len(model.packages))
|
|
77
|
+
runtimeMethodSets := make(runtimeMethodSetCache)
|
|
59
78
|
semPkgs := make([]*semanticPackage, 0, len(model.packages))
|
|
60
79
|
for _, semPkg := range model.packages {
|
|
61
80
|
semPkgs = append(semPkgs, semPkg)
|
|
@@ -70,7 +89,7 @@ func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*Lower
|
|
|
70
89
|
diagnostics = append(diagnostics, loweringUnsupported("package", semPkg.pkgPath, "missing semantic source package"))
|
|
71
90
|
continue
|
|
72
91
|
}
|
|
73
|
-
loweredPkg, pkgDiagnostics := o.lowerPackage(model, semPkg)
|
|
92
|
+
loweredPkg, pkgDiagnostics := o.lowerPackage(model, semPkg, lazyPackageVars, runtimeMethodSets, options)
|
|
74
93
|
diagnostics = append(diagnostics, pkgDiagnostics...)
|
|
75
94
|
if loweredPkg != nil {
|
|
76
95
|
program.packages = append(program.packages, loweredPkg)
|
|
@@ -82,18 +101,70 @@ func (o *LoweringOwner) Build(ctx context.Context, model *SemanticModel) (*Lower
|
|
|
82
101
|
return program, nil
|
|
83
102
|
}
|
|
84
103
|
|
|
85
|
-
func (o *LoweringOwner) lowerPackage(
|
|
104
|
+
func (o *LoweringOwner) lowerPackage(
|
|
105
|
+
model *SemanticModel,
|
|
106
|
+
semPkg *semanticPackage,
|
|
107
|
+
lazyPackageVarsByPkg map[string]map[types.Object]bool,
|
|
108
|
+
runtimeMethodSets runtimeMethodSetCache,
|
|
109
|
+
options LoweringOptions,
|
|
110
|
+
) (*loweredPackage, []Diagnostic) {
|
|
86
111
|
loweredPkg := &loweredPackage{
|
|
87
112
|
pkgPath: semPkg.pkgPath,
|
|
88
113
|
name: semPkg.name,
|
|
89
114
|
}
|
|
90
115
|
declFiles := packageDeclFiles(semPkg)
|
|
91
116
|
outputNames := packageOutputNames(semPkg)
|
|
92
|
-
|
|
93
|
-
|
|
117
|
+
protobufBindings, bindingDiagnostics := protobufTypeScriptBindings(semPkg, options)
|
|
118
|
+
for sourcePath, binding := range protobufBindings {
|
|
119
|
+
outputNames[sourcePath] = binding.outputName
|
|
120
|
+
}
|
|
121
|
+
lazyPackageVars := o.packageLazyVars(semPkg, lazyPackageVarsByPkg, declFiles)
|
|
122
|
+
diagnostics := append([]Diagnostic(nil), bindingDiagnostics...)
|
|
94
123
|
for idx, file := range semPkg.source.Syntax {
|
|
95
124
|
sourcePath := sourceFilePath(semPkg, idx, file)
|
|
96
|
-
|
|
125
|
+
if options.ProtobufTypeScriptBinding && protobufSRPCHasGoScriptReplacement(sourcePath) {
|
|
126
|
+
stub, stubDiagnostics := lowerProtobufSRPCTypeScriptBindingStub(semPkg, sourcePath, options)
|
|
127
|
+
diagnostics = append(diagnostics, stubDiagnostics...)
|
|
128
|
+
if stub != nil {
|
|
129
|
+
loweredPkg.files = append(loweredPkg.files, stub)
|
|
130
|
+
}
|
|
131
|
+
continue
|
|
132
|
+
}
|
|
133
|
+
if binding, ok := protobufBindings[sourcePath]; ok {
|
|
134
|
+
protobufAdapter := !binding.hasOneof && !strings.HasSuffix(filepath.Base(binding.sourcePath), "_srpc.pb.go")
|
|
135
|
+
loweredFile, fileDiagnostics := o.lowerFile(
|
|
136
|
+
model,
|
|
137
|
+
semPkg,
|
|
138
|
+
file,
|
|
139
|
+
sourcePath,
|
|
140
|
+
declFiles,
|
|
141
|
+
outputNames,
|
|
142
|
+
lazyPackageVars,
|
|
143
|
+
lazyPackageVarsByPkg,
|
|
144
|
+
runtimeMethodSets,
|
|
145
|
+
protobufAdapter,
|
|
146
|
+
options.DisplayRoot,
|
|
147
|
+
)
|
|
148
|
+
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
149
|
+
rewriteProtobufTypeScriptBindingFile(loweredFile, binding)
|
|
150
|
+
if loweredFile != nil {
|
|
151
|
+
loweredPkg.files = append(loweredPkg.files, loweredFile)
|
|
152
|
+
}
|
|
153
|
+
continue
|
|
154
|
+
}
|
|
155
|
+
loweredFile, fileDiagnostics := o.lowerFile(
|
|
156
|
+
model,
|
|
157
|
+
semPkg,
|
|
158
|
+
file,
|
|
159
|
+
sourcePath,
|
|
160
|
+
declFiles,
|
|
161
|
+
outputNames,
|
|
162
|
+
lazyPackageVars,
|
|
163
|
+
lazyPackageVarsByPkg,
|
|
164
|
+
runtimeMethodSets,
|
|
165
|
+
false,
|
|
166
|
+
options.DisplayRoot,
|
|
167
|
+
)
|
|
97
168
|
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
98
169
|
if loweredFile != nil {
|
|
99
170
|
loweredPkg.files = append(loweredPkg.files, loweredFile)
|
|
@@ -125,6 +196,10 @@ func (o *LoweringOwner) lowerFile(
|
|
|
125
196
|
declFiles map[types.Object]string,
|
|
126
197
|
outputNames map[string]string,
|
|
127
198
|
lazyPackageVars map[types.Object]bool,
|
|
199
|
+
lazyPackageVarsByPkg map[string]map[types.Object]bool,
|
|
200
|
+
runtimeMethodSets runtimeMethodSetCache,
|
|
201
|
+
protobufTypeScriptAdapter bool,
|
|
202
|
+
displayRoot string,
|
|
128
203
|
) (*loweredFile, []Diagnostic) {
|
|
129
204
|
associatedMethods := o.methodDeclsForFileTypes(semPkg, file)
|
|
130
205
|
relevantImportFiles := map[string]bool{sourcePath: true}
|
|
@@ -146,7 +221,7 @@ func (o *LoweringOwner) lowerFile(
|
|
|
146
221
|
importPaths := make(map[string]string)
|
|
147
222
|
importNames := make(map[string]string)
|
|
148
223
|
importObjects := make(map[*types.PkgName]string)
|
|
149
|
-
localRefs := o.analyzeLocalFileReferences(semPkg, file, sourcePath, associatedMethods, declFiles, outputNames)
|
|
224
|
+
localRefs := o.analyzeLocalFileReferences(semPkg, file, sourcePath, associatedMethods, declFiles, outputNames, runtimeMethodSets)
|
|
150
225
|
reservedImportAliases := localRefs.reservedNames
|
|
151
226
|
seenImport := make(map[string]bool)
|
|
152
227
|
for idx, importFile := range semPkg.source.Syntax {
|
|
@@ -231,18 +306,21 @@ func (o *LoweringOwner) lowerFile(
|
|
|
231
306
|
loweredFile.imports = append(loweredFile.imports, localImports...)
|
|
232
307
|
|
|
233
308
|
ctx := lowerFileContext{
|
|
234
|
-
model:
|
|
235
|
-
semPkg:
|
|
236
|
-
file:
|
|
237
|
-
importAliases:
|
|
238
|
-
importPaths:
|
|
239
|
-
importNames:
|
|
240
|
-
importObjects:
|
|
241
|
-
sourcePath:
|
|
242
|
-
localAliases:
|
|
243
|
-
lazyPackageVars:
|
|
244
|
-
|
|
245
|
-
|
|
309
|
+
model: model,
|
|
310
|
+
semPkg: semPkg,
|
|
311
|
+
file: file,
|
|
312
|
+
importAliases: importAliases,
|
|
313
|
+
importPaths: importPaths,
|
|
314
|
+
importNames: importNames,
|
|
315
|
+
importObjects: importObjects,
|
|
316
|
+
sourcePath: sourcePath,
|
|
317
|
+
localAliases: localRefs.aliases,
|
|
318
|
+
lazyPackageVars: lazyPackageVars,
|
|
319
|
+
lazyPackageVarsByPkg: lazyPackageVarsByPkg,
|
|
320
|
+
tempNames: newTempNameOwner(),
|
|
321
|
+
topLevel: true,
|
|
322
|
+
protobufTSAdapter: protobufTypeScriptAdapter,
|
|
323
|
+
displayRoot: displayRoot,
|
|
246
324
|
}
|
|
247
325
|
var diagnostics []Diagnostic
|
|
248
326
|
var packageInitCalls []string
|
|
@@ -451,6 +529,24 @@ type localFileReferenceAnalysis struct {
|
|
|
451
529
|
implicitRuntime map[string]bool
|
|
452
530
|
}
|
|
453
531
|
|
|
532
|
+
type runtimeMethodSetCache map[*types.Named][]types.Object
|
|
533
|
+
|
|
534
|
+
func (c runtimeMethodSetCache) methods(named *types.Named) []types.Object {
|
|
535
|
+
if named == nil {
|
|
536
|
+
return nil
|
|
537
|
+
}
|
|
538
|
+
if methods, ok := c[named]; ok {
|
|
539
|
+
return methods
|
|
540
|
+
}
|
|
541
|
+
methodSet := types.NewMethodSet(types.NewPointer(named))
|
|
542
|
+
methods := make([]types.Object, 0, methodSet.Len())
|
|
543
|
+
for method := range methodSet.Methods() {
|
|
544
|
+
methods = append(methods, method.Obj())
|
|
545
|
+
}
|
|
546
|
+
c[named] = methods
|
|
547
|
+
return methods
|
|
548
|
+
}
|
|
549
|
+
|
|
454
550
|
func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
455
551
|
semPkg *semanticPackage,
|
|
456
552
|
file *ast.File,
|
|
@@ -458,6 +554,7 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
458
554
|
associatedMethods []*ast.FuncDecl,
|
|
459
555
|
declFiles map[types.Object]string,
|
|
460
556
|
outputNames map[string]string,
|
|
557
|
+
runtimeMethodSets runtimeMethodSetCache,
|
|
461
558
|
) localFileReferenceAnalysis {
|
|
462
559
|
analysis := localFileReferenceAnalysis{
|
|
463
560
|
reservedNames: make(map[string]bool),
|
|
@@ -469,6 +566,8 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
469
566
|
}
|
|
470
567
|
seenObjects := make(map[types.Object]bool)
|
|
471
568
|
seenTypes := make(map[types.Type]bool)
|
|
569
|
+
seenRuntimeTypes := make(map[types.Type]bool)
|
|
570
|
+
seenRuntimeOwnerTypes := make(map[types.Type]bool)
|
|
472
571
|
var addTypeDeps func(typ types.Type)
|
|
473
572
|
var addRuntimeTypeDeps func(typ types.Type)
|
|
474
573
|
var addRuntimeTypeOwnerDeps func(typ types.Type)
|
|
@@ -636,6 +735,10 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
636
735
|
if typ == nil {
|
|
637
736
|
return
|
|
638
737
|
}
|
|
738
|
+
if seenRuntimeTypes[typ] {
|
|
739
|
+
return
|
|
740
|
+
}
|
|
741
|
+
seenRuntimeTypes[typ] = true
|
|
639
742
|
if alias, ok := typ.(*types.Alias); ok {
|
|
640
743
|
addObject(alias.Obj(), true)
|
|
641
744
|
if args := alias.TypeArgs(); args != nil {
|
|
@@ -651,9 +754,8 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
651
754
|
for method := range named.Methods() {
|
|
652
755
|
addObject(method, true)
|
|
653
756
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
addObject(method.Obj(), true)
|
|
757
|
+
for _, method := range runtimeMethodSets.methods(named) {
|
|
758
|
+
addObject(method, true)
|
|
657
759
|
}
|
|
658
760
|
if args := named.TypeArgs(); args != nil {
|
|
659
761
|
for t := range args.Types() {
|
|
@@ -680,6 +782,10 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
680
782
|
if typ == nil {
|
|
681
783
|
return
|
|
682
784
|
}
|
|
785
|
+
if seenRuntimeOwnerTypes[typ] {
|
|
786
|
+
return
|
|
787
|
+
}
|
|
788
|
+
seenRuntimeOwnerTypes[typ] = true
|
|
683
789
|
if alias, ok := typ.(*types.Alias); ok {
|
|
684
790
|
addObject(alias.Obj(), true)
|
|
685
791
|
if args := alias.TypeArgs(); args != nil {
|
|
@@ -773,6 +879,9 @@ func (o *LoweringOwner) analyzeLocalFileReferences(
|
|
|
773
879
|
}
|
|
774
880
|
ast.Inspect(file, inspect)
|
|
775
881
|
for _, methodDecl := range associatedMethods {
|
|
882
|
+
if sourcePos(semPkg.source, methodDecl.Pos()).file == sourcePath {
|
|
883
|
+
continue
|
|
884
|
+
}
|
|
776
885
|
ast.Inspect(methodDecl, inspect)
|
|
777
886
|
}
|
|
778
887
|
return analysis
|
|
@@ -984,36 +1093,61 @@ func safeParamName(param *types.Var, idx int) string {
|
|
|
984
1093
|
}
|
|
985
1094
|
|
|
986
1095
|
type lowerFileContext struct {
|
|
987
|
-
model
|
|
988
|
-
semPkg
|
|
989
|
-
file
|
|
990
|
-
importAliases
|
|
991
|
-
importPaths
|
|
992
|
-
importNames
|
|
993
|
-
importObjects
|
|
994
|
-
sourcePath
|
|
995
|
-
localAliases
|
|
996
|
-
lazyPackageVars
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1096
|
+
model *SemanticModel
|
|
1097
|
+
semPkg *semanticPackage
|
|
1098
|
+
file *ast.File
|
|
1099
|
+
importAliases map[string]string
|
|
1100
|
+
importPaths map[string]string
|
|
1101
|
+
importNames map[string]string
|
|
1102
|
+
importObjects map[*types.PkgName]string
|
|
1103
|
+
sourcePath string
|
|
1104
|
+
localAliases map[types.Object]string
|
|
1105
|
+
lazyPackageVars map[types.Object]bool
|
|
1106
|
+
lazyPackageVarsByPkg map[string]map[types.Object]bool
|
|
1107
|
+
identAliases map[types.Object]string
|
|
1108
|
+
identAliasRefs map[types.Object]bool
|
|
1109
|
+
tempNames *tempNameOwner
|
|
1110
|
+
signature *types.Signature
|
|
1111
|
+
typeParams map[string]bool
|
|
1112
|
+
staticTypeParams map[string]bool
|
|
1113
|
+
asyncFunction bool
|
|
1114
|
+
functionTypeDepth int
|
|
1115
|
+
deferState *loweredDeferState
|
|
1116
|
+
rangeBranch *loweredRangeBranch
|
|
1117
|
+
rangeBreak bool
|
|
1118
|
+
rangeContinue bool
|
|
1119
|
+
gotoLabels map[string]bool
|
|
1120
|
+
forwardGotos map[string]bool
|
|
1121
|
+
gotoStateLabels map[string]bool
|
|
1122
|
+
gotoStateVar string
|
|
1123
|
+
gotoStateLoop string
|
|
1124
|
+
functionScopedDecls bool
|
|
1125
|
+
loopLabel string
|
|
1126
|
+
switchBreak bool
|
|
1127
|
+
topLevel bool
|
|
1128
|
+
protobufTSAdapter bool
|
|
1129
|
+
displayRoot string
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
func (ctx lowerFileContext) diagnosticPosition(pos token.Pos) *DiagnosticPosition {
|
|
1133
|
+
if ctx.semPkg == nil {
|
|
1134
|
+
return nil
|
|
1135
|
+
}
|
|
1136
|
+
return diagnosticPositionFromSource(sourcePos(ctx.semPkg.source, pos), ctx.displayRoot)
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
func loweringUnsupportedAt(ctx lowerFileContext, node ast.Node, kind string, subject string, detail string) Diagnostic {
|
|
1140
|
+
diag := loweringUnsupported(kind, subject, detail)
|
|
1141
|
+
if node != nil {
|
|
1142
|
+
diag.Position = ctx.diagnosticPosition(node.Pos())
|
|
1143
|
+
}
|
|
1144
|
+
return diag
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
func loweringUnsupportedPos(ctx lowerFileContext, pos token.Pos, kind string, subject string, detail string) Diagnostic {
|
|
1148
|
+
diag := loweringUnsupported(kind, subject, detail)
|
|
1149
|
+
diag.Position = ctx.diagnosticPosition(pos)
|
|
1150
|
+
return diag
|
|
1017
1151
|
}
|
|
1018
1152
|
|
|
1019
1153
|
type tempNameOwner struct {
|
|
@@ -1102,7 +1236,7 @@ func (o *LoweringOwner) lowerDecl(ctx lowerFileContext, decl ast.Decl) ([]lowere
|
|
|
1102
1236
|
if receiver := receiverNamedTypeFromDecl(ctx, typed); receiver != nil && namedStructType(receiver) == nil {
|
|
1103
1237
|
fn, diagnostics := o.lowerNamedReceiverMethodDecl(ctx, typed, receiver)
|
|
1104
1238
|
if fn == nil {
|
|
1105
|
-
return nil, []Diagnostic{
|
|
1239
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, typed, "function", typed.Name.Name, "missing type information")}
|
|
1106
1240
|
}
|
|
1107
1241
|
return []loweredDecl{{function: fn}}, diagnostics
|
|
1108
1242
|
}
|
|
@@ -1110,11 +1244,11 @@ func (o *LoweringOwner) lowerDecl(ctx lowerFileContext, decl ast.Decl) ([]lowere
|
|
|
1110
1244
|
}
|
|
1111
1245
|
fn, diagnostics := o.lowerFuncDecl(ctx, typed)
|
|
1112
1246
|
if fn == nil {
|
|
1113
|
-
return nil, []Diagnostic{
|
|
1247
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, typed, "function", typed.Name.Name, "missing type information")}
|
|
1114
1248
|
}
|
|
1115
1249
|
return []loweredDecl{{function: fn}}, diagnostics
|
|
1116
1250
|
default:
|
|
1117
|
-
return nil, []Diagnostic{
|
|
1251
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, decl, "declaration", ctx.semPkg.pkgPath, "unsupported declaration kind")}
|
|
1118
1252
|
}
|
|
1119
1253
|
}
|
|
1120
1254
|
|
|
@@ -1162,7 +1296,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1162
1296
|
value = o.lowerValueForTarget(ctx, typed.Values[idx], obj.Type(), lowered)
|
|
1163
1297
|
value = o.lowerTopLevelInitializerValue(ctx, typed.Values[idx], value)
|
|
1164
1298
|
} else if len(embedPatterns) != 0 {
|
|
1165
|
-
embedded, embedDiagnostics := o.lowerGoEmbedValue(ctx, obj.Type(), embedPatterns)
|
|
1299
|
+
embedded, embedDiagnostics := o.lowerGoEmbedValue(ctx, typed.Pos(), obj.Type(), embedPatterns)
|
|
1166
1300
|
diagnostics = append(diagnostics, embedDiagnostics...)
|
|
1167
1301
|
if embedded != "" {
|
|
1168
1302
|
value = embedded
|
|
@@ -1171,7 +1305,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1171
1305
|
if _, ok := obj.(*types.Const); !ok && ctx.model.needsVarRef[obj] {
|
|
1172
1306
|
value = o.runtimeOwner.QualifiedHelper(RuntimeHelperVarRef) + "(" + value + ")"
|
|
1173
1307
|
}
|
|
1174
|
-
keyword :=
|
|
1308
|
+
keyword := strings.TrimSpace(declarationKeyword(ctx))
|
|
1175
1309
|
if _, ok := obj.(*types.Const); ok || decl.Tok == token.CONST {
|
|
1176
1310
|
keyword = "const"
|
|
1177
1311
|
}
|
|
@@ -1253,7 +1387,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1253
1387
|
}
|
|
1254
1388
|
}
|
|
1255
1389
|
default:
|
|
1256
|
-
diagnostics = append(diagnostics,
|
|
1390
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, typed, "declaration", ctx.semPkg.pkgPath, "unsupported general declaration"))
|
|
1257
1391
|
}
|
|
1258
1392
|
}
|
|
1259
1393
|
return decls, diagnostics
|
|
@@ -1402,6 +1536,9 @@ func packageDeclFiles(semPkg *semanticPackage) map[types.Object]string {
|
|
|
1402
1536
|
if semPkg == nil || semPkg.source == nil {
|
|
1403
1537
|
return nil
|
|
1404
1538
|
}
|
|
1539
|
+
if len(semPkg.source.Syntax) <= 1 {
|
|
1540
|
+
return nil
|
|
1541
|
+
}
|
|
1405
1542
|
declFiles := make(map[types.Object]string, len(semPkg.declarations))
|
|
1406
1543
|
for _, decl := range semPkg.declarations {
|
|
1407
1544
|
if decl.object != nil && decl.position.file != "" {
|
|
@@ -1423,6 +1560,31 @@ func packageOutputNames(semPkg *semanticPackage) map[string]string {
|
|
|
1423
1560
|
return outputNames
|
|
1424
1561
|
}
|
|
1425
1562
|
|
|
1563
|
+
func (o *LoweringOwner) packageLazyVars(
|
|
1564
|
+
semPkg *semanticPackage,
|
|
1565
|
+
cache map[string]map[types.Object]bool,
|
|
1566
|
+
declFiles map[types.Object]string,
|
|
1567
|
+
) map[types.Object]bool {
|
|
1568
|
+
if semPkg == nil {
|
|
1569
|
+
return nil
|
|
1570
|
+
}
|
|
1571
|
+
if cache == nil {
|
|
1572
|
+
if declFiles == nil {
|
|
1573
|
+
declFiles = packageDeclFiles(semPkg)
|
|
1574
|
+
}
|
|
1575
|
+
return o.lazyPackageVars(semPkg, declFiles)
|
|
1576
|
+
}
|
|
1577
|
+
if lazy, ok := cache[semPkg.pkgPath]; ok {
|
|
1578
|
+
return lazy
|
|
1579
|
+
}
|
|
1580
|
+
if declFiles == nil {
|
|
1581
|
+
declFiles = packageDeclFiles(semPkg)
|
|
1582
|
+
}
|
|
1583
|
+
lazy := o.lazyPackageVars(semPkg, declFiles)
|
|
1584
|
+
cache[semPkg.pkgPath] = lazy
|
|
1585
|
+
return lazy
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1426
1588
|
func (o *LoweringOwner) lazyPackageVars(semPkg *semanticPackage, declFiles map[types.Object]string) map[types.Object]bool {
|
|
1427
1589
|
if semPkg == nil || semPkg.source == nil {
|
|
1428
1590
|
return nil
|
|
@@ -1589,7 +1751,7 @@ func (o *LoweringOwner) packageVarIsLazy(ctx lowerFileContext, obj *types.Var) b
|
|
|
1589
1751
|
if semPkg == nil {
|
|
1590
1752
|
return false
|
|
1591
1753
|
}
|
|
1592
|
-
for lazyObj := range o.
|
|
1754
|
+
for lazyObj := range o.packageLazyVars(semPkg, ctx.lazyPackageVarsByPkg, nil) {
|
|
1593
1755
|
if lazyObj != nil && lazyObj.Name() == obj.Name() &&
|
|
1594
1756
|
lazyObj.Pkg() != nil && lazyObj.Pkg().Path() == obj.Pkg().Path() {
|
|
1595
1757
|
return true
|
|
@@ -1606,7 +1768,7 @@ func (o *LoweringOwner) packageVarNameIsLazy(ctx lowerFileContext, pkgPath, name
|
|
|
1606
1768
|
if semPkg == nil {
|
|
1607
1769
|
return false
|
|
1608
1770
|
}
|
|
1609
|
-
for lazyObj := range o.
|
|
1771
|
+
for lazyObj := range o.packageLazyVars(semPkg, ctx.lazyPackageVarsByPkg, nil) {
|
|
1610
1772
|
if lazyObj != nil && lazyObj.Name() == name {
|
|
1611
1773
|
return true
|
|
1612
1774
|
}
|
|
@@ -2010,16 +2172,17 @@ func goEmbedPatterns(groups ...*ast.CommentGroup) []string {
|
|
|
2010
2172
|
|
|
2011
2173
|
func (o *LoweringOwner) lowerGoEmbedValue(
|
|
2012
2174
|
ctx lowerFileContext,
|
|
2175
|
+
diagPos token.Pos,
|
|
2013
2176
|
typ types.Type,
|
|
2014
2177
|
patterns []string,
|
|
2015
2178
|
) (string, []Diagnostic) {
|
|
2016
2179
|
if isEmbedFSType(typ) {
|
|
2017
|
-
return o.lowerGoEmbedFSValue(ctx, patterns)
|
|
2180
|
+
return o.lowerGoEmbedFSValue(ctx, diagPos, patterns)
|
|
2018
2181
|
}
|
|
2019
2182
|
if len(patterns) != 1 {
|
|
2020
|
-
return "", []Diagnostic{
|
|
2183
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2021
2184
|
}
|
|
2022
|
-
cleanPattern, diagnostics := cleanGoEmbedFilePattern(ctx, patterns[0])
|
|
2185
|
+
cleanPattern, diagnostics := cleanGoEmbedFilePattern(ctx, diagPos, patterns[0])
|
|
2023
2186
|
if len(diagnostics) != 0 {
|
|
2024
2187
|
return "", diagnostics
|
|
2025
2188
|
}
|
|
@@ -2033,7 +2196,7 @@ func (o *LoweringOwner) lowerGoEmbedValue(
|
|
|
2033
2196
|
if slice, ok := types.Unalias(typ).Underlying().(*types.Slice); ok && isByteType(slice.Elem()) {
|
|
2034
2197
|
return byteSliceLiteral(data), nil
|
|
2035
2198
|
}
|
|
2036
|
-
diag :=
|
|
2199
|
+
diag := loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed target type")
|
|
2037
2200
|
diag.Detail = "target type: " + types.TypeString(typ, func(pkg *types.Package) string {
|
|
2038
2201
|
if pkg == nil {
|
|
2039
2202
|
return ""
|
|
@@ -2043,18 +2206,18 @@ func (o *LoweringOwner) lowerGoEmbedValue(
|
|
|
2043
2206
|
return "", []Diagnostic{diag}
|
|
2044
2207
|
}
|
|
2045
2208
|
|
|
2046
|
-
func (o *LoweringOwner) lowerGoEmbedFSValue(ctx lowerFileContext, patterns []string) (string, []Diagnostic) {
|
|
2209
|
+
func (o *LoweringOwner) lowerGoEmbedFSValue(ctx lowerFileContext, diagPos token.Pos, patterns []string) (string, []Diagnostic) {
|
|
2047
2210
|
embedAlias := ctx.importPaths["embed"]
|
|
2048
2211
|
if embedAlias == "" {
|
|
2049
|
-
return "", []Diagnostic{
|
|
2212
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed FS import")}
|
|
2050
2213
|
}
|
|
2051
2214
|
if len(patterns) == 0 {
|
|
2052
|
-
return "", []Diagnostic{
|
|
2215
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2053
2216
|
}
|
|
2054
2217
|
|
|
2055
2218
|
filesByPath := make(map[string][]byte)
|
|
2056
2219
|
for _, pattern := range patterns {
|
|
2057
|
-
files, diagnostics := expandGoEmbedPattern(ctx, pattern)
|
|
2220
|
+
files, diagnostics := expandGoEmbedPattern(ctx, diagPos, pattern)
|
|
2058
2221
|
if len(diagnostics) != 0 {
|
|
2059
2222
|
return "", diagnostics
|
|
2060
2223
|
}
|
|
@@ -2080,25 +2243,25 @@ type goEmbedFile struct {
|
|
|
2080
2243
|
data []byte
|
|
2081
2244
|
}
|
|
2082
2245
|
|
|
2083
|
-
func cleanGoEmbedFilePattern(ctx lowerFileContext, pattern string) (string, []Diagnostic) {
|
|
2084
|
-
cleanPattern, _, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2246
|
+
func cleanGoEmbedFilePattern(ctx lowerFileContext, diagPos token.Pos, pattern string) (string, []Diagnostic) {
|
|
2247
|
+
cleanPattern, _, diagnostics := cleanGoEmbedPattern(ctx, diagPos, pattern)
|
|
2085
2248
|
if len(diagnostics) != 0 {
|
|
2086
2249
|
return "", diagnostics
|
|
2087
2250
|
}
|
|
2088
2251
|
if strings.Contains(cleanPattern, "*") {
|
|
2089
|
-
return "", []Diagnostic{
|
|
2252
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2090
2253
|
}
|
|
2091
2254
|
info, err := os.Stat(filepath.Join(filepath.Dir(ctx.sourcePath), filepath.FromSlash(cleanPattern)))
|
|
2092
2255
|
if err != nil {
|
|
2093
2256
|
return "", []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2094
2257
|
}
|
|
2095
2258
|
if info.IsDir() {
|
|
2096
|
-
return "", []Diagnostic{
|
|
2259
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed directory target")}
|
|
2097
2260
|
}
|
|
2098
2261
|
return cleanPattern, nil
|
|
2099
2262
|
}
|
|
2100
2263
|
|
|
2101
|
-
func cleanGoEmbedPattern(ctx lowerFileContext, pattern string) (string, bool, []Diagnostic) {
|
|
2264
|
+
func cleanGoEmbedPattern(ctx lowerFileContext, diagPos token.Pos, pattern string) (string, bool, []Diagnostic) {
|
|
2102
2265
|
pattern = strings.Trim(pattern, "`\"")
|
|
2103
2266
|
all := false
|
|
2104
2267
|
if strings.HasPrefix(pattern, "all:") {
|
|
@@ -2111,13 +2274,13 @@ func cleanGoEmbedPattern(ctx lowerFileContext, pattern string) (string, bool, []
|
|
|
2111
2274
|
cleanPattern == "." ||
|
|
2112
2275
|
cleanPattern == ".." ||
|
|
2113
2276
|
strings.HasPrefix(cleanPattern, "../") {
|
|
2114
|
-
return "", false, []Diagnostic{
|
|
2277
|
+
return "", false, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2115
2278
|
}
|
|
2116
2279
|
return cleanPattern, all, nil
|
|
2117
2280
|
}
|
|
2118
2281
|
|
|
2119
|
-
func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile, []Diagnostic) {
|
|
2120
|
-
cleanPattern, all, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2282
|
+
func expandGoEmbedPattern(ctx lowerFileContext, diagPos token.Pos, pattern string) ([]goEmbedFile, []Diagnostic) {
|
|
2283
|
+
cleanPattern, all, diagnostics := cleanGoEmbedPattern(ctx, diagPos, pattern)
|
|
2121
2284
|
if len(diagnostics) != 0 {
|
|
2122
2285
|
return nil, diagnostics
|
|
2123
2286
|
}
|
|
@@ -2126,17 +2289,17 @@ func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile,
|
|
|
2126
2289
|
if strings.Contains(cleanPattern, "*") {
|
|
2127
2290
|
matches, err := filepath.Glob(filepath.Join(pkgDir, filepath.FromSlash(cleanPattern)))
|
|
2128
2291
|
if err != nil {
|
|
2129
|
-
return nil, []Diagnostic{
|
|
2292
|
+
return nil, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2130
2293
|
}
|
|
2131
2294
|
if len(matches) == 0 {
|
|
2132
|
-
return nil, []Diagnostic{
|
|
2295
|
+
return nil, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "go:embed pattern matched no files")}
|
|
2133
2296
|
}
|
|
2134
2297
|
paths = matches
|
|
2135
2298
|
}
|
|
2136
2299
|
|
|
2137
2300
|
var files []goEmbedFile
|
|
2138
2301
|
for _, path := range paths {
|
|
2139
|
-
collected, diagnostics := collectGoEmbedPath(ctx, pkgDir, path, all)
|
|
2302
|
+
collected, diagnostics := collectGoEmbedPath(ctx, diagPos, pkgDir, path, all)
|
|
2140
2303
|
if len(diagnostics) != 0 {
|
|
2141
2304
|
return nil, diagnostics
|
|
2142
2305
|
}
|
|
@@ -2148,7 +2311,7 @@ func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile,
|
|
|
2148
2311
|
return files, nil
|
|
2149
2312
|
}
|
|
2150
2313
|
|
|
2151
|
-
func collectGoEmbedPath(ctx lowerFileContext, pkgDir, absPath string, all bool) ([]goEmbedFile, []Diagnostic) {
|
|
2314
|
+
func collectGoEmbedPath(ctx lowerFileContext, diagPos token.Pos, pkgDir, absPath string, all bool) ([]goEmbedFile, []Diagnostic) {
|
|
2152
2315
|
info, err := os.Stat(absPath)
|
|
2153
2316
|
if err != nil {
|
|
2154
2317
|
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
@@ -2185,7 +2348,7 @@ func collectGoEmbedPath(ctx lowerFileContext, pkgDir, absPath string, all bool)
|
|
|
2185
2348
|
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2186
2349
|
}
|
|
2187
2350
|
if len(files) == 0 {
|
|
2188
|
-
return nil, []Diagnostic{
|
|
2351
|
+
return nil, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "go:embed directory matched no files")}
|
|
2189
2352
|
}
|
|
2190
2353
|
return files, nil
|
|
2191
2354
|
}
|
|
@@ -2306,7 +2469,7 @@ func (o *LoweringOwner) lowerInterfaceType(ctx lowerFileContext, semType *semant
|
|
|
2306
2469
|
}
|
|
2307
2470
|
code = code + "\n\n" + o.runtimeOwner.QualifiedHelper(RuntimeHelperRegisterInterfaceType) +
|
|
2308
2471
|
"(\n\t" + strconv.Quote(runtimeNamedTypeName(semType.named)) +
|
|
2309
|
-
",\n\tnull,\n\t" + o.runtimeMethodSignatures(iface) + "\n)"
|
|
2472
|
+
",\n\tnull,\n\t" + o.runtimeMethodSignatures(iface) + "\n);"
|
|
2310
2473
|
return loweredDecl{code: code, typeIndexExport: typeIndexExport, sideEffect: true}
|
|
2311
2474
|
}
|
|
2312
2475
|
|
|
@@ -2387,12 +2550,13 @@ func (o *LoweringOwner) runtimeMethodReturns(tuple *types.Tuple, seen map[types.
|
|
|
2387
2550
|
|
|
2388
2551
|
func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticType) (*loweredStruct, []Diagnostic) {
|
|
2389
2552
|
lowered := &loweredStruct{
|
|
2390
|
-
exported:
|
|
2391
|
-
indexExported:
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2553
|
+
exported: ctx.topLevel,
|
|
2554
|
+
indexExported: ctx.topLevel && ast.IsExported(semType.name),
|
|
2555
|
+
protobufPreserveJSON: ctx.protobufTSAdapter && o.protobufTypeScriptAdapterPreserveJSON(ctx, semType, make(map[*types.Named]bool)),
|
|
2556
|
+
name: safeIdentifier(semType.name),
|
|
2557
|
+
typeName: runtimeNamedTypeName(semType.named),
|
|
2558
|
+
cloneMethod: "clone",
|
|
2559
|
+
fields: make([]loweredStructField, 0, len(semType.fields)),
|
|
2396
2560
|
}
|
|
2397
2561
|
for idx, field := range semType.fields {
|
|
2398
2562
|
structValue := isStructValueType(field.typ)
|
|
@@ -2412,6 +2576,11 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2412
2576
|
runtimeType: o.runtimeTypeInfoExpr(field.typ),
|
|
2413
2577
|
doc: field.doc,
|
|
2414
2578
|
tag: field.tag,
|
|
2579
|
+
pkgPath: field.pkgPath,
|
|
2580
|
+
index: field.index,
|
|
2581
|
+
offset: field.offset,
|
|
2582
|
+
anonymous: field.embedded,
|
|
2583
|
+
exported: field.exported,
|
|
2415
2584
|
structValue: structValue,
|
|
2416
2585
|
arrayValue: isArrayType(field.typ),
|
|
2417
2586
|
})
|
|
@@ -2429,7 +2598,17 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2429
2598
|
}
|
|
2430
2599
|
var diagnostics []Diagnostic
|
|
2431
2600
|
for _, methodDecl := range methodDecls {
|
|
2432
|
-
|
|
2601
|
+
lowerDecl := methodDecl
|
|
2602
|
+
methodSourcePath := sourcePos(ctx.semPkg.source, methodDecl.Pos()).file
|
|
2603
|
+
if ctx.protobufTSAdapter &&
|
|
2604
|
+
methodSourcePath == ctx.sourcePath &&
|
|
2605
|
+
protobufTypeScriptBindingReplacesMethodName(methodDecl.Name.Name) &&
|
|
2606
|
+
!(lowered.protobufPreserveJSON && protobufTypeScriptBindingJSONMethodName(methodDecl.Name.Name)) {
|
|
2607
|
+
bodyless := *methodDecl
|
|
2608
|
+
bodyless.Body = nil
|
|
2609
|
+
lowerDecl = &bodyless
|
|
2610
|
+
}
|
|
2611
|
+
method, methodDiagnostics := o.lowerFuncDecl(ctx, lowerDecl)
|
|
2433
2612
|
diagnostics = append(diagnostics, methodDiagnostics...)
|
|
2434
2613
|
if method != nil {
|
|
2435
2614
|
if method.name == "clone" {
|
|
@@ -2445,6 +2624,133 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2445
2624
|
return lowered, diagnostics
|
|
2446
2625
|
}
|
|
2447
2626
|
|
|
2627
|
+
func (o *LoweringOwner) protobufTypeScriptAdapterPreserveJSON(
|
|
2628
|
+
ctx lowerFileContext,
|
|
2629
|
+
semType *semanticType,
|
|
2630
|
+
seen map[*types.Named]bool,
|
|
2631
|
+
) bool {
|
|
2632
|
+
if semType == nil || semType.named == nil {
|
|
2633
|
+
return false
|
|
2634
|
+
}
|
|
2635
|
+
named := semType.named.Origin()
|
|
2636
|
+
if named == nil || seen[named] {
|
|
2637
|
+
return false
|
|
2638
|
+
}
|
|
2639
|
+
seen[named] = true
|
|
2640
|
+
for _, methodDecl := range o.methodDeclsForType(ctx, named) {
|
|
2641
|
+
if methodDecl == nil || !protobufTypeScriptBindingJSONMethodName(methodDecl.Name.Name) {
|
|
2642
|
+
continue
|
|
2643
|
+
}
|
|
2644
|
+
if sourcePos(ctx.semPkg.source, methodDecl.Pos()).file != ctx.sourcePath {
|
|
2645
|
+
return true
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
for _, field := range semType.fields {
|
|
2649
|
+
if o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, field.typ, seen) {
|
|
2650
|
+
return true
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
return false
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
func (o *LoweringOwner) protobufTypeScriptAdapterTypeHasCustomJSON(
|
|
2657
|
+
ctx lowerFileContext,
|
|
2658
|
+
typ types.Type,
|
|
2659
|
+
seen map[*types.Named]bool,
|
|
2660
|
+
) bool {
|
|
2661
|
+
if typ == nil {
|
|
2662
|
+
return false
|
|
2663
|
+
}
|
|
2664
|
+
if alias, ok := typ.(*types.Alias); ok {
|
|
2665
|
+
if o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, alias.Rhs(), seen) {
|
|
2666
|
+
return true
|
|
2667
|
+
}
|
|
2668
|
+
if args := alias.TypeArgs(); args != nil {
|
|
2669
|
+
for t := range args.Types() {
|
|
2670
|
+
if o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, t, seen) {
|
|
2671
|
+
return true
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
return false
|
|
2676
|
+
}
|
|
2677
|
+
if named, ok := types.Unalias(typ).(*types.Named); ok {
|
|
2678
|
+
if o.protobufTypeScriptAdapterNamedTypeHasCustomJSON(ctx, named) {
|
|
2679
|
+
return true
|
|
2680
|
+
}
|
|
2681
|
+
if obj := named.Obj(); obj != nil && obj.Pkg() != nil && obj.Pkg().Path() == ctx.semPkg.pkgPath {
|
|
2682
|
+
semType := ctx.model.types[named]
|
|
2683
|
+
if semType == nil {
|
|
2684
|
+
semType = ctx.model.types[named.Origin()]
|
|
2685
|
+
}
|
|
2686
|
+
if semType != nil && o.protobufTypeScriptAdapterPreserveJSON(ctx, semType, seen) {
|
|
2687
|
+
return true
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
origin := named.Origin()
|
|
2691
|
+
if origin != nil {
|
|
2692
|
+
if seen[origin] {
|
|
2693
|
+
return false
|
|
2694
|
+
}
|
|
2695
|
+
seen[origin] = true
|
|
2696
|
+
}
|
|
2697
|
+
if args := named.TypeArgs(); args != nil {
|
|
2698
|
+
for t := range args.Types() {
|
|
2699
|
+
if o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, t, seen) {
|
|
2700
|
+
return true
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
if o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, named.Underlying(), seen) {
|
|
2705
|
+
return true
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2708
|
+
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
2709
|
+
case *types.Pointer:
|
|
2710
|
+
return o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, typed.Elem(), seen)
|
|
2711
|
+
case *types.Slice:
|
|
2712
|
+
return o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, typed.Elem(), seen)
|
|
2713
|
+
case *types.Array:
|
|
2714
|
+
return o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, typed.Elem(), seen)
|
|
2715
|
+
case *types.Map:
|
|
2716
|
+
return o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, typed.Key(), seen) ||
|
|
2717
|
+
o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, typed.Elem(), seen)
|
|
2718
|
+
case *types.Struct:
|
|
2719
|
+
for field := range typed.Fields() {
|
|
2720
|
+
if o.protobufTypeScriptAdapterTypeHasCustomJSON(ctx, field.Type(), seen) {
|
|
2721
|
+
return true
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
return false
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
func (o *LoweringOwner) protobufTypeScriptAdapterNamedTypeHasCustomJSON(
|
|
2729
|
+
ctx lowerFileContext,
|
|
2730
|
+
named *types.Named,
|
|
2731
|
+
) bool {
|
|
2732
|
+
if named == nil {
|
|
2733
|
+
return false
|
|
2734
|
+
}
|
|
2735
|
+
methodSet := types.NewMethodSet(types.NewPointer(named))
|
|
2736
|
+
for _, name := range []string{"MarshalJSON", "MarshalProtoJSON", "UnmarshalJSON", "UnmarshalProtoJSON"} {
|
|
2737
|
+
selection := methodSet.Lookup(nil, name)
|
|
2738
|
+
if selection == nil {
|
|
2739
|
+
continue
|
|
2740
|
+
}
|
|
2741
|
+
method, ok := selection.Obj().(*types.Func)
|
|
2742
|
+
if !ok {
|
|
2743
|
+
continue
|
|
2744
|
+
}
|
|
2745
|
+
sourcePath := sourcePos(ctx.semPkg.source, method.Pos()).file
|
|
2746
|
+
if sourcePath == "" || strings.HasSuffix(sourcePath, ".pb.go") {
|
|
2747
|
+
continue
|
|
2748
|
+
}
|
|
2749
|
+
return true
|
|
2750
|
+
}
|
|
2751
|
+
return false
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2448
2754
|
func (o *LoweringOwner) lowerEmbeddedMethodForwarders(
|
|
2449
2755
|
ctx lowerFileContext,
|
|
2450
2756
|
field semanticField,
|
|
@@ -2481,11 +2787,13 @@ func (o *LoweringOwner) lowerEmbeddedMethodForwarders(
|
|
|
2481
2787
|
async := o.functionAsync(ctx, method)
|
|
2482
2788
|
targetType := o.tsEmbeddedForwarderTargetType(ctx, field.typ)
|
|
2483
2789
|
lowered := loweredFunction{
|
|
2484
|
-
async:
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2790
|
+
async: async,
|
|
2791
|
+
sourcePath: ctx.sourcePath,
|
|
2792
|
+
name: methodMemberName(method.Name()),
|
|
2793
|
+
runtimeName: method.Name(),
|
|
2794
|
+
runtimeSignature: o.runtimeMethodSignature(method, make(map[types.Type]bool)),
|
|
2795
|
+
result: asyncResultType("any", async),
|
|
2796
|
+
deferState: &loweredDeferState{},
|
|
2489
2797
|
}
|
|
2490
2798
|
args := make([]string, 0, signature.Params().Len())
|
|
2491
2799
|
for idx := range signature.Params().Len() {
|
|
@@ -2624,6 +2932,7 @@ func (o *LoweringOwner) lowerNamedReceiverMethodDecl(
|
|
|
2624
2932
|
exported: ctx.topLevel,
|
|
2625
2933
|
indexExported: ctx.topLevel && (ast.IsExported(receiver.Obj().Name()) || ast.IsExported(decl.Name.Name)),
|
|
2626
2934
|
async: async,
|
|
2935
|
+
sourcePath: sourcePos(ctx.semPkg.source, decl.Pos()).file,
|
|
2627
2936
|
name: methodFunctionName(receiver, decl.Name.Name),
|
|
2628
2937
|
result: asyncResultType(result, async),
|
|
2629
2938
|
deferState: deferState,
|
|
@@ -2698,12 +3007,16 @@ func (o *LoweringOwner) lowerFuncDecl(ctx lowerFileContext, decl *ast.FuncDecl)
|
|
|
2698
3007
|
indexExported: ctx.topLevel && !blankName && !initFunc && (ast.IsExported(decl.Name.Name) || decl.Name.Name == "main"),
|
|
2699
3008
|
init: initFunc,
|
|
2700
3009
|
async: async,
|
|
3010
|
+
sourcePath: sourcePos(ctx.semPkg.source, decl.Pos()).file,
|
|
2701
3011
|
name: name,
|
|
2702
3012
|
runtimeName: runtimeName,
|
|
2703
3013
|
result: asyncResultType(result, async),
|
|
2704
3014
|
deferState: deferState,
|
|
2705
3015
|
namedResults: o.lowerNamedResults(functionCtx, signature),
|
|
2706
3016
|
}
|
|
3017
|
+
if decl.Recv != nil {
|
|
3018
|
+
lowered.runtimeSignature = o.runtimeMethodSignature(fnObj, make(map[types.Type]bool))
|
|
3019
|
+
}
|
|
2707
3020
|
if signature.TypeParams() != nil && signature.TypeParams().Len() != 0 {
|
|
2708
3021
|
lowered.typeParams = signatureTypeParamNames(signature)
|
|
2709
3022
|
lowered.params = append(lowered.params, loweredParam{
|
|
@@ -2846,6 +3159,9 @@ func expressionUsesObject(ctx lowerFileContext, expr ast.Expr, obj types.Object)
|
|
|
2846
3159
|
if expr == nil || obj == nil || ctx.semPkg == nil || ctx.semPkg.source == nil {
|
|
2847
3160
|
return false
|
|
2848
3161
|
}
|
|
3162
|
+
if ident, ok := ast.Unparen(expr).(*ast.Ident); ok {
|
|
3163
|
+
return ctx.semPkg.source.TypesInfo.Uses[ident] == obj || ctx.semPkg.source.TypesInfo.Defs[ident] == obj
|
|
3164
|
+
}
|
|
2849
3165
|
uses := false
|
|
2850
3166
|
ast.Inspect(expr, func(node ast.Node) bool {
|
|
2851
3167
|
if uses {
|
|
@@ -2925,9 +3241,22 @@ func (ctx lowerFileContext) withDeferState(deferState *loweredDeferState) lowerF
|
|
|
2925
3241
|
|
|
2926
3242
|
func (ctx lowerFileContext) withLocalScope() lowerFileContext {
|
|
2927
3243
|
ctx.topLevel = false
|
|
3244
|
+
ctx.functionScopedDecls = false
|
|
3245
|
+
return ctx
|
|
3246
|
+
}
|
|
3247
|
+
|
|
3248
|
+
func (ctx lowerFileContext) withFunctionScopedDecls() lowerFileContext {
|
|
3249
|
+
ctx.functionScopedDecls = true
|
|
2928
3250
|
return ctx
|
|
2929
3251
|
}
|
|
2930
3252
|
|
|
3253
|
+
func declarationKeyword(ctx lowerFileContext) string {
|
|
3254
|
+
if ctx.functionScopedDecls {
|
|
3255
|
+
return "var "
|
|
3256
|
+
}
|
|
3257
|
+
return "let "
|
|
3258
|
+
}
|
|
3259
|
+
|
|
2931
3260
|
func (ctx lowerFileContext) withRangeBranch(branch *loweredRangeBranch) lowerFileContext {
|
|
2932
3261
|
ctx.rangeBranch = branch
|
|
2933
3262
|
ctx.rangeBreak = true
|
|
@@ -3015,6 +3344,10 @@ func (o *LoweringOwner) lowerBlock(ctx lowerFileContext, block *ast.BlockStmt) (
|
|
|
3015
3344
|
}
|
|
3016
3345
|
|
|
3017
3346
|
func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]loweredStmt, []Diagnostic) {
|
|
3347
|
+
return o.lowerStmtInto(ctx, stmt, nil)
|
|
3348
|
+
}
|
|
3349
|
+
|
|
3350
|
+
func (o *LoweringOwner) lowerStmtInto(ctx lowerFileContext, stmt ast.Stmt, out []loweredStmt) ([]loweredStmt, []Diagnostic) {
|
|
3018
3351
|
switch typed := stmt.(type) {
|
|
3019
3352
|
case *ast.DeclStmt:
|
|
3020
3353
|
decls, diagnostics := o.lowerDecl(ctx, typed.Decl)
|
|
@@ -3030,27 +3363,28 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
3030
3363
|
stmts = append(stmts, loweredStmt{text: strings.TrimRight(b.String(), "\n")})
|
|
3031
3364
|
}
|
|
3032
3365
|
}
|
|
3033
|
-
return stmts, diagnostics
|
|
3366
|
+
return append(out, stmts...), diagnostics
|
|
3034
3367
|
case *ast.BlockStmt:
|
|
3035
3368
|
body, diagnostics := o.lowerBlock(ctx, typed)
|
|
3036
|
-
return
|
|
3369
|
+
return append(out, loweredStmt{hasBlock: true, children: body}), diagnostics
|
|
3037
3370
|
case *ast.AssignStmt:
|
|
3038
|
-
|
|
3371
|
+
stmts, diagnostics := o.lowerAssignStmt(ctx, typed)
|
|
3372
|
+
return append(out, stmts...), diagnostics
|
|
3039
3373
|
case *ast.SendStmt:
|
|
3040
3374
|
text, diagnostics := o.lowerSendStmt(ctx, typed)
|
|
3041
|
-
return
|
|
3375
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
3042
3376
|
case *ast.GoStmt:
|
|
3043
3377
|
text, diagnostics := o.lowerGoStmt(ctx, typed)
|
|
3044
|
-
return
|
|
3378
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
3045
3379
|
case *ast.DeferStmt:
|
|
3046
3380
|
text, diagnostics := o.lowerDeferStmt(ctx, typed)
|
|
3047
|
-
return
|
|
3381
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
3048
3382
|
case *ast.ExprStmt:
|
|
3049
3383
|
text, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
3050
|
-
return
|
|
3384
|
+
return append(out, loweredStmt{text: expressionStmtText(text)}), diagnostics
|
|
3051
3385
|
case *ast.ReturnStmt:
|
|
3052
3386
|
text, diagnostics := o.lowerReturnStmt(ctx, typed)
|
|
3053
|
-
return
|
|
3387
|
+
return append(out, loweredStmt{text: text}), diagnostics
|
|
3054
3388
|
case *ast.IfStmt:
|
|
3055
3389
|
var diagnostics []Diagnostic
|
|
3056
3390
|
var init []loweredStmt
|
|
@@ -3083,39 +3417,43 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
3083
3417
|
}
|
|
3084
3418
|
if len(init) != 0 {
|
|
3085
3419
|
init = append(init, stmt)
|
|
3086
|
-
|
|
3420
|
+
initPrelude = append(initPrelude, loweredStmt{children: init})
|
|
3421
|
+
return append(out, initPrelude...), diagnostics
|
|
3087
3422
|
}
|
|
3088
|
-
return
|
|
3423
|
+
return append(out, stmt), diagnostics
|
|
3089
3424
|
case *ast.ForStmt:
|
|
3090
3425
|
lowered, diagnostics := o.lowerForStmt(ctx, typed)
|
|
3091
|
-
return
|
|
3426
|
+
return append(out, lowered), diagnostics
|
|
3092
3427
|
case *ast.RangeStmt:
|
|
3093
3428
|
lowered, diagnostics := o.lowerRangeStmt(ctx, typed)
|
|
3094
|
-
return
|
|
3429
|
+
return append(out, lowered), diagnostics
|
|
3095
3430
|
case *ast.SelectStmt:
|
|
3096
3431
|
lowered, diagnostics := o.lowerSelectStmt(ctx, typed)
|
|
3097
|
-
return
|
|
3432
|
+
return append(out, loweredStmt{selectStmt: lowered}), diagnostics
|
|
3098
3433
|
case *ast.SwitchStmt:
|
|
3099
|
-
|
|
3434
|
+
stmts, diagnostics := o.lowerSwitchStmt(ctx, typed)
|
|
3435
|
+
return append(out, stmts...), diagnostics
|
|
3100
3436
|
case *ast.TypeSwitchStmt:
|
|
3101
|
-
|
|
3437
|
+
stmts, diagnostics := o.lowerTypeSwitchStmt(ctx, typed)
|
|
3438
|
+
return append(out, stmts...), diagnostics
|
|
3102
3439
|
case *ast.LabeledStmt:
|
|
3103
3440
|
lowered, diagnostics := o.lowerStmt(ctx, typed.Stmt)
|
|
3104
3441
|
if len(lowered) != 0 {
|
|
3105
3442
|
label := safeIdentifier(typed.Label.Name)
|
|
3106
3443
|
if lowered[0].text == "" {
|
|
3107
|
-
return
|
|
3444
|
+
return append(out, loweredStmt{text: label + ":", children: lowered}), diagnostics
|
|
3108
3445
|
}
|
|
3109
3446
|
if labeledTextCannotPrefix(lowered[0].text) {
|
|
3110
|
-
|
|
3447
|
+
out = append(out, loweredStmt{text: label + ":;"})
|
|
3448
|
+
return append(out, lowered...), diagnostics
|
|
3111
3449
|
}
|
|
3112
3450
|
lowered[0].text = label + ": " + lowered[0].text
|
|
3113
3451
|
}
|
|
3114
|
-
return lowered, diagnostics
|
|
3452
|
+
return append(out, lowered...), diagnostics
|
|
3115
3453
|
case *ast.IncDecStmt:
|
|
3116
3454
|
if star, ok := unwrapParenExpr(typed.X).(*ast.StarExpr); ok {
|
|
3117
3455
|
expr, diagnostics := o.lowerPointerStorageExpr(ctx, star.X)
|
|
3118
|
-
return
|
|
3456
|
+
return append(out, loweredStmt{text: expr + typed.Tok.String()}), diagnostics
|
|
3119
3457
|
}
|
|
3120
3458
|
if index, ok := unwrapParenExpr(typed.X).(*ast.IndexExpr); ok && isMapType(ctx.semPkg.source.TypesInfo.TypeOf(index.X)) {
|
|
3121
3459
|
right := "1"
|
|
@@ -3123,7 +3461,8 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
3123
3461
|
if typed.Tok == token.DEC {
|
|
3124
3462
|
tok = token.SUB_ASSIGN
|
|
3125
3463
|
}
|
|
3126
|
-
|
|
3464
|
+
stmts, diagnostics := o.lowerMapIndexUpdateStmts(ctx, index, tok, right, ctx.semPkg.source.TypesInfo.TypeOf(typed.X))
|
|
3465
|
+
return append(out, stmts...), diagnostics
|
|
3127
3466
|
}
|
|
3128
3467
|
if setter, ok := o.packageVarSetterForAssignment(ctx, typed.X); ok {
|
|
3129
3468
|
expr, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
@@ -3131,58 +3470,58 @@ func (o *LoweringOwner) lowerStmt(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
3131
3470
|
if typed.Tok == token.DEC {
|
|
3132
3471
|
op = "-"
|
|
3133
3472
|
}
|
|
3134
|
-
return
|
|
3473
|
+
return append(out, loweredStmt{text: setter + "(" + expr + " " + op + " 1)"}), diagnostics
|
|
3135
3474
|
}
|
|
3136
3475
|
expr, diagnostics := o.lowerExpr(ctx, typed.X)
|
|
3137
|
-
return
|
|
3476
|
+
return append(out, loweredStmt{text: expr + typed.Tok.String()}), diagnostics
|
|
3138
3477
|
case *ast.BranchStmt:
|
|
3139
3478
|
if typed.Label != nil {
|
|
3140
3479
|
switch typed.Tok {
|
|
3141
3480
|
case token.BREAK, token.CONTINUE:
|
|
3142
|
-
return
|
|
3481
|
+
return append(out, loweredStmt{text: typed.Tok.String() + " " + safeIdentifier(typed.Label.Name)}), nil
|
|
3143
3482
|
case token.GOTO:
|
|
3144
3483
|
label := safeIdentifier(typed.Label.Name)
|
|
3145
3484
|
if ctx.gotoStateLabels[label] {
|
|
3146
|
-
return
|
|
3147
|
-
{text: ctx.gotoStateVar + " = " + strconv.Quote(label)},
|
|
3148
|
-
{text: "continue " + ctx.gotoStateLoop},
|
|
3149
|
-
|
|
3485
|
+
return append(out,
|
|
3486
|
+
loweredStmt{text: ctx.gotoStateVar + " = " + strconv.Quote(label)},
|
|
3487
|
+
loweredStmt{text: "continue " + ctx.gotoStateLoop},
|
|
3488
|
+
), nil
|
|
3150
3489
|
}
|
|
3151
3490
|
if ctx.forwardGotos[label] {
|
|
3152
|
-
return
|
|
3491
|
+
return append(out, loweredStmt{text: "break " + label}), nil
|
|
3153
3492
|
}
|
|
3154
3493
|
if ctx.gotoLabels[label] {
|
|
3155
|
-
return
|
|
3494
|
+
return append(out, loweredStmt{text: "continue " + label}), nil
|
|
3156
3495
|
}
|
|
3157
|
-
return
|
|
3496
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported goto branch to "+label)}
|
|
3158
3497
|
default:
|
|
3159
|
-
return
|
|
3498
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported labeled branch")}
|
|
3160
3499
|
}
|
|
3161
3500
|
}
|
|
3162
3501
|
switch typed.Tok {
|
|
3163
3502
|
case token.BREAK, token.CONTINUE:
|
|
3164
3503
|
if typed.Tok == token.BREAK && ctx.loopLabel != "" && !ctx.switchBreak {
|
|
3165
|
-
return
|
|
3504
|
+
return append(out, loweredStmt{text: "break " + ctx.loopLabel}), nil
|
|
3166
3505
|
}
|
|
3167
3506
|
if typed.Tok == token.CONTINUE && ctx.loopLabel != "" {
|
|
3168
|
-
return
|
|
3507
|
+
return append(out, loweredStmt{text: "continue " + ctx.loopLabel}), nil
|
|
3169
3508
|
}
|
|
3170
3509
|
if typed.Tok == token.BREAK && ctx.rangeBranch != nil && ctx.rangeBreak {
|
|
3171
|
-
return
|
|
3510
|
+
return append(out, loweredStmt{text: "return false"}), nil
|
|
3172
3511
|
}
|
|
3173
3512
|
if typed.Tok == token.CONTINUE && ctx.rangeBranch != nil && ctx.rangeContinue {
|
|
3174
|
-
return
|
|
3513
|
+
return append(out, loweredStmt{text: "return true"}), nil
|
|
3175
3514
|
}
|
|
3176
|
-
return
|
|
3515
|
+
return append(out, loweredStmt{text: typed.Tok.String()}), nil
|
|
3177
3516
|
case token.FALLTHROUGH:
|
|
3178
|
-
return
|
|
3517
|
+
return append(out, loweredStmt{text: "fallthrough"}), nil
|
|
3179
3518
|
default:
|
|
3180
|
-
return
|
|
3519
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported branch")}
|
|
3181
3520
|
}
|
|
3182
3521
|
case *ast.EmptyStmt:
|
|
3183
|
-
return
|
|
3522
|
+
return out, nil
|
|
3184
3523
|
default:
|
|
3185
|
-
return
|
|
3524
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported statement kind")}
|
|
3186
3525
|
}
|
|
3187
3526
|
}
|
|
3188
3527
|
|
|
@@ -3213,7 +3552,7 @@ func (o *LoweringOwner) lowerElse(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
3213
3552
|
case *ast.IfStmt:
|
|
3214
3553
|
return o.lowerStmt(ctx, typed)
|
|
3215
3554
|
default:
|
|
3216
|
-
return nil, []Diagnostic{
|
|
3555
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported else statement")}
|
|
3217
3556
|
}
|
|
3218
3557
|
}
|
|
3219
3558
|
|
|
@@ -3337,12 +3676,13 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
3337
3676
|
}
|
|
3338
3677
|
}
|
|
3339
3678
|
if stmtCtx, nextCtx, ok := o.lowerDeclStatementContext(ctx, stmt); ok {
|
|
3340
|
-
|
|
3679
|
+
start := len(lowered)
|
|
3680
|
+
var stmtDiagnostics []Diagnostic
|
|
3681
|
+
lowered, stmtDiagnostics = o.lowerStmtInto(stmtCtx, stmt, lowered)
|
|
3341
3682
|
diagnostics = append(diagnostics, stmtDiagnostics...)
|
|
3342
|
-
if len(
|
|
3343
|
-
|
|
3683
|
+
if len(lowered) > start && len(leading) != 0 {
|
|
3684
|
+
lowered[start].leading = append(leading, lowered[start].leading...)
|
|
3344
3685
|
}
|
|
3345
|
-
lowered = append(lowered, stmtLowered...)
|
|
3346
3686
|
ctx = nextCtx
|
|
3347
3687
|
if endLine := sourceLine(ctx, stmt.End()); endLine != 0 {
|
|
3348
3688
|
prevEndLine = endLine
|
|
@@ -3367,12 +3707,13 @@ func (o *LoweringOwner) lowerStmtListAfter(
|
|
|
3367
3707
|
}
|
|
3368
3708
|
continue
|
|
3369
3709
|
}
|
|
3370
|
-
|
|
3710
|
+
start := len(lowered)
|
|
3711
|
+
var stmtDiagnostics []Diagnostic
|
|
3712
|
+
lowered, stmtDiagnostics = o.lowerStmtInto(ctx, stmt, lowered)
|
|
3371
3713
|
diagnostics = append(diagnostics, stmtDiagnostics...)
|
|
3372
|
-
if len(
|
|
3373
|
-
|
|
3714
|
+
if len(lowered) > start && len(leading) != 0 {
|
|
3715
|
+
lowered[start].leading = append(leading, lowered[start].leading...)
|
|
3374
3716
|
}
|
|
3375
|
-
lowered = append(lowered, stmtLowered...)
|
|
3376
3717
|
if endLine := sourceLine(ctx, stmt.End()); endLine != 0 {
|
|
3377
3718
|
prevEndLine = endLine
|
|
3378
3719
|
}
|
|
@@ -3510,7 +3851,7 @@ func (o *LoweringOwner) lowerGotoStateCluster(
|
|
|
3510
3851
|
for _, label := range cluster.labels {
|
|
3511
3852
|
labels[label.name] = true
|
|
3512
3853
|
}
|
|
3513
|
-
stateCtx := ctx.withGotoState(labels, stateVar, loopLabel)
|
|
3854
|
+
stateCtx := ctx.withGotoState(labels, stateVar, loopLabel).withFunctionScopedDecls()
|
|
3514
3855
|
|
|
3515
3856
|
var diagnostics []Diagnostic
|
|
3516
3857
|
initialState := cluster.labels[0].name
|
|
@@ -3606,7 +3947,7 @@ func (o *LoweringOwner) lowerBackwardGotoLoop(
|
|
|
3606
3947
|
var lowered []loweredStmt
|
|
3607
3948
|
var body []loweredStmt
|
|
3608
3949
|
var diagnostics []Diagnostic
|
|
3609
|
-
bodyCtx := ctx.withGotoLabels(gotoLabels)
|
|
3950
|
+
bodyCtx := ctx.withGotoLabels(gotoLabels).withFunctionScopedDecls()
|
|
3610
3951
|
if initialForwardLabel != "" {
|
|
3611
3952
|
skipVar := ctx.tempName("Skip")
|
|
3612
3953
|
init := loweredStmt{text: "let " + skipVar + " = true"}
|
|
@@ -3896,7 +4237,7 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3896
4237
|
}
|
|
3897
4238
|
prefix := ""
|
|
3898
4239
|
if stmt.Tok == token.DEFINE {
|
|
3899
|
-
prefix =
|
|
4240
|
+
prefix = declarationKeyword(ctx)
|
|
3900
4241
|
if !allShortAssignTargetsNew(ctx, stmt.Lhs) || o.tupleDeclarationNeedsElementStatements(ctx, stmt) {
|
|
3901
4242
|
return o.lowerTupleReassignmentStmt(ctx, stmt, right, diagnostics)
|
|
3902
4243
|
}
|
|
@@ -3968,7 +4309,7 @@ func (o *LoweringOwner) lowerAssignStmt(ctx lowerFileContext, stmt *ast.AssignSt
|
|
|
3968
4309
|
if ident, ok := lhs.(*ast.Ident); ok {
|
|
3969
4310
|
right = o.lowerDeclaredValue(ctx, ident, right)
|
|
3970
4311
|
}
|
|
3971
|
-
stmts = append(stmts, loweredStmt{text:
|
|
4312
|
+
stmts = append(stmts, loweredStmt{text: declarationKeyword(ctx) + left + o.shortDeclTypeAnnotation(ctx, lhs, stmt.Rhs[idx]) + " = " + right})
|
|
3972
4313
|
continue
|
|
3973
4314
|
}
|
|
3974
4315
|
if helper, ok := wideIntegerAssignHelper(targetType, stmt.Tok); ok {
|
|
@@ -4146,7 +4487,7 @@ func (o *LoweringOwner) lowerChannelReceiveAssignStmt(
|
|
|
4146
4487
|
diagnostics = append(diagnostics, leftDiagnostics...)
|
|
4147
4488
|
prefix := ""
|
|
4148
4489
|
if stmt.Tok == token.DEFINE {
|
|
4149
|
-
prefix =
|
|
4490
|
+
prefix = declarationKeyword(ctx)
|
|
4150
4491
|
left += o.shortDeclTypeAnnotation(ctx, stmt.Lhs[0], nil)
|
|
4151
4492
|
value = o.lowerDeclaredValue(ctx, stmt.Lhs[0], value)
|
|
4152
4493
|
}
|
|
@@ -4207,7 +4548,8 @@ func isIdentLikeExpr(expr ast.Expr) bool {
|
|
|
4207
4548
|
func shortDeclNeedsTypeAnnotation(typ types.Type) bool {
|
|
4208
4549
|
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
4209
4550
|
case *types.Pointer:
|
|
4210
|
-
|
|
4551
|
+
_, pointsToArray := types.Unalias(typed.Elem()).Underlying().(*types.Array)
|
|
4552
|
+
return pointsToArray || namedStructType(typed.Elem()) != nil || namedNonStructType(typed.Elem()) != nil
|
|
4211
4553
|
case *types.Map:
|
|
4212
4554
|
return true
|
|
4213
4555
|
case *types.Slice:
|
|
@@ -4249,7 +4591,7 @@ func (o *LoweringOwner) lowerTupleTargetAssignmentStmt(
|
|
|
4249
4591
|
left, diagnostics := o.lowerAssignmentTarget(ctx, lhs, declare)
|
|
4250
4592
|
prefix := ""
|
|
4251
4593
|
if declare {
|
|
4252
|
-
prefix =
|
|
4594
|
+
prefix = declarationKeyword(ctx)
|
|
4253
4595
|
left += o.shortDeclTypeAnnotation(ctx, lhs, nil)
|
|
4254
4596
|
value = o.lowerDeclaredValue(ctx, lhs, value)
|
|
4255
4597
|
}
|
|
@@ -5439,7 +5781,7 @@ func (o *LoweringOwner) lowerRangeStmt(ctx lowerFileContext, stmt *ast.RangeStmt
|
|
|
5439
5781
|
if isFunctionType(rangeType) {
|
|
5440
5782
|
signature := rangeFunctionSignature(rangeType)
|
|
5441
5783
|
if signature == nil {
|
|
5442
|
-
return loweredStmt{}, append(diagnostics,
|
|
5784
|
+
return loweredStmt{}, append(diagnostics, loweringUnsupportedAt(ctx, stmt, "statement", ctx.semPkg.pkgPath, "unsupported function range signature"))
|
|
5443
5785
|
}
|
|
5444
5786
|
lowered, funcDiagnostics := o.lowerRangeFuncStmt(ctx, stmt, rangeValue, signature)
|
|
5445
5787
|
diagnostics = append(diagnostics, funcDiagnostics...)
|
|
@@ -5519,7 +5861,7 @@ func (o *LoweringOwner) lowerRangeFuncStmt(
|
|
|
5519
5861
|
) (loweredStmt, []Diagnostic) {
|
|
5520
5862
|
yieldSignature, ok := types.Unalias(signature.Params().At(0).Type()).Underlying().(*types.Signature)
|
|
5521
5863
|
if !ok {
|
|
5522
|
-
return loweredStmt{}, []Diagnostic{
|
|
5864
|
+
return loweredStmt{}, []Diagnostic{loweringUnsupportedAt(ctx, stmt, "statement", ctx.semPkg.pkgPath, "unsupported function range yield signature")}
|
|
5523
5865
|
}
|
|
5524
5866
|
keyName := rangeKeyName(stmt.Key)
|
|
5525
5867
|
valueName := rangeKeyName(stmt.Value)
|
|
@@ -5602,7 +5944,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
5602
5944
|
for _, raw := range stmt.Body.List {
|
|
5603
5945
|
clause, ok := raw.(*ast.CommClause)
|
|
5604
5946
|
if !ok {
|
|
5605
|
-
diagnostics = append(diagnostics,
|
|
5947
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, raw, "statement", ctx.semPkg.pkgPath, "unsupported select clause"))
|
|
5606
5948
|
continue
|
|
5607
5949
|
}
|
|
5608
5950
|
switch comm := clause.Comm.(type) {
|
|
@@ -5655,7 +5997,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
5655
5997
|
})
|
|
5656
5998
|
caseID++
|
|
5657
5999
|
default:
|
|
5658
|
-
diagnostics = append(diagnostics,
|
|
6000
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, comm, "statement", ctx.semPkg.pkgPath, "unsupported select communication"))
|
|
5659
6001
|
}
|
|
5660
6002
|
}
|
|
5661
6003
|
lowered.returns = selectCasesReturn(lowered.cases)
|
|
@@ -5759,7 +6101,7 @@ func (o *LoweringOwner) lowerSelectReceiveComm(
|
|
|
5759
6101
|
}
|
|
5760
6102
|
receive, ok := receiveExpr.(*ast.UnaryExpr)
|
|
5761
6103
|
if !ok || receive.Op != token.ARROW {
|
|
5762
|
-
return "null", nil, []Diagnostic{
|
|
6104
|
+
return "null", nil, []Diagnostic{loweringUnsupportedAt(ctx, receiveExpr, "statement", ctx.semPkg.pkgPath, "unsupported select receive")}
|
|
5763
6105
|
}
|
|
5764
6106
|
channel, diagnostics := o.lowerExpr(ctx, receive.X)
|
|
5765
6107
|
if assign == nil {
|
|
@@ -5817,7 +6159,7 @@ func (o *LoweringOwner) lowerSwitchStmt(ctx lowerFileContext, stmt *ast.SwitchSt
|
|
|
5817
6159
|
for _, raw := range stmt.Body.List {
|
|
5818
6160
|
clause, ok := raw.(*ast.CaseClause)
|
|
5819
6161
|
if !ok {
|
|
5820
|
-
diagnostics = append(diagnostics,
|
|
6162
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, raw, "statement", ctx.semPkg.pkgPath, "unsupported switch clause"))
|
|
5821
6163
|
continue
|
|
5822
6164
|
}
|
|
5823
6165
|
bodyStmts := clause.Body
|
|
@@ -5912,7 +6254,7 @@ func (o *LoweringOwner) lowerTypeSwitchStmt(ctx lowerFileContext, stmt *ast.Type
|
|
|
5912
6254
|
valueExpr, varName, varRef, assignDiagnostics := o.lowerTypeSwitchAssign(ctx, stmt.Assign)
|
|
5913
6255
|
diagnostics = append(diagnostics, assignDiagnostics...)
|
|
5914
6256
|
if valueExpr == "" {
|
|
5915
|
-
return lowered, append(diagnostics,
|
|
6257
|
+
return lowered, append(diagnostics, loweringUnsupportedAt(ctx, stmt.Assign, "statement", ctx.semPkg.pkgPath, "unsupported type switch assignment"))
|
|
5916
6258
|
}
|
|
5917
6259
|
|
|
5918
6260
|
switchIR := &loweredTypeSwitch{
|
|
@@ -5923,7 +6265,7 @@ func (o *LoweringOwner) lowerTypeSwitchStmt(ctx lowerFileContext, stmt *ast.Type
|
|
|
5923
6265
|
for _, clauseStmt := range stmt.Body.List {
|
|
5924
6266
|
clause, ok := clauseStmt.(*ast.CaseClause)
|
|
5925
6267
|
if !ok {
|
|
5926
|
-
diagnostics = append(diagnostics,
|
|
6268
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, clauseStmt, "statement", ctx.semPkg.pkgPath, "unsupported type switch clause"))
|
|
5927
6269
|
continue
|
|
5928
6270
|
}
|
|
5929
6271
|
body, bodyDiagnostics := o.lowerStmtList(ctx.withoutRangeBreak().withSwitchBreak(), clause.Body)
|
|
@@ -6359,13 +6701,21 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6359
6701
|
return lowerPrefixUnaryExpr(typed.Op, value), diagnostics
|
|
6360
6702
|
}
|
|
6361
6703
|
if typed.Op == token.XOR {
|
|
6362
|
-
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok
|
|
6363
|
-
|
|
6364
|
-
|
|
6704
|
+
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok {
|
|
6705
|
+
if bits <= 32 {
|
|
6706
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
6707
|
+
"(~" + value + ", " + strconv.Itoa(bits) + ")", diagnostics
|
|
6708
|
+
}
|
|
6709
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Xor) +
|
|
6710
|
+
"(" + value + ", -1n)", diagnostics
|
|
6711
|
+
}
|
|
6712
|
+
if bits, ok := signedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok && bits > 32 {
|
|
6713
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperInt64Xor) +
|
|
6714
|
+
"(" + value + ", -1n)", diagnostics
|
|
6365
6715
|
}
|
|
6366
6716
|
return "~" + value, diagnostics
|
|
6367
6717
|
}
|
|
6368
|
-
return value, append(diagnostics,
|
|
6718
|
+
return value, append(diagnostics, loweringUnsupportedAt(ctx, typed, "expression", ctx.semPkg.pkgPath, "unsupported unary operator"))
|
|
6369
6719
|
case *ast.StarExpr:
|
|
6370
6720
|
return o.lowerPointerValueExpr(ctx, typed.X)
|
|
6371
6721
|
case *ast.ParenExpr:
|
|
@@ -6389,7 +6739,7 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6389
6739
|
case *ast.IndexListExpr:
|
|
6390
6740
|
return o.lowerExpr(ctx, typed.X)
|
|
6391
6741
|
default:
|
|
6392
|
-
return "undefined", []Diagnostic{
|
|
6742
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, typed, "expression", ctx.semPkg.pkgPath, "unsupported expression kind")}
|
|
6393
6743
|
}
|
|
6394
6744
|
}
|
|
6395
6745
|
|
|
@@ -6755,7 +7105,7 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
6755
7105
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperRecover) + "(" + strings.Join(args, ", ") + ")", diagnostics
|
|
6756
7106
|
case "close":
|
|
6757
7107
|
if len(args) != 1 {
|
|
6758
|
-
return "undefined", append(diagnostics,
|
|
7108
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "close requires one argument"))
|
|
6759
7109
|
}
|
|
6760
7110
|
return args[0] + "!.close()", diagnostics
|
|
6761
7111
|
}
|
|
@@ -6852,9 +7202,9 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
6852
7202
|
call := o.lowerCallableExpr(ctx, expr.Fun, callee) + "(" + strings.Join(args, ", ") + ")"
|
|
6853
7203
|
return o.awaitCallIfNeeded(ctx, expr.Fun, call), append(diagnostics, calleeDiagnostics...)
|
|
6854
7204
|
}
|
|
6855
|
-
return "undefined", append(diagnostics,
|
|
7205
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr.Fun, "call", ctx.semPkg.pkgPath, fmt.Sprintf("unsupported call target %T", expr.Fun)))
|
|
6856
7206
|
}
|
|
6857
|
-
return "undefined", append(diagnostics,
|
|
7207
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr.Fun, "call", ctx.semPkg.pkgPath, fmt.Sprintf("unsupported call target %T", expr.Fun)))
|
|
6858
7208
|
}
|
|
6859
7209
|
|
|
6860
7210
|
func (o *LoweringOwner) lowerCallableExpr(ctx lowerFileContext, expr ast.Expr, callee string) string {
|
|
@@ -7143,11 +7493,11 @@ func unsafePackageFunction(ctx lowerFileContext, expr ast.Expr, name string) boo
|
|
|
7143
7493
|
|
|
7144
7494
|
func (o *LoweringOwner) lowerMakeExpr(ctx lowerFileContext, expr *ast.CallExpr) (string, []Diagnostic) {
|
|
7145
7495
|
if len(expr.Args) < 1 {
|
|
7146
|
-
return "undefined", []Diagnostic{
|
|
7496
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "make requires a type argument")}
|
|
7147
7497
|
}
|
|
7148
7498
|
targetType := typeFromExpr(ctx, expr.Args[0])
|
|
7149
7499
|
if targetType == nil {
|
|
7150
|
-
return "undefined", []Diagnostic{
|
|
7500
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr.Args[0], "call", ctx.semPkg.pkgPath, "make requires a type expression")}
|
|
7151
7501
|
}
|
|
7152
7502
|
switch typed := types.Unalias(targetType).Underlying().(type) {
|
|
7153
7503
|
case *types.Slice:
|
|
@@ -7200,13 +7550,13 @@ func (o *LoweringOwner) lowerMakeExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
7200
7550
|
"<" + o.tsTypeFor(ctx, typed.Elem()) + ">(" + capacity + ", " +
|
|
7201
7551
|
o.lowerZeroValueExprFor(ctx, typed.Elem()) + ", " + strconv.Quote(channelDirectionString(typed.Dir())) + ")", diagnostics
|
|
7202
7552
|
default:
|
|
7203
|
-
return "undefined", []Diagnostic{
|
|
7553
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr.Args[0], "call", ctx.semPkg.pkgPath, "unsupported make type")}
|
|
7204
7554
|
}
|
|
7205
7555
|
}
|
|
7206
7556
|
|
|
7207
7557
|
func (o *LoweringOwner) lowerNewExpr(ctx lowerFileContext, expr *ast.CallExpr) (string, []Diagnostic) {
|
|
7208
7558
|
if len(expr.Args) != 1 {
|
|
7209
|
-
return "undefined", []Diagnostic{
|
|
7559
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "new requires one type argument")}
|
|
7210
7560
|
}
|
|
7211
7561
|
typ := typeFromExpr(ctx, expr.Args[0])
|
|
7212
7562
|
if named := namedStructType(typ); named != nil {
|
|
@@ -7222,7 +7572,7 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7222
7572
|
targetType types.Type,
|
|
7223
7573
|
) (string, []Diagnostic) {
|
|
7224
7574
|
if len(expr.Args) != 1 {
|
|
7225
|
-
return "undefined", []Diagnostic{
|
|
7575
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "unsupported conversion arity")}
|
|
7226
7576
|
}
|
|
7227
7577
|
value, diagnostics := o.lowerExpr(ctx, expr.Args[0])
|
|
7228
7578
|
sourceType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Args[0])
|
|
@@ -7317,8 +7667,10 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7317
7667
|
}
|
|
7318
7668
|
}
|
|
7319
7669
|
if named := namedFunctionType(targetType); named != nil {
|
|
7670
|
+
typeName := runtimeNamedTypeName(named)
|
|
7320
7671
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperNamedFunction) +
|
|
7321
|
-
"(" + value + ", " + strconv.Quote(
|
|
7672
|
+
"(" + value + ", " + strconv.Quote(typeName) + ", " +
|
|
7673
|
+
o.runtimeFunctionTypeInfo(named.Underlying().(*types.Signature), typeName) + ")", diagnostics
|
|
7322
7674
|
}
|
|
7323
7675
|
if named := namedNonStructType(targetType); named != nil {
|
|
7324
7676
|
if _, ok := named.Underlying().(*types.Slice); ok {
|
|
@@ -8191,7 +8543,7 @@ func (o *LoweringOwner) lowerAddressExpr(ctx lowerFileContext, expr ast.Expr) (s
|
|
|
8191
8543
|
case *ast.IndexExpr:
|
|
8192
8544
|
return o.lowerIndexAddressExpr(ctx, typed)
|
|
8193
8545
|
default:
|
|
8194
|
-
return "undefined", []Diagnostic{
|
|
8546
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, typed, "expression", ctx.semPkg.pkgPath, "unsupported address expression")}
|
|
8195
8547
|
}
|
|
8196
8548
|
}
|
|
8197
8549
|
|
|
@@ -8250,7 +8602,7 @@ func (o *LoweringOwner) lowerIndexAddressExpr(ctx lowerFileContext, expr *ast.In
|
|
|
8250
8602
|
diagnostics := append(targetDiagnostics, indexDiagnostics...)
|
|
8251
8603
|
targetType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
8252
8604
|
if isStringType(targetType) || isMapType(targetType) {
|
|
8253
|
-
return "undefined", append(diagnostics,
|
|
8605
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr, "expression", ctx.semPkg.pkgPath, "unsupported address expression"))
|
|
8254
8606
|
}
|
|
8255
8607
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperIndexRef) + "(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ")", diagnostics
|
|
8256
8608
|
}
|
|
@@ -8278,7 +8630,7 @@ func (o *LoweringOwner) lowerUnsafePointerIntegerExpr(
|
|
|
8278
8630
|
if !ok || len(call.Args) != 1 || !isUnsafePointerType(typeFromExpr(ctx, call.Fun)) {
|
|
8279
8631
|
return "", nil, false
|
|
8280
8632
|
}
|
|
8281
|
-
return o.
|
|
8633
|
+
return o.lowerIndexByteAddressIntegerExpr(ctx, call.Args[0])
|
|
8282
8634
|
}
|
|
8283
8635
|
|
|
8284
8636
|
func (o *LoweringOwner) lowerIndexAddressIntegerExpr(
|
|
@@ -8304,6 +8656,30 @@ func (o *LoweringOwner) lowerIndexAddressIntegerExpr(
|
|
|
8304
8656
|
"(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ")", diagnostics, true
|
|
8305
8657
|
}
|
|
8306
8658
|
|
|
8659
|
+
func (o *LoweringOwner) lowerIndexByteAddressIntegerExpr(
|
|
8660
|
+
ctx lowerFileContext,
|
|
8661
|
+
expr ast.Expr,
|
|
8662
|
+
) (string, []Diagnostic, bool) {
|
|
8663
|
+
address, ok := unwrapParenExpr(expr).(*ast.UnaryExpr)
|
|
8664
|
+
if !ok || address.Op != token.AND {
|
|
8665
|
+
return "", nil, false
|
|
8666
|
+
}
|
|
8667
|
+
indexExpr, ok := unwrapParenExpr(address.X).(*ast.IndexExpr)
|
|
8668
|
+
if !ok {
|
|
8669
|
+
return "", nil, false
|
|
8670
|
+
}
|
|
8671
|
+
target, targetDiagnostics := o.lowerExpr(ctx, indexExpr.X)
|
|
8672
|
+
index, indexDiagnostics := o.lowerExpr(ctx, indexExpr.Index)
|
|
8673
|
+
diagnostics := append(targetDiagnostics, indexDiagnostics...)
|
|
8674
|
+
targetType := ctx.semPkg.source.TypesInfo.TypeOf(indexExpr.X)
|
|
8675
|
+
if isStringType(targetType) || isMapType(targetType) {
|
|
8676
|
+
return "", diagnostics, false
|
|
8677
|
+
}
|
|
8678
|
+
elementSize := goScriptElementByteSize(ctx, indexElementType(targetType))
|
|
8679
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperIndexByteAddress) +
|
|
8680
|
+
"(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ", " + strconv.FormatInt(elementSize, 10) + ")", diagnostics, true
|
|
8681
|
+
}
|
|
8682
|
+
|
|
8307
8683
|
func (o *LoweringOwner) lowerPointerValueExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
8308
8684
|
if value, diagnostics, ok := o.lowerUnsafeStringPointerValue(ctx, expr); ok {
|
|
8309
8685
|
return value, diagnostics
|
|
@@ -8311,6 +8687,12 @@ func (o *LoweringOwner) lowerPointerValueExpr(ctx lowerFileContext, expr ast.Exp
|
|
|
8311
8687
|
if value, diagnostics, ok := o.lowerUnsafeStringByteSlicePointerValue(ctx, expr); ok {
|
|
8312
8688
|
return value, diagnostics
|
|
8313
8689
|
}
|
|
8690
|
+
if ref, diagnostics, ok := o.lowerUnsafeArrayPointerRefExpr(ctx, expr); ok {
|
|
8691
|
+
return ref + ".value", diagnostics
|
|
8692
|
+
}
|
|
8693
|
+
if ref, diagnostics, ok := o.lowerUnsafePointerRefExpr(ctx, expr); ok {
|
|
8694
|
+
return ref + ".value", diagnostics
|
|
8695
|
+
}
|
|
8314
8696
|
base, diagnostics := o.lowerExpr(ctx, expr)
|
|
8315
8697
|
typeArg := ""
|
|
8316
8698
|
if pointer, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(expr)).Underlying().(*types.Pointer); ok {
|
|
@@ -8442,8 +8824,13 @@ func (o *LoweringOwner) lowerUnsafeArrayPointerConversion(
|
|
|
8442
8824
|
return "", nil, false
|
|
8443
8825
|
}
|
|
8444
8826
|
ref, diagnostics := o.lowerAddressExpr(ctx, index)
|
|
8827
|
+
sourceElementSize := goScriptElementByteSize(ctx, indexElementType(ctx.semPkg.source.TypesInfo.TypeOf(index.X)))
|
|
8828
|
+
targetElementSize := goScriptElementByteSize(ctx, array.Elem())
|
|
8445
8829
|
helper := o.runtimeOwner.QualifiedHelper(RuntimeHelperArrayPointerFromIndexRef) +
|
|
8446
|
-
"<" + o.tsTypeFor(ctx, array.Elem()) + ">(" + ref + ", " +
|
|
8830
|
+
"<" + o.tsTypeFor(ctx, array.Elem()) + ">(" + ref + ", " +
|
|
8831
|
+
strconv.FormatInt(array.Len(), 10) + ", " +
|
|
8832
|
+
strconv.FormatInt(sourceElementSize, 10) + ", " +
|
|
8833
|
+
strconv.FormatInt(targetElementSize, 10) + ")"
|
|
8447
8834
|
return "(" + helper + " as unknown as " + o.tsTypeFor(ctx, targetType) + ")", diagnostics, true
|
|
8448
8835
|
}
|
|
8449
8836
|
|
|
@@ -8537,6 +8924,12 @@ func sameLoweredSourceExpr(ctx lowerFileContext, left ast.Expr, right ast.Expr)
|
|
|
8537
8924
|
}
|
|
8538
8925
|
|
|
8539
8926
|
func (o *LoweringOwner) lowerPointerStorageExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
8927
|
+
if ref, diagnostics, ok := o.lowerUnsafeArrayPointerRefExpr(ctx, expr); ok {
|
|
8928
|
+
return ref + ".value", diagnostics
|
|
8929
|
+
}
|
|
8930
|
+
if ref, diagnostics, ok := o.lowerUnsafePointerRefExpr(ctx, expr); ok {
|
|
8931
|
+
return ref + ".value", diagnostics
|
|
8932
|
+
}
|
|
8540
8933
|
if ref, diagnostics, ok := o.lowerUnsafePointerStorageExpr(ctx, expr); ok {
|
|
8541
8934
|
return ref, diagnostics
|
|
8542
8935
|
}
|
|
@@ -8544,6 +8937,42 @@ func (o *LoweringOwner) lowerPointerStorageExpr(ctx lowerFileContext, expr ast.E
|
|
|
8544
8937
|
return base + "!.value", diagnostics
|
|
8545
8938
|
}
|
|
8546
8939
|
|
|
8940
|
+
func (o *LoweringOwner) lowerUnsafeArrayPointerRefExpr(
|
|
8941
|
+
ctx lowerFileContext,
|
|
8942
|
+
expr ast.Expr,
|
|
8943
|
+
) (string, []Diagnostic, bool) {
|
|
8944
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
8945
|
+
if !ok || len(call.Args) != 1 {
|
|
8946
|
+
return "", nil, false
|
|
8947
|
+
}
|
|
8948
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
8949
|
+
if targetType == nil {
|
|
8950
|
+
return "", nil, false
|
|
8951
|
+
}
|
|
8952
|
+
return o.lowerUnsafeArrayPointerConversion(ctx, targetType, call.Args[0])
|
|
8953
|
+
}
|
|
8954
|
+
|
|
8955
|
+
func (o *LoweringOwner) lowerUnsafePointerRefExpr(
|
|
8956
|
+
ctx lowerFileContext,
|
|
8957
|
+
expr ast.Expr,
|
|
8958
|
+
) (string, []Diagnostic, bool) {
|
|
8959
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
8960
|
+
if !ok || len(call.Args) != 1 {
|
|
8961
|
+
return "", nil, false
|
|
8962
|
+
}
|
|
8963
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
8964
|
+
if targetType == nil {
|
|
8965
|
+
return "", nil, false
|
|
8966
|
+
}
|
|
8967
|
+
pointer, _ := types.Unalias(targetType).Underlying().(*types.Pointer)
|
|
8968
|
+
if pointer == nil || !isUnsafePointerType(ctx.semPkg.source.TypesInfo.TypeOf(call.Args[0])) {
|
|
8969
|
+
return "", nil, false
|
|
8970
|
+
}
|
|
8971
|
+
value, diagnostics := o.lowerExpr(ctx, call.Args[0])
|
|
8972
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUnsafePointerRef) +
|
|
8973
|
+
"<" + o.tsTypeFor(ctx, pointer.Elem()) + ">(" + value + ")", diagnostics, true
|
|
8974
|
+
}
|
|
8975
|
+
|
|
8547
8976
|
func (o *LoweringOwner) lowerUnsafePointerStorageExpr(
|
|
8548
8977
|
ctx lowerFileContext,
|
|
8549
8978
|
expr ast.Expr,
|
|
@@ -8713,15 +9142,11 @@ func (o *LoweringOwner) lowerCompositeLit(
|
|
|
8713
9142
|
if mapType, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(lit)).Underlying().(*types.Map); ok {
|
|
8714
9143
|
return o.lowerMapCompositeLit(ctx, lit, mapType)
|
|
8715
9144
|
}
|
|
8716
|
-
position := sourcePos(ctx.semPkg.source, lit.Pos())
|
|
8717
9145
|
detail := "unsupported composite literal"
|
|
8718
|
-
if position.file != "" {
|
|
8719
|
-
detail += " at " + filepath.Base(position.file) + ":" + strconv.Itoa(position.line)
|
|
8720
|
-
}
|
|
8721
9146
|
if typ := ctx.semPkg.source.TypesInfo.TypeOf(lit); typ != nil {
|
|
8722
9147
|
detail += " of type " + typ.String()
|
|
8723
9148
|
}
|
|
8724
|
-
return "undefined", []Diagnostic{
|
|
9149
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, lit, "expression", ctx.semPkg.pkgPath, detail)}
|
|
8725
9150
|
}
|
|
8726
9151
|
|
|
8727
9152
|
func (o *LoweringOwner) lowerStructCompositeLit(
|
|
@@ -8756,7 +9181,7 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
8756
9181
|
fieldType = field.Type()
|
|
8757
9182
|
}
|
|
8758
9183
|
if fieldName == "" {
|
|
8759
|
-
diagnostics = append(diagnostics,
|
|
9184
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, elt, "expression", ctx.semPkg.pkgPath, "unsupported struct literal field"))
|
|
8760
9185
|
continue
|
|
8761
9186
|
}
|
|
8762
9187
|
value, valueDiagnostics := o.lowerExpr(ctx, valueExpr)
|
|
@@ -8867,7 +9292,7 @@ func (o *LoweringOwner) lowerAnonymousStructCompositeLit(
|
|
|
8867
9292
|
fieldType = field.Type()
|
|
8868
9293
|
}
|
|
8869
9294
|
if fieldName == "" {
|
|
8870
|
-
diagnostics = append(diagnostics,
|
|
9295
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, elt, "expression", ctx.semPkg.pkgPath, "unsupported anonymous struct literal field"))
|
|
8871
9296
|
continue
|
|
8872
9297
|
}
|
|
8873
9298
|
value, valueDiagnostics := o.lowerExpr(ctx, valueExpr)
|
|
@@ -8976,7 +9401,7 @@ func (o *LoweringOwner) lowerMapCompositeLit(
|
|
|
8976
9401
|
for _, elt := range lit.Elts {
|
|
8977
9402
|
keyed, ok := elt.(*ast.KeyValueExpr)
|
|
8978
9403
|
if !ok {
|
|
8979
|
-
diagnostics = append(diagnostics,
|
|
9404
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, elt, "expression", ctx.semPkg.pkgPath, "unsupported map literal entry"))
|
|
8980
9405
|
continue
|
|
8981
9406
|
}
|
|
8982
9407
|
key, keyDiagnostics := o.lowerExpr(ctx, keyed.Key)
|
|
@@ -9444,7 +9869,7 @@ func (o *LoweringOwner) shallowRuntimeTypeInfoExpr(typ types.Type) string {
|
|
|
9444
9869
|
case *types.Pointer:
|
|
9445
9870
|
return "{ kind: " + typeKind + ".Pointer, elemType: { kind: " + typeKind + ".Basic, name: \"unknown\" } }"
|
|
9446
9871
|
case *types.Struct:
|
|
9447
|
-
return "{ kind: " + typeKind + ".Struct, methods: [], fields:
|
|
9872
|
+
return "{ kind: " + typeKind + ".Struct, methods: [], fields: [] }"
|
|
9448
9873
|
case *types.Slice:
|
|
9449
9874
|
return "{ kind: " + typeKind + ".Slice, elemType: { kind: " + typeKind + ".Basic, name: \"unknown\" } }"
|
|
9450
9875
|
case *types.Array:
|
|
@@ -9460,6 +9885,11 @@ func (o *LoweringOwner) shallowRuntimeTypeInfoExpr(typ types.Type) string {
|
|
|
9460
9885
|
|
|
9461
9886
|
func (o *LoweringOwner) runtimeStructFieldsExpr(structType *types.Struct, seen map[types.Type]bool) string {
|
|
9462
9887
|
fields := make([]string, 0, structType.NumFields())
|
|
9888
|
+
var vars []*types.Var
|
|
9889
|
+
for field := range structType.Fields() {
|
|
9890
|
+
vars = append(vars, field)
|
|
9891
|
+
}
|
|
9892
|
+
offsets := structFieldOffsets(goScriptTypeSizes(), vars)
|
|
9463
9893
|
for idx := range structType.NumFields() {
|
|
9464
9894
|
field := structType.Field(idx)
|
|
9465
9895
|
fieldName := tsStructFieldName(field.Name(), idx)
|
|
@@ -9467,30 +9897,71 @@ func (o *LoweringOwner) runtimeStructFieldsExpr(structType *types.Struct, seen m
|
|
|
9467
9897
|
if fieldName != field.Name() {
|
|
9468
9898
|
runtimeName = field.Name()
|
|
9469
9899
|
}
|
|
9900
|
+
pkgPath := ""
|
|
9901
|
+
if !field.Exported() && field.Pkg() != nil {
|
|
9902
|
+
pkgPath = field.Pkg().Path()
|
|
9903
|
+
}
|
|
9470
9904
|
fieldInfo := runtimeStructFieldInfoExpr(
|
|
9471
9905
|
o.runtimeTypeInfoExprWithSeen(field.Type(), seen),
|
|
9906
|
+
fieldName,
|
|
9472
9907
|
runtimeName,
|
|
9473
9908
|
structType.Tag(idx),
|
|
9909
|
+
pkgPath,
|
|
9910
|
+
field.Embedded(),
|
|
9911
|
+
[]int{idx},
|
|
9912
|
+
offsets[idx],
|
|
9913
|
+
field.Exported(),
|
|
9474
9914
|
)
|
|
9475
|
-
fields = append(fields,
|
|
9915
|
+
fields = append(fields, fieldInfo)
|
|
9476
9916
|
}
|
|
9477
|
-
return "
|
|
9917
|
+
return "[" + strings.Join(fields, ", ") + "]"
|
|
9478
9918
|
}
|
|
9479
9919
|
|
|
9480
|
-
func runtimeStructFieldInfoExpr(
|
|
9481
|
-
|
|
9482
|
-
|
|
9920
|
+
func runtimeStructFieldInfoExpr(
|
|
9921
|
+
runtimeType string,
|
|
9922
|
+
storageKey string,
|
|
9923
|
+
runtimeName string,
|
|
9924
|
+
tag string,
|
|
9925
|
+
pkgPath string,
|
|
9926
|
+
anonymous bool,
|
|
9927
|
+
index []int,
|
|
9928
|
+
offset int64,
|
|
9929
|
+
exported bool,
|
|
9930
|
+
) string {
|
|
9931
|
+
name := runtimeName
|
|
9932
|
+
if name == "" {
|
|
9933
|
+
name = storageKey
|
|
9934
|
+
}
|
|
9935
|
+
fields := []string{
|
|
9936
|
+
"name: " + strconv.Quote(name),
|
|
9937
|
+
"key: " + strconv.Quote(storageKey),
|
|
9938
|
+
"type: " + runtimeType,
|
|
9483
9939
|
}
|
|
9484
|
-
fields := []string{"type: " + runtimeType}
|
|
9485
9940
|
if runtimeName != "" {
|
|
9486
|
-
fields = append(fields, "
|
|
9941
|
+
fields = append(fields, "pkgPath: "+strconv.Quote(pkgPath))
|
|
9942
|
+
} else if pkgPath != "" {
|
|
9943
|
+
fields = append(fields, "pkgPath: "+strconv.Quote(pkgPath))
|
|
9487
9944
|
}
|
|
9488
9945
|
if tag != "" {
|
|
9489
9946
|
fields = append(fields, "tag: "+strconv.Quote(tag))
|
|
9490
9947
|
}
|
|
9948
|
+
if anonymous {
|
|
9949
|
+
fields = append(fields, "anonymous: true")
|
|
9950
|
+
}
|
|
9951
|
+
fields = append(fields, "index: "+runtimeStructFieldIndexExpr(index))
|
|
9952
|
+
fields = append(fields, "offset: "+strconv.FormatInt(offset, 10))
|
|
9953
|
+
fields = append(fields, "exported: "+strconv.FormatBool(exported))
|
|
9491
9954
|
return "{ " + strings.Join(fields, ", ") + " }"
|
|
9492
9955
|
}
|
|
9493
9956
|
|
|
9957
|
+
func runtimeStructFieldIndexExpr(index []int) string {
|
|
9958
|
+
values := make([]string, 0, len(index))
|
|
9959
|
+
for _, value := range index {
|
|
9960
|
+
values = append(values, strconv.Itoa(value))
|
|
9961
|
+
}
|
|
9962
|
+
return "[" + strings.Join(values, ", ") + "]"
|
|
9963
|
+
}
|
|
9964
|
+
|
|
9494
9965
|
func (o *LoweringOwner) runtimeFunctionTypeInfo(signature *types.Signature, name string) string {
|
|
9495
9966
|
return o.runtimeFunctionTypeInfoWithSeen(signature, name, make(map[types.Type]bool))
|
|
9496
9967
|
}
|
|
@@ -10172,6 +10643,42 @@ func isMapType(typ types.Type) bool {
|
|
|
10172
10643
|
return ok
|
|
10173
10644
|
}
|
|
10174
10645
|
|
|
10646
|
+
func indexElementType(typ types.Type) types.Type {
|
|
10647
|
+
if pointer, ok := types.Unalias(typ).Underlying().(*types.Pointer); ok {
|
|
10648
|
+
typ = pointer.Elem()
|
|
10649
|
+
}
|
|
10650
|
+
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
10651
|
+
case *types.Slice:
|
|
10652
|
+
return typed.Elem()
|
|
10653
|
+
case *types.Array:
|
|
10654
|
+
return typed.Elem()
|
|
10655
|
+
default:
|
|
10656
|
+
return nil
|
|
10657
|
+
}
|
|
10658
|
+
}
|
|
10659
|
+
|
|
10660
|
+
func goScriptElementByteSize(ctx lowerFileContext, typ types.Type) int64 {
|
|
10661
|
+
if typ == nil {
|
|
10662
|
+
return 1
|
|
10663
|
+
}
|
|
10664
|
+
if sizes := ctx.semPkg.source.TypesSizes; sizes != nil {
|
|
10665
|
+
if size := sizes.Sizeof(typ); size > 0 {
|
|
10666
|
+
return size
|
|
10667
|
+
}
|
|
10668
|
+
}
|
|
10669
|
+
if bits, ok := integerBits(typ); ok && bits > 0 {
|
|
10670
|
+
return int64((bits + 7) / 8)
|
|
10671
|
+
}
|
|
10672
|
+
if isFloatType(typ) {
|
|
10673
|
+
basic, _ := types.Unalias(typ).Underlying().(*types.Basic)
|
|
10674
|
+
if basic != nil && basic.Kind() == types.Float32 {
|
|
10675
|
+
return 4
|
|
10676
|
+
}
|
|
10677
|
+
return 8
|
|
10678
|
+
}
|
|
10679
|
+
return 1
|
|
10680
|
+
}
|
|
10681
|
+
|
|
10175
10682
|
func isChannelType(typ types.Type) bool {
|
|
10176
10683
|
if typ == nil {
|
|
10177
10684
|
return false
|
|
@@ -10245,6 +10752,9 @@ func isFloatType(typ types.Type) bool {
|
|
|
10245
10752
|
}
|
|
10246
10753
|
|
|
10247
10754
|
func unsignedIntegerBits(typ types.Type) (int, bool) {
|
|
10755
|
+
if typ == nil {
|
|
10756
|
+
return 0, false
|
|
10757
|
+
}
|
|
10248
10758
|
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
10249
10759
|
if !ok || basic.Info()&types.IsUnsigned == 0 {
|
|
10250
10760
|
return 0, false
|
|
@@ -10262,6 +10772,9 @@ func unsignedIntegerBits(typ types.Type) (int, bool) {
|
|
|
10262
10772
|
}
|
|
10263
10773
|
|
|
10264
10774
|
func signedIntegerBits(typ types.Type) (int, bool) {
|
|
10775
|
+
if typ == nil {
|
|
10776
|
+
return 0, false
|
|
10777
|
+
}
|
|
10265
10778
|
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
10266
10779
|
if !ok || basic.Info()&types.IsInteger == 0 || basic.Info()&types.IsUnsigned != 0 {
|
|
10267
10780
|
return 0, false
|
|
@@ -10609,16 +11122,28 @@ func (o *LoweringOwner) genericTypeDescriptorExpr(ctx lowerFileContext, typ type
|
|
|
10609
11122
|
}
|
|
10610
11123
|
if methods := o.genericMethodDescriptors(ctx, typ); methods != "" {
|
|
10611
11124
|
parts = append(parts, "methods: "+methods)
|
|
11125
|
+
if signatures := o.genericMethodSignatureDescriptors(typ); signatures != "" &&
|
|
11126
|
+
genericTypeDescriptorNeedsMethodSignatures(typ) {
|
|
11127
|
+
parts = append(parts, "methodSignatures: "+signatures)
|
|
11128
|
+
}
|
|
10612
11129
|
}
|
|
10613
11130
|
return "{ " + strings.Join(parts, ", ") + " }"
|
|
10614
11131
|
}
|
|
10615
11132
|
|
|
11133
|
+
func genericTypeDescriptorNeedsMethodSignatures(typ types.Type) bool {
|
|
11134
|
+
named, _ := genericMethodSetDescriptorTarget(typ)
|
|
11135
|
+
if named == nil {
|
|
11136
|
+
return false
|
|
11137
|
+
}
|
|
11138
|
+
return namedStructType(named) == nil && !isInterfaceType(named)
|
|
11139
|
+
}
|
|
11140
|
+
|
|
10616
11141
|
func (o *LoweringOwner) genericMethodDescriptors(ctx lowerFileContext, typ types.Type) string {
|
|
10617
|
-
named,
|
|
11142
|
+
named, methodSetType := genericMethodSetDescriptorTarget(typ)
|
|
10618
11143
|
if named == nil {
|
|
10619
11144
|
return ""
|
|
10620
11145
|
}
|
|
10621
|
-
return o.genericMethodDescriptorsForType(ctx, named,
|
|
11146
|
+
return o.genericMethodDescriptorsForType(ctx, named, methodSetType)
|
|
10622
11147
|
}
|
|
10623
11148
|
|
|
10624
11149
|
func (o *LoweringOwner) genericMethodDescriptorsForType(
|
|
@@ -10659,6 +11184,33 @@ func (o *LoweringOwner) genericMethodDescriptorsForType(
|
|
|
10659
11184
|
return "{" + strings.Join(methods, ", ") + "}"
|
|
10660
11185
|
}
|
|
10661
11186
|
|
|
11187
|
+
func (o *LoweringOwner) genericMethodSignatureDescriptors(typ types.Type) string {
|
|
11188
|
+
_, methodSetType := genericMethodSetDescriptorTarget(typ)
|
|
11189
|
+
if methodSetType == nil {
|
|
11190
|
+
return ""
|
|
11191
|
+
}
|
|
11192
|
+
methodSet := types.NewMethodSet(methodSetType)
|
|
11193
|
+
methods := make([]string, 0, methodSet.Len())
|
|
11194
|
+
for method := range methodSet.Methods() {
|
|
11195
|
+
fn, _ := method.Obj().(*types.Func)
|
|
11196
|
+
if fn != nil {
|
|
11197
|
+
methods = append(methods, o.runtimeMethodSignature(fn, make(map[types.Type]bool)))
|
|
11198
|
+
}
|
|
11199
|
+
}
|
|
11200
|
+
if len(methods) == 0 {
|
|
11201
|
+
return ""
|
|
11202
|
+
}
|
|
11203
|
+
return "[" + strings.Join(methods, ", ") + "]"
|
|
11204
|
+
}
|
|
11205
|
+
|
|
11206
|
+
func genericMethodSetDescriptorTarget(typ types.Type) (*types.Named, types.Type) {
|
|
11207
|
+
named, _ := types.Unalias(typ).(*types.Named)
|
|
11208
|
+
if named == nil {
|
|
11209
|
+
return namedNonStructMethodSetType(typ)
|
|
11210
|
+
}
|
|
11211
|
+
return named, named
|
|
11212
|
+
}
|
|
11213
|
+
|
|
10662
11214
|
func namedNonStructMethodSetType(typ types.Type) (*types.Named, types.Type) {
|
|
10663
11215
|
if named := namedNonStructType(typ); named != nil {
|
|
10664
11216
|
return named, named
|