jsgen: fix direct map key access and map.len (fix #24616, fix #24605) (#24620)

This commit is contained in:
Gonzalo Chumillas 2025-05-31 06:00:34 +01:00 committed by GitHub
parent bb2d605653
commit b84512d408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 17 deletions

View file

@ -8,11 +8,11 @@ pub:
fn (mut m map) internal_set(key JS.Any, val JS.Any) { fn (mut m map) internal_set(key JS.Any, val JS.Any) {
//$if es5 { //$if es5 {
#if ('$toJS' in key) key = key.$toJS(); #if (key.hasOwnProperty('$toJS')) key = key.$toJS();
#if (!(key in m.val.map)) m.val.length++; #if (!(key in m.val.map)) m.val.length++;
#m.val.map[key] = val #m.val.map[key] = val
/*} $else { /*} $else {
# if ('$toJS' in key) key = key.$toJS(); # if (key.hasOwnProperty('$toJS')) key = key.$toJS();
# m.val.m.set(key,val); # m.val.m.set(key,val);
}*/ }*/
_ := key _ := key
@ -22,10 +22,10 @@ fn (mut m map) internal_set(key JS.Any, val JS.Any) {
fn (mut m map) internal_get(key JS.Any) JS.Any { fn (mut m map) internal_get(key JS.Any) JS.Any {
mut val := JS.Any(unsafe { nil }) mut val := JS.Any(unsafe { nil })
//$if es5 { //$if es5 {
#if (typeof key != "string" && '$toJS' in key) key = key.$toJS(); #if (typeof key != "string" && key.hasOwnProperty('$toJS')) key = key.$toJS();
#val = m.val.map[key] #val = m.val.map[key]
/*} $else { /*} $else {
# if ('$toJS' in key) key = key.$toJS(); # if (key.hasOwnProperty('$toJS')) key = key.$toJS();
# val = m.val.m.get(key) # val = m.val.m.get(key)
}*/ }*/
_ := key _ := key
@ -34,11 +34,11 @@ fn (mut m map) internal_get(key JS.Any) JS.Any {
#map.prototype.get = function (key) { return map_internal_get(this,key); } #map.prototype.get = function (key) { return map_internal_get(this,key); }
#map.prototype.set = function(key,val) { map_internal_set(this,key,val); } #map.prototype.set = function(key,val) { map_internal_set(this,key,val); }
#map.prototype.has = function (key) { if (typeof key != "string" && '$toJS' in key) { key = key.$toJS() } return key in this.map; } #map.prototype.has = function (key) { if (typeof key != "string" && key.hasOwnProperty('$toJS')) { key = key.$toJS() } return key in this.map; }
// Removes the mapping of a particular key from the map. // Removes the mapping of a particular key from the map.
@[unsafe] @[unsafe]
pub fn (mut m map) delete(key JS.Any) { pub fn (mut m map) delete(key JS.Any) {
#let k = '$toJS' in key ? key.$toJS() : key; #let k = key.hasOwnProperty('$toJS') ? key.$toJS() : key;
#if (delete m.val.map[k]) { m.val.length--; }; #if (delete m.val.map[k]) { m.val.length--; };

View file

@ -494,7 +494,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
typ_name: typ_name typ_name: typ_name
val_name: 'map' val_name: 'map'
default_value: 'new map({})' default_value: 'new map({})'
constructor: 'this.map = map; this.length = 0;' constructor: 'this.map = map; this.length = Object.keys(this.map).length;'
value_of: 'this' value_of: 'this'
to_string: 'this.map.toString()' to_string: 'this.map.toString()'
eq: 'new bool(vEq(self, other))' eq: 'new bool(vEq(self, other))'

View file

@ -24,8 +24,8 @@ fn map_any[T](items []T, cb fn (item T) bool) bool {
return false return false
} }
fn test_map_values_method() { fn test_values_method() {
// testing map[int]stirng // testing map[int]string
items_1 := { items_1 := {
1: 'item_1' 1: 'item_1'
2: 'item_2' 2: 'item_2'
@ -84,7 +84,7 @@ fn test_map_values_method() {
}) })
} }
fn test_map_values_method_with_generic_constraints() { fn test_values_method_with_generic_constraints() {
// test with string constraint // test with string constraint
string_map := { string_map := {
'first': 'hello' 'first': 'hello'
@ -106,7 +106,17 @@ fn test_map_values_method_with_generic_constraints() {
assert int_result.contains(2) assert int_result.contains(2)
} }
fn test_map_keys_method() { fn test_keys_method() {
// testing map[int]string keys
items_1 := {
1: 'item_1'
2: 'item_2'
3: 'item_3'
}
for key in items_1.keys() {
assert 'item_${key}' == items_1[key]
}
// testing map[string]int keys // testing map[string]int keys
items_2 := { items_2 := {
'item_1': 1 'item_1': 1
@ -147,7 +157,7 @@ fn test_map_keys_method() {
assert point_keys.contains('unit_y') assert point_keys.contains('unit_y')
} }
fn test_map_keys_method_with_generic_constraints() { fn test_keys_method_with_generic_constraints() {
// test with string values // test with string values
string_map := { string_map := {
'first': 'hello' 'first': 'hello'
@ -176,9 +186,51 @@ fn test_map_keys_method_with_generic_constraints() {
assert empty_keys.len == 0 assert empty_keys.len == 0
} }
fn main() { fn test_direct_map_access() {
test_map_values_method() // testing map[int]string
test_map_values_method_with_generic_constraints() items_1 := {
test_map_keys_method() 1: 'one'
test_map_keys_method_with_generic_constraints() 2: 'two'
3: 'three'
}
assert items_1[1] == 'one'
assert items_1[2] == 'two'
assert items_1[3] == 'three'
// testing map[string]int
items_2 := {
'one': 1
'two': 2
'three': 3
}
assert items_2['one'] == 1
assert items_2['two'] == 2
assert items_2['three'] == 3
}
fn test_map_len() {
// testing on the fly maps
items_1 := {
'one': 1
'two': 2
}
assert items_1.len == 2
// testing empty map length
mut items_2 := map[string]int{}
assert items_2.len == 0
// testing dynamic addition map length
items_2['one'] = 1
items_2['two'] = 2
assert items_2.len == 2
}
fn main() {
test_values_method()
test_values_method_with_generic_constraints()
test_keys_method()
test_keys_method_with_generic_constraints()
test_direct_map_access()
test_map_len()
} }