mirror of
https://github.com/vlang/v.git
synced 2025-09-11 08:25:42 -04:00
parent
3f76b69165
commit
27829d56cd
@ -329,6 +329,20 @@ fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeConfig) {
|
||||
g.writeln('function ${c.typ_name}__eq(self,other) { return ${c.eq}; } ')
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_nil_const() {
|
||||
g.writeln('const nil__ = new \$ref(new nil());')
|
||||
g.gen_builtin_prototype(
|
||||
typ_name: 'nil'
|
||||
val_name: 'str'
|
||||
default_value: 'new String("&nil")'
|
||||
constructor: 'this.str = str.toString(); this.len = this.str.length'
|
||||
value_of: 'null'
|
||||
to_string: '"&nil"'
|
||||
eq: 'new bool(self.valueOf() === other.valueOf())'
|
||||
to_jsval: 'null'
|
||||
)
|
||||
}
|
||||
|
||||
// generate builtin type definitions, used for casting and methods.
|
||||
fn (mut g JsGen) gen_builtin_type_defs() {
|
||||
g.inc_indent()
|
||||
|
@ -143,6 +143,7 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) stri
|
||||
graph.add(g.file.mod.name, imports)
|
||||
// builtin types
|
||||
if g.file.mod.name == 'builtin' && !g.generated_builtin {
|
||||
g.gen_nil_const()
|
||||
g.gen_builtin_type_defs()
|
||||
g.writeln('Object.defineProperty(array.prototype,"len", { get: function() {return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ')
|
||||
g.writeln('Object.defineProperty(map.prototype,"len", { get: function() {return new int(this.length);}, set: function(l) { } }); ')
|
||||
@ -965,7 +966,7 @@ fn (mut g JsGen) expr(node_ ast.Expr) {
|
||||
g.gen_lock_expr(node)
|
||||
}
|
||||
ast.Nil {
|
||||
g.write('null')
|
||||
g.write('nil__')
|
||||
}
|
||||
ast.NodeError {}
|
||||
ast.None {
|
||||
@ -1345,7 +1346,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||
g.expr(left)
|
||||
}
|
||||
|
||||
is_ptr := stmt.op == .assign && stmt.left_types[i].is_ptr() && !array_set
|
||||
is_ptr := stmt.op == .assign && stmt.right_types[i].is_ptr() && !array_set
|
||||
if is_ptr {
|
||||
g.write('.val')
|
||||
}
|
||||
|
74
vlib/v/gen/js/tests/unsafe.v
Normal file
74
vlib/v/gen/js/tests/unsafe.v
Normal file
@ -0,0 +1,74 @@
|
||||
struct Bar {
|
||||
value int
|
||||
}
|
||||
|
||||
struct Foo1 {
|
||||
mut:
|
||||
name &string
|
||||
}
|
||||
|
||||
struct Foo2 {
|
||||
mut:
|
||||
name ?&string
|
||||
}
|
||||
|
||||
struct Foo3 {
|
||||
mut:
|
||||
bar &Bar
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Basic test of assigning nil to a string pointer
|
||||
mut str := 'hi!'
|
||||
mut str_ptr := &str
|
||||
unsafe {
|
||||
str_ptr = nil
|
||||
}
|
||||
println(str_ptr) // should print '&nil'
|
||||
assert str_ptr == unsafe { nil }
|
||||
|
||||
// Test initializing a pointer field with nil
|
||||
f1 := Foo1{
|
||||
name: unsafe { nil }
|
||||
}
|
||||
assert f1.name == unsafe { nil }
|
||||
|
||||
// Test assigning nil to an optional pointer field
|
||||
mut f2 := Foo2{}
|
||||
unsafe {
|
||||
f2.name = nil
|
||||
}
|
||||
if f2.name != none {
|
||||
assert f2.name == unsafe { nil }
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
|
||||
// Test assigning nil to a struct pointer
|
||||
mut f3 := &Foo2{}
|
||||
unsafe {
|
||||
f3 = nil
|
||||
}
|
||||
assert f3 == unsafe { nil }
|
||||
|
||||
// Test with custom struct fields
|
||||
mut f4 := Foo3{
|
||||
bar: &Bar{42}
|
||||
}
|
||||
unsafe {
|
||||
f4.bar = nil
|
||||
}
|
||||
assert f4.bar == unsafe { nil }
|
||||
|
||||
// Test with nil pointers in arrays
|
||||
mut ptrs := []&string{len: 3, init: unsafe { nil }}
|
||||
p0, p1 := 'hello', 'world'
|
||||
ptrs[0] = &p0
|
||||
ptrs[1] = &p1
|
||||
unsafe {
|
||||
ptrs[2] = nil
|
||||
}
|
||||
assert ptrs[0] != unsafe { nil }
|
||||
assert ptrs[1] != unsafe { nil }
|
||||
assert ptrs[2] == unsafe { nil }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user