goscript 0.1.2 → 0.1.4

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.
Files changed (138) hide show
  1. package/cmd/goscript/cmd_compile.go +28 -8
  2. package/cmd/goscript/cmd_compile_test.go +105 -6
  3. package/compiler/build-flags.go +9 -10
  4. package/compiler/gotest/runner_test.go +127 -0
  5. package/compiler/lowered-program.go +1 -0
  6. package/compiler/lowering.go +1325 -194
  7. package/compiler/lowering_bench_test.go +350 -0
  8. package/compiler/override-registry_test.go +43 -0
  9. package/compiler/package-graph.go +61 -4
  10. package/compiler/package-graph_test.go +30 -0
  11. package/compiler/semantic-model-types.go +8 -0
  12. package/compiler/semantic-model.go +447 -22
  13. package/compiler/semantic-model_test.go +138 -0
  14. package/compiler/skeleton_test.go +1436 -50
  15. package/compiler/typescript-emitter.go +47 -4
  16. package/dist/gs/builtin/builtin.d.ts +2 -2
  17. package/dist/gs/builtin/builtin.js +20 -0
  18. package/dist/gs/builtin/builtin.js.map +1 -1
  19. package/dist/gs/builtin/channel.js +36 -9
  20. package/dist/gs/builtin/channel.js.map +1 -1
  21. package/dist/gs/builtin/slice.js +5 -0
  22. package/dist/gs/builtin/slice.js.map +1 -1
  23. package/dist/gs/builtin/type.d.ts +1 -1
  24. package/dist/gs/builtin/type.js +80 -8
  25. package/dist/gs/builtin/type.js.map +1 -1
  26. package/dist/gs/bytes/bytes.gs.d.ts +7 -5
  27. package/dist/gs/bytes/bytes.gs.js +10 -4
  28. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  29. package/dist/gs/compress/zlib/index.d.ts +3 -3
  30. package/dist/gs/compress/zlib/index.js +88 -26
  31. package/dist/gs/compress/zlib/index.js.map +1 -1
  32. package/dist/gs/crypto/sha1/index.d.ts +5 -0
  33. package/dist/gs/crypto/sha1/index.js +103 -0
  34. package/dist/gs/crypto/sha1/index.js.map +1 -0
  35. package/dist/gs/crypto/sha256/index.js +2 -5
  36. package/dist/gs/crypto/sha256/index.js.map +1 -1
  37. package/dist/gs/crypto/sha512/index.js +2 -5
  38. package/dist/gs/crypto/sha512/index.js.map +1 -1
  39. package/dist/gs/embed/index.d.ts +6 -0
  40. package/dist/gs/embed/index.js +210 -5
  41. package/dist/gs/embed/index.js.map +1 -1
  42. package/dist/gs/fmt/fmt.d.ts +4 -4
  43. package/dist/gs/fmt/fmt.js +93 -19
  44. package/dist/gs/fmt/fmt.js.map +1 -1
  45. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +118 -6
  46. package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
  47. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
  48. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
  49. package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
  50. package/dist/gs/io/fs/readdir.js +5 -3
  51. package/dist/gs/io/fs/readdir.js.map +1 -1
  52. package/dist/gs/io/io.d.ts +18 -11
  53. package/dist/gs/io/io.js +107 -44
  54. package/dist/gs/io/io.js.map +1 -1
  55. package/dist/gs/math/bits/index.d.ts +26 -5
  56. package/dist/gs/math/bits/index.js +13 -24
  57. package/dist/gs/math/bits/index.js.map +1 -1
  58. package/dist/gs/net/http/httptest/index.js +7 -5
  59. package/dist/gs/net/http/httptest/index.js.map +1 -1
  60. package/dist/gs/net/http/index.d.ts +11 -1
  61. package/dist/gs/net/http/index.js +157 -11
  62. package/dist/gs/net/http/index.js.map +1 -1
  63. package/dist/gs/os/types_js.gs.d.ts +6 -2
  64. package/dist/gs/os/types_js.gs.js +169 -8
  65. package/dist/gs/os/types_js.gs.js.map +1 -1
  66. package/dist/gs/os/zero_copy_posix.gs.js +1 -1
  67. package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
  68. package/dist/gs/reflect/type.d.ts +1 -0
  69. package/dist/gs/reflect/type.js +80 -51
  70. package/dist/gs/reflect/type.js.map +1 -1
  71. package/dist/gs/strings/reader.d.ts +1 -1
  72. package/dist/gs/strings/reader.js +2 -2
  73. package/dist/gs/strings/reader.js.map +1 -1
  74. package/dist/gs/sync/sync.d.ts +2 -1
  75. package/dist/gs/sync/sync.js +37 -16
  76. package/dist/gs/sync/sync.js.map +1 -1
  77. package/dist/gs/syscall/js/index.js +9 -0
  78. package/dist/gs/syscall/js/index.js.map +1 -1
  79. package/dist/gs/testing/testing.js +8 -6
  80. package/dist/gs/testing/testing.js.map +1 -1
  81. package/gs/builtin/builtin.ts +25 -2
  82. package/gs/builtin/channel.ts +47 -9
  83. package/gs/builtin/runtime-contract.test.ts +78 -0
  84. package/gs/builtin/slice.ts +7 -0
  85. package/gs/builtin/type.ts +97 -8
  86. package/gs/bytes/bytes.gs.ts +19 -10
  87. package/gs/bytes/bytes.test.ts +17 -0
  88. package/gs/compress/zlib/index.test.ts +97 -0
  89. package/gs/compress/zlib/index.ts +117 -27
  90. package/gs/compress/zlib/meta.json +4 -1
  91. package/gs/context/context.test.ts +5 -1
  92. package/gs/crypto/sha1/index.test.ts +45 -0
  93. package/gs/crypto/sha1/index.ts +127 -0
  94. package/gs/crypto/sha1/meta.json +8 -0
  95. package/gs/crypto/sha256/index.test.ts +14 -2
  96. package/gs/crypto/sha256/index.ts +3 -6
  97. package/gs/crypto/sha512/index.test.ts +17 -2
  98. package/gs/crypto/sha512/index.ts +3 -6
  99. package/gs/embed/index.test.ts +87 -0
  100. package/gs/embed/index.ts +229 -5
  101. package/gs/fmt/fmt.test.ts +61 -3
  102. package/gs/fmt/fmt.ts +115 -22
  103. package/gs/fmt/meta.json +6 -1
  104. package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +8 -1
  105. package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +139 -11
  106. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +1 -1
  107. package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
  108. package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
  109. package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
  110. package/gs/io/fs/readdir.test.ts +38 -0
  111. package/gs/io/fs/readdir.ts +7 -3
  112. package/gs/io/io.test.ts +135 -0
  113. package/gs/io/io.ts +143 -63
  114. package/gs/io/meta.json +7 -1
  115. package/gs/math/bits/index.ts +52 -28
  116. package/gs/net/http/httptest/index.test.ts +34 -2
  117. package/gs/net/http/httptest/index.ts +23 -8
  118. package/gs/net/http/index.test.ts +46 -0
  119. package/gs/net/http/index.ts +178 -12
  120. package/gs/os/file_unix_js.test.ts +52 -0
  121. package/gs/os/meta.json +4 -0
  122. package/gs/os/readdir.test.ts +56 -0
  123. package/gs/os/types_js.gs.ts +169 -8
  124. package/gs/os/zero_copy_posix.gs.ts +1 -2
  125. package/gs/reflect/deepequal.test.ts +10 -1
  126. package/gs/reflect/type.ts +91 -56
  127. package/gs/reflect/typefor.test.ts +31 -1
  128. package/gs/strings/meta.json +5 -2
  129. package/gs/strings/reader.test.ts +2 -2
  130. package/gs/strings/reader.ts +2 -2
  131. package/gs/sync/meta.json +2 -0
  132. package/gs/sync/sync.test.ts +41 -1
  133. package/gs/sync/sync.ts +41 -16
  134. package/gs/syscall/js/index.test.ts +18 -0
  135. package/gs/syscall/js/index.ts +12 -0
  136. package/gs/testing/testing.test.ts +32 -3
  137. package/gs/testing/testing.ts +13 -10
  138. package/package.json +1 -1
