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
package/gs/sync/sync.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  // low-level library routines. Higher-level synchronization is better done via
4
4
  // channels and communication.
5
5
 
6
+ import { comparableEqual } from '@goscript/builtin/index.js'
7
+
6
8
  // Locker represents an object that can be locked and unlocked
7
9
  export interface Locker {
8
10
  Lock(): Promise<void>
@@ -334,7 +336,10 @@ export class Map {
334
336
  public async Delete(key: any): Promise<void> {
335
337
  await this._m.Lock()
336
338
  try {
337
- this._data.delete(key)
339
+ const entry = this.findEntry(key)
340
+ if (entry.found) {
341
+ this._data.delete(entry.key)
342
+ }
338
343
  } finally {
339
344
  this._m.Unlock()
340
345
  }
@@ -344,10 +349,11 @@ export class Map {
344
349
  public async CompareAndDelete(key: any, old: any): Promise<boolean> {
345
350
  await this._m.Lock()
346
351
  try {
347
- if (!this._data.has(key) || this._data.get(key) !== old) {
352
+ const entry = this.findEntry(key)
353
+ if (!entry.found || !comparableEqual(entry.value, old)) {
348
354
  return false
349
355
  }
350
- this._data.delete(key)
356
+ this._data.delete(entry.key)
351
357
  return true
352
358
  } finally {
353
359
  this._m.Unlock()
@@ -356,10 +362,11 @@ export class Map {
356
362
 
357
363
  // CompareAndSwap swaps the old and new values for key if the stored value is old.
358
364
  public CompareAndSwap(key: any, old: any, value: any): boolean {
359
- if (!this._data.has(key) || this._data.get(key) !== old) {
365
+ const entry = this.findEntry(key)
366
+ if (!entry.found || !comparableEqual(entry.value, old)) {
360
367
  return false
361
368
  }
362
- this._data.set(key, value)
369
+ this._data.set(entry.key, value)
363
370
  return true
364
371
  }
365
372
 
@@ -367,8 +374,8 @@ export class Map {
367
374
  public async Load(key: any): Promise<[any, boolean]> {
368
375
  await this._m.RLock()
369
376
  try {
370
- const value = this._data.get(key)
371
- return [value, this._data.has(key)]
377
+ const entry = this.findEntry(key)
378
+ return entry.found ? [entry.value, true] : [undefined, false]
372
379
  } finally {
373
380
  this._m.RUnlock()
374
381
  }
@@ -378,10 +385,12 @@ export class Map {
378
385
  public async LoadAndDelete(key: any): Promise<[any, boolean]> {
379
386
  await this._m.Lock()
380
387
  try {
381
- const value = this._data.get(key)
382
- const loaded = this._data.has(key)
383
- this._data.delete(key)
384
- return [value, loaded]
388
+ const entry = this.findEntry(key)
389
+ if (!entry.found) {
390
+ return [undefined, false]
391
+ }
392
+ this._data.delete(entry.key)
393
+ return [entry.value, true]
385
394
  } finally {
386
395
  this._m.Unlock()
387
396
  }
@@ -391,8 +400,9 @@ export class Map {
391
400
  public async LoadOrStore(key: any, value: any): Promise<[any, boolean]> {
392
401
  await this._m.Lock()
393
402
  try {
394
- if (this._data.has(key)) {
395
- return [this._data.get(key), true]
403
+ const entry = this.findEntry(key)
404
+ if (entry.found) {
405
+ return [entry.value, true]
396
406
  }
397
407
  this._data.set(key, value)
398
408
  return [value, false]
@@ -423,12 +433,27 @@ export class Map {
423
433
  public async Store(key: any, value: any): Promise<void> {
424
434
  await this._m.Lock()
425
435
  try {
426
- this._data.set(key, value)
436
+ const entry = this.findEntry(key)
437
+ this._data.set(entry.found ? entry.key : key, value)
427
438
  } finally {
428
439
  this._m.Unlock()
429
440
  }
430
441
  }
431
442
 
443
+ private findEntry(
444
+ key: any,
445
+ ): { found: false } | { found: true; key: any; value: any } {
446
+ if (this._data.has(key)) {
447
+ return { found: true, key, value: this._data.get(key) }
448
+ }
449
+ for (const [candidate, value] of this._data.entries()) {
450
+ if (candidate !== key && comparableEqual(candidate, key)) {
451
+ return { found: true, key: candidate, value }
452
+ }
453
+ }
454
+ return { found: false }
455
+ }
456
+
432
457
  // Swap swaps the value for a key and returns the previous value if any
433
458
  public async Swap(key: any, value: any): Promise<[any, boolean]> {
434
459
  await this._m.Lock()
@@ -458,12 +483,12 @@ export class Pool {
458
483
  }
459
484
 
460
485
  // Get selects an arbitrary item from the Pool, removes it from the Pool, and returns it to the caller
461
- public Get(): any {
486
+ public async Get(): Promise<any> {
462
487
  if (this._pool.length > 0) {
463
488
  return this._pool.pop()
464
489
  }
465
490
  if (this.New) {
466
- return this.New()
491
+ return await this.New()
467
492
  }
468
493
  return null
469
494
  }
@@ -0,0 +1,18 @@
1
+ import { describe, expect, test } from 'vitest'
2
+
3
+ import * as $ from '@goscript/builtin/index.js'
4
+
5
+ import { ValueOf } from './index.js'
6
+
7
+ describe('syscall/js override', () => {
8
+ test('ValueOf unwraps generated interface numeric boxes', () => {
9
+ const value = ValueOf(
10
+ $.namedValueInterfaceValue(41, 'int', {}, {
11
+ kind: $.TypeKind.Basic,
12
+ name: 'int',
13
+ }),
14
+ )
15
+
16
+ expect(value.Int()).toBe(41)
17
+ })
18
+ })
@@ -365,6 +365,9 @@ export function ValueOf(x: unknown): Value {
365
365
  if (x instanceof Func) {
366
366
  return x.Value.clone()
367
367
  }
368
+ if (isGoInterfaceValue(x)) {
369
+ return ValueOf(x.__goValue)
370
+ }
368
371
  if (x === null || x === undefined) {
369
372
  return Null()
370
373
  }
@@ -394,6 +397,15 @@ export function ValueOf(x: unknown): Value {
394
397
  return new Value({ raw: x })
395
398
  }
396
399
 
400
+ function isGoInterfaceValue(value: unknown): value is { __goValue: unknown } {
401
+ return (
402
+ value !== null &&
403
+ typeof value === 'object' &&
404
+ '__goValue' in value &&
405
+ typeof (value as { __goType?: unknown }).__goType === 'string'
406
+ )
407
+ }
408
+
397
409
  export function FuncOf(
398
410
  fn: (this$: Value, args: $.Slice<Value>) => unknown,
399
411
  ): Func {
@@ -1,4 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest'
2
+ import { existsSync, writeFileSync } from 'node:fs'
3
+ import { join } from 'node:path'
2
4
 
3
5
  import { B, F, Short, T, type TB } from './testing.js'
4
6
  import { runTests } from './testing.js'
@@ -101,7 +103,9 @@ describe('testing.T', () => {
101
103
 
102
104
  t.Cleanup(null)
103
105
 
104
- await expect(t.runCleanups()).rejects.toThrow('testing: nil cleanup function')
106
+ await expect(t.runCleanups()).rejects.toThrow(
107
+ 'testing: nil cleanup function',
108
+ )
105
109
  })
106
110
 
107
111
  it('returns a non-nil context', () => {
@@ -110,6 +114,21 @@ describe('testing.T', () => {
110
114
  expect(t.Context()).not.toBeNull()
111
115
  })
112
116
 
117
+ it('creates unique TempDir paths and removes them during cleanup', async () => {
118
+ const t = new T('root')
119
+
120
+ const first = t.TempDir()
121
+ const second = t.TempDir()
122
+ expect(first).not.toBe(second)
123
+ writeFileSync(join(first, 'marker.txt'), 'marker')
124
+ expect(existsSync(first)).toBe(true)
125
+
126
+ await t.runCleanups()
127
+
128
+ expect(existsSync(first)).toBe(false)
129
+ expect(existsSync(second)).toBe(false)
130
+ })
131
+
113
132
  it('formats common testing printf verbs', () => {
114
133
  const t = new T('root')
115
134
  const messages: string[] = []
@@ -118,13 +137,23 @@ describe('testing.T', () => {
118
137
  messages.push(String(message))
119
138
  }
120
139
  try {
121
- t.Logf('quoted=%q value=%#v plus=%+v number=%d string=%s plain=%v', 'key', 7, { ok: true }, 3, 'ok', true)
140
+ t.Logf(
141
+ 'quoted=%q value=%#v plus=%+v number=%d string=%s plain=%v',
142
+ 'key',
143
+ 7,
144
+ { ok: true },
145
+ 3,
146
+ 'ok',
147
+ true,
148
+ )
122
149
  t.flushLogs()
123
150
  } finally {
124
151
  console.log = originalLog
125
152
  }
126
153
 
127
- expect(messages).toEqual([' quoted="key" value=7 plus=[object Object] number=3 string=ok plain=true'])
154
+ expect(messages).toEqual([
155
+ ' quoted="key" value=7 plus=[object Object] number=3 string=ok plain=true',
156
+ ])
128
157
  })
129
158
 
130
159
  it('formats Go-style error objects with Error methods', () => {
@@ -1,4 +1,4 @@
1
- import { mkdirSync } from 'node:fs'
1
+ import * as nodeFS from 'node:fs'
2
2
  import { tmpdir } from 'node:os'
3
3
  import { join } from 'node:path'
4
4
 
@@ -153,20 +153,23 @@ export class T {
153
153
  }
154
154
 
155
155
  public TempDir(): string {
156
- const path = join(
157
- tmpdir(),
158
- 'goscript-test-' +
159
- this.testName.replace(/[^A-Za-z0-9_.-]/g, '_') +
160
- '-' +
161
- String(this.tempDirs.length),
156
+ const path = (nodeFS as any).mkdtempSync(
157
+ join(
158
+ tmpdir(),
159
+ 'goscript-test-' +
160
+ this.testName.replace(/[^A-Za-z0-9_.-]/g, '_') +
161
+ '-' +
162
+ String(this.tempDirs.length),
163
+ ) + '-',
162
164
  )
163
- mkdirSync(path, { recursive: true })
164
165
  this.tempDirs.push(path)
166
+ this.Cleanup(() => {
167
+ ;(nodeFS as any).rmSync(path, { force: true, recursive: true })
168
+ })
165
169
  return path
166
170
  }
167
171
 
168
- public Parallel(): void {
169
- }
172
+ public Parallel(): void {}
170
173
 
171
174
  public Setenv(key: string, value: string): void {
172
175
  const proc = (globalThis as any).process as
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "goscript",
3
3
  "description": "Go to TypeScript transpiler",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "author": {
6
6
  "name": "Aperture Robotics LLC.",
7
7
  "email": "support@aperture.us",