goscript 0.0.59 → 0.0.60

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.
@@ -2,7 +2,6 @@ package compiler
2
2
 
3
3
  import (
4
4
  "encoding/json"
5
- "fmt"
6
5
  "go/ast"
7
6
  "go/token"
8
7
  "go/types"
@@ -1472,6 +1471,14 @@ func (a *Analysis) loadGsMetadata(metaFilePath string) *GsMetadata {
1472
1471
  return &metadata
1473
1472
  }
1474
1473
 
1474
+ // isHandwrittenPackage checks if a package path corresponds to a handwritten package in gs/
1475
+ func (a *Analysis) isHandwrittenPackage(pkgPath string) bool {
1476
+ // Check if the package exists in the embedded gs/ directory
1477
+ metaFilePath := filepath.Join("gs", pkgPath, "meta.json")
1478
+ _, err := goscript.GsOverrides.ReadFile(metaFilePath)
1479
+ return err == nil
1480
+ }
1481
+
1475
1482
  // IsMethodAsync checks if a method call is async based on package metadata
1476
1483
  func (a *Analysis) IsMethodAsync(pkgPath, typeName, methodName string) bool {
1477
1484
  // First, check pre-computed method async status
@@ -2246,13 +2253,49 @@ func (v *analysisVisitor) analyzeAllMethodsAsync() {
2246
2253
  // Initialize visitingMethods map
2247
2254
  v.visitingMethods = make(map[MethodKey]bool)
2248
2255
 
2249
- // Analyze methods in current package
2250
- v.analyzePackageMethodsAsync(v.pkg)
2256
+ // Fixed-point iteration: keep analyzing until nothing changes
2257
+ // This handles cases where method A calls method B, but B is analyzed after A
2258
+ maxIterations := 10
2259
+ for iteration := 0; iteration < maxIterations; iteration++ {
2260
+ // Clear visitingMethods map for this iteration
2261
+ v.visitingMethods = make(map[MethodKey]bool)
2251
2262
 
2252
- // Analyze methods in all dependency packages
2253
- for _, pkg := range v.analysis.AllPackages {
2254
- if pkg != v.pkg {
2255
- v.analyzePackageMethodsAsync(pkg)
2263
+ // Track if anything changed in this iteration
2264
+ changed := false
2265
+
2266
+ // Save previous state
2267
+ previousState := make(map[MethodKey]bool)
2268
+ for k, v := range v.analysis.MethodAsyncStatus {
2269
+ previousState[k] = v
2270
+ }
2271
+
2272
+ // Re-analyze methods in current package
2273
+ v.analyzePackageMethodsAsync(v.pkg)
2274
+
2275
+ // Re-analyze methods in all dependency packages
2276
+ for _, pkg := range v.analysis.AllPackages {
2277
+ if pkg != v.pkg {
2278
+ v.analyzePackageMethodsAsync(pkg)
2279
+ }
2280
+ }
2281
+
2282
+ // Check if anything changed
2283
+ for k, newValue := range v.analysis.MethodAsyncStatus {
2284
+ oldValue, existed := previousState[k]
2285
+ if !existed {
2286
+ // New method added - check if it's async (if sync, no need to re-analyze dependents)
2287
+ if newValue {
2288
+ changed = true
2289
+ }
2290
+ } else if oldValue != newValue {
2291
+ // Method changed from sync to async (or vice versa)
2292
+ changed = true
2293
+ }
2294
+ }
2295
+
2296
+ // If nothing changed, we've reached a fixed point
2297
+ if !changed {
2298
+ break
2256
2299
  }
2257
2300
  }
2258
2301
 
@@ -2311,11 +2354,6 @@ func (v *analysisVisitor) analyzeFunctionLiteralAsync(funcLit *ast.FuncLit, pkg
2311
2354
  func (v *analysisVisitor) analyzeMethodAsync(funcDecl *ast.FuncDecl, pkg *packages.Package) {
2312
2355
  methodKey := v.getMethodKey(funcDecl, pkg)
2313
2356
 
2314
- // Check if already analyzed
2315
- if _, exists := v.analysis.MethodAsyncStatus[methodKey]; exists {
2316
- return
2317
- }
2318
-
2319
2357
  // Check for cycles
2320
2358
  if v.visitingMethods[methodKey] {
2321
2359
  // Cycle detected, assume sync to break recursion
@@ -2329,17 +2367,32 @@ func (v *analysisVisitor) analyzeMethodAsync(funcDecl *ast.FuncDecl, pkg *packag
2329
2367
  // Determine if method is async
2330
2368
  isAsync := false
2331
2369
 
2332
- // Determine if this is a truly external package vs a package being compiled locally
2333
- isExternalPackage := pkg.Types != v.pkg.Types && v.analysis.AllPackages[pkg.Types.Path()] == nil
2370
+ // Determine if this is a handwritten package (from gs/ directory)
2371
+ // Handwritten packages should not have their bodies analyzed
2372
+ isHandwrittenPackage := v.analysis.isHandwrittenPackage(methodKey.PackagePath)
2334
2373
 
2335
- if isExternalPackage {
2336
- // Truly external package: check metadata first
2337
- isAsync = v.checkExternalMethodMetadata(methodKey.PackagePath, methodKey.ReceiverType, methodKey.MethodName)
2338
- }
2339
- // If not determined async yet and body exists, analyze it
2340
- if !isAsync && funcDecl.Body != nil {
2374
+ if isHandwrittenPackage {
2375
+ // For handwritten packages, check if we have pre-loaded metadata
2376
+ metadataKey := MethodKey{
2377
+ PackagePath: methodKey.PackagePath,
2378
+ ReceiverType: methodKey.ReceiverType,
2379
+ MethodName: methodKey.MethodName,
2380
+ }
2381
+ metadataIsAsync, hasMetadata := v.analysis.MethodAsyncStatus[metadataKey]
2382
+
2383
+ if hasMetadata {
2384
+ // Use explicit metadata from handwritten packages (gs/)
2385
+ isAsync = metadataIsAsync
2386
+ } else {
2387
+ // Handwritten package but no explicit metadata: assume sync
2388
+ isAsync = false
2389
+ }
2390
+ } else if funcDecl.Body != nil {
2391
+ // Not a handwritten package and has body: always analyze for async operations
2392
+ // This allows fixed-point iteration to update results
2341
2393
  isAsync = v.containsAsyncOperationsComplete(funcDecl.Body, pkg)
2342
2394
  }
2395
+ // Otherwise leave isAsync as false
2343
2396
 
2344
2397
  // Store result in MethodAsyncStatus
2345
2398
  v.analysis.MethodAsyncStatus[methodKey] = isAsync
@@ -2417,16 +2470,8 @@ func (v *analysisVisitor) containsAsyncOperationsComplete(node ast.Node, pkg *pa
2417
2470
 
2418
2471
  case *ast.CallExpr:
2419
2472
  // Check if we're calling a function known to be async
2420
- isCallAsyncResult := v.isCallAsync(s, pkg)
2421
- if isCallAsyncResult {
2473
+ if v.isCallAsync(s, pkg) {
2422
2474
  hasAsync = true
2423
- callName := ""
2424
- if ident, ok := s.Fun.(*ast.Ident); ok {
2425
- callName = ident.Name
2426
- } else if sel, ok := s.Fun.(*ast.SelectorExpr); ok {
2427
- callName = sel.Sel.Name
2428
- }
2429
- asyncReasons = append(asyncReasons, fmt.Sprintf("async call: %s", callName))
2430
2475
  return false
2431
2476
  }
2432
2477
  }
package/go.mod CHANGED
@@ -3,18 +3,18 @@ module github.com/aperturerobotics/goscript
3
3
  go 1.25.3
4
4
 
5
5
  require (
6
- github.com/aperturerobotics/cli v1.0.0
6
+ github.com/aperturerobotics/cli v1.0.1
7
7
  github.com/aperturerobotics/protobuf-go-lite v0.11.0
8
- github.com/aperturerobotics/util v1.31.3
8
+ github.com/aperturerobotics/util v1.31.4
9
9
  github.com/pkg/errors v0.9.1
10
10
  github.com/sirupsen/logrus v1.9.3
11
11
  golang.org/x/tools v0.38.0
12
12
  )
13
13
 
14
14
  require (
15
- github.com/aperturerobotics/common v0.22.10 // indirect
15
+ github.com/aperturerobotics/common v0.22.12 // indirect
16
16
  github.com/aperturerobotics/json-iterator-lite v1.0.1-0.20240713111131-be6bf89c3008 // indirect
17
- github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
17
+ github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
18
18
  golang.org/x/mod v0.29.0 // indirect
19
19
  golang.org/x/sync v0.17.0 // indirect
20
20
  golang.org/x/sys v0.37.0 // indirect
package/go.sum CHANGED
@@ -1,13 +1,19 @@
1
1
  github.com/aperturerobotics/cli v1.0.0 h1:s3xT2h7eBih4/4yZKTn/HQ6P+qpk6ygWZl2416xAI1M=
2
2
  github.com/aperturerobotics/cli v1.0.0/go.mod h1:wtlINjMcKuwyV1x4ftReuA6hHZcPB8kPMXHyQqGFCSc=
3
+ github.com/aperturerobotics/cli v1.0.1 h1:9KsECHGESJ/iGU13Z4zNQzKFz5bMave4bA6lPXGjtOU=
4
+ github.com/aperturerobotics/cli v1.0.1/go.mod h1:s1Gh4eTOGGlrPqpyi/q8aIQwk0T6yDCF7C2xPyBMtek=
3
5
  github.com/aperturerobotics/common v0.22.10 h1:XFfXq9NGrirjW6rtqq525qiY1IN+1siGBZwIsvBJGfQ=
4
6
  github.com/aperturerobotics/common v0.22.10/go.mod h1:xMXHNN6oCvG0FfG1tY6+2Si7iWh1QfSSCSrqohFUeIk=
7
+ github.com/aperturerobotics/common v0.22.12 h1:uSo+fDQg6xCoNI34Y7gueW1cW9Cy4d/2FQb/T006LZQ=
8
+ github.com/aperturerobotics/common v0.22.12/go.mod h1:xMXHNN6oCvG0FfG1tY6+2Si7iWh1QfSSCSrqohFUeIk=
5
9
  github.com/aperturerobotics/json-iterator-lite v1.0.1-0.20240713111131-be6bf89c3008 h1:So9JeziaWKx2Fw8sK4AUN/szqKtJ0jEMhS6bU4sHbxs=
6
10
  github.com/aperturerobotics/json-iterator-lite v1.0.1-0.20240713111131-be6bf89c3008/go.mod h1:snaApCEDtrHHP6UWSLKiYNOZU9A5NyzccKenx9oZEzg=
7
11
  github.com/aperturerobotics/protobuf-go-lite v0.11.0 h1:IAaZISqrEpodqECYxk0yKWgROEbZtMhs7bErP+Zma9o=
8
12
  github.com/aperturerobotics/protobuf-go-lite v0.11.0/go.mod h1:c4kGy7Dkfz6B1m0t4QBIMQoNeQ7m+nYj3Qxxnlwhygo=
9
13
  github.com/aperturerobotics/util v1.31.3 h1:3irvlwlwwvOl4jD2lHg/N8bBp9B/3kx9Ec4qlJxQKEU=
10
14
  github.com/aperturerobotics/util v1.31.3/go.mod h1:G5yKUDojt6uzVvs7kGByey0lBfKdDg4O4jXmdkSqO6Y=
15
+ github.com/aperturerobotics/util v1.31.4 h1:2F4j5CML/Hb4dQT1E1pjkZd3AdJhsAQiaRCR9pD/dwo=
16
+ github.com/aperturerobotics/util v1.31.4/go.mod h1:qfeWUnkC60QpjxH4yocO6Q/No+J1E488yzuconPgF8c=
11
17
  github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
12
18
  github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
13
19
  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -25,6 +31,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
25
31
  github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
26
32
  github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
27
33
  github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
34
+ github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg=
35
+ github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
28
36
  golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
29
37
  golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
30
38
  golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "goscript",
3
3
  "description": "Go to TypeScript transpiler",
4
- "version": "0.0.59",
4
+ "version": "0.0.60",
5
5
  "author": {
6
6
  "name": "Aperture Robotics LLC.",
7
7
  "email": "support@aperture.us",