goscript 0.2.5 → 0.2.7

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 (264) hide show
  1. package/cmd/goscript/cmd-compile.go +7 -0
  2. package/cmd/goscript/cmd_compile_test.go +83 -0
  3. package/compiler/compile-request.go +3 -0
  4. package/compiler/compiler-cache.go +828 -0
  5. package/compiler/compiler-cache_test.go +705 -0
  6. package/compiler/config.go +2 -0
  7. package/compiler/index.test.ts +26 -1
  8. package/compiler/index.ts +5 -0
  9. package/compiler/lowered-program.go +31 -20
  10. package/compiler/lowering.go +349 -93
  11. package/compiler/lowering_bench_test.go +1 -0
  12. package/compiler/override-facts.go +309 -8
  13. package/compiler/override-parity-verifier.go +45 -1
  14. package/compiler/override-parity-verifier_test.go +100 -0
  15. package/compiler/override-registry_test.go +1 -0
  16. package/compiler/package-graph.go +40 -12
  17. package/compiler/package-graph_test.go +29 -0
  18. package/compiler/runtime-contract.go +8 -0
  19. package/compiler/service.go +98 -11
  20. package/compiler/skeleton_test.go +110 -14
  21. package/compiler/typescript-emitter.go +120 -23
  22. package/dist/compiler/index.d.ts +2 -0
  23. package/dist/compiler/index.js +3 -0
  24. package/dist/compiler/index.js.map +1 -1
  25. package/dist/gs/builtin/builtin.d.ts +24 -33
  26. package/dist/gs/builtin/builtin.js +54 -61
  27. package/dist/gs/builtin/builtin.js.map +1 -1
  28. package/dist/gs/builtin/hostio.d.ts +1 -0
  29. package/dist/gs/builtin/hostio.js +1 -1
  30. package/dist/gs/builtin/hostio.js.map +1 -1
  31. package/dist/gs/builtin/index.d.ts +1 -0
  32. package/dist/gs/builtin/index.js +1 -0
  33. package/dist/gs/builtin/index.js.map +1 -1
  34. package/dist/gs/builtin/panic.d.ts +18 -0
  35. package/dist/gs/builtin/panic.js +98 -0
  36. package/dist/gs/builtin/panic.js.map +1 -0
  37. package/dist/gs/builtin/slice.d.ts +10 -0
  38. package/dist/gs/builtin/slice.js +110 -53
  39. package/dist/gs/builtin/slice.js.map +1 -1
  40. package/dist/gs/builtin/type.js +15 -3
  41. package/dist/gs/builtin/type.js.map +1 -1
  42. package/dist/gs/builtin/varRef.d.ts +1 -1
  43. package/dist/gs/builtin/varRef.js +3 -2
  44. package/dist/gs/builtin/varRef.js.map +1 -1
  45. package/dist/gs/bytes/bytes.gs.js +51 -38
  46. package/dist/gs/bytes/bytes.gs.js.map +1 -1
  47. package/dist/gs/bytes/reader.gs.d.ts +1 -1
  48. package/dist/gs/bytes/reader.gs.js +6 -7
  49. package/dist/gs/bytes/reader.gs.js.map +1 -1
  50. package/dist/gs/cmp/index.d.ts +1 -1
  51. package/dist/gs/cmp/index.js +43 -10
  52. package/dist/gs/cmp/index.js.map +1 -1
  53. package/dist/gs/context/context.d.ts +2 -2
  54. package/dist/gs/context/context.js +1 -1
  55. package/dist/gs/context/context.js.map +1 -1
  56. package/dist/gs/embed/index.js +1 -1
  57. package/dist/gs/embed/index.js.map +1 -1
  58. package/dist/gs/encoding/binary/index.js +201 -8
  59. package/dist/gs/encoding/binary/index.js.map +1 -1
  60. package/dist/gs/encoding/json/index.d.ts +5 -0
  61. package/dist/gs/encoding/json/index.js +388 -25
  62. package/dist/gs/encoding/json/index.js.map +1 -1
  63. package/dist/gs/errors/errors.js +17 -24
  64. package/dist/gs/errors/errors.js.map +1 -1
  65. package/dist/gs/fmt/fmt.js +129 -35
  66. package/dist/gs/fmt/fmt.js.map +1 -1
  67. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1 -1
  68. package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -1
  69. package/dist/gs/internal/bytealg/index.js +43 -8
  70. package/dist/gs/internal/bytealg/index.js.map +1 -1
  71. package/dist/gs/internal/byteorder/index.d.ts +2 -2
  72. package/dist/gs/internal/byteorder/index.js +2 -2
  73. package/dist/gs/internal/byteorder/index.js.map +1 -1
  74. package/dist/gs/io/fs/format.js +2 -2
  75. package/dist/gs/io/fs/format.js.map +1 -1
  76. package/dist/gs/io/fs/fs.d.ts +1 -1
  77. package/dist/gs/io/fs/fs.js +1 -1
  78. package/dist/gs/io/fs/fs.js.map +1 -1
  79. package/dist/gs/io/io.d.ts +21 -21
  80. package/dist/gs/io/io.js +49 -50
  81. package/dist/gs/io/io.js.map +1 -1
  82. package/dist/gs/math/bits/index.js +26 -8
  83. package/dist/gs/math/bits/index.js.map +1 -1
  84. package/dist/gs/math/copysign.gs.js +10 -17
  85. package/dist/gs/math/copysign.gs.js.map +1 -1
  86. package/dist/gs/math/pow.gs.js +5 -0
  87. package/dist/gs/math/pow.gs.js.map +1 -1
  88. package/dist/gs/math/signbit.gs.js +6 -2
  89. package/dist/gs/math/signbit.gs.js.map +1 -1
  90. package/dist/gs/mime/index.js +1 -0
  91. package/dist/gs/mime/index.js.map +1 -1
  92. package/dist/gs/net/http/index.d.ts +6 -6
  93. package/dist/gs/net/http/index.js +507 -43
  94. package/dist/gs/net/http/index.js.map +1 -1
  95. package/dist/gs/os/stat.gs.d.ts +2 -2
  96. package/dist/gs/os/types.gs.d.ts +1 -1
  97. package/dist/gs/os/types.gs.js +1 -1
  98. package/dist/gs/os/types.gs.js.map +1 -1
  99. package/dist/gs/os/types_js.gs.d.ts +1 -1
  100. package/dist/gs/os/types_js.gs.js +7 -7
  101. package/dist/gs/os/types_js.gs.js.map +1 -1
  102. package/dist/gs/os/types_unix.gs.d.ts +1 -1
  103. package/dist/gs/os/types_unix.gs.js +1 -1
  104. package/dist/gs/os/types_unix.gs.js.map +1 -1
  105. package/dist/gs/os/zero_copy_posix.gs.d.ts +1 -1
  106. package/dist/gs/os/zero_copy_posix.gs.js +1 -1
  107. package/dist/gs/os/zero_copy_posix.gs.js.map +1 -1
  108. package/dist/gs/path/filepath/match.js +8 -4
  109. package/dist/gs/path/filepath/match.js.map +1 -1
  110. package/dist/gs/path/filepath/path.js +216 -42
  111. package/dist/gs/path/filepath/path.js.map +1 -1
  112. package/dist/gs/path/match.js +6 -3
  113. package/dist/gs/path/match.js.map +1 -1
  114. package/dist/gs/reflect/type.d.ts +5 -4
  115. package/dist/gs/reflect/type.js +29 -11
  116. package/dist/gs/reflect/type.js.map +1 -1
  117. package/dist/gs/slices/slices.js +11 -11
  118. package/dist/gs/slices/slices.js.map +1 -1
  119. package/dist/gs/strconv/atof.gs.js +156 -43
  120. package/dist/gs/strconv/atof.gs.js.map +1 -1
  121. package/dist/gs/strconv/atoi.gs.d.ts +3 -2
  122. package/dist/gs/strconv/atoi.gs.js +86 -67
  123. package/dist/gs/strconv/atoi.gs.js.map +1 -1
  124. package/dist/gs/strconv/ftoa.gs.js +73 -3
  125. package/dist/gs/strconv/ftoa.gs.js.map +1 -1
  126. package/dist/gs/strconv/itoa.gs.d.ts +4 -4
  127. package/dist/gs/strconv/itoa.gs.js +5 -4
  128. package/dist/gs/strconv/itoa.gs.js.map +1 -1
  129. package/dist/gs/strconv/quote.gs.d.ts +1 -1
  130. package/dist/gs/strconv/quote.gs.js +311 -103
  131. package/dist/gs/strconv/quote.gs.js.map +1 -1
  132. package/dist/gs/strings/reader.d.ts +1 -1
  133. package/dist/gs/strings/reader.js +8 -8
  134. package/dist/gs/strings/reader.js.map +1 -1
  135. package/dist/gs/strings/strings.js +87 -61
  136. package/dist/gs/strings/strings.js.map +1 -1
  137. package/dist/gs/sync/atomic/doc_64.gs.d.ts +14 -14
  138. package/dist/gs/sync/atomic/doc_64.gs.js +10 -10
  139. package/dist/gs/sync/atomic/doc_64.gs.js.map +1 -1
  140. package/dist/gs/sync/atomic/type.gs.d.ts +22 -22
  141. package/dist/gs/sync/atomic/type.gs.js +4 -4
  142. package/dist/gs/sync/atomic/type.gs.js.map +1 -1
  143. package/dist/gs/sync/sync.js +50 -12
  144. package/dist/gs/sync/sync.js.map +1 -1
  145. package/dist/gs/syscall/fs.d.ts +6 -6
  146. package/dist/gs/syscall/fs.js +1 -1
  147. package/dist/gs/syscall/fs.js.map +1 -1
  148. package/dist/gs/time/time.d.ts +18 -18
  149. package/dist/gs/time/time.js +58 -55
  150. package/dist/gs/time/time.js.map +1 -1
  151. package/dist/gs/unicode/tables.d.ts +11 -0
  152. package/dist/gs/unicode/tables.js +635 -0
  153. package/dist/gs/unicode/tables.js.map +1 -0
  154. package/dist/gs/unicode/unicode.d.ts +58 -38
  155. package/dist/gs/unicode/unicode.js +362 -278
  156. package/dist/gs/unicode/unicode.js.map +1 -1
  157. package/go.sum +13 -0
  158. package/gs/builtin/builtin.ts +83 -93
  159. package/gs/builtin/hostio.ts +1 -1
  160. package/gs/builtin/index.ts +1 -0
  161. package/gs/builtin/panic.test.ts +189 -0
  162. package/gs/builtin/panic.ts +107 -0
  163. package/gs/builtin/runtime-contract.test.ts +5 -5
  164. package/gs/builtin/slice.test.ts +23 -0
  165. package/gs/builtin/slice.ts +133 -95
  166. package/gs/builtin/type.ts +16 -3
  167. package/gs/builtin/varRef.ts +4 -2
  168. package/gs/builtin/wide-int.test.ts +41 -0
  169. package/gs/bytes/bytes.gs.ts +54 -41
  170. package/gs/bytes/bytes.test.ts +18 -1
  171. package/gs/bytes/reader.gs.ts +7 -8
  172. package/gs/cmp/index.test.ts +55 -0
  173. package/gs/cmp/index.ts +45 -9
  174. package/gs/context/context.ts +3 -3
  175. package/gs/embed/index.ts +2 -2
  176. package/gs/encoding/binary/index.test.ts +104 -0
  177. package/gs/encoding/binary/index.ts +259 -11
  178. package/gs/encoding/json/index.test.ts +107 -0
  179. package/gs/encoding/json/index.ts +400 -29
  180. package/gs/errors/errors.test.ts +44 -1
  181. package/gs/errors/errors.ts +15 -31
  182. package/gs/fmt/fmt.test.ts +70 -2
  183. package/gs/fmt/fmt.ts +128 -34
  184. package/gs/golang.org/x/crypto/cryptobyte/index.ts +1 -1
  185. package/gs/internal/bytealg/index.test.ts +26 -1
  186. package/gs/internal/bytealg/index.ts +44 -8
  187. package/gs/internal/byteorder/index.ts +6 -4
  188. package/gs/io/fs/format.ts +2 -2
  189. package/gs/io/fs/fs.ts +2 -2
  190. package/gs/io/fs/stat.test.ts +2 -2
  191. package/gs/io/fs/sub.test.ts +2 -2
  192. package/gs/io/fs/walk.test.ts +2 -2
  193. package/gs/io/io.test.ts +47 -5
  194. package/gs/io/io.ts +73 -73
  195. package/gs/io/limit.test.ts +103 -0
  196. package/gs/math/bits/index.test.ts +128 -0
  197. package/gs/math/bits/index.ts +26 -8
  198. package/gs/math/copysign.gs.test.ts +3 -1
  199. package/gs/math/copysign.gs.ts +10 -22
  200. package/gs/math/pow.gs.test.ts +4 -5
  201. package/gs/math/pow.gs.ts +5 -0
  202. package/gs/math/signbit.gs.test.ts +2 -1
  203. package/gs/math/signbit.gs.ts +6 -3
  204. package/gs/mime/index.ts +1 -0
  205. package/gs/net/http/index.test.ts +683 -2
  206. package/gs/net/http/index.ts +598 -57
  207. package/gs/net/http/meta.json +3 -0
  208. package/gs/os/stat.gs.ts +2 -2
  209. package/gs/os/types.gs.ts +2 -2
  210. package/gs/os/types_js.gs.ts +9 -9
  211. package/gs/os/types_unix.gs.ts +2 -2
  212. package/gs/os/zero_copy_posix.gs.ts +2 -2
  213. package/gs/path/filepath/match.test.ts +16 -0
  214. package/gs/path/filepath/match.ts +8 -4
  215. package/gs/path/filepath/path.test.ts +91 -9
  216. package/gs/path/filepath/path.ts +223 -49
  217. package/gs/path/match.test.ts +32 -0
  218. package/gs/path/match.ts +6 -3
  219. package/gs/reflect/deepequal.test.ts +1 -1
  220. package/gs/reflect/field.test.ts +1 -1
  221. package/gs/reflect/function-types.test.ts +6 -6
  222. package/gs/reflect/sliceat.test.ts +13 -13
  223. package/gs/reflect/structof.test.ts +4 -4
  224. package/gs/reflect/type.ts +34 -14
  225. package/gs/reflect/typefor.test.ts +5 -5
  226. package/gs/runtime/pprof/index.test.ts +20 -0
  227. package/gs/runtime/trace/index.test.ts +3 -0
  228. package/gs/slices/slices.test.ts +31 -0
  229. package/gs/slices/slices.ts +11 -11
  230. package/gs/strconv/append.test.ts +99 -0
  231. package/gs/strconv/atof.gs.ts +156 -42
  232. package/gs/strconv/atof.test.ts +45 -0
  233. package/gs/strconv/atoi.gs.ts +87 -69
  234. package/gs/strconv/atoi.test.ts +49 -0
  235. package/gs/strconv/ftoa.gs.ts +85 -10
  236. package/gs/strconv/ftoa.test.ts +43 -0
  237. package/gs/strconv/itoa.gs.ts +10 -9
  238. package/gs/strconv/quote.gs.ts +335 -108
  239. package/gs/strconv/quote.test.ts +111 -0
  240. package/gs/strings/reader.test.ts +10 -10
  241. package/gs/strings/reader.ts +9 -9
  242. package/gs/strings/strings.test.ts +18 -5
  243. package/gs/strings/strings.ts +81 -68
  244. package/gs/sync/atomic/doc_64.gs.ts +24 -24
  245. package/gs/sync/atomic/doc_64.test.ts +5 -5
  246. package/gs/sync/atomic/type.gs.ts +28 -28
  247. package/gs/sync/sync.test.ts +109 -1
  248. package/gs/sync/sync.ts +46 -12
  249. package/gs/syscall/fs.ts +8 -8
  250. package/gs/syscall/net.test.ts +1 -1
  251. package/gs/time/parse.test.ts +45 -0
  252. package/gs/time/time.test.ts +46 -23
  253. package/gs/time/time.ts +69 -66
  254. package/gs/unicode/gen.go +198 -0
  255. package/gs/unicode/tables.ts +646 -0
  256. package/gs/unicode/unicode.test.ts +69 -0
  257. package/gs/unicode/unicode.ts +396 -312
  258. package/package.json +2 -2
  259. package/dist/gs/github.com/aperturerobotics/util/conc/index.d.ts +0 -20
  260. package/dist/gs/github.com/aperturerobotics/util/conc/index.js +0 -134
  261. package/dist/gs/github.com/aperturerobotics/util/conc/index.js.map +0 -1
  262. package/gs/github.com/aperturerobotics/util/conc/index.test.ts +0 -30
  263. package/gs/github.com/aperturerobotics/util/conc/index.ts +0 -172
  264. package/gs/github.com/aperturerobotics/util/conc/meta.json +0 -9
