js: fix interfaces behaviour & disable struct deep copy for now (#12333)
parent
d33f7d12f7
commit
a32dae335a
|
@ -2,6 +2,6 @@ Drawing with mouse events using DOM API. Adopted from MDN examples.
|
|||
|
||||
# Compiling
|
||||
```
|
||||
v -b js_browser examples/js_dom_draw/draw.v
|
||||
v -b js_browser examples/js_dom_draw/draw.js.v
|
||||
```
|
||||
Then you can open `index.html` with your favourite browser.
|
||||
|
|
|
@ -27,8 +27,14 @@ fn draw_line(context ctx.CanvasRenderingContext2D, x1 int, y1 int, x2 int, y2 in
|
|||
context.close_path()
|
||||
}
|
||||
|
||||
struct DrawState {
|
||||
mut:
|
||||
drawing bool
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
/*
|
||||
document := jsdom.document
|
||||
|
||||
elem := document.get_element_by_id('myButton') ?
|
||||
|
@ -36,39 +42,36 @@ fn main() {
|
|||
canv := jsdom.get_html_canvas_element(elemc) or { panic('expected canvas') }
|
||||
|
||||
context := get_2dcontext(canv) or { panic('wow') }
|
||||
mut drawing := false
|
||||
mut x := int(0)
|
||||
mut y := int(0)
|
||||
canv.add_event_listener('mousedown', fn [mut drawing, mut x, mut y] (_ jsdom.IEventTarget, event jsdom.IEvent) {
|
||||
drawing = true
|
||||
mut state := DrawState{}
|
||||
canv.add_event_listener('mousedown', fn [mut state] (_ jsdom.IEventTarget, event jsdom.IEvent) {
|
||||
state.drawing = true
|
||||
if event is jsdom.MouseEvent {
|
||||
x = event.offset_x()
|
||||
y = event.offset_y()
|
||||
state.x = event.offset_x()
|
||||
state.y = event.offset_y()
|
||||
}
|
||||
})
|
||||
|
||||
canv.add_event_listener('mousemove', fn [context, drawing, mut x, mut y] (_ jsdom.IEventTarget, event jsdom.IEvent) {
|
||||
if drawing {
|
||||
canv.add_event_listener('mousemove', fn [context, mut state] (_ jsdom.IEventTarget, event jsdom.IEvent) {
|
||||
if state.drawing {
|
||||
if event is jsdom.MouseEvent {
|
||||
draw_line(context, x, y, event.offset_x(), event.offset_y())
|
||||
x = event.offset_x()
|
||||
y = event.offset_y()
|
||||
draw_line(context, state.x, state.y, event.offset_x(), event.offset_y())
|
||||
state.x = event.offset_x()
|
||||
state.y = event.offset_y()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
jsdom.window.add_event_listener('mouseup', fn [context, mut drawing, mut x, mut y] (_ jsdom.IEventTarget, event jsdom.IEvent) {
|
||||
if drawing {
|
||||
jsdom.window.add_event_listener('mouseup', fn [context, mut state] (_ jsdom.IEventTarget, event jsdom.IEvent) {
|
||||
if state.drawing {
|
||||
if event is jsdom.MouseEvent {
|
||||
draw_line(context, x, y, event.offset_x(), event.offset_y())
|
||||
draw_line(context, state.x, state.y, event.offset_x(), event.offset_y())
|
||||
}
|
||||
x = 0
|
||||
y = 0
|
||||
drawing = false
|
||||
state.x = 0
|
||||
state.y = 0
|
||||
state.drawing = false
|
||||
}
|
||||
})
|
||||
elem.add_event_listener('click', fn [context, canv] (_ jsdom.IEventTarget, _ jsdom.IEvent) {
|
||||
context.clear_rect(0, 0, canv.width(), canv.height())
|
||||
})
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ fn (mut g JsGen) get_str_fn(typ ast.Type) string {
|
|||
unwrapped = ast.u64_type
|
||||
}
|
||||
}
|
||||
|
||||
if typ.has_flag(.optional) {
|
||||
unwrapped.set_flag(.optional)
|
||||
}
|
||||
|
@ -50,6 +51,9 @@ fn (mut g JsGen) final_gen_str(typ StrType) {
|
|||
return
|
||||
}
|
||||
styp := typ.styp
|
||||
if styp == 'any' {
|
||||
return
|
||||
}
|
||||
str_fn_name := styp_to_str_fn_name(styp)
|
||||
if typ.typ.has_flag(.optional) {
|
||||
g.gen_str_for_option(typ.typ, styp, str_fn_name)
|
||||
|
@ -346,37 +350,25 @@ fn (mut g JsGen) gen_str_for_interface(info ast.Interface, styp string, str_fn_n
|
|||
for typ in info.types {
|
||||
subtype := g.table.get_type_symbol(typ)
|
||||
mut func_name := g.get_str_fn(typ)
|
||||
sym_has_str_method, _, _ := subtype.str_method_info()
|
||||
sym_has_str_method, str_method_expects_ptr, _ := subtype.str_method_info()
|
||||
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
|
||||
func_name = 'indent_$func_name'
|
||||
}
|
||||
|
||||
deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '.valueOf()' }
|
||||
// str_intp
|
||||
|
||||
if typ == ast.string_type {
|
||||
/*
|
||||
mut val := '${func_name}(${deref}($subtype.cname*)x._$subtype.cname'
|
||||
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
|
||||
val += ', indent_count'
|
||||
}
|
||||
val += ')'
|
||||
val = val
|
||||
*/
|
||||
res := '"TODO"'
|
||||
fn_builder.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
|
||||
fn_builder.write_string(' return $res;')
|
||||
fn_builder.write_string('\tif (x.val instanceof string)')
|
||||
fn_builder.write_string(' return "new string(${clean_interface_v_type_name}(" + x.val.str + ")");')
|
||||
} else {
|
||||
/*
|
||||
mut val := '${func_name}(${deref}($subtype.cname*)x._$subtype.cname'
|
||||
mut val := '${func_name}(x $deref'
|
||||
if should_use_indent_func(subtype.kind) && !sym_has_str_method {
|
||||
val += ', indent_count'
|
||||
}
|
||||
val += ')'
|
||||
val = val
|
||||
*/
|
||||
res := '"TODO'
|
||||
fn_builder.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
|
||||
fn_builder.write_string(' return $res;\n')
|
||||
|
||||
fn_builder.write_string('\tif (x.val instanceof $subtype.cname)')
|
||||
fn_builder.write_string(' return new string("${clean_interface_v_type_name}(" + ${val}.str + ")");\n')
|
||||
}
|
||||
}
|
||||
fn_builder.writeln('\treturn new string("unknown interface value");')
|
||||
|
|
|
@ -46,7 +46,7 @@ fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
|
|||
styp = 'new ${g.js_name(sym.name)}(${g.to_js_typ_def_val(sym.name)})'
|
||||
}
|
||||
.voidptr {
|
||||
styp = 'null'
|
||||
styp = 'new voidptr(null)'
|
||||
}
|
||||
else {
|
||||
// TODO
|
||||
|
@ -108,7 +108,7 @@ fn (mut g JsGen) sym_to_js_typ(sym ast.TypeSymbol) string {
|
|||
styp = 'array'
|
||||
}
|
||||
.voidptr {
|
||||
styp = 'any'
|
||||
styp = 'voidptr'
|
||||
}
|
||||
.rune {
|
||||
styp = 'rune'
|
||||
|
@ -137,7 +137,7 @@ fn (mut g JsGen) base_type(_t ast.Type) string {
|
|||
pub fn (mut g JsGen) typ(t ast.Type) string {
|
||||
sym := g.table.get_final_type_symbol(t)
|
||||
if sym.kind == .voidptr {
|
||||
return 'any'
|
||||
return 'voidptr'
|
||||
}
|
||||
|
||||
styp := g.base_type(t)
|
||||
|
@ -157,7 +157,7 @@ pub fn (mut g JsGen) doc_typ(t ast.Type) string {
|
|||
styp = 'void'
|
||||
}
|
||||
.voidptr {
|
||||
styp = 'any'
|
||||
styp = 'voidptr'
|
||||
}
|
||||
.byteptr, .charptr {
|
||||
styp = '${g.sym_to_js_typ(sym)}'
|
||||
|
@ -438,6 +438,18 @@ fn (mut g JsGen) gen_builtin_type_defs() {
|
|||
to_jsval: 'this.arr'
|
||||
)
|
||||
}
|
||||
'voidptr' {
|
||||
g.gen_builtin_prototype(
|
||||
typ_name: typ_name
|
||||
val_name: 'val'
|
||||
default_value: 'null'
|
||||
constructor: 'this.val = val;'
|
||||
value_of: 'this'
|
||||
to_string: '"voidptr(" + this.val + ")"'
|
||||
eq: 'this.val === other.val'
|
||||
to_jsval: 'this.val'
|
||||
)
|
||||
}
|
||||
'any' {
|
||||
g.gen_builtin_prototype(
|
||||
typ_name: typ_name
|
||||
|
|
|
@ -155,15 +155,32 @@ fn (mut g JsGen) gen_copy_for_struct(info ast.Struct, styp string, copy_fn_name
|
|||
g.definitions.writeln(fn_builder.str())
|
||||
}
|
||||
|
||||
fn_builder.writeln('function ${copy_fn_name}(it) {')
|
||||
fn_builder.writeln('function ${copy_fn_name}(it) { return it }')
|
||||
|
||||
/*
|
||||
tmp := g.new_tmp_var()
|
||||
fn_builder.writeln('\tlet $tmp = new ${styp}({});')
|
||||
for field in info.fields {
|
||||
println(field)
|
||||
if field.name.len == 0 {
|
||||
|
||||
} else {
|
||||
mut shall_copy := true
|
||||
for attr in field.attrs {
|
||||
if attr.name == 'noinit' {
|
||||
shall_copy = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if shall_copy {
|
||||
func_name := g.get_copy_fn(field.typ)
|
||||
fn_builder.writeln('\t${tmp}.$field.name = ${func_name}(it.$field.name);')
|
||||
} else {
|
||||
fn_builder.writeln('\t${tmp}.$field.name = it.$field.name')
|
||||
}
|
||||
fn_builder.writeln('\treturn $tmp;\n}')
|
||||
}
|
||||
}
|
||||
fn_builder.writeln('\treturn $tmp;\n}')*/
|
||||
}
|
||||
|
||||
fn (mut g JsGen) final_gen_copy(typ StrType) {
|
||||
|
@ -181,9 +198,9 @@ fn (mut g JsGen) final_gen_copy(typ StrType) {
|
|||
g.gen_copy_for_option(typ.typ, styp, copy_fn_name)
|
||||
return
|
||||
}
|
||||
match sym.kind {
|
||||
.byte, .u8, .u16, .u32, .u64, .i16, .int, .i64, .isize, .usize, .bool, .int_literal,
|
||||
.float_literal, .f32, .f64 {
|
||||
match styp {
|
||||
'byte', 'u8', 'u16', 'u32', 'u64', 'i16', 'int', 'i64', 'isize', 'usize', 'bool',
|
||||
'int_literal', 'float_literal', 'f32', 'f64', 'voidptr' {
|
||||
g.definitions.writeln('function ${sym.cname}_\$copy(it) { return new ${sym.cname}(it.val); }')
|
||||
return
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ const (
|
|||
'Array', 'Map', 'document']
|
||||
// used to generate type structs
|
||||
v_types = ['i8', 'i16', 'int', 'i64', 'byte', 'u16', 'u32', 'u64', 'f32', 'f64',
|
||||
'int_literal', 'float_literal', 'bool', 'string', 'map', 'array', 'rune', 'any']
|
||||
'int_literal', 'float_literal', 'bool', 'string', 'map', 'array', 'rune', 'any', 'voidptr']
|
||||
shallow_equatables = [ast.Kind.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64,
|
||||
.int_literal, .float_literal, .bool, .string]
|
||||
)
|
||||
|
@ -1709,7 +1709,7 @@ fn (mut g JsGen) gen_interface_decl(it ast.InterfaceDecl) {
|
|||
// TODO: interfaces are always `pub`?
|
||||
name := g.js_name(it.name)
|
||||
g.push_pub_var('/** @type $name */\n\t\t$name')
|
||||
g.writeln('function ${g.js_name(it.name)} (arg) { return arg; }')
|
||||
g.writeln('function ${g.js_name(it.name)} (arg) { return new \$ref(arg); }')
|
||||
}
|
||||
|
||||
fn (mut g JsGen) gen_optional_error(expr ast.Expr) {
|
||||
|
@ -2335,6 +2335,7 @@ fn (mut g JsGen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var M
|
|||
g.write(' instanceof ')
|
||||
g.expr(branch.exprs[sumtype_index])
|
||||
} else if sym.kind == .interface_ {
|
||||
g.write('.val')
|
||||
if branch.exprs[sumtype_index] is ast.TypeNode {
|
||||
g.write(' instanceof ')
|
||||
g.expr(branch.exprs[sumtype_index])
|
||||
|
|
Loading…
Reference in New Issue