goscript 0.1.3 → 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.
- package/cmd/goscript/cmd_compile.go +28 -8
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/gotest/runner_test.go +127 -0
- package/compiler/lowering.go +596 -136
- package/compiler/lowering_bench_test.go +350 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/semantic-model-types.go +8 -0
- package/compiler/semantic-model.go +447 -22
- package/compiler/semantic-model_test.go +138 -0
- package/compiler/skeleton_test.go +948 -14
- package/compiler/typescript-emitter.go +19 -2
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.js +5 -0
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +1 -1
- package/dist/gs/builtin/type.js +72 -5
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +3 -3
- package/dist/gs/compress/zlib/index.js +88 -26
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +118 -6
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/io/fs/readdir.js +5 -3
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/io.d.ts +10 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +26 -5
- package/dist/gs/math/bits/index.js +13 -24
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +3 -1
- package/dist/gs/net/http/index.js +18 -1
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +169 -8
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +1 -0
- package/dist/gs/reflect/type.js +80 -51
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +2 -2
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +8 -6
- package/dist/gs/testing/testing.js.map +1 -1
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +45 -0
- package/gs/builtin/slice.ts +7 -0
- package/gs/builtin/type.ts +85 -5
- package/gs/compress/zlib/index.test.ts +97 -0
- package/gs/compress/zlib/index.ts +117 -27
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +8 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +139 -11
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +7 -3
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +114 -52
- package/gs/io/meta.json +7 -1
- package/gs/math/bits/index.ts +52 -28
- package/gs/net/http/index.test.ts +16 -0
- package/gs/net/http/index.ts +19 -2
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/types_js.gs.ts +169 -8
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/type.ts +91 -56
- package/gs/reflect/typefor.test.ts +31 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +32 -3
- package/gs/testing/testing.ts +13 -10
- 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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
371
|
-
return [value,
|
|
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
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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
|
-
|
|
395
|
-
|
|
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.
|
|
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
|
+
})
|
package/gs/syscall/js/index.ts
CHANGED
|
@@ -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(
|
|
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(
|
|
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([
|
|
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', () => {
|
package/gs/testing/testing.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
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 =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|