@@ -33,12 +33,15 @@ const (
33
33
  RuntimeHelperPrint RuntimeHelper = "builtin.print"
34
34
  RuntimeHelperInt RuntimeHelper = "builtin.int"
35
35
  RuntimeHelperUint RuntimeHelper = "builtin.uint"
36
+ RuntimeHelperInt64 RuntimeHelper = "builtin.int64"
37
+ RuntimeHelperUint64 RuntimeHelper = "builtin.uint64"
36
38
  RuntimeHelperByte RuntimeHelper = "builtin.byte"
37
39
  RuntimeHelperLen RuntimeHelper = "builtin.len"
38
40
  RuntimeHelperCap RuntimeHelper = "builtin.cap"
39
41
  RuntimeHelperClear RuntimeHelper = "builtin.clear"
40
42
  RuntimeHelperPanic RuntimeHelper = "builtin.panic"
41
43
  RuntimeHelperRecover RuntimeHelper = "builtin.recover"
44
+ RuntimeHelperRecovered RuntimeHelper = "builtin.recovered"
42
45
  RuntimeHelperMin RuntimeHelper = "builtin.min"
43
46
  RuntimeHelperMax RuntimeHelper = "builtin.max"
44
47
  RuntimeHelperComplex RuntimeHelper = "builtin.complex"
@@ -103,6 +106,7 @@ const (
103
106
  RuntimeHelperSliceHeaderRef RuntimeHelper = "slice.sliceHeaderRef"
104
107
  RuntimeHelperGenericBytesOrStringToString RuntimeHelper = "slice.genericBytesOrStringToString"
105
108
  RuntimeHelperIndexStringOrBytes RuntimeHelper = "slice.indexStringOrBytes"
109
+ RuntimeHelperArrayIndex RuntimeHelper = "slice.arrayIndex"
106
110
  RuntimeHelperSliceStringOrBytes RuntimeHelper = "slice.sliceStringOrBytes"
107
111
  RuntimeHelperIndexRef RuntimeHelper = "slice.indexRef"
108
112
  RuntimeHelperIndexAddress RuntimeHelper = "slice.indexAddress"
@@ -267,12 +271,15 @@ func runtimeHelperContracts() []RuntimeHelperContract {
267
271
  runtimeHelper(RuntimeHelperPrint, "print", RuntimeHelperCategoryBuiltin),
268
272
  runtimeHelper(RuntimeHelperInt, "int", RuntimeHelperCategoryBuiltin),
269
273
  runtimeHelper(RuntimeHelperUint, "uint", RuntimeHelperCategoryBuiltin),
274
+ runtimeHelper(RuntimeHelperInt64, "int64", RuntimeHelperCategoryBuiltin),
275
+ runtimeHelper(RuntimeHelperUint64, "uint64", RuntimeHelperCategoryBuiltin),
270
276
  runtimeHelper(RuntimeHelperByte, "byte", RuntimeHelperCategoryBuiltin),
271
277
  runtimeHelper(RuntimeHelperLen, "len", RuntimeHelperCategoryBuiltin),
272
278
  runtimeHelper(RuntimeHelperCap, "cap", RuntimeHelperCategoryBuiltin),
273
279
  runtimeHelper(RuntimeHelperClear, "clear", RuntimeHelperCategoryBuiltin),
274
280
  runtimeHelper(RuntimeHelperPanic, "panic", RuntimeHelperCategoryBuiltin),
275
281
  runtimeHelper(RuntimeHelperRecover, "recover", RuntimeHelperCategoryBuiltin),
282
+ runtimeHelper(RuntimeHelperRecovered, "recovered", RuntimeHelperCategoryBuiltin),
276
283
  runtimeHelper(RuntimeHelperMin, "min", RuntimeHelperCategoryBuiltin),
277
284
  runtimeHelper(RuntimeHelperMax, "max", RuntimeHelperCategoryBuiltin),
278
285
  runtimeHelper(RuntimeHelperComplex, "complex", RuntimeHelperCategoryBuiltin),
@@ -334,6 +341,7 @@ func runtimeHelperContracts() []RuntimeHelperContract {
334
341
  runtimeHelper(RuntimeHelperSliceHeaderRef, "sliceHeaderRef", RuntimeHelperCategorySlice),
335
342
  runtimeHelper(RuntimeHelperGenericBytesOrStringToString, "genericBytesOrStringToString", RuntimeHelperCategorySlice),
336
343
  runtimeHelper(RuntimeHelperIndexStringOrBytes, "indexStringOrBytes", RuntimeHelperCategorySlice),
344
+ runtimeHelper(RuntimeHelperArrayIndex, "arrayIndex", RuntimeHelperCategorySlice),
337
345
  runtimeHelper(RuntimeHelperSliceStringOrBytes, "sliceStringOrBytes", RuntimeHelperCategorySlice),
338
346
  runtimeHelper(RuntimeHelperIndexRef, "indexRef", RuntimeHelperCategorySlice),
339
347
  runtimeHelper(RuntimeHelperIndexAddress, "indexAddress", RuntimeHelperCategorySlice),
@@ -12,6 +12,7 @@ type CompileService struct {
12
12
  semanticOwner *SemanticModelOwner
13
13
  loweringOwner *LoweringOwner
14
14
  emitterOwner *TypeScriptEmitOwner
15
+ cacheOwner *CompilerCacheOwner
15
16
  runtimeOwner *RuntimeContractOwner
16
17
  overrideOwner *OverrideRegistryOwner
17
18
  parityOwner *OverrideParityVerifier
@@ -27,6 +28,7 @@ func NewCompileService(overrideDirs ...string) *CompileService {
27
28
  semanticOwner: NewSemanticModelOwner(overrideOwner),
28
29
  loweringOwner: NewLoweringOwner(runtimeOwner, overrideOwner),
29
30
  emitterOwner: NewTypeScriptEmitOwner(runtimeOwner),
31
+ cacheOwner: NewCompilerCacheOwner(),
30
32
  runtimeOwner: runtimeOwner,
31
33
  overrideOwner: overrideOwner,
32
34
  parityOwner: NewOverrideParityVerifier(),
@@ -58,6 +60,11 @@ func (s *CompileService) TypeScriptEmitOwner() *TypeScriptEmitOwner {
58
60
  return s.emitterOwner
59
61
  }
60
62
 
63
+ // CompilerCacheOwner returns the compiler cache owner.
64
+ func (s *CompileService) CompilerCacheOwner() *CompilerCacheOwner {
65
+ return s.cacheOwner
66
+ }
67
+
61
68
  // RuntimeContractOwner returns the runtime contract owner.
62
69
  func (s *CompileService) RuntimeContractOwner() *RuntimeContractOwner {
63
70
  return s.runtimeOwner
@@ -88,6 +95,44 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
88
95
  return NewCompileService(req.OverrideDirs...).Compile(ctx, req)
89
96
  }
90
97
 
98
+ var overrideFacts *OverrideFacts
99
+ var cacheReplayTried bool
100
+ if s.cacheOwner.Enabled(req) {
101
+ graph, graphDiagnostics := s.graphOwner.LoadIdentity(ctx, req)
102
+ diagnostics = append(diagnostics, graphDiagnostics...)
103
+ if graph != nil {
104
+ result.OriginalPackages = append([]string(nil), graph.RequestedPackagePaths...)
105
+ }
106
+ if diagnosticsHaveErrors(diagnostics) {
107
+ result.Diagnostics = diagnostics
108
+ return result, NewCompileError(diagnostics)
109
+ }
110
+
111
+ var factsDiagnostics []Diagnostic
112
+ overrideFacts, factsDiagnostics = s.overrideOwner.Facts(ctx)
113
+ diagnostics = append(diagnostics, factsDiagnostics...)
114
+ if diagnosticsHaveErrors(diagnostics) {
115
+ result.Diagnostics = diagnostics
116
+ return result, NewCompileError(diagnostics)
117
+ }
118
+
119
+ if compilerCacheFastReplayAllowed(req, graph, overrideFacts) {
120
+ overridePlan, overrideDiagnostics := s.overrideOwner.CopyPlan(ctx, req, graph)
121
+ diagnostics = append(diagnostics, overrideDiagnostics...)
122
+ if diagnosticsHaveErrors(diagnostics) {
123
+ result.Diagnostics = diagnostics
124
+ return result, NewCompileError(diagnostics)
125
+ }
126
+ cacheEntries := s.cacheOwner.Entries(req, graph, overridePlan)
127
+ if cached, ok := s.cacheOwner.Replay(ctx, req, cacheEntries); ok {
128
+ cached.OriginalPackages = append([]string(nil), result.OriginalPackages...)
129
+ cached.Diagnostics = diagnostics
130
+ return cached, nil
131
+ }
132
+ cacheReplayTried = true
133
+ }
134
+ }
135
+
91
136
  graph, graphDiagnostics := s.graphOwner.Load(ctx, req)
92
137
  diagnostics = append(diagnostics, graphDiagnostics...)
93
138
  if graph != nil {
@@ -98,11 +143,14 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
98
143
  return result, NewCompileError(diagnostics)
99
144
  }
100
145
 
101
- overrideFacts, factsDiagnostics := s.overrideOwner.Facts(ctx)
102
- diagnostics = append(diagnostics, factsDiagnostics...)
103
- if diagnosticsHaveErrors(diagnostics) {
104
- result.Diagnostics = diagnostics
105
- return result, NewCompileError(diagnostics)
146
+ if overrideFacts == nil {
147
+ var factsDiagnostics []Diagnostic
148
+ overrideFacts, factsDiagnostics = s.overrideOwner.Facts(ctx)
149
+ diagnostics = append(diagnostics, factsDiagnostics...)
150
+ if diagnosticsHaveErrors(diagnostics) {
151
+ result.Diagnostics = diagnostics
152
+ return result, NewCompileError(diagnostics)
153
+ }
106
154
  }
107
155
  parityDiagnostics := s.parityOwner.Verify(ctx, graph, overrideFacts)
108
156
  diagnostics = append(diagnostics, parityDiagnostics...)
@@ -111,6 +159,26 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
111
159
  return result, NewCompileError(diagnostics)
112
160
  }
113
161
 
162
+ var cacheEntries []compilerCacheEntry
163
+ var overridePlan *overrideCopyPlan
164
+ if s.cacheOwner.Enabled(req) {
165
+ var overrideDiagnostics []Diagnostic
166
+ overridePlan, overrideDiagnostics = s.overrideOwner.CopyPlan(ctx, req, graph)
167
+ diagnostics = append(diagnostics, overrideDiagnostics...)
168
+ if diagnosticsHaveErrors(diagnostics) {
169
+ result.Diagnostics = diagnostics
170
+ return result, NewCompileError(diagnostics)
171
+ }
172
+ cacheEntries = s.cacheOwner.Entries(req, graph, overridePlan)
173
+ if !cacheReplayTried {
174
+ if cached, ok := s.cacheOwner.Replay(ctx, req, cacheEntries); ok {
175
+ cached.OriginalPackages = append([]string(nil), result.OriginalPackages...)
176
+ cached.Diagnostics = diagnostics
177
+ return cached, nil
178
+ }
179
+ }
180
+ }
181
+
114
182
  semanticModel, semanticDiagnostics := s.semanticOwner.Build(ctx, graph)
115
183
  diagnostics = append(diagnostics, semanticDiagnostics...)
116
184
  if diagnosticsHaveErrors(diagnostics) {
@@ -118,11 +186,14 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
118
186
  return result, NewCompileError(diagnostics)
119
187
  }
120
188
 
121
- overridePlan, overrideDiagnostics := s.overrideOwner.CopyPlan(ctx, req, graph)
122
- diagnostics = append(diagnostics, overrideDiagnostics...)
123
- if diagnosticsHaveErrors(diagnostics) {
124
- result.Diagnostics = diagnostics
125
- return result, NewCompileError(diagnostics)
189
+ if overridePlan == nil {
190
+ var overrideDiagnostics []Diagnostic
191
+ overridePlan, overrideDiagnostics = s.overrideOwner.CopyPlan(ctx, req, graph)
192
+ diagnostics = append(diagnostics, overrideDiagnostics...)
193
+ if diagnosticsHaveErrors(diagnostics) {
194
+ result.Diagnostics = diagnostics
195
+ return result, NewCompileError(diagnostics)
196
+ }
126
197
  }
127
198
 
128
199
  loweredProgram, loweringDiagnostics := s.loweringOwner.Build(ctx, semanticModel, LoweringOptions{
@@ -130,6 +201,7 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
130
201
  DisplayRoot: req.Dir,
131
202
  OutputPath: req.OutputPath,
132
203
  ProtobufTypeScriptBinding: req.ProtobufTypeScriptBinding,
204
+ TrimTypeInfo: !packageGraphContainsPackage(graph, "reflect"),
133
205
  })
134
206
  diagnostics = append(diagnostics, loweringDiagnostics...)
135
207
  if diagnosticsHaveErrors(diagnostics) {
@@ -137,13 +209,20 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
137
209
  return result, NewCompileError(diagnostics)
138
210
  }
139
211
 
140
- compiledPackages, emitDiagnostics := s.emitterOwner.Emit(ctx, req, loweredProgram)
212
+ files, emitDiagnostics := s.emitterOwner.EmitToMemory(ctx, loweredProgram)
141
213
  diagnostics = append(diagnostics, emitDiagnostics...)
142
214
  if diagnosticsHaveErrors(diagnostics) {
143
215
  result.Diagnostics = diagnostics
144
216
  return result, NewCompileError(diagnostics)
145
217
  }
218
+ compiledPackages, writeDiagnostics := s.emitterOwner.WriteFiles(ctx, req, loweredProgram, files)
219
+ diagnostics = append(diagnostics, writeDiagnostics...)
220
+ if diagnosticsHaveErrors(diagnostics) {
221
+ result.Diagnostics = diagnostics
222
+ return result, NewCompileError(diagnostics)
223
+ }
146
224
  result.CompiledPackages = append(result.CompiledPackages, compiledPackages...)
225
+ s.cacheOwner.StoreGenerated(req, cacheEntries, loweredProgram, files)
147
226
 
148
227
  copiedPackages, copyDiagnostics := s.overrideOwner.CopyPackages(ctx, req, overridePlan)
149
228
  diagnostics = append(diagnostics, copyDiagnostics...)
@@ -153,7 +232,15 @@ func (s *CompileService) Compile(ctx context.Context, req *CompileRequest) (*Com
153
232
  return result, NewCompileError(diagnostics)
154
233
  }
155
234
  result.CopiedPackages = append(result.CopiedPackages, copiedPackages...)
235
+ s.cacheOwner.StoreCopied(req, cacheEntries, overridePlan)
156
236
 
157
237
  result.Diagnostics = diagnostics
158
238
  return result, nil
159
239
  }
240
+
241
+ func compilerCacheFastReplayAllowed(req *CompileRequest, graph *PackageGraph, facts *OverrideFacts) bool {
242
+ if req == nil || req.DependencyMode != DependencyModeAll {
243
+ return false
244
+ }
245
+ return !overrideParityRequiresTypedGraph(graph, facts)
246
+ }
@@ -741,7 +741,7 @@ func TestCompilePackagesLowersWideIntegerConstantsForUint64Targets(t *testing.T)
741
741
  t.Fatal(err.Error())
742
742
  }
743
743
  text := string(content)
744
- for _, want := range []string{`$.uint("18014398509481983", 64)`, `$.uint("9007199254740993", 64)`} {
744
+ for _, want := range []string{`18014398509481983n`, `9007199254740993n`} {
745
745
  if !strings.Contains(text, want) {
746
746
  t.Fatalf("missing wide integer constant %q in generated output:\n%s", want, text)
747
747
  }
@@ -1584,7 +1584,7 @@ func TestCompilePackagesLowersUnsafeBytePointerArithmetic(t *testing.T) {
1584
1584
  t.Fatal(err.Error())
1585
1585
  }
1586
1586
  text := string(content)
1587
- if !strings.Contains(text, "$.indexByteAddress(bits!, $.uint64Shr(idx, 6), 8)") {
1587
+ if !strings.Contains(text, "$.indexByteAddress(bits!, Number($.uint64Shr(idx, 6)), 8)") {
1588
1588
  t.Fatalf("missing byte-addressed unsafe pointer root:\n%s", text)
1589
1589
  }
1590
1590
  if !strings.Contains(text, "$.unsafePointerRef<number>(ptr).value =") {
@@ -1640,7 +1640,7 @@ func TestCompilePackagesLowersGMSUnsafeArrayPointerConversions(t *testing.T) {
1640
1640
  t.Fatal(err.Error())
1641
1641
  }
1642
1642
  text := string(content)
1643
- if !strings.Contains(text, "$.arrayPointerFromIndexRef<number>($.indexRef([n.value], 0), 8, 8, 1)") {
1643
+ if !strings.Contains(text, "$.arrayPointerFromIndexRef<bigint>($.indexRef([n.value], 0), 8, 8, 1)") {
1644
1644
  t.Fatalf("missing scalar unsafe array pointer conversion:\n%s", text)
1645
1645
  }
1646
1646
  if !strings.Contains(text, "$.arrayPointerFromIndexRef<number>($.indexRef($.stringToBytes(str.value), 0), 2147418112, 1, 1)") {
@@ -1714,8 +1714,8 @@ func TestCompilePackagesEmitsStructMethodsAndPointerAssertions(t *testing.T) {
1714
1714
  "Counter.prototype.Set.call(pointer, 2)",
1715
1715
  "Counter.prototype.Set.call(NewCounter(), 5)",
1716
1716
  "let [, ok] = $.typeAssertTuple<Counter | $.VarRef<Counter> | null>(iface, { kind: $.TypeKind.Pointer, elemType: \"main.Counter\" })",
1717
- "{ name: \"Value\", key: \"Value\", type: { kind: $.TypeKind.Basic, name: \"int\" }, tag: \"json:\\\"value\\\"\", index: [0], offset: 0, exported: true }",
1718
- "{ name: \"ID\", key: \"ID\", type: { kind: $.TypeKind.Basic, name: \"int32\", typeName: \"main.ObjectID\" }, index: [1], offset: 8, exported: true }",
1717
+ "{ name: \"Value\", key: \"Value\", type: { kind: $.TypeKind.Basic, name: \"int\" }, tag: \"json:\\\"value\\\"\" }",
1718
+ "{ name: \"ID\", key: \"ID\", type: { kind: $.TypeKind.Basic, name: \"int32\", typeName: \"main.ObjectID\" } }",
1719
1719
  } {
1720
1720
  if !strings.Contains(text, want) {
1721
1721
  t.Fatalf("missing %q in generated output:\n%s", want, text)
@@ -1723,6 +1723,102 @@ func TestCompilePackagesEmitsStructMethodsAndPointerAssertions(t *testing.T) {
1723
1723
  }
1724
1724
  }
1725
1725
 
1726
+ func TestCompilePackagesTypeInfoTrimFollowsReflectReachability(t *testing.T) {
1727
+ source := func(importReflect bool) string {
1728
+ lines := []string{
1729
+ "package main",
1730
+ }
1731
+ if importReflect {
1732
+ lines = append(lines,
1733
+ "import \"reflect\"",
1734
+ "var _ = reflect.TypeOf(Sample{})",
1735
+ )
1736
+ }
1737
+ lines = append(lines,
1738
+ "type Reader interface { Read(v int) string }",
1739
+ "type Sample struct { Name string `json:\"name\"` }",
1740
+ "func (Sample) Read(v int) string { return \"\" }",
1741
+ "func main() {}",
1742
+ "",
1743
+ )
1744
+ return strings.Join(lines, "\n")
1745
+ }
1746
+
1747
+ t.Run("reflect absent trims registration payload", func(t *testing.T) {
1748
+ moduleDir := writePackageGraphFixture(t, map[string]string{
1749
+ "go.mod": "module example.test/typeinfotrim\n\ngo 1.25.3\n",
1750
+ "main.go": source(false),
1751
+ })
1752
+ outputDir := filepath.Join(t.TempDir(), "output")
1753
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir}, nil, nil)
1754
+ if err != nil {
1755
+ t.Fatal(err.Error())
1756
+ }
1757
+
1758
+ if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
1759
+ t.Fatal(err.Error())
1760
+ }
1761
+ content, err := os.ReadFile(filepath.Join(outputDir, "@goscript", "example.test", "typeinfotrim", "main.gs.ts"))
1762
+ if err != nil {
1763
+ t.Fatal(err.Error())
1764
+ }
1765
+ text := string(content)
1766
+ for _, want := range []string{
1767
+ `args: [{ type: { kind: $.TypeKind.Basic, name: "unknown" } }]`,
1768
+ `returns: [{ type: { kind: $.TypeKind.Basic, name: "string" } }]`,
1769
+ `{ name: "Name", key: "Name", type: { kind: $.TypeKind.Basic, name: "string" }, tag: "json:\"name\"" }`,
1770
+ } {
1771
+ if !strings.Contains(text, want) {
1772
+ t.Fatalf("missing trimmed type-info payload %q:\n%s", want, text)
1773
+ }
1774
+ }
1775
+ for _, dropped := range []string{
1776
+ `args: [{ name: "v", type: { kind: $.TypeKind.Basic, name: "int" } }]`,
1777
+ `returns: [{ name: "_r0", type: { kind: $.TypeKind.Basic, name: "string" } }]`,
1778
+ `index: [0]`,
1779
+ `offset: 0`,
1780
+ `exported: true`,
1781
+ } {
1782
+ if strings.Contains(text, dropped) {
1783
+ t.Fatalf("trimmed type-info payload kept %q:\n%s", dropped, text)
1784
+ }
1785
+ }
1786
+ })
1787
+
1788
+ t.Run("reflect reachable keeps full registration payload", func(t *testing.T) {
1789
+ moduleDir := writePackageGraphFixture(t, map[string]string{
1790
+ "go.mod": "module example.test/typeinfofull\n\ngo 1.25.3\n",
1791
+ "main.go": source(true),
1792
+ })
1793
+ outputDir := filepath.Join(t.TempDir(), "output")
1794
+ comp, err := NewCompiler(&Config{Dir: moduleDir, OutputPath: outputDir, AllDependencies: true}, nil, nil)
1795
+ if err != nil {
1796
+ t.Fatal(err.Error())
1797
+ }
1798
+
1799
+ if _, err := comp.CompilePackages(context.Background(), "."); err != nil {
1800
+ t.Fatal(err.Error())
1801
+ }
1802
+ content, err := os.ReadFile(filepath.Join(outputDir, "@goscript", "example.test", "typeinfofull", "main.gs.ts"))
1803
+ if err != nil {
1804
+ t.Fatal(err.Error())
1805
+ }
1806
+ text := string(content)
1807
+ for _, want := range []string{
1808
+ `args: [{ name: "v", type: { kind: $.TypeKind.Basic, name: "int" } }]`,
1809
+ `returns: [{ name: "_r0", type: { kind: $.TypeKind.Basic, name: "string" } }]`,
1810
+ `{ name: "Name", key: "Name", type: { kind: $.TypeKind.Basic, name: "string" }, tag: "json:\"name\"", index: [0], offset: 0, exported: true }`,
1811
+ } {
1812
+ if !strings.Contains(text, want) {
1813
+ t.Fatalf("missing full type-info payload %q:\n%s", want, text)
1814
+ }
1815
+ }
1816
+ if strings.Contains(text, `args: [{ type: { kind: $.TypeKind.Basic, name: "unknown" } }]`) {
1817
+ t.Fatalf("reflect-reachable type-info payload was trimmed:\n%s", text)
1818
+ }
1819
+ })
1820
+ }
1821
+
1726
1822
  func TestCompilePackagesEscapesReservedTypeNames(t *testing.T) {
1727
1823
  moduleDir := writePackageGraphFixture(t, map[string]string{
1728
1824
  "go.mod": "module example.test/reservedtypes\n\ngo 1.25.3\n",
@@ -2129,12 +2225,12 @@ func TestCompilePackagesEmitsArraySliceMapStringAndNamedMethods(t *testing.T) {
2129
2225
  "let empty: $.Slice<number> = $.arrayToSlice<number>([])",
2130
2226
  "let literal: $.Slice<number> = $.arrayToSlice<number>([1, 2])",
2131
2227
  "literal = $.append(literal, 3)",
2132
- "slice![0] = arr[1]",
2228
+ "slice![0] = $.arrayIndex(arr, 1)",
2133
2229
  "let m: globalThis.Map<string, number> | null = $.makeMap<string, number>()",
2134
2230
  "$.mapSet(m, \"one\", 1)",
2135
2231
  "let [value, ok] = $.mapGet<string, number, number>(m, \"missing\", 0)",
2136
2232
  "slice![0]",
2137
- "literal![2]",
2233
+ "$.arrayIndex(literal!, 2)",
2138
2234
  "let list: $.VarRef<MySlice> = $.varRef(null as MySlice)",
2139
2235
  "MySlice_Add(list, 7)",
2140
2236
  "$.indexStringOrBytes(text, 0)",
@@ -2661,7 +2757,7 @@ func TestCompilePackagesEmitsInterfacesMethodValuesTypeSwitchesAndFunctionAssert
2661
2757
  "Read(): string",
2662
2758
  "Close(): string",
2663
2759
  "$.registerInterfaceType(\n\t\"main.ReadCloser\"",
2664
- "{ name: \"Close\", args: [], returns: [{ name: \"_r0\", type: { kind: $.TypeKind.Basic, name: \"string\" } }] }]\n);",
2760
+ "{ name: \"Close\", args: [], returns: [{ type: { kind: $.TypeKind.Basic, name: \"string\" } }] }",
2665
2761
  "((__receiver) => () => __receiver.Inc())($.pointerValue<Counter>(counter))",
2666
2762
  "$.namedFunction(greet, \"main.Greeter\", ({ kind: $.TypeKind.Function, name: \"main.Greeter\"",
2667
2763
  "params: [{ kind: $.TypeKind.Basic, name: \"string\" }]",
@@ -5129,9 +5225,9 @@ func TestCompilePackagesLowersUnaryBitwiseComplement(t *testing.T) {
5129
5225
  }
5130
5226
  text := string(content)
5131
5227
  for _, want := range []string{
5132
- "return $.uint($.uint64Xor(crc, -1n), 64)",
5228
+ "return $.uint64Xor(crc, -1n)",
5133
5229
  "mask = mask & ~((3))",
5134
- "$.println($.int64Xor(value, -1n), $.uint($.uint64Xor(wide, -1n), 64), $.int($.int64Xor(signed, -1n)), $.uint(invert($.uint(wide, 64)), 64), value & ~(3), mask, 0o700)",
5230
+ "$.println(Number($.int64Xor(value, -1n)), $.uint64Xor(wide, -1n), $.int64Xor(signed, -1n), invert(wide), value & ~(3), mask, 0o700)",
5135
5231
  } {
5136
5232
  if !strings.Contains(text, want) {
5137
5233
  t.Fatalf("missing %q in generated output:\n%s", want, text)
@@ -5207,8 +5303,8 @@ func TestCompilePackagesNormalizesWideIntegerReturnTargets(t *testing.T) {
5207
5303
  t.Fatal(err.Error())
5208
5304
  }
5209
5305
  text := string(content)
5210
- if !strings.Contains(text, "return $.uint(await $.pointerValue<Exclude<hash.Hash64, null>>(h).Sum64(), 64)") {
5211
- t.Fatalf("missing uint64 return normalization:\n%s", text)
5306
+ if !strings.Contains(text, "return await $.pointerValue<Exclude<hash.Hash64, null>>(h).Sum64()") {
5307
+ t.Fatalf("missing uint64 return passthrough:\n%s", text)
5212
5308
  }
5213
5309
  }
5214
5310
 
@@ -5362,7 +5458,7 @@ func TestCompilePackagesUnwrapsImportedArrayPackageVarReads(t *testing.T) {
5362
5458
  }
5363
5459
  text := string(content)
5364
5460
  for _, want := range []string{
5365
- "$.pointerValue<number[]>(dep.Table)[1]",
5461
+ "$.arrayIndex($.pointerValue<number[]>(dep.Table), 1)",
5366
5462
  "dep.Sum($.pointerValue<number[]>(dep.Table))",
5367
5463
  } {
5368
5464
  if !strings.Contains(text, want) {
@@ -5450,7 +5546,7 @@ func TestCompilePackagesUnwrapsAliasedArrayPackageVarReads(t *testing.T) {
5450
5546
  }
5451
5547
  text := string(content)
5452
5548
  for _, want := range []string{
5453
- "$.pointerValue<number[]>(__goscript_table.Table)[1]",
5549
+ "$.arrayIndex($.pointerValue<number[]>(__goscript_table.Table), 1)",
5454
5550
  "Sum($.pointerValue<number[]>(__goscript_table.Table))",
5455
5551
  } {
5456
5552
  if !strings.Contains(text, want) {
@@ -56,7 +56,36 @@ func (o *TypeScriptEmitOwner) Emit(
56
56
  if diagnosticsHaveErrors(diagnostics) {
57
57
  return nil, diagnostics
58
58
  }
59
+ return o.WriteFiles(ctx, req, program, files)
60
+ }
61
+
62
+ // WriteFiles writes an in-memory emitted file tree to the request output root.
63
+ func (o *TypeScriptEmitOwner) WriteFiles(
64
+ ctx context.Context,
65
+ req *CompileRequest,
66
+ program *LoweredProgram,
67
+ files map[string]string,
68
+ ) ([]string, []Diagnostic) {
69
+ if err := ctx.Err(); err != nil {
70
+ return nil, []Diagnostic{contextCanceledDiagnostic(err)}
71
+ }
72
+ if req == nil {
73
+ return nil, []Diagnostic{{
74
+ Severity: DiagnosticSeverityError,
75
+ Code: "goscript/emitter:no-request",
76
+ Message: "TypeScript emission requires a compile request",
77
+ }}
78
+ }
79
+ if program == nil {
80
+ return nil, []Diagnostic{{
81
+ Severity: DiagnosticSeverityError,
82
+ Code: "goscript/emitter:no-program",
83
+ Message: "TypeScript emission requires a lowered program",
84
+ }}
85
+ }
86
+
59
87
  var compiled []string
88
+ var diagnostics []Diagnostic
60
89
  for _, pkg := range program.packages {
61
90
  if err := ctx.Err(); err != nil {
62
91
  diagnostics = append(diagnostics, Diagnostic{
@@ -125,14 +154,14 @@ func (o *TypeScriptEmitOwner) EmitToMemory(
125
154
  return files, []Diagnostic{contextCanceledDiagnostic(err)}
126
155
  }
127
156
  for _, file := range pkg.files {
128
- files["@goscript/"+pkg.pkgPath+"/"+file.outputName] = o.renderLoweredFile(pkg, file)
157
+ files["@goscript/"+pkg.pkgPath+"/"+file.outputName] = o.renderLoweredFile(pkg, file, program.trimTypeInfo)
129
158
  }
130
159
  files["@goscript/"+pkg.pkgPath+"/index.ts"] = renderIndex(pkg)
131
160
  }
132
161
  return files, nil
133
162
  }
134
163
 
135
- func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *loweredFile) string {
164
+ func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *loweredFile, trimTypeInfo bool) string {
136
165
  var b strings.Builder
137
166
  b.Grow(estimateLoweredFileSize(file))
138
167
  if file.sourcePath != "" {
@@ -178,7 +207,7 @@ func (o *TypeScriptEmitOwner) renderLoweredFile(pkg *loweredPackage, file *lower
178
207
  writeDecl := func(decl loweredDecl) {
179
208
  if decl.structType != nil {
180
209
  writeSeparator()
181
- renderStruct(&b, decl.structType, o.runtimeOwner)
210
+ renderStruct(&b, decl.structType, o.runtimeOwner, trimTypeInfo)
182
211
  return
183
212
  }
184
213
  if decl.function != nil {
@@ -378,7 +407,7 @@ func structZeroValueDeps(structType *loweredStruct, names map[string]bool) []str
378
407
  return deps
379
408
  }
380
409
 
381
- func renderStruct(b *strings.Builder, structType *loweredStruct, runtimeOwner *RuntimeContractOwner) {
410
+ func renderStruct(b *strings.Builder, structType *loweredStruct, runtimeOwner *RuntimeContractOwner, trimTypeInfo bool) {
382
411
  varRef := runtimeOwner.QualifiedHelper(RuntimeHelperVarRef)
383
412
  markStructValue := runtimeOwner.QualifiedHelper(RuntimeHelperMarkAsStructValue)
384
413
  cloneStructValue := runtimeOwner.QualifiedHelper(RuntimeHelperCloneStructValue)
@@ -524,7 +553,7 @@ func renderStruct(b *strings.Builder, structType *loweredStruct, runtimeOwner *R
524
553
  if idx != 0 {
525
554
  b.WriteString(", ")
526
555
  }
527
- b.WriteString(runtimeMethodSignatureExpr(method))
556
+ b.WriteString(runtimeMethodSignatureExpr(method, trimTypeInfo))
528
557
  }
529
558
  b.WriteString("],\n\t\t")
530
559
  b.WriteString(structType.name)
@@ -533,23 +562,30 @@ func renderStruct(b *strings.Builder, structType *loweredStruct, runtimeOwner *R
533
562
  if idx != 0 {
534
563
  b.WriteString(", ")
535
564
  }
536
- b.WriteString(runtimeStructFieldInfoExpr(
537
- field.runtimeType,
538
- field.name,
539
- field.runtimeName,
540
- field.tag,
541
- field.pkgPath,
542
- field.anonymous,
543
- field.index,
544
- field.offset,
545
- field.exported,
546
- ))
565
+ if trimTypeInfo {
566
+ b.WriteString(trimmedRuntimeStructFieldInfoExpr(field.runtimeType, field.name, field.runtimeName, field.tag, field.anonymous))
567
+ } else {
568
+ b.WriteString(runtimeStructFieldInfoExpr(
569
+ field.runtimeType,
570
+ field.name,
571
+ field.runtimeName,
572
+ field.tag,
573
+ field.pkgPath,
574
+ field.anonymous,
575
+ field.index,
576
+ field.offset,
577
+ field.exported,
578
+ ))
579
+ }
547
580
  }
548
581
  b.WriteString("]\n\t)\n")
549
582
  b.WriteString("}\n")
550
583
  }
551
584
 
552
- func runtimeMethodSignatureExpr(method loweredFunction) string {
585
+ func runtimeMethodSignatureExpr(method loweredFunction, trimTypeInfo bool) string {
586
+ if trimTypeInfo && method.runtimeTrimmedSignature != "" {
587
+ return method.runtimeTrimmedSignature
588
+ }
553
589
  if method.runtimeSignature != "" {
554
590
  return method.runtimeSignature
555
591
  }
@@ -560,6 +596,31 @@ func runtimeMethodSignatureExpr(method loweredFunction) string {
560
596
  return "{ name: " + strconvQuote(methodName) + ", args: [], returns: [] }"
561
597
  }
562
598
 
599
+ func trimmedRuntimeStructFieldInfoExpr(
600
+ runtimeType string,
601
+ storageKey string,
602
+ runtimeName string,
603
+ tag string,
604
+ anonymous bool,
605
+ ) string {
606
+ name := runtimeName
607
+ if name == "" {
608
+ name = storageKey
609
+ }
610
+ fields := []string{
611
+ "name: " + strconvQuote(name),
612
+ "key: " + strconvQuote(storageKey),
613
+ "type: " + runtimeType,
614
+ }
615
+ if tag != "" {
616
+ fields = append(fields, "tag: "+strconvQuote(tag))
617
+ }
618
+ if anonymous {
619
+ fields = append(fields, "anonymous: true")
620
+ }
621
+ return "{ " + strings.Join(fields, ", ") + " }"
622
+ }
623
+
563
624
  func writeLineComment(b *strings.Builder, indent string, comment string) {
564
625
  comment = strings.TrimSpace(comment)
565
626
  if comment == "" {
@@ -619,9 +680,10 @@ func renderFunction(b *strings.Builder, fn *loweredFunction) {
619
680
  }
620
681
  renderStmts(b, fn.paramBindings, 1)
621
682
  renderNamedResults(b, fn.namedResults, 1)
622
- renderDeferStack(b, fn.deferState, 1)
623
- renderStmts(b, fn.body, 1)
624
- renderUnreachableReturn(b, fn, 1)
683
+ renderBodyWithDefer(b, fn, 1)
684
+ if fn.deferState == nil || !fn.deferState.recover {
685
+ renderUnreachableReturn(b, fn, 1)
686
+ }
625
687
  b.WriteString("}\n")
626
688
  }
627
689
 
@@ -663,9 +725,10 @@ func renderMethod(b *strings.Builder, fn *loweredFunction) {
663
725
  }
664
726
  renderStmts(b, fn.paramBindings, 2)
665
727
  renderNamedResults(b, fn.namedResults, 2)
666
- renderDeferStack(b, fn.deferState, 2)
667
- renderStmts(b, fn.body, 2)
668
- renderUnreachableReturn(b, fn, 2)
728
+ renderBodyWithDefer(b, fn, 2)
729
+ if fn.deferState == nil || !fn.deferState.recover {
730
+ renderUnreachableReturn(b, fn, 2)
731
+ }
669
732
  writeIndent(b, 1)
670
733
  b.WriteString("}\n")
671
734
  }
@@ -736,6 +799,40 @@ func renderDeferStack(b *strings.Builder, state *loweredDeferState, indent int)
736
799
  b.WriteString("using __defer = new $.DisposableStack()\n")
737
800
  }
738
801
 
802
+ // renderBodyWithDefer emits the defer stack, body, and trailing return for a
803
+ // function. When the function uses recover, it wraps the defer stack and body in
804
+ // a try/catch so the deferred functions run during stack unwinding (via the
805
+ // using-declaration's disposal) before the catch decides whether the panic was
806
+ // recovered; an unrecovered panic rethrows, a recovered one falls through to the
807
+ // function's named-result return. Functions without recover keep the plain
808
+ // using-declaration shape.
809
+ func renderBodyWithDefer(b *strings.Builder, fn *loweredFunction, indent int) {
810
+ if fn.deferState == nil || !fn.deferState.recover {
811
+ renderDeferStack(b, fn.deferState, indent)
812
+ renderStmts(b, fn.body, indent)
813
+ return
814
+ }
815
+ writeIndent(b, indent)
816
+ b.WriteString("try {\n")
817
+ renderDeferStack(b, fn.deferState, indent+1)
818
+ renderStmts(b, fn.body, indent+1)
819
+ writeIndent(b, indent)
820
+ b.WriteString("} catch (e) {\n")
821
+ writeIndent(b, indent+1)
822
+ b.WriteString("if (!$.recovered(e)) {\n")
823
+ writeIndent(b, indent+2)
824
+ b.WriteString("throw e\n")
825
+ writeIndent(b, indent+1)
826
+ b.WriteString("}\n")
827
+ writeIndent(b, indent)
828
+ b.WriteString("}\n")
829
+ if fn.recoverReturn != "" {
830
+ writeIndent(b, indent)
831
+ b.WriteString(fn.recoverReturn)
832
+ b.WriteString("\n")
833
+ }
834
+ }
835
+
739
836
  func renderStmts(b *strings.Builder, stmts []loweredStmt, indent int) {
740
837
  for idx, stmt := range stmts {
741
838
  renderLeadingLines(b, stmt.leading, indent)
@@ -8,6 +8,8 @@ export interface CompileConfig {
8
8
  output?: string;
9
9
  /** The working directory for the compiler. Defaults to the current working directory. */
10
10
  dir?: string;
11
+ /** Explicit compiler package artifact cache root. Defaults to disabled. */
12
+ compilerCacheRoot?: string;
11
13
  /** Compile all transitive dependencies of the requested package. */
12
14
  allDependencies?: boolean;
13
15
  /** Go import paths to reject from the compiled package graph. */
@@ -28,6 +28,9 @@ export async function compile(config) {
28
28
  if (config.allDependencies) {
29
29
  args.push('--all-dependencies');
30
30
  }
31
+ if (config.compilerCacheRoot) {
32
+ args.push('--compiler-cache-root', path.resolve(config.compilerCacheRoot));
33
+ }
31
34
  const packageBlocklist = normalizePackageBlocklist(config.packageBlocklist);
32
35
  if (packageBlocklist) {
33
36
  args.push('--package-blocklist', packageBlocklist);