goscript 0.2.0 → 0.2.2
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/cmd/goscript-wasm/main.go +38 -6
- package/compiler/diagnostic.go +104 -12
- package/compiler/diagnostic_test.go +106 -0
- package/compiler/gotest/runner.go +99 -17
- package/compiler/gotest/runner_test.go +65 -0
- package/compiler/index.test.ts +23 -0
- package/compiler/lowered-program.go +9 -7
- package/compiler/lowering.go +361 -72
- package/compiler/lowering_bench_test.go +1 -0
- package/compiler/lowering_internal_test.go +18 -0
- package/compiler/protobuf-ts-binding.go +65 -12
- package/compiler/protobuf-ts-binding_test.go +339 -0
- package/compiler/runtime-contract.go +4 -0
- package/compiler/runtime-contract_test.go +2 -0
- package/compiler/service.go +1 -0
- package/compiler/skeleton_test.go +60 -3
- package/compiler/wasm/compile_test.go +37 -4
- package/compiler/wasm-api.go +57 -7
- package/dist/gs/builtin/hostio.js +6 -1
- package/dist/gs/builtin/hostio.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +11 -1
- package/dist/gs/builtin/slice.js +158 -2
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/crypto/aes/index.d.ts +15 -0
- package/dist/gs/crypto/aes/index.js +57 -0
- package/dist/gs/crypto/aes/index.js.map +1 -0
- package/dist/gs/crypto/cipher/index.d.ts +41 -0
- package/dist/gs/crypto/cipher/index.js +255 -0
- package/dist/gs/crypto/cipher/index.js.map +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +1 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +30 -5
- 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/golang.org/x/crypto/chacha20poly1305/index.d.ts +31 -0
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.js +117 -0
- package/dist/gs/golang.org/x/crypto/chacha20poly1305/index.js.map +1 -0
- package/dist/gs/internal/byteorder/index.js +2 -2
- package/dist/gs/internal/byteorder/index.js.map +1 -1
- package/dist/gs/io/io.js +18 -2
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/reflect/type.js +57 -0
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/runtime/debug/index.js +2 -1
- package/dist/gs/runtime/debug/index.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/go.mod +2 -2
- package/go.sum +2 -0
- package/gs/builtin/hostio.test.ts +22 -1
- package/gs/builtin/hostio.ts +6 -1
- package/gs/builtin/runtime-contract.test.ts +28 -0
- package/gs/builtin/slice.ts +225 -20
- package/gs/crypto/aes/index.test.ts +120 -0
- package/gs/crypto/aes/index.ts +76 -0
- package/gs/crypto/cipher/index.ts +345 -0
- package/gs/crypto/cipher/meta.json +6 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +162 -0
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +41 -5
- 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/golang.org/x/crypto/chacha20poly1305/index.test.ts +91 -0
- package/gs/golang.org/x/crypto/chacha20poly1305/index.ts +245 -0
- package/gs/internal/byteorder/index.test.ts +2 -2
- package/gs/internal/byteorder/index.ts +2 -2
- package/gs/io/io.test.ts +56 -1
- package/gs/io/io.ts +19 -2
- package/gs/reflect/type.ts +64 -0
- package/gs/reflect/typefor.test.ts +21 -1
- package/gs/runtime/debug/index.test.ts +32 -4
- package/gs/runtime/debug/index.ts +5 -2
- package/gs/sync/atomic/doc_64.gs.ts +6 -7
- package/gs/sync/atomic/doc_64.test.ts +43 -0
- package/package.json +10 -3
package/compiler/lowering.go
CHANGED
|
@@ -28,6 +28,8 @@ type LoweringOwner struct {
|
|
|
28
28
|
type LoweringOptions struct {
|
|
29
29
|
// SourceRoot is the request source root that may contain sibling protobuf TypeScript files.
|
|
30
30
|
SourceRoot string
|
|
31
|
+
// DisplayRoot is the request root used to format source file names in diagnostics.
|
|
32
|
+
DisplayRoot string
|
|
31
33
|
// OutputPath is the TypeScript output root used for generated relative imports.
|
|
32
34
|
OutputPath string
|
|
33
35
|
// ProtobufTypeScriptBinding binds .pb.go files to sibling .pb.ts files.
|
|
@@ -141,6 +143,7 @@ func (o *LoweringOwner) lowerPackage(
|
|
|
141
143
|
lazyPackageVarsByPkg,
|
|
142
144
|
runtimeMethodSets,
|
|
143
145
|
protobufAdapter,
|
|
146
|
+
options.DisplayRoot,
|
|
144
147
|
)
|
|
145
148
|
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
146
149
|
rewriteProtobufTypeScriptBindingFile(loweredFile, binding)
|
|
@@ -160,6 +163,7 @@ func (o *LoweringOwner) lowerPackage(
|
|
|
160
163
|
lazyPackageVarsByPkg,
|
|
161
164
|
runtimeMethodSets,
|
|
162
165
|
false,
|
|
166
|
+
options.DisplayRoot,
|
|
163
167
|
)
|
|
164
168
|
diagnostics = append(diagnostics, fileDiagnostics...)
|
|
165
169
|
if loweredFile != nil {
|
|
@@ -195,6 +199,7 @@ func (o *LoweringOwner) lowerFile(
|
|
|
195
199
|
lazyPackageVarsByPkg map[string]map[types.Object]bool,
|
|
196
200
|
runtimeMethodSets runtimeMethodSetCache,
|
|
197
201
|
protobufTypeScriptAdapter bool,
|
|
202
|
+
displayRoot string,
|
|
198
203
|
) (*loweredFile, []Diagnostic) {
|
|
199
204
|
associatedMethods := o.methodDeclsForFileTypes(semPkg, file)
|
|
200
205
|
relevantImportFiles := map[string]bool{sourcePath: true}
|
|
@@ -315,6 +320,7 @@ func (o *LoweringOwner) lowerFile(
|
|
|
315
320
|
tempNames: newTempNameOwner(),
|
|
316
321
|
topLevel: true,
|
|
317
322
|
protobufTSAdapter: protobufTypeScriptAdapter,
|
|
323
|
+
displayRoot: displayRoot,
|
|
318
324
|
}
|
|
319
325
|
var diagnostics []Diagnostic
|
|
320
326
|
var packageInitCalls []string
|
|
@@ -1120,6 +1126,28 @@ type lowerFileContext struct {
|
|
|
1120
1126
|
switchBreak bool
|
|
1121
1127
|
topLevel bool
|
|
1122
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
|
|
1123
1151
|
}
|
|
1124
1152
|
|
|
1125
1153
|
type tempNameOwner struct {
|
|
@@ -1208,7 +1236,7 @@ func (o *LoweringOwner) lowerDecl(ctx lowerFileContext, decl ast.Decl) ([]lowere
|
|
|
1208
1236
|
if receiver := receiverNamedTypeFromDecl(ctx, typed); receiver != nil && namedStructType(receiver) == nil {
|
|
1209
1237
|
fn, diagnostics := o.lowerNamedReceiverMethodDecl(ctx, typed, receiver)
|
|
1210
1238
|
if fn == nil {
|
|
1211
|
-
return nil, []Diagnostic{
|
|
1239
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, typed, "function", typed.Name.Name, "missing type information")}
|
|
1212
1240
|
}
|
|
1213
1241
|
return []loweredDecl{{function: fn}}, diagnostics
|
|
1214
1242
|
}
|
|
@@ -1216,11 +1244,11 @@ func (o *LoweringOwner) lowerDecl(ctx lowerFileContext, decl ast.Decl) ([]lowere
|
|
|
1216
1244
|
}
|
|
1217
1245
|
fn, diagnostics := o.lowerFuncDecl(ctx, typed)
|
|
1218
1246
|
if fn == nil {
|
|
1219
|
-
return nil, []Diagnostic{
|
|
1247
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, typed, "function", typed.Name.Name, "missing type information")}
|
|
1220
1248
|
}
|
|
1221
1249
|
return []loweredDecl{{function: fn}}, diagnostics
|
|
1222
1250
|
default:
|
|
1223
|
-
return nil, []Diagnostic{
|
|
1251
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, decl, "declaration", ctx.semPkg.pkgPath, "unsupported declaration kind")}
|
|
1224
1252
|
}
|
|
1225
1253
|
}
|
|
1226
1254
|
|
|
@@ -1268,7 +1296,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1268
1296
|
value = o.lowerValueForTarget(ctx, typed.Values[idx], obj.Type(), lowered)
|
|
1269
1297
|
value = o.lowerTopLevelInitializerValue(ctx, typed.Values[idx], value)
|
|
1270
1298
|
} else if len(embedPatterns) != 0 {
|
|
1271
|
-
embedded, embedDiagnostics := o.lowerGoEmbedValue(ctx, obj.Type(), embedPatterns)
|
|
1299
|
+
embedded, embedDiagnostics := o.lowerGoEmbedValue(ctx, typed.Pos(), obj.Type(), embedPatterns)
|
|
1272
1300
|
diagnostics = append(diagnostics, embedDiagnostics...)
|
|
1273
1301
|
if embedded != "" {
|
|
1274
1302
|
value = embedded
|
|
@@ -1359,7 +1387,7 @@ func (o *LoweringOwner) lowerGenDecl(ctx lowerFileContext, decl *ast.GenDecl) ([
|
|
|
1359
1387
|
}
|
|
1360
1388
|
}
|
|
1361
1389
|
default:
|
|
1362
|
-
diagnostics = append(diagnostics,
|
|
1390
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, typed, "declaration", ctx.semPkg.pkgPath, "unsupported general declaration"))
|
|
1363
1391
|
}
|
|
1364
1392
|
}
|
|
1365
1393
|
return decls, diagnostics
|
|
@@ -2144,16 +2172,17 @@ func goEmbedPatterns(groups ...*ast.CommentGroup) []string {
|
|
|
2144
2172
|
|
|
2145
2173
|
func (o *LoweringOwner) lowerGoEmbedValue(
|
|
2146
2174
|
ctx lowerFileContext,
|
|
2175
|
+
diagPos token.Pos,
|
|
2147
2176
|
typ types.Type,
|
|
2148
2177
|
patterns []string,
|
|
2149
2178
|
) (string, []Diagnostic) {
|
|
2150
2179
|
if isEmbedFSType(typ) {
|
|
2151
|
-
return o.lowerGoEmbedFSValue(ctx, patterns)
|
|
2180
|
+
return o.lowerGoEmbedFSValue(ctx, diagPos, patterns)
|
|
2152
2181
|
}
|
|
2153
2182
|
if len(patterns) != 1 {
|
|
2154
|
-
return "", []Diagnostic{
|
|
2183
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2155
2184
|
}
|
|
2156
|
-
cleanPattern, diagnostics := cleanGoEmbedFilePattern(ctx, patterns[0])
|
|
2185
|
+
cleanPattern, diagnostics := cleanGoEmbedFilePattern(ctx, diagPos, patterns[0])
|
|
2157
2186
|
if len(diagnostics) != 0 {
|
|
2158
2187
|
return "", diagnostics
|
|
2159
2188
|
}
|
|
@@ -2167,7 +2196,7 @@ func (o *LoweringOwner) lowerGoEmbedValue(
|
|
|
2167
2196
|
if slice, ok := types.Unalias(typ).Underlying().(*types.Slice); ok && isByteType(slice.Elem()) {
|
|
2168
2197
|
return byteSliceLiteral(data), nil
|
|
2169
2198
|
}
|
|
2170
|
-
diag :=
|
|
2199
|
+
diag := loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed target type")
|
|
2171
2200
|
diag.Detail = "target type: " + types.TypeString(typ, func(pkg *types.Package) string {
|
|
2172
2201
|
if pkg == nil {
|
|
2173
2202
|
return ""
|
|
@@ -2177,18 +2206,18 @@ func (o *LoweringOwner) lowerGoEmbedValue(
|
|
|
2177
2206
|
return "", []Diagnostic{diag}
|
|
2178
2207
|
}
|
|
2179
2208
|
|
|
2180
|
-
func (o *LoweringOwner) lowerGoEmbedFSValue(ctx lowerFileContext, patterns []string) (string, []Diagnostic) {
|
|
2209
|
+
func (o *LoweringOwner) lowerGoEmbedFSValue(ctx lowerFileContext, diagPos token.Pos, patterns []string) (string, []Diagnostic) {
|
|
2181
2210
|
embedAlias := ctx.importPaths["embed"]
|
|
2182
2211
|
if embedAlias == "" {
|
|
2183
|
-
return "", []Diagnostic{
|
|
2212
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed FS import")}
|
|
2184
2213
|
}
|
|
2185
2214
|
if len(patterns) == 0 {
|
|
2186
|
-
return "", []Diagnostic{
|
|
2215
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern list")}
|
|
2187
2216
|
}
|
|
2188
2217
|
|
|
2189
2218
|
filesByPath := make(map[string][]byte)
|
|
2190
2219
|
for _, pattern := range patterns {
|
|
2191
|
-
files, diagnostics := expandGoEmbedPattern(ctx, pattern)
|
|
2220
|
+
files, diagnostics := expandGoEmbedPattern(ctx, diagPos, pattern)
|
|
2192
2221
|
if len(diagnostics) != 0 {
|
|
2193
2222
|
return "", diagnostics
|
|
2194
2223
|
}
|
|
@@ -2214,25 +2243,25 @@ type goEmbedFile struct {
|
|
|
2214
2243
|
data []byte
|
|
2215
2244
|
}
|
|
2216
2245
|
|
|
2217
|
-
func cleanGoEmbedFilePattern(ctx lowerFileContext, pattern string) (string, []Diagnostic) {
|
|
2218
|
-
cleanPattern, _, diagnostics := cleanGoEmbedPattern(ctx, pattern)
|
|
2246
|
+
func cleanGoEmbedFilePattern(ctx lowerFileContext, diagPos token.Pos, pattern string) (string, []Diagnostic) {
|
|
2247
|
+
cleanPattern, _, diagnostics := cleanGoEmbedPattern(ctx, diagPos, pattern)
|
|
2219
2248
|
if len(diagnostics) != 0 {
|
|
2220
2249
|
return "", diagnostics
|
|
2221
2250
|
}
|
|
2222
2251
|
if strings.Contains(cleanPattern, "*") {
|
|
2223
|
-
return "", []Diagnostic{
|
|
2252
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2224
2253
|
}
|
|
2225
2254
|
info, err := os.Stat(filepath.Join(filepath.Dir(ctx.sourcePath), filepath.FromSlash(cleanPattern)))
|
|
2226
2255
|
if err != nil {
|
|
2227
2256
|
return "", []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2228
2257
|
}
|
|
2229
2258
|
if info.IsDir() {
|
|
2230
|
-
return "", []Diagnostic{
|
|
2259
|
+
return "", []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed directory target")}
|
|
2231
2260
|
}
|
|
2232
2261
|
return cleanPattern, nil
|
|
2233
2262
|
}
|
|
2234
2263
|
|
|
2235
|
-
func cleanGoEmbedPattern(ctx lowerFileContext, pattern string) (string, bool, []Diagnostic) {
|
|
2264
|
+
func cleanGoEmbedPattern(ctx lowerFileContext, diagPos token.Pos, pattern string) (string, bool, []Diagnostic) {
|
|
2236
2265
|
pattern = strings.Trim(pattern, "`\"")
|
|
2237
2266
|
all := false
|
|
2238
2267
|
if strings.HasPrefix(pattern, "all:") {
|
|
@@ -2245,13 +2274,13 @@ func cleanGoEmbedPattern(ctx lowerFileContext, pattern string) (string, bool, []
|
|
|
2245
2274
|
cleanPattern == "." ||
|
|
2246
2275
|
cleanPattern == ".." ||
|
|
2247
2276
|
strings.HasPrefix(cleanPattern, "../") {
|
|
2248
|
-
return "", false, []Diagnostic{
|
|
2277
|
+
return "", false, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2249
2278
|
}
|
|
2250
2279
|
return cleanPattern, all, nil
|
|
2251
2280
|
}
|
|
2252
2281
|
|
|
2253
|
-
func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile, []Diagnostic) {
|
|
2254
|
-
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)
|
|
2255
2284
|
if len(diagnostics) != 0 {
|
|
2256
2285
|
return nil, diagnostics
|
|
2257
2286
|
}
|
|
@@ -2260,17 +2289,17 @@ func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile,
|
|
|
2260
2289
|
if strings.Contains(cleanPattern, "*") {
|
|
2261
2290
|
matches, err := filepath.Glob(filepath.Join(pkgDir, filepath.FromSlash(cleanPattern)))
|
|
2262
2291
|
if err != nil {
|
|
2263
|
-
return nil, []Diagnostic{
|
|
2292
|
+
return nil, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "unsupported go:embed pattern")}
|
|
2264
2293
|
}
|
|
2265
2294
|
if len(matches) == 0 {
|
|
2266
|
-
return nil, []Diagnostic{
|
|
2295
|
+
return nil, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "go:embed pattern matched no files")}
|
|
2267
2296
|
}
|
|
2268
2297
|
paths = matches
|
|
2269
2298
|
}
|
|
2270
2299
|
|
|
2271
2300
|
var files []goEmbedFile
|
|
2272
2301
|
for _, path := range paths {
|
|
2273
|
-
collected, diagnostics := collectGoEmbedPath(ctx, pkgDir, path, all)
|
|
2302
|
+
collected, diagnostics := collectGoEmbedPath(ctx, diagPos, pkgDir, path, all)
|
|
2274
2303
|
if len(diagnostics) != 0 {
|
|
2275
2304
|
return nil, diagnostics
|
|
2276
2305
|
}
|
|
@@ -2282,7 +2311,7 @@ func expandGoEmbedPattern(ctx lowerFileContext, pattern string) ([]goEmbedFile,
|
|
|
2282
2311
|
return files, nil
|
|
2283
2312
|
}
|
|
2284
2313
|
|
|
2285
|
-
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) {
|
|
2286
2315
|
info, err := os.Stat(absPath)
|
|
2287
2316
|
if err != nil {
|
|
2288
2317
|
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
@@ -2319,7 +2348,7 @@ func collectGoEmbedPath(ctx lowerFileContext, pkgDir, absPath string, all bool)
|
|
|
2319
2348
|
return nil, []Diagnostic{goEmbedReadDiagnostic(ctx, err)}
|
|
2320
2349
|
}
|
|
2321
2350
|
if len(files) == 0 {
|
|
2322
|
-
return nil, []Diagnostic{
|
|
2351
|
+
return nil, []Diagnostic{loweringUnsupportedPos(ctx, diagPos, "declaration", ctx.semPkg.pkgPath, "go:embed directory matched no files")}
|
|
2323
2352
|
}
|
|
2324
2353
|
return files, nil
|
|
2325
2354
|
}
|
|
@@ -2440,7 +2469,7 @@ func (o *LoweringOwner) lowerInterfaceType(ctx lowerFileContext, semType *semant
|
|
|
2440
2469
|
}
|
|
2441
2470
|
code = code + "\n\n" + o.runtimeOwner.QualifiedHelper(RuntimeHelperRegisterInterfaceType) +
|
|
2442
2471
|
"(\n\t" + strconv.Quote(runtimeNamedTypeName(semType.named)) +
|
|
2443
|
-
",\n\tnull,\n\t" + o.runtimeMethodSignatures(iface) + "\n)"
|
|
2472
|
+
",\n\tnull,\n\t" + o.runtimeMethodSignatures(iface) + "\n);"
|
|
2444
2473
|
return loweredDecl{code: code, typeIndexExport: typeIndexExport, sideEffect: true}
|
|
2445
2474
|
}
|
|
2446
2475
|
|
|
@@ -2521,12 +2550,13 @@ func (o *LoweringOwner) runtimeMethodReturns(tuple *types.Tuple, seen map[types.
|
|
|
2521
2550
|
|
|
2522
2551
|
func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticType) (*loweredStruct, []Diagnostic) {
|
|
2523
2552
|
lowered := &loweredStruct{
|
|
2524
|
-
exported:
|
|
2525
|
-
indexExported:
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
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)),
|
|
2530
2560
|
}
|
|
2531
2561
|
for idx, field := range semType.fields {
|
|
2532
2562
|
structValue := isStructValueType(field.typ)
|
|
@@ -2569,7 +2599,11 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2569
2599
|
var diagnostics []Diagnostic
|
|
2570
2600
|
for _, methodDecl := range methodDecls {
|
|
2571
2601
|
lowerDecl := methodDecl
|
|
2572
|
-
|
|
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)) {
|
|
2573
2607
|
bodyless := *methodDecl
|
|
2574
2608
|
bodyless.Body = nil
|
|
2575
2609
|
lowerDecl = &bodyless
|
|
@@ -2590,6 +2624,133 @@ func (o *LoweringOwner) lowerStructType(ctx lowerFileContext, semType *semanticT
|
|
|
2590
2624
|
return lowered, diagnostics
|
|
2591
2625
|
}
|
|
2592
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
|
+
|
|
2593
2754
|
func (o *LoweringOwner) lowerEmbeddedMethodForwarders(
|
|
2594
2755
|
ctx lowerFileContext,
|
|
2595
2756
|
field semanticField,
|
|
@@ -2627,6 +2788,7 @@ func (o *LoweringOwner) lowerEmbeddedMethodForwarders(
|
|
|
2627
2788
|
targetType := o.tsEmbeddedForwarderTargetType(ctx, field.typ)
|
|
2628
2789
|
lowered := loweredFunction{
|
|
2629
2790
|
async: async,
|
|
2791
|
+
sourcePath: ctx.sourcePath,
|
|
2630
2792
|
name: methodMemberName(method.Name()),
|
|
2631
2793
|
runtimeName: method.Name(),
|
|
2632
2794
|
runtimeSignature: o.runtimeMethodSignature(method, make(map[types.Type]bool)),
|
|
@@ -2770,6 +2932,7 @@ func (o *LoweringOwner) lowerNamedReceiverMethodDecl(
|
|
|
2770
2932
|
exported: ctx.topLevel,
|
|
2771
2933
|
indexExported: ctx.topLevel && (ast.IsExported(receiver.Obj().Name()) || ast.IsExported(decl.Name.Name)),
|
|
2772
2934
|
async: async,
|
|
2935
|
+
sourcePath: sourcePos(ctx.semPkg.source, decl.Pos()).file,
|
|
2773
2936
|
name: methodFunctionName(receiver, decl.Name.Name),
|
|
2774
2937
|
result: asyncResultType(result, async),
|
|
2775
2938
|
deferState: deferState,
|
|
@@ -2844,6 +3007,7 @@ func (o *LoweringOwner) lowerFuncDecl(ctx lowerFileContext, decl *ast.FuncDecl)
|
|
|
2844
3007
|
indexExported: ctx.topLevel && !blankName && !initFunc && (ast.IsExported(decl.Name.Name) || decl.Name.Name == "main"),
|
|
2845
3008
|
init: initFunc,
|
|
2846
3009
|
async: async,
|
|
3010
|
+
sourcePath: sourcePos(ctx.semPkg.source, decl.Pos()).file,
|
|
2847
3011
|
name: name,
|
|
2848
3012
|
runtimeName: runtimeName,
|
|
2849
3013
|
result: asyncResultType(result, async),
|
|
@@ -3329,9 +3493,9 @@ func (o *LoweringOwner) lowerStmtInto(ctx lowerFileContext, stmt ast.Stmt, out [
|
|
|
3329
3493
|
if ctx.gotoLabels[label] {
|
|
3330
3494
|
return append(out, loweredStmt{text: "continue " + label}), nil
|
|
3331
3495
|
}
|
|
3332
|
-
return out, []Diagnostic{
|
|
3496
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported goto branch to "+label)}
|
|
3333
3497
|
default:
|
|
3334
|
-
return out, []Diagnostic{
|
|
3498
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported labeled branch")}
|
|
3335
3499
|
}
|
|
3336
3500
|
}
|
|
3337
3501
|
switch typed.Tok {
|
|
@@ -3352,12 +3516,12 @@ func (o *LoweringOwner) lowerStmtInto(ctx lowerFileContext, stmt ast.Stmt, out [
|
|
|
3352
3516
|
case token.FALLTHROUGH:
|
|
3353
3517
|
return append(out, loweredStmt{text: "fallthrough"}), nil
|
|
3354
3518
|
default:
|
|
3355
|
-
return out, []Diagnostic{
|
|
3519
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported branch")}
|
|
3356
3520
|
}
|
|
3357
3521
|
case *ast.EmptyStmt:
|
|
3358
3522
|
return out, nil
|
|
3359
3523
|
default:
|
|
3360
|
-
return out, []Diagnostic{
|
|
3524
|
+
return out, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported statement kind")}
|
|
3361
3525
|
}
|
|
3362
3526
|
}
|
|
3363
3527
|
|
|
@@ -3388,7 +3552,7 @@ func (o *LoweringOwner) lowerElse(ctx lowerFileContext, stmt ast.Stmt) ([]lowere
|
|
|
3388
3552
|
case *ast.IfStmt:
|
|
3389
3553
|
return o.lowerStmt(ctx, typed)
|
|
3390
3554
|
default:
|
|
3391
|
-
return nil, []Diagnostic{
|
|
3555
|
+
return nil, []Diagnostic{loweringUnsupportedAt(ctx, typed, "statement", ctx.semPkg.pkgPath, "unsupported else statement")}
|
|
3392
3556
|
}
|
|
3393
3557
|
}
|
|
3394
3558
|
|
|
@@ -4390,6 +4554,8 @@ func shortDeclNeedsTypeAnnotation(typ types.Type) bool {
|
|
|
4390
4554
|
return true
|
|
4391
4555
|
case *types.Slice:
|
|
4392
4556
|
return true
|
|
4557
|
+
case *types.Chan:
|
|
4558
|
+
return true
|
|
4393
4559
|
default:
|
|
4394
4560
|
return false
|
|
4395
4561
|
}
|
|
@@ -5617,7 +5783,7 @@ func (o *LoweringOwner) lowerRangeStmt(ctx lowerFileContext, stmt *ast.RangeStmt
|
|
|
5617
5783
|
if isFunctionType(rangeType) {
|
|
5618
5784
|
signature := rangeFunctionSignature(rangeType)
|
|
5619
5785
|
if signature == nil {
|
|
5620
|
-
return loweredStmt{}, append(diagnostics,
|
|
5786
|
+
return loweredStmt{}, append(diagnostics, loweringUnsupportedAt(ctx, stmt, "statement", ctx.semPkg.pkgPath, "unsupported function range signature"))
|
|
5621
5787
|
}
|
|
5622
5788
|
lowered, funcDiagnostics := o.lowerRangeFuncStmt(ctx, stmt, rangeValue, signature)
|
|
5623
5789
|
diagnostics = append(diagnostics, funcDiagnostics...)
|
|
@@ -5697,7 +5863,7 @@ func (o *LoweringOwner) lowerRangeFuncStmt(
|
|
|
5697
5863
|
) (loweredStmt, []Diagnostic) {
|
|
5698
5864
|
yieldSignature, ok := types.Unalias(signature.Params().At(0).Type()).Underlying().(*types.Signature)
|
|
5699
5865
|
if !ok {
|
|
5700
|
-
return loweredStmt{}, []Diagnostic{
|
|
5866
|
+
return loweredStmt{}, []Diagnostic{loweringUnsupportedAt(ctx, stmt, "statement", ctx.semPkg.pkgPath, "unsupported function range yield signature")}
|
|
5701
5867
|
}
|
|
5702
5868
|
keyName := rangeKeyName(stmt.Key)
|
|
5703
5869
|
valueName := rangeKeyName(stmt.Value)
|
|
@@ -5780,7 +5946,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
5780
5946
|
for _, raw := range stmt.Body.List {
|
|
5781
5947
|
clause, ok := raw.(*ast.CommClause)
|
|
5782
5948
|
if !ok {
|
|
5783
|
-
diagnostics = append(diagnostics,
|
|
5949
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, raw, "statement", ctx.semPkg.pkgPath, "unsupported select clause"))
|
|
5784
5950
|
continue
|
|
5785
5951
|
}
|
|
5786
5952
|
switch comm := clause.Comm.(type) {
|
|
@@ -5833,7 +5999,7 @@ func (o *LoweringOwner) lowerSelectStmt(ctx lowerFileContext, stmt *ast.SelectSt
|
|
|
5833
5999
|
})
|
|
5834
6000
|
caseID++
|
|
5835
6001
|
default:
|
|
5836
|
-
diagnostics = append(diagnostics,
|
|
6002
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, comm, "statement", ctx.semPkg.pkgPath, "unsupported select communication"))
|
|
5837
6003
|
}
|
|
5838
6004
|
}
|
|
5839
6005
|
lowered.returns = selectCasesReturn(lowered.cases)
|
|
@@ -5937,7 +6103,7 @@ func (o *LoweringOwner) lowerSelectReceiveComm(
|
|
|
5937
6103
|
}
|
|
5938
6104
|
receive, ok := receiveExpr.(*ast.UnaryExpr)
|
|
5939
6105
|
if !ok || receive.Op != token.ARROW {
|
|
5940
|
-
return "null", nil, []Diagnostic{
|
|
6106
|
+
return "null", nil, []Diagnostic{loweringUnsupportedAt(ctx, receiveExpr, "statement", ctx.semPkg.pkgPath, "unsupported select receive")}
|
|
5941
6107
|
}
|
|
5942
6108
|
channel, diagnostics := o.lowerExpr(ctx, receive.X)
|
|
5943
6109
|
if assign == nil {
|
|
@@ -5995,7 +6161,7 @@ func (o *LoweringOwner) lowerSwitchStmt(ctx lowerFileContext, stmt *ast.SwitchSt
|
|
|
5995
6161
|
for _, raw := range stmt.Body.List {
|
|
5996
6162
|
clause, ok := raw.(*ast.CaseClause)
|
|
5997
6163
|
if !ok {
|
|
5998
|
-
diagnostics = append(diagnostics,
|
|
6164
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, raw, "statement", ctx.semPkg.pkgPath, "unsupported switch clause"))
|
|
5999
6165
|
continue
|
|
6000
6166
|
}
|
|
6001
6167
|
bodyStmts := clause.Body
|
|
@@ -6090,7 +6256,7 @@ func (o *LoweringOwner) lowerTypeSwitchStmt(ctx lowerFileContext, stmt *ast.Type
|
|
|
6090
6256
|
valueExpr, varName, varRef, assignDiagnostics := o.lowerTypeSwitchAssign(ctx, stmt.Assign)
|
|
6091
6257
|
diagnostics = append(diagnostics, assignDiagnostics...)
|
|
6092
6258
|
if valueExpr == "" {
|
|
6093
|
-
return lowered, append(diagnostics,
|
|
6259
|
+
return lowered, append(diagnostics, loweringUnsupportedAt(ctx, stmt.Assign, "statement", ctx.semPkg.pkgPath, "unsupported type switch assignment"))
|
|
6094
6260
|
}
|
|
6095
6261
|
|
|
6096
6262
|
switchIR := &loweredTypeSwitch{
|
|
@@ -6101,7 +6267,7 @@ func (o *LoweringOwner) lowerTypeSwitchStmt(ctx lowerFileContext, stmt *ast.Type
|
|
|
6101
6267
|
for _, clauseStmt := range stmt.Body.List {
|
|
6102
6268
|
clause, ok := clauseStmt.(*ast.CaseClause)
|
|
6103
6269
|
if !ok {
|
|
6104
|
-
diagnostics = append(diagnostics,
|
|
6270
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, clauseStmt, "statement", ctx.semPkg.pkgPath, "unsupported type switch clause"))
|
|
6105
6271
|
continue
|
|
6106
6272
|
}
|
|
6107
6273
|
body, bodyDiagnostics := o.lowerStmtList(ctx.withoutRangeBreak().withSwitchBreak(), clause.Body)
|
|
@@ -6537,13 +6703,21 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6537
6703
|
return lowerPrefixUnaryExpr(typed.Op, value), diagnostics
|
|
6538
6704
|
}
|
|
6539
6705
|
if typed.Op == token.XOR {
|
|
6540
|
-
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok
|
|
6541
|
-
|
|
6542
|
-
|
|
6706
|
+
if bits, ok := unsignedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok {
|
|
6707
|
+
if bits <= 32 {
|
|
6708
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint) +
|
|
6709
|
+
"(~" + value + ", " + strconv.Itoa(bits) + ")", diagnostics
|
|
6710
|
+
}
|
|
6711
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUint64Xor) +
|
|
6712
|
+
"(" + value + ", -1n)", diagnostics
|
|
6713
|
+
}
|
|
6714
|
+
if bits, ok := signedIntegerBits(ctx.semPkg.source.TypesInfo.TypeOf(typed)); ok && bits > 32 {
|
|
6715
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperInt64Xor) +
|
|
6716
|
+
"(" + value + ", -1n)", diagnostics
|
|
6543
6717
|
}
|
|
6544
6718
|
return "~" + value, diagnostics
|
|
6545
6719
|
}
|
|
6546
|
-
return value, append(diagnostics,
|
|
6720
|
+
return value, append(diagnostics, loweringUnsupportedAt(ctx, typed, "expression", ctx.semPkg.pkgPath, "unsupported unary operator"))
|
|
6547
6721
|
case *ast.StarExpr:
|
|
6548
6722
|
return o.lowerPointerValueExpr(ctx, typed.X)
|
|
6549
6723
|
case *ast.ParenExpr:
|
|
@@ -6567,7 +6741,7 @@ func (o *LoweringOwner) lowerExpr(ctx lowerFileContext, expr ast.Expr) (string,
|
|
|
6567
6741
|
case *ast.IndexListExpr:
|
|
6568
6742
|
return o.lowerExpr(ctx, typed.X)
|
|
6569
6743
|
default:
|
|
6570
|
-
return "undefined", []Diagnostic{
|
|
6744
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, typed, "expression", ctx.semPkg.pkgPath, "unsupported expression kind")}
|
|
6571
6745
|
}
|
|
6572
6746
|
}
|
|
6573
6747
|
|
|
@@ -6933,7 +7107,7 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
6933
7107
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperRecover) + "(" + strings.Join(args, ", ") + ")", diagnostics
|
|
6934
7108
|
case "close":
|
|
6935
7109
|
if len(args) != 1 {
|
|
6936
|
-
return "undefined", append(diagnostics,
|
|
7110
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "close requires one argument"))
|
|
6937
7111
|
}
|
|
6938
7112
|
return args[0] + "!.close()", diagnostics
|
|
6939
7113
|
}
|
|
@@ -7030,9 +7204,9 @@ func (o *LoweringOwner) lowerCallExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
7030
7204
|
call := o.lowerCallableExpr(ctx, expr.Fun, callee) + "(" + strings.Join(args, ", ") + ")"
|
|
7031
7205
|
return o.awaitCallIfNeeded(ctx, expr.Fun, call), append(diagnostics, calleeDiagnostics...)
|
|
7032
7206
|
}
|
|
7033
|
-
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)))
|
|
7034
7208
|
}
|
|
7035
|
-
return "undefined", append(diagnostics,
|
|
7209
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr.Fun, "call", ctx.semPkg.pkgPath, fmt.Sprintf("unsupported call target %T", expr.Fun)))
|
|
7036
7210
|
}
|
|
7037
7211
|
|
|
7038
7212
|
func (o *LoweringOwner) lowerCallableExpr(ctx lowerFileContext, expr ast.Expr, callee string) string {
|
|
@@ -7321,11 +7495,11 @@ func unsafePackageFunction(ctx lowerFileContext, expr ast.Expr, name string) boo
|
|
|
7321
7495
|
|
|
7322
7496
|
func (o *LoweringOwner) lowerMakeExpr(ctx lowerFileContext, expr *ast.CallExpr) (string, []Diagnostic) {
|
|
7323
7497
|
if len(expr.Args) < 1 {
|
|
7324
|
-
return "undefined", []Diagnostic{
|
|
7498
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "make requires a type argument")}
|
|
7325
7499
|
}
|
|
7326
7500
|
targetType := typeFromExpr(ctx, expr.Args[0])
|
|
7327
7501
|
if targetType == nil {
|
|
7328
|
-
return "undefined", []Diagnostic{
|
|
7502
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr.Args[0], "call", ctx.semPkg.pkgPath, "make requires a type expression")}
|
|
7329
7503
|
}
|
|
7330
7504
|
switch typed := types.Unalias(targetType).Underlying().(type) {
|
|
7331
7505
|
case *types.Slice:
|
|
@@ -7378,13 +7552,13 @@ func (o *LoweringOwner) lowerMakeExpr(ctx lowerFileContext, expr *ast.CallExpr)
|
|
|
7378
7552
|
"<" + o.tsTypeFor(ctx, typed.Elem()) + ">(" + capacity + ", " +
|
|
7379
7553
|
o.lowerZeroValueExprFor(ctx, typed.Elem()) + ", " + strconv.Quote(channelDirectionString(typed.Dir())) + ")", diagnostics
|
|
7380
7554
|
default:
|
|
7381
|
-
return "undefined", []Diagnostic{
|
|
7555
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr.Args[0], "call", ctx.semPkg.pkgPath, "unsupported make type")}
|
|
7382
7556
|
}
|
|
7383
7557
|
}
|
|
7384
7558
|
|
|
7385
7559
|
func (o *LoweringOwner) lowerNewExpr(ctx lowerFileContext, expr *ast.CallExpr) (string, []Diagnostic) {
|
|
7386
7560
|
if len(expr.Args) != 1 {
|
|
7387
|
-
return "undefined", []Diagnostic{
|
|
7561
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "new requires one type argument")}
|
|
7388
7562
|
}
|
|
7389
7563
|
typ := typeFromExpr(ctx, expr.Args[0])
|
|
7390
7564
|
if named := namedStructType(typ); named != nil {
|
|
@@ -7400,7 +7574,7 @@ func (o *LoweringOwner) lowerConversionExpr(
|
|
|
7400
7574
|
targetType types.Type,
|
|
7401
7575
|
) (string, []Diagnostic) {
|
|
7402
7576
|
if len(expr.Args) != 1 {
|
|
7403
|
-
return "undefined", []Diagnostic{
|
|
7577
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, expr, "call", ctx.semPkg.pkgPath, "unsupported conversion arity")}
|
|
7404
7578
|
}
|
|
7405
7579
|
value, diagnostics := o.lowerExpr(ctx, expr.Args[0])
|
|
7406
7580
|
sourceType := ctx.semPkg.source.TypesInfo.TypeOf(expr.Args[0])
|
|
@@ -8371,7 +8545,7 @@ func (o *LoweringOwner) lowerAddressExpr(ctx lowerFileContext, expr ast.Expr) (s
|
|
|
8371
8545
|
case *ast.IndexExpr:
|
|
8372
8546
|
return o.lowerIndexAddressExpr(ctx, typed)
|
|
8373
8547
|
default:
|
|
8374
|
-
return "undefined", []Diagnostic{
|
|
8548
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, typed, "expression", ctx.semPkg.pkgPath, "unsupported address expression")}
|
|
8375
8549
|
}
|
|
8376
8550
|
}
|
|
8377
8551
|
|
|
@@ -8430,7 +8604,7 @@ func (o *LoweringOwner) lowerIndexAddressExpr(ctx lowerFileContext, expr *ast.In
|
|
|
8430
8604
|
diagnostics := append(targetDiagnostics, indexDiagnostics...)
|
|
8431
8605
|
targetType := ctx.semPkg.source.TypesInfo.TypeOf(expr.X)
|
|
8432
8606
|
if isStringType(targetType) || isMapType(targetType) {
|
|
8433
|
-
return "undefined", append(diagnostics,
|
|
8607
|
+
return "undefined", append(diagnostics, loweringUnsupportedAt(ctx, expr, "expression", ctx.semPkg.pkgPath, "unsupported address expression"))
|
|
8434
8608
|
}
|
|
8435
8609
|
return o.runtimeOwner.QualifiedHelper(RuntimeHelperIndexRef) + "(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ")", diagnostics
|
|
8436
8610
|
}
|
|
@@ -8458,7 +8632,7 @@ func (o *LoweringOwner) lowerUnsafePointerIntegerExpr(
|
|
|
8458
8632
|
if !ok || len(call.Args) != 1 || !isUnsafePointerType(typeFromExpr(ctx, call.Fun)) {
|
|
8459
8633
|
return "", nil, false
|
|
8460
8634
|
}
|
|
8461
|
-
return o.
|
|
8635
|
+
return o.lowerIndexByteAddressIntegerExpr(ctx, call.Args[0])
|
|
8462
8636
|
}
|
|
8463
8637
|
|
|
8464
8638
|
func (o *LoweringOwner) lowerIndexAddressIntegerExpr(
|
|
@@ -8484,6 +8658,30 @@ func (o *LoweringOwner) lowerIndexAddressIntegerExpr(
|
|
|
8484
8658
|
"(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ")", diagnostics, true
|
|
8485
8659
|
}
|
|
8486
8660
|
|
|
8661
|
+
func (o *LoweringOwner) lowerIndexByteAddressIntegerExpr(
|
|
8662
|
+
ctx lowerFileContext,
|
|
8663
|
+
expr ast.Expr,
|
|
8664
|
+
) (string, []Diagnostic, bool) {
|
|
8665
|
+
address, ok := unwrapParenExpr(expr).(*ast.UnaryExpr)
|
|
8666
|
+
if !ok || address.Op != token.AND {
|
|
8667
|
+
return "", nil, false
|
|
8668
|
+
}
|
|
8669
|
+
indexExpr, ok := unwrapParenExpr(address.X).(*ast.IndexExpr)
|
|
8670
|
+
if !ok {
|
|
8671
|
+
return "", nil, false
|
|
8672
|
+
}
|
|
8673
|
+
target, targetDiagnostics := o.lowerExpr(ctx, indexExpr.X)
|
|
8674
|
+
index, indexDiagnostics := o.lowerExpr(ctx, indexExpr.Index)
|
|
8675
|
+
diagnostics := append(targetDiagnostics, indexDiagnostics...)
|
|
8676
|
+
targetType := ctx.semPkg.source.TypesInfo.TypeOf(indexExpr.X)
|
|
8677
|
+
if isStringType(targetType) || isMapType(targetType) {
|
|
8678
|
+
return "", diagnostics, false
|
|
8679
|
+
}
|
|
8680
|
+
elementSize := goScriptElementByteSize(ctx, indexElementType(targetType))
|
|
8681
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperIndexByteAddress) +
|
|
8682
|
+
"(" + o.lowerIndexTarget(ctx, target, targetType) + ", " + index + ", " + strconv.FormatInt(elementSize, 10) + ")", diagnostics, true
|
|
8683
|
+
}
|
|
8684
|
+
|
|
8487
8685
|
func (o *LoweringOwner) lowerPointerValueExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
8488
8686
|
if value, diagnostics, ok := o.lowerUnsafeStringPointerValue(ctx, expr); ok {
|
|
8489
8687
|
return value, diagnostics
|
|
@@ -8491,6 +8689,12 @@ func (o *LoweringOwner) lowerPointerValueExpr(ctx lowerFileContext, expr ast.Exp
|
|
|
8491
8689
|
if value, diagnostics, ok := o.lowerUnsafeStringByteSlicePointerValue(ctx, expr); ok {
|
|
8492
8690
|
return value, diagnostics
|
|
8493
8691
|
}
|
|
8692
|
+
if ref, diagnostics, ok := o.lowerUnsafeArrayPointerRefExpr(ctx, expr); ok {
|
|
8693
|
+
return ref + "!.value", diagnostics
|
|
8694
|
+
}
|
|
8695
|
+
if ref, diagnostics, ok := o.lowerUnsafePointerRefExpr(ctx, expr); ok {
|
|
8696
|
+
return ref + ".value", diagnostics
|
|
8697
|
+
}
|
|
8494
8698
|
base, diagnostics := o.lowerExpr(ctx, expr)
|
|
8495
8699
|
typeArg := ""
|
|
8496
8700
|
if pointer, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(expr)).Underlying().(*types.Pointer); ok {
|
|
@@ -8622,8 +8826,13 @@ func (o *LoweringOwner) lowerUnsafeArrayPointerConversion(
|
|
|
8622
8826
|
return "", nil, false
|
|
8623
8827
|
}
|
|
8624
8828
|
ref, diagnostics := o.lowerAddressExpr(ctx, index)
|
|
8829
|
+
sourceElementSize := goScriptElementByteSize(ctx, indexElementType(ctx.semPkg.source.TypesInfo.TypeOf(index.X)))
|
|
8830
|
+
targetElementSize := goScriptElementByteSize(ctx, array.Elem())
|
|
8625
8831
|
helper := o.runtimeOwner.QualifiedHelper(RuntimeHelperArrayPointerFromIndexRef) +
|
|
8626
|
-
"<" + o.tsTypeFor(ctx, array.Elem()) + ">(" + ref + ", " +
|
|
8832
|
+
"<" + o.tsTypeFor(ctx, array.Elem()) + ">(" + ref + ", " +
|
|
8833
|
+
strconv.FormatInt(array.Len(), 10) + ", " +
|
|
8834
|
+
strconv.FormatInt(sourceElementSize, 10) + ", " +
|
|
8835
|
+
strconv.FormatInt(targetElementSize, 10) + ")"
|
|
8627
8836
|
return "(" + helper + " as unknown as " + o.tsTypeFor(ctx, targetType) + ")", diagnostics, true
|
|
8628
8837
|
}
|
|
8629
8838
|
|
|
@@ -8717,6 +8926,12 @@ func sameLoweredSourceExpr(ctx lowerFileContext, left ast.Expr, right ast.Expr)
|
|
|
8717
8926
|
}
|
|
8718
8927
|
|
|
8719
8928
|
func (o *LoweringOwner) lowerPointerStorageExpr(ctx lowerFileContext, expr ast.Expr) (string, []Diagnostic) {
|
|
8929
|
+
if ref, diagnostics, ok := o.lowerUnsafeArrayPointerRefExpr(ctx, expr); ok {
|
|
8930
|
+
return ref + "!.value", diagnostics
|
|
8931
|
+
}
|
|
8932
|
+
if ref, diagnostics, ok := o.lowerUnsafePointerRefExpr(ctx, expr); ok {
|
|
8933
|
+
return ref + ".value", diagnostics
|
|
8934
|
+
}
|
|
8720
8935
|
if ref, diagnostics, ok := o.lowerUnsafePointerStorageExpr(ctx, expr); ok {
|
|
8721
8936
|
return ref, diagnostics
|
|
8722
8937
|
}
|
|
@@ -8724,6 +8939,42 @@ func (o *LoweringOwner) lowerPointerStorageExpr(ctx lowerFileContext, expr ast.E
|
|
|
8724
8939
|
return base + "!.value", diagnostics
|
|
8725
8940
|
}
|
|
8726
8941
|
|
|
8942
|
+
func (o *LoweringOwner) lowerUnsafeArrayPointerRefExpr(
|
|
8943
|
+
ctx lowerFileContext,
|
|
8944
|
+
expr ast.Expr,
|
|
8945
|
+
) (string, []Diagnostic, bool) {
|
|
8946
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
8947
|
+
if !ok || len(call.Args) != 1 {
|
|
8948
|
+
return "", nil, false
|
|
8949
|
+
}
|
|
8950
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
8951
|
+
if targetType == nil {
|
|
8952
|
+
return "", nil, false
|
|
8953
|
+
}
|
|
8954
|
+
return o.lowerUnsafeArrayPointerConversion(ctx, targetType, call.Args[0])
|
|
8955
|
+
}
|
|
8956
|
+
|
|
8957
|
+
func (o *LoweringOwner) lowerUnsafePointerRefExpr(
|
|
8958
|
+
ctx lowerFileContext,
|
|
8959
|
+
expr ast.Expr,
|
|
8960
|
+
) (string, []Diagnostic, bool) {
|
|
8961
|
+
call, ok := unwrapParenExpr(expr).(*ast.CallExpr)
|
|
8962
|
+
if !ok || len(call.Args) != 1 {
|
|
8963
|
+
return "", nil, false
|
|
8964
|
+
}
|
|
8965
|
+
targetType := typeFromExpr(ctx, call.Fun)
|
|
8966
|
+
if targetType == nil {
|
|
8967
|
+
return "", nil, false
|
|
8968
|
+
}
|
|
8969
|
+
pointer, _ := types.Unalias(targetType).Underlying().(*types.Pointer)
|
|
8970
|
+
if pointer == nil || !isUnsafePointerType(ctx.semPkg.source.TypesInfo.TypeOf(call.Args[0])) {
|
|
8971
|
+
return "", nil, false
|
|
8972
|
+
}
|
|
8973
|
+
value, diagnostics := o.lowerExpr(ctx, call.Args[0])
|
|
8974
|
+
return o.runtimeOwner.QualifiedHelper(RuntimeHelperUnsafePointerRef) +
|
|
8975
|
+
"<" + o.tsTypeFor(ctx, pointer.Elem()) + ">(" + value + ")", diagnostics, true
|
|
8976
|
+
}
|
|
8977
|
+
|
|
8727
8978
|
func (o *LoweringOwner) lowerUnsafePointerStorageExpr(
|
|
8728
8979
|
ctx lowerFileContext,
|
|
8729
8980
|
expr ast.Expr,
|
|
@@ -8893,15 +9144,11 @@ func (o *LoweringOwner) lowerCompositeLit(
|
|
|
8893
9144
|
if mapType, ok := types.Unalias(ctx.semPkg.source.TypesInfo.TypeOf(lit)).Underlying().(*types.Map); ok {
|
|
8894
9145
|
return o.lowerMapCompositeLit(ctx, lit, mapType)
|
|
8895
9146
|
}
|
|
8896
|
-
position := sourcePos(ctx.semPkg.source, lit.Pos())
|
|
8897
9147
|
detail := "unsupported composite literal"
|
|
8898
|
-
if position.file != "" {
|
|
8899
|
-
detail += " at " + filepath.Base(position.file) + ":" + strconv.Itoa(position.line)
|
|
8900
|
-
}
|
|
8901
9148
|
if typ := ctx.semPkg.source.TypesInfo.TypeOf(lit); typ != nil {
|
|
8902
9149
|
detail += " of type " + typ.String()
|
|
8903
9150
|
}
|
|
8904
|
-
return "undefined", []Diagnostic{
|
|
9151
|
+
return "undefined", []Diagnostic{loweringUnsupportedAt(ctx, lit, "expression", ctx.semPkg.pkgPath, detail)}
|
|
8905
9152
|
}
|
|
8906
9153
|
|
|
8907
9154
|
func (o *LoweringOwner) lowerStructCompositeLit(
|
|
@@ -8936,7 +9183,7 @@ func (o *LoweringOwner) lowerStructCompositeLit(
|
|
|
8936
9183
|
fieldType = field.Type()
|
|
8937
9184
|
}
|
|
8938
9185
|
if fieldName == "" {
|
|
8939
|
-
diagnostics = append(diagnostics,
|
|
9186
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, elt, "expression", ctx.semPkg.pkgPath, "unsupported struct literal field"))
|
|
8940
9187
|
continue
|
|
8941
9188
|
}
|
|
8942
9189
|
value, valueDiagnostics := o.lowerExpr(ctx, valueExpr)
|
|
@@ -9047,7 +9294,7 @@ func (o *LoweringOwner) lowerAnonymousStructCompositeLit(
|
|
|
9047
9294
|
fieldType = field.Type()
|
|
9048
9295
|
}
|
|
9049
9296
|
if fieldName == "" {
|
|
9050
|
-
diagnostics = append(diagnostics,
|
|
9297
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, elt, "expression", ctx.semPkg.pkgPath, "unsupported anonymous struct literal field"))
|
|
9051
9298
|
continue
|
|
9052
9299
|
}
|
|
9053
9300
|
value, valueDiagnostics := o.lowerExpr(ctx, valueExpr)
|
|
@@ -9156,7 +9403,7 @@ func (o *LoweringOwner) lowerMapCompositeLit(
|
|
|
9156
9403
|
for _, elt := range lit.Elts {
|
|
9157
9404
|
keyed, ok := elt.(*ast.KeyValueExpr)
|
|
9158
9405
|
if !ok {
|
|
9159
|
-
diagnostics = append(diagnostics,
|
|
9406
|
+
diagnostics = append(diagnostics, loweringUnsupportedAt(ctx, elt, "expression", ctx.semPkg.pkgPath, "unsupported map literal entry"))
|
|
9160
9407
|
continue
|
|
9161
9408
|
}
|
|
9162
9409
|
key, keyDiagnostics := o.lowerExpr(ctx, keyed.Key)
|
|
@@ -10398,6 +10645,42 @@ func isMapType(typ types.Type) bool {
|
|
|
10398
10645
|
return ok
|
|
10399
10646
|
}
|
|
10400
10647
|
|
|
10648
|
+
func indexElementType(typ types.Type) types.Type {
|
|
10649
|
+
if pointer, ok := types.Unalias(typ).Underlying().(*types.Pointer); ok {
|
|
10650
|
+
typ = pointer.Elem()
|
|
10651
|
+
}
|
|
10652
|
+
switch typed := types.Unalias(typ).Underlying().(type) {
|
|
10653
|
+
case *types.Slice:
|
|
10654
|
+
return typed.Elem()
|
|
10655
|
+
case *types.Array:
|
|
10656
|
+
return typed.Elem()
|
|
10657
|
+
default:
|
|
10658
|
+
return nil
|
|
10659
|
+
}
|
|
10660
|
+
}
|
|
10661
|
+
|
|
10662
|
+
func goScriptElementByteSize(ctx lowerFileContext, typ types.Type) int64 {
|
|
10663
|
+
if typ == nil {
|
|
10664
|
+
return 1
|
|
10665
|
+
}
|
|
10666
|
+
if sizes := ctx.semPkg.source.TypesSizes; sizes != nil {
|
|
10667
|
+
if size := sizes.Sizeof(typ); size > 0 {
|
|
10668
|
+
return size
|
|
10669
|
+
}
|
|
10670
|
+
}
|
|
10671
|
+
if bits, ok := integerBits(typ); ok && bits > 0 {
|
|
10672
|
+
return int64((bits + 7) / 8)
|
|
10673
|
+
}
|
|
10674
|
+
if isFloatType(typ) {
|
|
10675
|
+
basic, _ := types.Unalias(typ).Underlying().(*types.Basic)
|
|
10676
|
+
if basic != nil && basic.Kind() == types.Float32 {
|
|
10677
|
+
return 4
|
|
10678
|
+
}
|
|
10679
|
+
return 8
|
|
10680
|
+
}
|
|
10681
|
+
return 1
|
|
10682
|
+
}
|
|
10683
|
+
|
|
10401
10684
|
func isChannelType(typ types.Type) bool {
|
|
10402
10685
|
if typ == nil {
|
|
10403
10686
|
return false
|
|
@@ -10471,6 +10754,9 @@ func isFloatType(typ types.Type) bool {
|
|
|
10471
10754
|
}
|
|
10472
10755
|
|
|
10473
10756
|
func unsignedIntegerBits(typ types.Type) (int, bool) {
|
|
10757
|
+
if typ == nil {
|
|
10758
|
+
return 0, false
|
|
10759
|
+
}
|
|
10474
10760
|
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
10475
10761
|
if !ok || basic.Info()&types.IsUnsigned == 0 {
|
|
10476
10762
|
return 0, false
|
|
@@ -10488,6 +10774,9 @@ func unsignedIntegerBits(typ types.Type) (int, bool) {
|
|
|
10488
10774
|
}
|
|
10489
10775
|
|
|
10490
10776
|
func signedIntegerBits(typ types.Type) (int, bool) {
|
|
10777
|
+
if typ == nil {
|
|
10778
|
+
return 0, false
|
|
10779
|
+
}
|
|
10491
10780
|
basic, ok := types.Unalias(typ).Underlying().(*types.Basic)
|
|
10492
10781
|
if !ok || basic.Info()&types.IsInteger == 0 || basic.Info()&types.IsUnsigned != 0 {
|
|
10493
10782
|
return 0, false
|