goscript 0.0.49 → 0.0.50
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/compiler/analysis.go +1003 -557
- package/compiler/analysis_test.go +12 -15
- package/compiler/compiler.go +69 -37
- package/compiler/decl.go +22 -0
- package/compiler/expr-call-async.go +46 -52
- package/compiler/expr-call-type-conversion.go +6 -10
- package/compiler/expr-call.go +58 -27
- package/compiler/spec-value.go +2 -2
- package/compiler/spec.go +84 -40
- package/compiler/stmt-assign.go +7 -4
- package/compiler/stmt.go +63 -5
- package/compiler/type.go +13 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/context/context.d.ts +16 -18
- package/dist/gs/context/context.js +23 -13
- package/dist/gs/context/context.js.map +1 -1
- package/dist/gs/fmt/fmt.js +3 -1
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/reflect/type.js +5 -8
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/time/time.d.ts +2 -1
- package/dist/gs/time/time.js +29 -19
- package/dist/gs/time/time.js.map +1 -1
- package/gs/builtin/builtin.ts +1 -7
- package/gs/context/context.ts +63 -45
- package/gs/fmt/fmt.ts +5 -1
- package/gs/reflect/type.ts +5 -10
- package/gs/time/time.ts +35 -21
- package/package.json +2 -2
- package/gs/TODO.md +0 -129
package/gs/context/context.ts
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
import * as $ from '@goscript/builtin/index.js'
|
|
2
2
|
|
|
3
|
-
export const Canceled =
|
|
4
|
-
Canceled.name = 'CanceledError'
|
|
3
|
+
export const Canceled = $.newError('context canceled')
|
|
5
4
|
|
|
6
|
-
export
|
|
7
|
-
constructor() {
|
|
8
|
-
super('context deadline exceeded')
|
|
9
|
-
this.name = 'DeadlineExceededError'
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
export const DeadlineExceeded = new DeadlineExceededError()
|
|
5
|
+
export const DeadlineExceeded = $.newError('context deadline exceeded')
|
|
13
6
|
|
|
14
7
|
// Function types
|
|
15
8
|
export type CancelFunc = () => void
|
|
16
|
-
export type CancelCauseFunc = (cause:
|
|
9
|
+
export type CancelCauseFunc = (cause: $.GoError) => void
|
|
17
10
|
|
|
18
11
|
// Context interface matching Go's context.Context
|
|
19
|
-
export
|
|
12
|
+
export type Context = null | {
|
|
20
13
|
// Deadline returns the time when work done on behalf of this context should be canceled
|
|
21
14
|
Deadline(): [Date | null, boolean]
|
|
22
15
|
|
|
@@ -24,17 +17,20 @@ export interface Context {
|
|
|
24
17
|
Done(): $.Channel<{}>
|
|
25
18
|
|
|
26
19
|
// Err returns a non-nil error value after Done is closed
|
|
27
|
-
Err():
|
|
20
|
+
Err(): $.GoError
|
|
28
21
|
|
|
29
22
|
// Value returns the value associated with this context for key, or null
|
|
30
23
|
Value(key: any): any
|
|
31
24
|
}
|
|
32
25
|
|
|
26
|
+
// ContextNonNil is a non-nil context
|
|
27
|
+
export type ContextNonNil = Exclude<Context, null>
|
|
28
|
+
|
|
33
29
|
// Base implementation for all contexts
|
|
34
|
-
abstract class baseContext implements
|
|
30
|
+
abstract class baseContext implements ContextNonNil {
|
|
35
31
|
abstract Deadline(): [Date | null, boolean]
|
|
36
32
|
abstract Done(): $.Channel<{}>
|
|
37
|
-
abstract Err():
|
|
33
|
+
abstract Err(): $.GoError
|
|
38
34
|
abstract Value(key: any): any
|
|
39
35
|
}
|
|
40
36
|
|
|
@@ -54,7 +50,7 @@ class backgroundContext extends baseContext {
|
|
|
54
50
|
return backgroundContext.neverClosedChannel
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
Err():
|
|
53
|
+
Err(): $.GoError {
|
|
58
54
|
return null
|
|
59
55
|
}
|
|
60
56
|
|
|
@@ -66,14 +62,14 @@ class backgroundContext extends baseContext {
|
|
|
66
62
|
// Value context wraps a parent and adds a key-value pair
|
|
67
63
|
class valueContext extends baseContext {
|
|
68
64
|
constructor(
|
|
69
|
-
private parent:
|
|
65
|
+
private parent: ContextNonNil,
|
|
70
66
|
private key: any,
|
|
71
67
|
private val: any,
|
|
72
68
|
) {
|
|
73
69
|
super()
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
getParent():
|
|
72
|
+
getParent(): ContextNonNil {
|
|
77
73
|
return this.parent
|
|
78
74
|
}
|
|
79
75
|
|
|
@@ -85,7 +81,7 @@ class valueContext extends baseContext {
|
|
|
85
81
|
return this.parent.Done()
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
Err():
|
|
84
|
+
Err(): $.GoError {
|
|
89
85
|
return this.parent.Err()
|
|
90
86
|
}
|
|
91
87
|
|
|
@@ -100,14 +96,14 @@ class valueContext extends baseContext {
|
|
|
100
96
|
// Cancel context that can be canceled
|
|
101
97
|
class cancelContext extends baseContext {
|
|
102
98
|
protected doneChannel: $.Channel<{}>
|
|
103
|
-
protected err:
|
|
104
|
-
protected cause:
|
|
99
|
+
protected err: $.GoError = null
|
|
100
|
+
protected cause: $.GoError = null
|
|
105
101
|
protected children: Set<cancelContext> = new Set()
|
|
106
|
-
protected parent:
|
|
102
|
+
protected parent: ContextNonNil
|
|
107
103
|
protected parentCancelCtx: cancelContext | null = null
|
|
108
104
|
protected removeFromParent: (() => void) | null = null
|
|
109
105
|
|
|
110
|
-
constructor(parent:
|
|
106
|
+
constructor(parent: ContextNonNil) {
|
|
111
107
|
super()
|
|
112
108
|
this.parent = parent
|
|
113
109
|
this.doneChannel = $.makeChannel<{}>(0, {}, 'both')
|
|
@@ -121,7 +117,7 @@ class cancelContext extends baseContext {
|
|
|
121
117
|
return this.doneChannel
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
Err():
|
|
120
|
+
Err(): $.GoError {
|
|
125
121
|
return this.err
|
|
126
122
|
}
|
|
127
123
|
|
|
@@ -129,14 +125,11 @@ class cancelContext extends baseContext {
|
|
|
129
125
|
return this.parent.Value(key)
|
|
130
126
|
}
|
|
131
127
|
|
|
132
|
-
getCause():
|
|
133
|
-
|
|
134
|
-
return this.cause
|
|
135
|
-
}
|
|
136
|
-
return this.err
|
|
128
|
+
getCause(): $.GoError {
|
|
129
|
+
return this.cause ?? this.err
|
|
137
130
|
}
|
|
138
131
|
|
|
139
|
-
cancel(removeFromParent: boolean, err:
|
|
132
|
+
cancel(removeFromParent: boolean, err: $.GoError, cause: $.GoError): void {
|
|
140
133
|
if (this.err !== null) {
|
|
141
134
|
return // Already canceled
|
|
142
135
|
}
|
|
@@ -205,7 +198,7 @@ class timerContext extends cancelContext {
|
|
|
205
198
|
private deadline: Date
|
|
206
199
|
private timer: any
|
|
207
200
|
|
|
208
|
-
constructor(parent:
|
|
201
|
+
constructor(parent: ContextNonNil, deadline: Date) {
|
|
209
202
|
super(parent)
|
|
210
203
|
this.deadline = deadline
|
|
211
204
|
}
|
|
@@ -229,7 +222,7 @@ class timerContext extends cancelContext {
|
|
|
229
222
|
}, duration)
|
|
230
223
|
}
|
|
231
224
|
|
|
232
|
-
cancel(removeFromParent: boolean, err:
|
|
225
|
+
cancel(removeFromParent: boolean, err: $.GoError, cause: $.GoError): void {
|
|
233
226
|
super.cancel(removeFromParent, err, cause)
|
|
234
227
|
if (this.timer) {
|
|
235
228
|
clearTimeout(this.timer)
|
|
@@ -240,7 +233,7 @@ class timerContext extends cancelContext {
|
|
|
240
233
|
|
|
241
234
|
// Without cancel context - inherits values but not cancellation
|
|
242
235
|
class withoutCancelContext extends baseContext {
|
|
243
|
-
constructor(private parent:
|
|
236
|
+
constructor(private parent: ContextNonNil) {
|
|
244
237
|
super()
|
|
245
238
|
}
|
|
246
239
|
|
|
@@ -252,7 +245,7 @@ class withoutCancelContext extends baseContext {
|
|
|
252
245
|
return backgroundContext.getNeverClosedChannel()
|
|
253
246
|
}
|
|
254
247
|
|
|
255
|
-
Err():
|
|
248
|
+
Err(): $.GoError {
|
|
256
249
|
return null
|
|
257
250
|
}
|
|
258
251
|
|
|
@@ -276,7 +269,10 @@ export function TODO(): Context {
|
|
|
276
269
|
}
|
|
277
270
|
|
|
278
271
|
// WithCancel returns a copy of parent with a new Done channel
|
|
279
|
-
export function WithCancel(parent: Context): [
|
|
272
|
+
export function WithCancel(parent: Context): [ContextNonNil, CancelFunc] {
|
|
273
|
+
if (parent === null) {
|
|
274
|
+
throw new Error('cannot create context from nil parent')
|
|
275
|
+
}
|
|
280
276
|
const ctx = new cancelContext(parent)
|
|
281
277
|
ctx.propagateCancel()
|
|
282
278
|
|
|
@@ -289,20 +285,28 @@ export function WithCancel(parent: Context): [Context, CancelFunc] {
|
|
|
289
285
|
}
|
|
290
286
|
|
|
291
287
|
// WithCancelCause returns a copy of parent with a new Done channel and cause recording
|
|
292
|
-
export function WithCancelCause(
|
|
288
|
+
export function WithCancelCause(
|
|
289
|
+
parent: Context,
|
|
290
|
+
): [ContextNonNil, CancelCauseFunc] {
|
|
291
|
+
if (parent === null) {
|
|
292
|
+
throw new Error('cannot create context from nil parent')
|
|
293
|
+
}
|
|
293
294
|
const ctx = new cancelContext(parent)
|
|
294
295
|
ctx.propagateCancel()
|
|
295
296
|
|
|
296
297
|
return [
|
|
297
298
|
ctx,
|
|
298
|
-
(cause:
|
|
299
|
+
(cause: $.GoError) => {
|
|
299
300
|
ctx.cancel(true, Canceled, cause)
|
|
300
301
|
},
|
|
301
302
|
]
|
|
302
303
|
}
|
|
303
304
|
|
|
304
305
|
// WithDeadline returns a copy of parent with the deadline adjusted to be no later than d
|
|
305
|
-
export function WithDeadline(
|
|
306
|
+
export function WithDeadline(
|
|
307
|
+
parent: Context,
|
|
308
|
+
d: Date,
|
|
309
|
+
): [ContextNonNil, CancelFunc] {
|
|
306
310
|
return WithDeadlineCause(parent, d, null)
|
|
307
311
|
}
|
|
308
312
|
|
|
@@ -310,8 +314,11 @@ export function WithDeadline(parent: Context, d: Date): [Context, CancelFunc] {
|
|
|
310
314
|
export function WithDeadlineCause(
|
|
311
315
|
parent: Context,
|
|
312
316
|
d: Date,
|
|
313
|
-
cause:
|
|
314
|
-
): [
|
|
317
|
+
cause: $.GoError,
|
|
318
|
+
): [ContextNonNil, CancelFunc] {
|
|
319
|
+
if (parent === null) {
|
|
320
|
+
throw new Error('cannot create context from nil parent')
|
|
321
|
+
}
|
|
315
322
|
// Check if parent deadline is already earlier
|
|
316
323
|
const [parentDeadline, ok] = parent.Deadline()
|
|
317
324
|
if (ok && parentDeadline && parentDeadline <= d) {
|
|
@@ -335,7 +342,7 @@ export function WithDeadlineCause(
|
|
|
335
342
|
export function WithTimeout(
|
|
336
343
|
parent: Context,
|
|
337
344
|
timeout: number,
|
|
338
|
-
): [
|
|
345
|
+
): [ContextNonNil, CancelFunc] {
|
|
339
346
|
return WithDeadline(parent, new Date(Date.now() + timeout))
|
|
340
347
|
}
|
|
341
348
|
|
|
@@ -343,23 +350,31 @@ export function WithTimeout(
|
|
|
343
350
|
export function WithTimeoutCause(
|
|
344
351
|
parent: Context,
|
|
345
352
|
timeout: number,
|
|
346
|
-
cause:
|
|
347
|
-
): [
|
|
353
|
+
cause: $.GoError,
|
|
354
|
+
): [ContextNonNil, CancelFunc] {
|
|
348
355
|
return WithDeadlineCause(parent, new Date(Date.now() + timeout), cause)
|
|
349
356
|
}
|
|
350
357
|
|
|
351
358
|
// WithValue returns a copy of parent with the value associated with key
|
|
352
|
-
export function WithValue(parent: Context, key: any, val: any):
|
|
359
|
+
export function WithValue(parent: Context, key: any, val: any): ContextNonNil {
|
|
360
|
+
if (parent === null) {
|
|
361
|
+
throw new Error('cannot create context from nil parent')
|
|
362
|
+
}
|
|
353
363
|
return new valueContext(parent, key, val)
|
|
354
364
|
}
|
|
355
365
|
|
|
356
366
|
// WithoutCancel returns a context that inherits values but not cancellation
|
|
357
|
-
export function WithoutCancel(parent: Context):
|
|
367
|
+
export function WithoutCancel(parent: Context): ContextNonNil {
|
|
368
|
+
if (parent === null) {
|
|
369
|
+
throw new Error('cannot create context from nil parent')
|
|
370
|
+
}
|
|
358
371
|
return new withoutCancelContext(parent)
|
|
359
372
|
}
|
|
360
373
|
|
|
361
374
|
// Cause returns the underlying cause of the context's cancellation
|
|
362
|
-
export function Cause(ctx: Context):
|
|
375
|
+
export function Cause(ctx: Context): $.GoError {
|
|
376
|
+
if (!ctx) return null
|
|
377
|
+
|
|
363
378
|
let c = ctx
|
|
364
379
|
// Unwrap value contexts
|
|
365
380
|
while (c instanceof valueContext) {
|
|
@@ -375,6 +390,9 @@ export function Cause(ctx: Context): Error | null {
|
|
|
375
390
|
|
|
376
391
|
// AfterFunc runs f in a separate goroutine after ctx is done
|
|
377
392
|
export function AfterFunc(ctx: Context, f: () => void): () => boolean {
|
|
393
|
+
if (ctx === null) {
|
|
394
|
+
throw new Error('cannot create context from nil parent')
|
|
395
|
+
}
|
|
378
396
|
let stopped = false
|
|
379
397
|
let done = false
|
|
380
398
|
|
package/gs/fmt/fmt.ts
CHANGED
|
@@ -202,7 +202,11 @@ let stdout = {
|
|
|
202
202
|
write: (data: string) => {
|
|
203
203
|
// Use process.stdout.write if available (Node.js), otherwise fallback to console.log
|
|
204
204
|
// but we need to avoid adding extra newlines that console.log adds
|
|
205
|
-
if (
|
|
205
|
+
if (
|
|
206
|
+
typeof process !== 'undefined' &&
|
|
207
|
+
process.stdout &&
|
|
208
|
+
process.stdout.write
|
|
209
|
+
) {
|
|
206
210
|
process.stdout.write(data)
|
|
207
211
|
} else {
|
|
208
212
|
// In browser environments, we need to use console.log but handle newlines carefully
|
package/gs/reflect/type.ts
CHANGED
|
@@ -15,12 +15,7 @@ export class rtype {
|
|
|
15
15
|
|
|
16
16
|
Pointers(): boolean {
|
|
17
17
|
const k = this.kind
|
|
18
|
-
return
|
|
19
|
-
k === Ptr ||
|
|
20
|
-
k === Map ||
|
|
21
|
-
k === Slice ||
|
|
22
|
-
k === Interface
|
|
23
|
-
)
|
|
18
|
+
return k === Ptr || k === Map || k === Slice || k === Interface
|
|
24
19
|
}
|
|
25
20
|
}
|
|
26
21
|
|
|
@@ -127,13 +122,13 @@ export const BothDir: ChanDir = 3
|
|
|
127
122
|
export function ChanDir_String(d: ChanDir): string {
|
|
128
123
|
switch (d) {
|
|
129
124
|
case RecvDir:
|
|
130
|
-
return
|
|
125
|
+
return 'RecvDir'
|
|
131
126
|
case SendDir:
|
|
132
|
-
return
|
|
127
|
+
return 'SendDir'
|
|
133
128
|
case BothDir:
|
|
134
|
-
return
|
|
129
|
+
return 'BothDir'
|
|
135
130
|
default:
|
|
136
|
-
return
|
|
131
|
+
return 'ChanDir(' + d + ')'
|
|
137
132
|
}
|
|
138
133
|
}
|
|
139
134
|
|
package/gs/time/time.ts
CHANGED
|
@@ -5,21 +5,32 @@ export class Time {
|
|
|
5
5
|
private _monotonic?: number // high-resolution monotonic timestamp in nanoseconds
|
|
6
6
|
private _location: Location // timezone location
|
|
7
7
|
|
|
8
|
-
constructor(
|
|
8
|
+
constructor(_props?: {}) {
|
|
9
|
+
// Default constructor creates a zero time (Unix epoch in UTC)
|
|
10
|
+
this._date = new globalThis.Date(0)
|
|
11
|
+
this._nsec = 0
|
|
12
|
+
this._monotonic = undefined
|
|
13
|
+
this._location = UTC
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// create is a static factory method that creates a Time instance with specific parameters
|
|
17
|
+
public static create(
|
|
9
18
|
date: globalThis.Date,
|
|
10
19
|
nsec: number = 0,
|
|
11
20
|
monotonic?: number,
|
|
12
21
|
location?: Location,
|
|
13
|
-
) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
): Time {
|
|
23
|
+
const time = new Time()
|
|
24
|
+
time._date = new globalThis.Date(date.getTime())
|
|
25
|
+
time._nsec = nsec
|
|
26
|
+
time._monotonic = monotonic
|
|
27
|
+
time._location = location || UTC
|
|
28
|
+
return time
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
// clone returns a copy of this Time instance
|
|
21
32
|
public clone(): Time {
|
|
22
|
-
return
|
|
33
|
+
return Time.create(this._date, this._nsec, this._monotonic, this._location)
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
// Unix returns t as a Unix time, the number of seconds elapsed since January 1, 1970 UTC
|
|
@@ -492,7 +503,7 @@ export class Time {
|
|
|
492
503
|
const newNsec = this._nsec + (durationNs % 1000000)
|
|
493
504
|
const newMonotonic =
|
|
494
505
|
this._monotonic !== undefined ? this._monotonic + durationNs : undefined
|
|
495
|
-
return
|
|
506
|
+
return Time.create(newDate, newNsec, newMonotonic, this._location)
|
|
496
507
|
}
|
|
497
508
|
|
|
498
509
|
// Equal reports whether t and u represent the same time instant
|
|
@@ -531,7 +542,7 @@ export class Time {
|
|
|
531
542
|
public Round(_d: Duration): Time {
|
|
532
543
|
// Implementation would round to nearest duration
|
|
533
544
|
// For now, simplified version that strips monotonic reading
|
|
534
|
-
return
|
|
545
|
+
return Time.create(this._date, this._nsec, undefined, this._location)
|
|
535
546
|
}
|
|
536
547
|
|
|
537
548
|
// Truncate returns the result of rounding t down to a multiple of d
|
|
@@ -539,7 +550,7 @@ export class Time {
|
|
|
539
550
|
public Truncate(_d: Duration): Time {
|
|
540
551
|
// Implementation would truncate to duration
|
|
541
552
|
// For now, simplified version that strips monotonic reading
|
|
542
|
-
return
|
|
553
|
+
return Time.create(this._date, this._nsec, undefined, this._location)
|
|
543
554
|
}
|
|
544
555
|
|
|
545
556
|
// String returns the time formatted as a string
|
|
@@ -571,8 +582,11 @@ export function Duration_lt(receiver: Duration, other: Duration): boolean {
|
|
|
571
582
|
return receiver < other
|
|
572
583
|
}
|
|
573
584
|
|
|
574
|
-
// Duration multiplication function
|
|
575
|
-
export function Duration_multiply(
|
|
585
|
+
// Duration multiplication function
|
|
586
|
+
export function Duration_multiply(
|
|
587
|
+
receiver: Duration,
|
|
588
|
+
multiplier: number,
|
|
589
|
+
): Duration {
|
|
576
590
|
return receiver * multiplier
|
|
577
591
|
}
|
|
578
592
|
|
|
@@ -775,7 +789,7 @@ export function Now(): Time {
|
|
|
775
789
|
monotonic = performance.now() * 1000000
|
|
776
790
|
}
|
|
777
791
|
|
|
778
|
-
return
|
|
792
|
+
return Time.create(date, 0, monotonic)
|
|
779
793
|
}
|
|
780
794
|
|
|
781
795
|
// Date returns the Time corresponding to
|
|
@@ -820,7 +834,7 @@ export function Date(
|
|
|
820
834
|
Math.floor(nsec / 1000000),
|
|
821
835
|
)
|
|
822
836
|
}
|
|
823
|
-
return
|
|
837
|
+
return Time.create(date, nsec % 1000000000, undefined, loc) // No monotonic reading
|
|
824
838
|
}
|
|
825
839
|
|
|
826
840
|
// Common locations
|
|
@@ -871,13 +885,13 @@ export const Kitchen = '3:04PM'
|
|
|
871
885
|
export function Unix(sec: number, nsec: number = 0): Time {
|
|
872
886
|
const ms = sec * 1000 + Math.floor(nsec / 1000000)
|
|
873
887
|
const remainingNsec = nsec % 1000000
|
|
874
|
-
return
|
|
888
|
+
return Time.create(new globalThis.Date(ms), remainingNsec, undefined, UTC)
|
|
875
889
|
}
|
|
876
890
|
|
|
877
891
|
// UnixMilli returns the local Time corresponding to the given Unix time,
|
|
878
892
|
// msec milliseconds since January 1, 1970 UTC
|
|
879
893
|
export function UnixMilli(msec: number): Time {
|
|
880
|
-
return
|
|
894
|
+
return Time.create(new globalThis.Date(msec), 0, undefined, UTC)
|
|
881
895
|
}
|
|
882
896
|
|
|
883
897
|
// UnixMicro returns the local Time corresponding to the given Unix time,
|
|
@@ -885,7 +899,7 @@ export function UnixMilli(msec: number): Time {
|
|
|
885
899
|
export function UnixMicro(usec: number): Time {
|
|
886
900
|
const ms = Math.floor(usec / 1000)
|
|
887
901
|
const nsec = (usec % 1000) * 1000
|
|
888
|
-
return
|
|
902
|
+
return Time.create(new globalThis.Date(ms), nsec, undefined, UTC)
|
|
889
903
|
}
|
|
890
904
|
|
|
891
905
|
// UnixNano returns the local Time corresponding to the given Unix time,
|
|
@@ -893,7 +907,7 @@ export function UnixMicro(usec: number): Time {
|
|
|
893
907
|
export function UnixNano(nsec: number): Time {
|
|
894
908
|
const ms = Math.floor(nsec / 1000000)
|
|
895
909
|
const remainingNsec = nsec % 1000000
|
|
896
|
-
return
|
|
910
|
+
return Time.create(new globalThis.Date(ms), remainingNsec, undefined, UTC)
|
|
897
911
|
}
|
|
898
912
|
|
|
899
913
|
// ParseDuration parses a duration string
|
|
@@ -965,7 +979,7 @@ export function ParseInLocation(
|
|
|
965
979
|
`parsing time "${value}" as "${layout}": cannot parse`,
|
|
966
980
|
)
|
|
967
981
|
}
|
|
968
|
-
return
|
|
982
|
+
return Time.create(date, 0, undefined, loc)
|
|
969
983
|
}
|
|
970
984
|
|
|
971
985
|
if (layout === DateTime || layout === '2006-01-02 15:04:05') {
|
|
@@ -979,7 +993,7 @@ export function ParseInLocation(
|
|
|
979
993
|
`parsing time "${value}" as "${layout}": cannot parse`,
|
|
980
994
|
)
|
|
981
995
|
}
|
|
982
|
-
return
|
|
996
|
+
return Time.create(date, 0, undefined, loc)
|
|
983
997
|
}
|
|
984
998
|
|
|
985
999
|
// Fallback to standard Date parsing
|
|
@@ -993,7 +1007,7 @@ export function ParseInLocation(
|
|
|
993
1007
|
`parsing time "${value}" as "${layout}": cannot parse`,
|
|
994
1008
|
)
|
|
995
1009
|
}
|
|
996
|
-
return
|
|
1010
|
+
return Time.create(date, 0, undefined, loc)
|
|
997
1011
|
}
|
|
998
1012
|
|
|
999
1013
|
// After waits for the duration to elapse and then returns the current time
|
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.
|
|
4
|
+
"version": "0.0.50",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Aperture Robotics LLC.",
|
|
7
7
|
"email": "support@aperture.us",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"release:commit": "git reset && git add package.json && git commit -s -m \"release: v$npm_package_version\" && git tag v$npm_package_version",
|
|
62
62
|
"release:publish": "git push && git push --tags && npm run build && npm publish",
|
|
63
63
|
"lint": "npm run lint:go && npm run lint:js",
|
|
64
|
-
"lint:go": "
|
|
64
|
+
"lint:go": "golangci-lint run .",
|
|
65
65
|
"lint:js": "eslint -c eslint.config.mjs ./",
|
|
66
66
|
"lint:js:fix": "eslint -c eslint.config.mjs ./ --fix",
|
|
67
67
|
"prepare": "husky",
|
package/gs/TODO.md
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# TODO: Wrapper Type Refactor for gs/ Directory
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
The compiler has been refactored to generate wrapper types as type aliases instead of classes, with methods as standalone functions. This requires corresponding updates to the gs/ directory to remove the old class-based implementations and valueOf type parameters.
|
|
5
|
-
|
|
6
|
-
## Required Changes
|
|
7
|
-
|
|
8
|
-
### 1. Remove Wrapper Type Classes
|
|
9
|
-
All wrapper type classes in gs/ need to be converted to type aliases with standalone functions:
|
|
10
|
-
|
|
11
|
-
**Current pattern (to be removed):**
|
|
12
|
-
```typescript
|
|
13
|
-
export class FileMode {
|
|
14
|
-
constructor(private _value: number) {}
|
|
15
|
-
|
|
16
|
-
valueOf(): number {
|
|
17
|
-
return this._value;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
String(): string {
|
|
21
|
-
return fileModeString(this._value);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
IsDir(): boolean {
|
|
25
|
-
return (this._value & ModeDir) !== 0;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
**New pattern (to implement):**
|
|
31
|
-
```typescript
|
|
32
|
-
export type FileMode = number;
|
|
33
|
-
|
|
34
|
-
export function FileMode_String(receiver: FileMode): string {
|
|
35
|
-
return fileModeString(receiver);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function FileMode_IsDir(receiver: FileMode): boolean {
|
|
39
|
-
return (receiver & ModeDir) !== 0;
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 2. Files that need wrapper type refactoring:
|
|
44
|
-
- `gs/os/types_js.gs.ts` - FileMode and other os types
|
|
45
|
-
- `gs/time/time.ts` - Duration and other time types
|
|
46
|
-
- `gs/syscall/` - Various syscall wrapper types
|
|
47
|
-
- Any other files that implement wrapper types as classes
|
|
48
|
-
|
|
49
|
-
### 3. Remove valueOf Type Parameters
|
|
50
|
-
The `@builtin` package needs to be updated to remove valueOf type parameters from builtin functions.
|
|
51
|
-
|
|
52
|
-
**Current pattern (to be removed):**
|
|
53
|
-
```typescript
|
|
54
|
-
function int<T extends { valueOf(): number }>(value: T): number {
|
|
55
|
-
return value.valueOf();
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**New pattern (to implement):**
|
|
60
|
-
```typescript
|
|
61
|
-
function int(value: number): number {
|
|
62
|
-
return value;
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 4. Update Method Call Sites
|
|
67
|
-
Any existing method call sites in gs/ files need to be updated:
|
|
68
|
-
|
|
69
|
-
**Current pattern (to be updated):**
|
|
70
|
-
```typescript
|
|
71
|
-
mode.String() // method call on wrapper class
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**New pattern:**
|
|
75
|
-
```typescript
|
|
76
|
-
FileMode_String(mode) // function call with receiver
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### 5. Remove .valueOf() Calls
|
|
80
|
-
The compiler still generates `.valueOf()` calls for wrapper types. These need to be eliminated:
|
|
81
|
-
|
|
82
|
-
**Current generated pattern (to be fixed):**
|
|
83
|
-
```typescript
|
|
84
|
-
return receiver.valueOf() & 0o111;
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Target pattern:**
|
|
88
|
-
```typescript
|
|
89
|
-
return receiver & 0o111;
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Implementation Notes
|
|
93
|
-
|
|
94
|
-
### Analysis Changes Completed
|
|
95
|
-
- ✅ Modified analysis to detect wrapper types ahead of time
|
|
96
|
-
- ✅ Added receiver mapping for wrapper function identifiers
|
|
97
|
-
- ✅ Removed shadowingContext dependency
|
|
98
|
-
|
|
99
|
-
### Compiler Changes Completed
|
|
100
|
-
- ✅ Updated `WriteNamedTypeWithMethods()` to generate type aliases
|
|
101
|
-
- ✅ Updated method call handling to use function calls
|
|
102
|
-
- ✅ Updated type conversion logic for wrapper types
|
|
103
|
-
- ✅ Removed constructor generation for wrapper types
|
|
104
|
-
|
|
105
|
-
### Remaining Compiler Issues
|
|
106
|
-
- ❌ Stop generating `.valueOf()` calls for wrapper types in:
|
|
107
|
-
- `compiler/expr.go` - `needsValueOfForBitwiseOp()` function
|
|
108
|
-
- `compiler/expr-call-type-conversion.go` - various conversion functions
|
|
109
|
-
- Need to update logic to not add `.valueOf()` for wrapper types since they're now primitive types
|
|
110
|
-
|
|
111
|
-
### Testing
|
|
112
|
-
Use the `wrapper_type_args` compliance test to verify changes:
|
|
113
|
-
```bash
|
|
114
|
-
go test -timeout 30s -run ^TestCompliance/wrapper_type_args$ ./compiler
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Migration Strategy
|
|
118
|
-
1. First complete the compiler changes to stop generating `.valueOf()` calls
|
|
119
|
-
2. Update each gs/ package incrementally
|
|
120
|
-
3. Test each package after refactoring
|
|
121
|
-
4. Update builtin functions to remove valueOf type parameters
|
|
122
|
-
5. Run full test suite to ensure compatibility
|
|
123
|
-
|
|
124
|
-
## Benefits After Completion
|
|
125
|
-
- Cleaner generated TypeScript code
|
|
126
|
-
- Better performance (no wrapper class overhead)
|
|
127
|
-
- More idiomatic TypeScript types
|
|
128
|
-
- Simplified runtime type system
|
|
129
|
-
- Easier debugging and maintenance
|