@@ -88,12 +88,21 @@ func (o *SemanticModelOwner) Build(ctx context.Context, graph *PackageGraph) (*S
88
88
  if diagnosticsHaveErrors(diagnostics) {
89
89
  return model, diagnostics
90
90
  }
91
+ anonymousInterfaceGraph, anonymousInterfaceDiagnostics := o.resolveAnonymousInterfaceImplementationGraph(ctx, model)
92
+ diagnostics = append(diagnostics, anonymousInterfaceDiagnostics...)
93
+ if diagnosticsHaveErrors(diagnostics) {
94
+ return model, diagnostics
95
+ }
91
96
  for {
92
97
  asyncCount := semanticAsyncFunctionCount(model)
93
98
  diagnostics = append(diagnostics, o.applyInterfaceAsyncMethods(ctx, model, interfaceGraph)...)
94
99
  if diagnosticsHaveErrors(diagnostics) {
95
100
  return model, diagnostics
96
101
  }
102
+ diagnostics = append(diagnostics, o.applyAnonymousInterfaceAsyncMethods(ctx, model, anonymousInterfaceGraph)...)
103
+ if diagnosticsHaveErrors(diagnostics) {
104
+ return model, diagnostics
105
+ }
97
106
  diagnostics = append(diagnostics, o.propagateFunctionAsync(ctx, model)...)
98
107
  if diagnosticsHaveErrors(diagnostics) {
99
108
  return model, diagnostics
@@ -107,15 +116,18 @@ func (o *SemanticModelOwner) Build(ctx context.Context, graph *PackageGraph) (*S
107
116
 
108
117
  func newSemanticModel() *SemanticModel {
109
118
  return &SemanticModel{
110
- packages: make(map[string]*semanticPackage),
111
- addressTaken: make(map[types.Object]bool),
112
- needsVarRef: make(map[types.Object]bool),
113
- functions: make(map[*types.Func]*semanticFunction),
114
- functionsByFullName: make(map[string]*semanticFunction),
115
- functionLookupMisses: make(map[*types.Func]bool),
116
- types: make(map[*types.Named]*semanticType),
117
- values: make(map[types.Object]*semanticValue),
118
- generatedImports: make(map[string]map[string]bool),
119
+ packages: make(map[string]*semanticPackage),
120
+ addressTaken: make(map[types.Object]bool),
121
+ needsVarRef: make(map[types.Object]bool),
122
+ functions: make(map[*types.Func]*semanticFunction),
123
+ functionsByFullName: make(map[string]*semanticFunction),
124
+ functionLookupMisses: make(map[*types.Func]bool),
125
+ functionFullNames: make(map[*types.Func]string),
126
+ types: make(map[*types.Named]*semanticType),
127
+ values: make(map[types.Object]*semanticValue),
128
+ generatedImports: make(map[string]map[string]bool),
129
+ asyncInterfaceMethods: make(map[string]bool),
130
+ asyncInterfaceMethodObjs: make(map[*types.Func]bool),
119
131
  }
120
132
  }
121
133
 
@@ -555,7 +567,7 @@ func (o *SemanticModelOwner) addFunction(
555
567
  return existing
556
568
  }
557
569
  }
558
- if fullName := fn.FullName(); fullName != "" {
570
+ if fullName := model.functionFullName(fn); fullName != "" {
559
571
  if existing := model.functionsByFullName[fullName]; existing != nil {
560
572
  model.functions[fn] = existing
561
573
  if origin := fn.Origin(); origin != nil {
@@ -583,7 +595,7 @@ func (o *SemanticModelOwner) addFunction(
583
595
  if origin := fn.Origin(); origin != nil {
584
596
  model.functions[origin] = semFn
585
597
  }
586
- if fullName := fn.FullName(); fullName != "" {
598
+ if fullName := model.functionFullName(fn); fullName != "" {
587
599
  if existing := model.functionsByFullName[fullName]; existing == nil {
588
600
  model.functionsByFullName[fullName] = semFn
589
601
  }
@@ -932,7 +944,7 @@ func semanticFunctionFor(model *SemanticModel, fn *types.Func) *semanticFunction
932
944
  return semFn
933
945
  }
934
946
  }
935
- if fullName := fn.FullName(); fullName != "" {
947
+ if fullName := model.functionFullName(fn); fullName != "" {
936
948
  if semFn := model.functionsByFullName[fullName]; semFn != nil {
937
949
  model.functions[fn] = semFn
938
950
  return semFn
@@ -989,6 +1001,8 @@ func callUsesFunctionValue(pkg *packages.Package, expr ast.Expr) bool {
989
1001
  switch typed := expr.(type) {
990
1002
  case *ast.CallExpr:
991
1003
  return true
1004
+ case *ast.TypeAssertExpr:
1005
+ return true
992
1006
  case *ast.SelectorExpr:
993
1007
  selection := pkg.TypesInfo.Selections[typed]
994
1008
  if selection != nil {
@@ -1125,8 +1139,7 @@ func (o *SemanticModelOwner) propagateFunctionAsync(ctx context.Context, model *
1125
1139
  return []Diagnostic{contextCanceledDiagnostic(err)}
1126
1140
  }
1127
1141
  for called := range semFn.calls {
1128
- calledFn := semanticFunctionFor(model, called)
1129
- if calledFn != nil && calledFn.async {
1142
+ if model.functionAsync(called) {
1130
1143
  if markFunctionAsync(semFn, "call:"+called.FullName()) {
1131
1144
  changed = true
1132
1145
  }
@@ -1167,17 +1180,15 @@ func (o *SemanticModelOwner) resolveInterfaceImplementationGraph(
1167
1180
  ctx context.Context,
1168
1181
  model *SemanticModel,
1169
1182
  ) ([]semanticInterfaceImplementationGraphEntry, []Diagnostic) {
1170
- var interfaces []*types.Named
1183
+ interfaces := collectInterfaceImplementationCandidates(model)
1171
1184
  var concretes []*types.Named
1172
1185
  for named, semType := range model.types {
1173
1186
  if err := ctx.Err(); err != nil {
1174
1187
  return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1175
1188
  }
1176
- if semType.isInterface {
1177
- interfaces = append(interfaces, named)
1178
- continue
1189
+ if !semType.isInterface {
1190
+ concretes = append(concretes, namedOriginOrSelf(named))
1179
1191
  }
1180
- concretes = append(concretes, named)
1181
1192
  }
1182
1193
  sortNamedTypes(interfaces)
1183
1194
  sortNamedTypes(concretes)
@@ -1209,6 +1220,338 @@ func (o *SemanticModelOwner) resolveInterfaceImplementationGraph(
1209
1220
  return implementationGraph, nil
1210
1221
  }
1211
1222
 
1223
+ func (o *SemanticModelOwner) resolveAnonymousInterfaceImplementationGraph(
1224
+ ctx context.Context,
1225
+ model *SemanticModel,
1226
+ ) ([]semanticAnonymousInterfaceImplementation, []Diagnostic) {
1227
+ interfaces := collectAnonymousInterfaceImplementationCandidates(model)
1228
+ var concretes []*types.Named
1229
+ for named, semType := range model.types {
1230
+ if err := ctx.Err(); err != nil {
1231
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1232
+ }
1233
+ if !semType.isInterface {
1234
+ concretes = append(concretes, namedOriginOrSelf(named))
1235
+ }
1236
+ }
1237
+ methodSets := implementationMethodSets(concretes)
1238
+ for _, namedIface := range collectNamedInterfaceImplementationCandidates(model) {
1239
+ methodSets = append(methodSets, semanticImplementationMethodSet{
1240
+ typ: namedIface,
1241
+ receiver: namedIface,
1242
+ methods: methodSetMap(namedIface),
1243
+ })
1244
+ }
1245
+
1246
+ implementationGraph := make([]semanticAnonymousInterfaceImplementation, 0)
1247
+ for _, iface := range interfaces {
1248
+ if err := ctx.Err(); err != nil {
1249
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1250
+ }
1251
+ iface.Complete()
1252
+ ifaceMethods := interfaceMethodMap(iface)
1253
+ if len(ifaceMethods) == 0 {
1254
+ continue
1255
+ }
1256
+ for _, methodSet := range methodSets {
1257
+ if err := ctx.Err(); err != nil {
1258
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
1259
+ }
1260
+ if !implementationHasMethods(methodSet.methods, ifaceMethods) {
1261
+ continue
1262
+ }
1263
+ receiver := methodSet.receiver
1264
+ if (methodSet.typ.TypeArgs() == nil || methodSet.typ.TypeArgs().Len() == 0) &&
1265
+ methodSet.typ.TypeParams() != nil && methodSet.typ.TypeParams().Len() != 0 {
1266
+ args := typeParamTypes(methodSet.typ.TypeParams())
1267
+ if instantiated, err := types.Instantiate(nil, methodSet.typ, args, false); err == nil {
1268
+ receiver = instantiated
1269
+ if methodSet.pointer {
1270
+ receiver = types.NewPointer(instantiated)
1271
+ }
1272
+ }
1273
+ }
1274
+ if !types.Implements(receiver, iface) {
1275
+ continue
1276
+ }
1277
+ implementationGraph = append(implementationGraph, semanticAnonymousInterfaceImplementation{
1278
+ ifaceMethods: ifaceMethods,
1279
+ implMethods: implementationMethodMap(methodSet.methods, ifaceMethods),
1280
+ })
1281
+ }
1282
+ }
1283
+ return implementationGraph, nil
1284
+ }
1285
+
1286
+ func collectInterfaceImplementationCandidates(model *SemanticModel) []*types.Named {
1287
+ if model == nil {
1288
+ return nil
1289
+ }
1290
+ seen := make(map[string]bool)
1291
+ var interfaces []*types.Named
1292
+ add := func(named *types.Named) {
1293
+ if named == nil || named.Obj() == nil || named.Obj().Pkg() == nil {
1294
+ return
1295
+ }
1296
+ named = namedOriginOrSelf(named)
1297
+ if _, ok := types.Unalias(named.Underlying()).(*types.Interface); !ok {
1298
+ return
1299
+ }
1300
+ key := named.Obj().Pkg().Path() + "." + named.Obj().Name()
1301
+ if seen[key] {
1302
+ return
1303
+ }
1304
+ seen[key] = true
1305
+ interfaces = append(interfaces, named)
1306
+ }
1307
+ var collect func(types.Type)
1308
+ seenTypes := make(map[types.Type]bool)
1309
+ collect = func(typ types.Type) {
1310
+ if typ == nil {
1311
+ return
1312
+ }
1313
+ typ = types.Unalias(typ)
1314
+ if seenTypes[typ] {
1315
+ return
1316
+ }
1317
+ seenTypes[typ] = true
1318
+ switch typed := typ.(type) {
1319
+ case *types.Named:
1320
+ add(typed)
1321
+ collect(typed.Underlying())
1322
+ case *types.Pointer:
1323
+ collect(typed.Elem())
1324
+ case *types.Slice:
1325
+ collect(typed.Elem())
1326
+ case *types.Array:
1327
+ collect(typed.Elem())
1328
+ case *types.Map:
1329
+ collect(typed.Key())
1330
+ collect(typed.Elem())
1331
+ case *types.Chan:
1332
+ collect(typed.Elem())
1333
+ case *types.Struct:
1334
+ for field := range typed.Fields() {
1335
+ collect(field.Type())
1336
+ }
1337
+ case *types.Interface:
1338
+ typed.Complete()
1339
+ for method := range typed.Methods() {
1340
+ collect(method.Type())
1341
+ }
1342
+ case *types.Signature:
1343
+ if typed.Recv() != nil {
1344
+ collect(typed.Recv().Type())
1345
+ }
1346
+ collectTuple(collect, typed.Params())
1347
+ collectTuple(collect, typed.Results())
1348
+ }
1349
+ }
1350
+ for _, semType := range model.types {
1351
+ collect(semType.named)
1352
+ for _, field := range semType.fields {
1353
+ collect(field.typ)
1354
+ }
1355
+ }
1356
+ for _, semFn := range model.functions {
1357
+ collect(semFn.signature)
1358
+ }
1359
+ for _, semValue := range model.values {
1360
+ collect(semValue.typ)
1361
+ }
1362
+ for _, semPkg := range model.packages {
1363
+ for _, assertion := range semPkg.typeAssertions {
1364
+ collect(assertion.source)
1365
+ collect(assertion.target)
1366
+ }
1367
+ for _, fact := range semPkg.nilFacts {
1368
+ collect(fact.typ)
1369
+ }
1370
+ }
1371
+ return interfaces
1372
+ }
1373
+
1374
+ func collectAnonymousInterfaceImplementationCandidates(model *SemanticModel) []*types.Interface {
1375
+ if model == nil {
1376
+ return nil
1377
+ }
1378
+ seen := make(map[*types.Interface]bool)
1379
+ var interfaces []*types.Interface
1380
+ add := func(iface *types.Interface) {
1381
+ if iface == nil || seen[iface] {
1382
+ return
1383
+ }
1384
+ seen[iface] = true
1385
+ interfaces = append(interfaces, iface)
1386
+ }
1387
+ var collect func(types.Type)
1388
+ seenTypes := make(map[types.Type]bool)
1389
+ collect = func(typ types.Type) {
1390
+ if typ == nil {
1391
+ return
1392
+ }
1393
+ typ = types.Unalias(typ)
1394
+ if seenTypes[typ] {
1395
+ return
1396
+ }
1397
+ seenTypes[typ] = true
1398
+ switch typed := typ.(type) {
1399
+ case *types.Named:
1400
+ collect(typed.Underlying())
1401
+ case *types.Pointer:
1402
+ collect(typed.Elem())
1403
+ case *types.Slice:
1404
+ collect(typed.Elem())
1405
+ case *types.Array:
1406
+ collect(typed.Elem())
1407
+ case *types.Map:
1408
+ collect(typed.Key())
1409
+ collect(typed.Elem())
1410
+ case *types.Chan:
1411
+ collect(typed.Elem())
1412
+ case *types.Struct:
1413
+ for field := range typed.Fields() {
1414
+ collect(field.Type())
1415
+ }
1416
+ case *types.Interface:
1417
+ typed.Complete()
1418
+ add(typed)
1419
+ for method := range typed.Methods() {
1420
+ collect(method.Type())
1421
+ }
1422
+ case *types.Signature:
1423
+ if typed.Recv() != nil {
1424
+ collect(typed.Recv().Type())
1425
+ }
1426
+ collectTuple(collect, typed.Params())
1427
+ collectTuple(collect, typed.Results())
1428
+ }
1429
+ }
1430
+ for _, semType := range model.types {
1431
+ collect(semType.named)
1432
+ for _, field := range semType.fields {
1433
+ collect(field.typ)
1434
+ }
1435
+ }
1436
+ for _, semFn := range model.functions {
1437
+ collect(semFn.signature)
1438
+ }
1439
+ for _, semValue := range model.values {
1440
+ collect(semValue.typ)
1441
+ }
1442
+ for _, semPkg := range model.packages {
1443
+ for _, assertion := range semPkg.typeAssertions {
1444
+ collect(assertion.source)
1445
+ collect(assertion.target)
1446
+ }
1447
+ for _, fact := range semPkg.nilFacts {
1448
+ collect(fact.typ)
1449
+ }
1450
+ }
1451
+ return interfaces
1452
+ }
1453
+
1454
+ func collectNamedInterfaceImplementationCandidates(model *SemanticModel) []*types.Named {
1455
+ if model == nil {
1456
+ return nil
1457
+ }
1458
+ seen := make(map[string]bool)
1459
+ var interfaces []*types.Named
1460
+ add := func(named *types.Named) {
1461
+ if named == nil {
1462
+ return
1463
+ }
1464
+ if _, ok := types.Unalias(named.Underlying()).(*types.Interface); !ok {
1465
+ return
1466
+ }
1467
+ key := types.TypeString(named, func(pkg *types.Package) string {
1468
+ if pkg == nil {
1469
+ return ""
1470
+ }
1471
+ return pkg.Path()
1472
+ })
1473
+ if seen[key] {
1474
+ return
1475
+ }
1476
+ seen[key] = true
1477
+ interfaces = append(interfaces, named)
1478
+ }
1479
+ var collect func(types.Type)
1480
+ seenTypes := make(map[types.Type]bool)
1481
+ collect = func(typ types.Type) {
1482
+ if typ == nil {
1483
+ return
1484
+ }
1485
+ typ = types.Unalias(typ)
1486
+ if seenTypes[typ] {
1487
+ return
1488
+ }
1489
+ seenTypes[typ] = true
1490
+ switch typed := typ.(type) {
1491
+ case *types.Named:
1492
+ add(typed)
1493
+ collect(typed.Underlying())
1494
+ case *types.Pointer:
1495
+ collect(typed.Elem())
1496
+ case *types.Slice:
1497
+ collect(typed.Elem())
1498
+ case *types.Array:
1499
+ collect(typed.Elem())
1500
+ case *types.Map:
1501
+ collect(typed.Key())
1502
+ collect(typed.Elem())
1503
+ case *types.Chan:
1504
+ collect(typed.Elem())
1505
+ case *types.Struct:
1506
+ for field := range typed.Fields() {
1507
+ collect(field.Type())
1508
+ }
1509
+ case *types.Interface:
1510
+ typed.Complete()
1511
+ for method := range typed.Methods() {
1512
+ collect(method.Type())
1513
+ }
1514
+ case *types.Signature:
1515
+ if typed.Recv() != nil {
1516
+ collect(typed.Recv().Type())
1517
+ }
1518
+ collectTuple(collect, typed.Params())
1519
+ collectTuple(collect, typed.Results())
1520
+ }
1521
+ }
1522
+ for _, semType := range model.types {
1523
+ collect(semType.named)
1524
+ for _, field := range semType.fields {
1525
+ collect(field.typ)
1526
+ }
1527
+ }
1528
+ for _, semFn := range model.functions {
1529
+ collect(semFn.signature)
1530
+ }
1531
+ for _, semValue := range model.values {
1532
+ collect(semValue.typ)
1533
+ }
1534
+ for _, semPkg := range model.packages {
1535
+ for _, assertion := range semPkg.typeAssertions {
1536
+ collect(assertion.source)
1537
+ collect(assertion.target)
1538
+ }
1539
+ for _, fact := range semPkg.nilFacts {
1540
+ collect(fact.typ)
1541
+ }
1542
+ }
1543
+ return interfaces
1544
+ }
1545
+
1546
+ func collectTuple(collect func(types.Type), tuple *types.Tuple) {
1547
+ if tuple == nil {
1548
+ return
1549
+ }
1550
+ for v := range tuple.Variables() {
1551
+ collect(v.Type())
1552
+ }
1553
+ }
1554
+
1212
1555
  func (o *SemanticModelOwner) applyInterfaceAsyncMethods(
1213
1556
  ctx context.Context,
1214
1557
  model *SemanticModel,
@@ -1226,10 +1569,11 @@ func (o *SemanticModelOwner) applyInterfaceAsyncMethods(
1226
1569
  asyncMethods: make(map[string]bool),
1227
1570
  }
1228
1571
  for methodName, implMethod := range graphEntry.implMethods {
1229
- implFn := model.functions[implMethod]
1572
+ implFn := semanticFunctionFor(model, implMethod)
1230
1573
  if implFn != nil && implFn.async {
1231
1574
  implementation.asyncMethods[methodName] = true
1232
- if ifaceFn := model.functions[graphEntry.ifaceMethods[methodName]]; ifaceFn != nil {
1575
+ model.markInterfaceMethodAsync(graphEntry.ifaceMethods[methodName])
1576
+ if ifaceFn := semanticFunctionFor(model, graphEntry.ifaceMethods[methodName]); ifaceFn != nil {
1233
1577
  markFunctionAsync(ifaceFn, "interface-implementation")
1234
1578
  }
1235
1579
  }
@@ -1238,13 +1582,61 @@ func (o *SemanticModelOwner) applyInterfaceAsyncMethods(
1238
1582
  if !async {
1239
1583
  continue
1240
1584
  }
1241
- markFunctionAsync(model.functions[graphEntry.implMethods[methodName]], "interface-method")
1585
+ markFunctionAsync(semanticFunctionFor(model, graphEntry.implMethods[methodName]), "interface-method")
1242
1586
  }
1243
1587
  model.interfaceImplementations = append(model.interfaceImplementations, implementation)
1244
1588
  }
1245
1589
  return nil
1246
1590
  }
1247
1591
 
1592
+ func (o *SemanticModelOwner) applyAnonymousInterfaceAsyncMethods(
1593
+ ctx context.Context,
1594
+ model *SemanticModel,
1595
+ interfaceGraph []semanticAnonymousInterfaceImplementation,
1596
+ ) []Diagnostic {
1597
+ for _, graphEntry := range interfaceGraph {
1598
+ if err := ctx.Err(); err != nil {
1599
+ return []Diagnostic{contextCanceledDiagnostic(err)}
1600
+ }
1601
+ for methodName, implMethod := range graphEntry.implMethods {
1602
+ if model.functionAsync(implMethod) {
1603
+ model.markInterfaceMethodAsync(graphEntry.ifaceMethods[methodName])
1604
+ }
1605
+ }
1606
+ }
1607
+ return nil
1608
+ }
1609
+
1610
+ func (m *SemanticModel) functionAsync(fn *types.Func) bool {
1611
+ semFn := semanticFunctionFor(m, fn)
1612
+ if semFn != nil && semFn.async {
1613
+ return true
1614
+ }
1615
+ return m.interfaceMethodAsync(fn)
1616
+ }
1617
+
1618
+ func (m *SemanticModel) markInterfaceMethodAsync(fn *types.Func) {
1619
+ if m == nil || fn == nil {
1620
+ return
1621
+ }
1622
+ m.asyncInterfaceMethodObjs[fn] = true
1623
+ key := m.functionFullName(fn)
1624
+ if key != "" {
1625
+ m.asyncInterfaceMethods[key] = true
1626
+ }
1627
+ }
1628
+
1629
+ func (m *SemanticModel) interfaceMethodAsync(fn *types.Func) bool {
1630
+ if m == nil || fn == nil {
1631
+ return false
1632
+ }
1633
+ if m.asyncInterfaceMethodObjs[fn] {
1634
+ return true
1635
+ }
1636
+ key := m.functionFullName(fn)
1637
+ return key != "" && m.asyncInterfaceMethods[key]
1638
+ }
1639
+
1248
1640
  func contextCanceledDiagnostic(err error) Diagnostic {
1249
1641
  return Diagnostic{
1250
1642
  Severity: DiagnosticSeverityError,
@@ -1304,6 +1696,29 @@ func interfaceMethodMap(iface *types.Interface) map[string]*types.Func {
1304
1696
  return methods
1305
1697
  }
1306
1698
 
1699
+ func (m *SemanticModel) functionFullName(fn *types.Func) string {
1700
+ if m == nil || fn == nil {
1701
+ return ""
1702
+ }
1703
+ original := fn
1704
+ if fullName, ok := m.functionFullNames[original]; ok {
1705
+ return fullName
1706
+ }
1707
+ if origin := fn.Origin(); origin != nil && origin != fn {
1708
+ if fullName, ok := m.functionFullNames[origin]; ok {
1709
+ m.functionFullNames[original] = fullName
1710
+ return fullName
1711
+ }
1712
+ fn = origin
1713
+ }
1714
+ fullName := fn.FullName()
1715
+ m.functionFullNames[fn] = fullName
1716
+ if original != fn {
1717
+ m.functionFullNames[original] = fullName
1718
+ }
1719
+ return fullName
1720
+ }
1721
+
1307
1722
  func implementationMethodSets(concretes []*types.Named) []semanticImplementationMethodSet {
1308
1723
  methodSets := make([]semanticImplementationMethodSet, 0, len(concretes)*2)
1309
1724
  for _, concrete := range concretes {
@@ -1378,6 +1793,16 @@ func typeParamTypes(params *types.TypeParamList) []types.Type {
1378
1793
  return args
1379
1794
  }
1380
1795
 
1796
+ func namedOriginOrSelf(named *types.Named) *types.Named {
1797
+ if named == nil {
1798
+ return nil
1799
+ }
1800
+ if origin := named.Origin(); origin != nil {
1801
+ return origin
1802
+ }
1803
+ return named
1804
+ }
1805
+
1381
1806
  func sortNamedTypes(named []*types.Named) {
1382
1807
  slices.SortFunc(named, func(a, b *types.Named) int {
1383
1808
  return cmp.Compare(namedTypeKey(a), namedTypeKey(b))