mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
This commit is contained in:
parent
3ecffe68ff
commit
90fdf102fc
4 changed files with 228 additions and 13 deletions
|
@ -47,6 +47,20 @@ pub fn (mut m map) delete(key JS.Any) {
|
|||
|
||||
pub fn (m &map) free() {}
|
||||
|
||||
pub fn (m map) keys() array {
|
||||
ret := JS.makeEmptyArray()
|
||||
#for (var key in m.map) array_push(ret,new string(`${key}`),false);
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
pub fn (m map) values() array {
|
||||
ret := JS.makeEmptyArray()
|
||||
#for (var key in m.map) array_push(ret,m.map[key],false);
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
//#Object.defineProperty(map.prototype,"len",{get: function() { return this.map.size; }})
|
||||
#map.prototype.toString = function () {
|
||||
#function fmtKey(key) { return typeof key == 'string' ? '\'' + key + '\'' : key}
|
||||
|
|
|
@ -267,8 +267,11 @@ fn (mut g JsGen) method_call(node ast.CallExpr) {
|
|||
left_sym := g.table.sym(node.left_type)
|
||||
final_left_sym := g.table.final_sym(node.left_type)
|
||||
|
||||
if final_left_sym.kind == .array {
|
||||
if final_left_sym.kind == .array && it.name in ['map', 'filter'] {
|
||||
if final_left_sym.kind == .map && it.name in special_map_methods {
|
||||
g.gen_map_method_call(it)
|
||||
return
|
||||
} else if final_left_sym.kind == .array {
|
||||
if it.name in ['map', 'filter'] {
|
||||
g.expr(it.left)
|
||||
mut ltyp := it.left_type
|
||||
for ltyp.is_ptr() {
|
||||
|
@ -310,18 +313,17 @@ fn (mut g JsGen) method_call(node ast.CallExpr) {
|
|||
return
|
||||
}
|
||||
|
||||
if final_left_sym.kind == .array {
|
||||
if it.name in special_array_methods {
|
||||
g.gen_array_method_call(it)
|
||||
return
|
||||
}
|
||||
if it.name in special_array_methods {
|
||||
g.gen_array_method_call(it)
|
||||
return
|
||||
}
|
||||
}
|
||||
if final_left_sym.kind == .array
|
||||
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
|
||||
if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
|
||||
// `array_Xyz_clone` => `array_clone`
|
||||
receiver_type_name = 'array'
|
||||
|
||||
if node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last',
|
||||
'pop', 'clone', 'reverse', 'slice', 'pointers'] {
|
||||
if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) {
|
||||
// `array_Xyz_clone` => `array_clone`
|
||||
receiver_type_name = 'array'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
vlib/v/gen/js/map.v
Normal file
15
vlib/v/gen/js/map.v
Normal file
|
@ -0,0 +1,15 @@
|
|||
module js
|
||||
|
||||
import v.ast
|
||||
|
||||
const special_map_methods = [
|
||||
'keys',
|
||||
'values',
|
||||
]
|
||||
|
||||
fn (mut g JsGen) gen_map_method_call(node ast.CallExpr) {
|
||||
g.write('map_${node.name}(')
|
||||
g.expr(node.left)
|
||||
g.gen_deref_ptr(node.left_type)
|
||||
g.write(')')
|
||||
}
|
184
vlib/v/gen/js/tests/map.v
Normal file
184
vlib/v/gen/js/tests/map.v
Normal file
|
@ -0,0 +1,184 @@
|
|||
struct Point {
|
||||
x f64
|
||||
y f64
|
||||
}
|
||||
|
||||
fn generic_map[T](items map[string]T) []T {
|
||||
return items.values()
|
||||
}
|
||||
|
||||
fn generic_map_with_constraint[T](items map[string]T) []T {
|
||||
return items.values()
|
||||
}
|
||||
|
||||
fn generic_map_keys[T](items map[string]T) []string {
|
||||
return items.keys()
|
||||
}
|
||||
|
||||
fn map_any[T](items []T, cb fn (item T) bool) bool {
|
||||
for item in items {
|
||||
if cb(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fn test_map_values_method() {
|
||||
// testing map[int]stirng
|
||||
items_1 := {
|
||||
1: 'item_1'
|
||||
2: 'item_2'
|
||||
3: 'item_3'
|
||||
}
|
||||
assert items_1.values().len == 3
|
||||
for i, item in items_1.values() {
|
||||
assert item == 'item_${i + 1}'
|
||||
}
|
||||
|
||||
// testing map[string]int
|
||||
items_2 := {
|
||||
'item_1': 1
|
||||
'item_2': 2
|
||||
'item_3': 3
|
||||
'item_4': 4
|
||||
}
|
||||
assert items_2.values().len == 4
|
||||
for i, item in items_2.values() {
|
||||
assert item == i + 1
|
||||
}
|
||||
|
||||
// testing generics
|
||||
items_3 := {
|
||||
'a': 10
|
||||
'b': 20
|
||||
'c': 30
|
||||
}
|
||||
generic_values := generic_map(items_3)
|
||||
assert generic_values.len == 3
|
||||
assert generic_values.contains(10)
|
||||
assert generic_values.contains(20)
|
||||
assert generic_values.contains(30)
|
||||
|
||||
// testing empty map
|
||||
empty_map := map[string]int{}
|
||||
empty_values := empty_map.values()
|
||||
assert empty_values.len == 0
|
||||
|
||||
// testing map with complex types (struct)
|
||||
points := {
|
||||
'origin': Point{0.0, 0.0}
|
||||
'unit_x': Point{1.0, 0.0}
|
||||
'unit_y': Point{0.0, 1.0}
|
||||
}
|
||||
point_values := points.values()
|
||||
assert point_values.len == 3
|
||||
assert map_any(point_values, fn (point Point) bool {
|
||||
return point.x == 0.0 && point.y == 0.0
|
||||
})
|
||||
assert map_any(point_values, fn (point Point) bool {
|
||||
return point.x == 1.0 && point.y == 0.0
|
||||
})
|
||||
assert map_any(point_values, fn (point Point) bool {
|
||||
return point.x == 0.0 && point.y == 1.0
|
||||
})
|
||||
}
|
||||
|
||||
fn test_map_values_method_with_generic_constraints() {
|
||||
// test with string constraint
|
||||
string_map := {
|
||||
'first': 'hello'
|
||||
'second': 'world'
|
||||
}
|
||||
string_result := generic_map_with_constraint(string_map)
|
||||
assert string_result.len == 2
|
||||
assert string_result.contains('hello')
|
||||
assert string_result.contains('world')
|
||||
|
||||
// test with int constraint
|
||||
int_map := {
|
||||
'one': 1
|
||||
'two': 2
|
||||
}
|
||||
int_result := generic_map_with_constraint(int_map)
|
||||
assert int_result.len == 2
|
||||
assert int_result.contains(1)
|
||||
assert int_result.contains(2)
|
||||
}
|
||||
|
||||
fn test_map_keys_method() {
|
||||
// testing map[string]int keys
|
||||
items_2 := {
|
||||
'item_1': 1
|
||||
'item_2': 2
|
||||
'item_3': 3
|
||||
'item_4': 4
|
||||
}
|
||||
keys_2 := items_2.keys()
|
||||
assert keys_2.len == 4
|
||||
assert keys_2.contains('item_1')
|
||||
assert keys_2.contains('item_2')
|
||||
assert keys_2.contains('item_3')
|
||||
assert keys_2.contains('item_4')
|
||||
|
||||
// testing empty map keys
|
||||
empty_map := map[string]int{}
|
||||
empty_keys := empty_map.keys()
|
||||
assert empty_keys.len == 0
|
||||
|
||||
// testing map with single element keys
|
||||
single_item := {
|
||||
'only': 42
|
||||
}
|
||||
single_keys := single_item.keys()
|
||||
assert single_keys.len == 1
|
||||
assert single_keys[0] == 'only'
|
||||
|
||||
// testing map with complex types as values but simple keys
|
||||
points := {
|
||||
'origin': Point{0.0, 0.0}
|
||||
'unit_x': Point{1.0, 0.0}
|
||||
'unit_y': Point{0.0, 1.0}
|
||||
}
|
||||
point_keys := points.keys()
|
||||
assert point_keys.len == 3
|
||||
assert point_keys.contains('origin')
|
||||
assert point_keys.contains('unit_x')
|
||||
assert point_keys.contains('unit_y')
|
||||
}
|
||||
|
||||
fn test_map_keys_method_with_generic_constraints() {
|
||||
// test with string values
|
||||
string_map := {
|
||||
'first': 'hello'
|
||||
'second': 'world'
|
||||
'third': 'test'
|
||||
}
|
||||
string_keys := generic_map_keys(string_map)
|
||||
assert string_keys.len == 3
|
||||
assert string_keys.contains('first')
|
||||
assert string_keys.contains('second')
|
||||
assert string_keys.contains('third')
|
||||
|
||||
// test with struct values
|
||||
point_map := {
|
||||
'origin': Point{0.0, 0.0}
|
||||
'center': Point{5.0, 5.0}
|
||||
}
|
||||
point_keys := generic_map_keys(point_map)
|
||||
assert point_keys.len == 2
|
||||
assert point_keys.contains('origin')
|
||||
assert point_keys.contains('center')
|
||||
|
||||
// test with empty map
|
||||
empty_map := map[string]int{}
|
||||
empty_keys := generic_map_keys(empty_map)
|
||||
assert empty_keys.len == 0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_map_values_method()
|
||||
test_map_values_method_with_generic_constraints()
|
||||
test_map_keys_method()
|
||||
test_map_keys_method_with_generic_constraints()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue