goscript 0.0.56 → 0.0.58
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 +89 -4
- package/compiler/assignment.go +64 -2
- package/compiler/compiler.go +3 -0
- package/compiler/composite-lit.go +21 -4
- package/compiler/decl.go +360 -7
- package/compiler/expr-selector.go +4 -4
- package/compiler/expr.go +64 -5
- package/compiler/spec-struct.go +7 -3
- package/compiler/spec-value.go +41 -10
- package/compiler/spec.go +19 -4
- package/compiler/stmt.go +92 -11
- package/dist/gs/builtin/type.d.ts +1 -0
- package/dist/gs/builtin/type.js +54 -7
- package/dist/gs/builtin/type.js.map +1 -1
- package/gs/builtin/type.ts +58 -8
- package/package.json +1 -1
package/gs/builtin/type.ts
CHANGED
|
@@ -445,7 +445,9 @@ function matchesStructType(value: any, info: TypeInfo): boolean {
|
|
|
445
445
|
|
|
446
446
|
// For named struct types with constructors, use instanceof (nominal matching)
|
|
447
447
|
if (info.ctor && value instanceof info.ctor) {
|
|
448
|
-
|
|
448
|
+
// With inversion: struct value assertions should ONLY match structs marked as values
|
|
449
|
+
// In Go: j.(MyStruct) should only succeed if j contains a struct value (not pointer)
|
|
450
|
+
return isMarkedAsStructValue(value)
|
|
449
451
|
}
|
|
450
452
|
|
|
451
453
|
// For named struct types with constructors, if instanceof fails, return false
|
|
@@ -659,6 +661,24 @@ function matchesArrayOrSliceType(value: any, info: TypeInfo): boolean {
|
|
|
659
661
|
return true
|
|
660
662
|
}
|
|
661
663
|
|
|
664
|
+
// Symbol used to mark struct instances that represent values (not pointers)
|
|
665
|
+
const STRUCT_VALUE_MARKER = Symbol('structValue')
|
|
666
|
+
|
|
667
|
+
// Mark a struct instance as representing a value (not pointer)
|
|
668
|
+
export function markAsStructValue<T>(value: T): T {
|
|
669
|
+
if (typeof value === 'object' && value !== null) {
|
|
670
|
+
(value as any)[STRUCT_VALUE_MARKER] = true
|
|
671
|
+
}
|
|
672
|
+
return value
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Check if a struct instance is marked as a value
|
|
676
|
+
function isMarkedAsStructValue(value: any): boolean {
|
|
677
|
+
return typeof value === 'object' && value !== null && value[STRUCT_VALUE_MARKER] === true
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
|
|
662
682
|
/**
|
|
663
683
|
* Checks if a value matches a pointer type info.
|
|
664
684
|
*
|
|
@@ -668,24 +688,48 @@ function matchesArrayOrSliceType(value: any, info: TypeInfo): boolean {
|
|
|
668
688
|
*/
|
|
669
689
|
function matchesPointerType(value: any, info: TypeInfo): boolean {
|
|
670
690
|
// Allow null/undefined values to match pointer types to support nil pointer assertions
|
|
671
|
-
// This enables Go's nil pointer type assertions like `ptr, ok := i.(*SomeType)` to work correctly
|
|
672
691
|
if (value === null || value === undefined) {
|
|
673
692
|
return true
|
|
674
693
|
}
|
|
675
694
|
|
|
676
|
-
|
|
677
|
-
if (typeof value !== 'object' || !('value' in value)) {
|
|
695
|
+
if (typeof value !== 'object' || value === null) {
|
|
678
696
|
return false
|
|
679
697
|
}
|
|
680
698
|
|
|
681
699
|
if (!isPointerTypeInfo(info)) return false
|
|
682
700
|
|
|
683
|
-
if (info.elemType)
|
|
684
|
-
|
|
685
|
-
|
|
701
|
+
if (!info.elemType) return false
|
|
702
|
+
|
|
703
|
+
let elem = info.elemType
|
|
704
|
+
let elemName: string
|
|
705
|
+
if (typeof elem === 'string') {
|
|
706
|
+
elemName = elem
|
|
707
|
+
} else if (elem.name) {
|
|
708
|
+
elemName = elem.name
|
|
709
|
+
} else {
|
|
710
|
+
return false
|
|
686
711
|
}
|
|
687
712
|
|
|
688
|
-
|
|
713
|
+
// Check if this is a registered struct type
|
|
714
|
+
const registered = typeRegistry.get(elemName)
|
|
715
|
+
if (registered && registered.kind === TypeKind.Struct && registered.ctor) {
|
|
716
|
+
// For struct types, check if the value is marked as a pointer or is a VarRef
|
|
717
|
+
if ('value' in value) {
|
|
718
|
+
// VarRef case - check the inner value
|
|
719
|
+
let elemTypeInfo = normalizeTypeInfo(elem)
|
|
720
|
+
return matchesType(value.value, elemTypeInfo)
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// Direct struct instance - with inversion, only match if NOT marked as value (i.e., is a pointer)
|
|
724
|
+
return value instanceof registered.ctor && !isMarkedAsStructValue(value)
|
|
725
|
+
} else {
|
|
726
|
+
// For non-struct types, only VarRef objects should match
|
|
727
|
+
if (!('value' in value)) {
|
|
728
|
+
return false
|
|
729
|
+
}
|
|
730
|
+
let elemTypeInfo = normalizeTypeInfo(elem)
|
|
731
|
+
return matchesType(value.value, elemTypeInfo)
|
|
732
|
+
}
|
|
689
733
|
}
|
|
690
734
|
|
|
691
735
|
/**
|
|
@@ -885,6 +929,12 @@ export function typeAssert<T>(
|
|
|
885
929
|
|
|
886
930
|
const matches = matchesType(value, normalizedType)
|
|
887
931
|
if (matches) {
|
|
932
|
+
// Special handling for pointer type assertions:
|
|
933
|
+
// If the value is a VarRef and we're asserting to a pointer type,
|
|
934
|
+
// return the inner value (value.value), not the VarRef object itself
|
|
935
|
+
if (isPointerTypeInfo(normalizedType) && typeof value === 'object' && value !== null && 'value' in value) {
|
|
936
|
+
return { value: value.value as T, ok: true }
|
|
937
|
+
}
|
|
888
938
|
return { value: value as T, ok: true }
|
|
889
939
|
}
|
|
890
940
|
|